@paprflare/tally 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types/result.ts","../src/types/ledger.ts","../src/types/voucher.ts","../src/xml/envelope.ts","../src/xml/builders/ledger.ts","../src/xml/builders/voucher.ts","../src/xml/builders/collection.ts","../src/xml/parsers/response-parser.ts","../src/xml/parsers/collection-parser.ts","../src/tally/transport.ts","../src/tally/client.ts"],"names":["err","z","parser","XMLParser"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Tally's HTTP layer is not a reliable signal of success. A failed voucher\r\n * import still comes back as HTTP 200 with a <LINEERROR> buried in the body.\r\n * Network failures, XML parse failures, and Tally-side rejections are three\r\n * different failure classes with three different recovery strategies (retry,\r\n * fix-your-builder-bug, fix-your-data) — so we keep them as distinct codes\r\n * instead of collapsing everything into a generic Error.\r\n */\r\nexport type TallyErrorCode =\r\n | \"NETWORK_ERROR\" // request never reached Tally, or Tally never responded — safe to retry\r\n | \"TIMEOUT\" // request sent, no response within the configured window — retry with caution (may have applied)\r\n | \"PARSE_ERROR\" // Tally responded, but the XML didn't match any known shape — SDK bug or Tally version drift\r\n | \"TALLY_REJECTED\" // Tally understood the request and rejected it (LINEERROR) — do not retry as-is\r\n | \"VALIDATION_ERROR\" // the input never left the process — caught by the Zod schema before XML was built\r\n | \"NOT_FOUND\" // a get-by-name lookup returned no matching object\r\n | \"UNKNOWN\";\r\n\r\nexport interface TallyError {\r\n code: TallyErrorCode;\r\n message: string;\r\n /** Raw <LINEERROR> text from Tally, when code === \"TALLY_REJECTED\" */\r\n tallyMessage?: string;\r\n /** The XML request body that produced this error, kept for debugging/logging */\r\n requestXml?: string;\r\n /** The raw XML response body, when one was received */\r\n responseXml?: string;\r\n /** Underlying cause (e.g. an AxiosError, a ZodError), for stack traces */\r\n cause?: unknown;\r\n}\r\n\r\nexport type Result<T, E = TallyError> =\r\n | { ok: true; value: T }\r\n | { ok: false; error: E };\r\n\r\nexport function ok<T>(value: T): Result<T, never> {\r\n return { ok: true, value };\r\n}\r\n\r\nexport function err<E = TallyError>(error: E): Result<never, E> {\r\n return { ok: false, error };\r\n}\r\n\r\nexport function tallyError(\r\n code: TallyErrorCode,\r\n message: string,\r\n extra?: Partial<Omit<TallyError, \"code\" | \"message\">>\r\n): TallyError {\r\n return { code, message, ...extra };\r\n}\r\n\r\n/** Narrow a Result to its value, or throw — for callers who'd rather not\r\n * thread Result through their own code. Named unwrap (not \"get\") so misuse\r\n * is obvious at the call site. */\r\nexport function unwrap<T>(result: Result<T, TallyError>): T {\r\n if (result.ok) return result.value;\r\n const err = result.error;\r\n const e = new Error(`[${err.code}] ${err.message}`);\r\n (e as Error & { cause?: unknown }).cause = err.cause ?? err;\r\n throw e;\r\n}\r\n\r\nexport interface TallyConfig {\r\n host: string;\r\n port: number;\r\n /** Defaults to false; set true only for instances behind TLS termination */\r\n https?: boolean;\r\n /** Defaults to the active company in Tally if omitted */\r\n company?: string;\r\n /** Request timeout in ms; Tally can be slow on large COLLECTION exports */\r\n timeoutMs?: number;\r\n /** Retries on NETWORK_ERROR/TIMEOUT only — never on TALLY_REJECTED */\r\n retries?: number;\r\n}","import { z } from \"zod\";\r\n\r\n/**\r\n * GSTIN format check is intentionally loose (Tally itself doesn't hard-reject\r\n * malformed GSTINs on import, it just stores what you give it) — we validate\r\n * shape, not checksum, to avoid the SDK rejecting valid-but-unusual entries\r\n * (e.g. SEZ/UN body GSTINs) that a strict regex would choke on.\r\n */\r\nconst gstinSchema = z\r\n .string()\r\n .regex(\r\n /^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z]{1}[1-9A-Z]{1}Z[0-9A-Z]{1}$/,\r\n \"Invalid GSTIN format\",\r\n )\r\n .optional();\r\n\r\nexport const LedgerInputSchema = z.object({\r\n name: z.string().min(1),\r\n /** Tally group name, e.g. \"Sundry Debtors\", \"Sundry Creditors\", \"Bank Accounts\" */\r\n group: z.string().min(1),\r\n gstin: gstinSchema,\r\n openingBalance: z.number().optional(),\r\n /** \"Debit\" | \"Credit\" — required by Tally when openingBalance is set */\r\n openingBalanceType: z.enum([\"Debit\", \"Credit\"]).optional(),\r\n address: z.array(z.string()).optional(),\r\n state: z.string().optional(),\r\n pincode: z.string().optional(),\r\n email: z.string().email().optional(),\r\n phone: z.string().optional(),\r\n});\r\nexport type LedgerInput = z.infer<typeof LedgerInputSchema>;\r\n\r\nexport const LedgerSchema = z.object({\r\n name: z.string(),\r\n guid: z.string(),\r\n group: z.string(),\r\n gstin: z.string().optional(),\r\n /** Signed: positive = debit balance, negative = credit balance (normalized\r\n * at the parser layer — Tally's raw XML encodes sign via a separate\r\n * DR/CR-style attribute, never as a literal minus on the export). */\r\n closingBalance: z.number().optional(),\r\n state: z.string().optional(),\r\n});\r\nexport type Ledger = z.infer<typeof LedgerSchema>;\r\n\r\nexport const StockItemSchema = z.object({\r\n name: z.string(),\r\n guid: z.string(),\r\n unit: z.string(),\r\n closingQty: z.number().optional(),\r\n closingValue: z.number().optional(),\r\n /** HSN/SAC code, when GST is enabled in the company */\r\n hsnCode: z.string().optional(),\r\n gstRate: z.number().optional(),\r\n});\r\nexport type StockItem = z.infer<typeof StockItemSchema>;\r\n\r\nexport const StockItemInputSchema = z.object({\r\n name: z.string().min(1),\r\n /** Tally stock group name, e.g. \"Primary\" */\r\n group: z.string().default(\"Primary\"),\r\n unit: z.string().min(1),\r\n hsnCode: z.string().optional(),\r\n gstRate: z.number().optional(),\r\n openingQty: z.number().optional(),\r\n openingRate: z.number().optional(),\r\n});\r\nexport type StockItemInput = z.infer<typeof StockItemInputSchema>;\r\n\r\nexport const CompanySchema = z.object({\r\n name: z.string(),\r\n guid: z.string(),\r\n startingFrom: z.string().optional(),\r\n endingAt: z.string().optional(),\r\n});\r\nexport type Company = z.infer<typeof CompanySchema>;\r\n\r\nexport const OutstandingEntrySchema = z.object({\r\n ledgerName: z.string(),\r\n voucherNumber: z.string(),\r\n voucherDate: z.coerce.date(),\r\n dueDate: z.coerce.date().optional(),\r\n /** Positive = they owe you, negative = you owe them */\r\n pendingAmount: z.number(),\r\n overdueDays: z.number().optional(),\r\n});\r\nexport type OutstandingEntry = z.infer<typeof OutstandingEntrySchema>;\r\n","import { z } from \"zod\";\r\n\r\n/**\r\n * Tally treats \"voucher\" as one umbrella concept, but Sales/Purchase vouchers\r\n * are item+ledger hybrids (stock movement AND money movement) while\r\n * Payment/Receipt/Journal are pure ledger-to-ledger entries. Modeling all\r\n * five as one flat object either makes every field optional (so TypeScript\r\n * can't catch \"Sales voucher missing items\") or forces five near-duplicate\r\n * interfaces with no shared base.\r\n *\r\n * Instead: a shared base schema for fields every voucher has, extended by a\r\n * discriminated union on `voucherType` so each variant only carries the\r\n * fields that are actually valid for it, and the XML builder's switch\r\n * statement gets exhaustiveness-checked by the compiler (see\r\n * packages/xml/src/builders/voucher.ts).\r\n */\r\n\r\nconst baseVoucherFields = {\r\n date: z.coerce.date(),\r\n narration: z.string().optional(),\r\n /** Tally auto-numbers if omitted; only set this if you're syncing from an\r\n * external system that owns numbering (e.g. an e-invoice generator). */\r\n voucherNumber: z.string().optional(),\r\n reference: z.string().optional(),\r\n};\r\n\r\nconst lineItemSchema = z.object({\r\n /** Must match an existing Tally stock item name exactly (case-sensitive) */\r\n stockItem: z.string().min(1),\r\n quantity: z.number().positive(),\r\n rate: z.number().nonnegative(),\r\n /** Defaults to quantity * rate; pass explicitly to override rounding */\r\n amount: z.number().optional(),\r\n});\r\nexport type LineItem = z.infer<typeof lineItemSchema>;\r\n\r\nconst taxLedgerSchema = z.object({\r\n /** e.g. \"Output CGST\", \"Output SGST\", \"Output IGST\" — must exist in Tally */\r\n ledger: z.string().min(1),\r\n amount: z.number(),\r\n});\r\n\r\nexport const SalesVoucherInputSchema = z.object({\r\n voucherType: z.literal(\"Sales\"),\r\n ...baseVoucherFields,\r\n /** Sundry Debtor ledger name being billed */\r\n party: z.string().min(1),\r\n items: z.array(lineItemSchema).min(1),\r\n /** Sales/revenue ledger to credit; defaults to \"Sales\" */\r\n salesLedger: z.string().default(\"Sales\"),\r\n taxes: z.array(taxLedgerSchema).optional(),\r\n});\r\nexport type SalesVoucherInput = z.infer<typeof SalesVoucherInputSchema>;\r\n\r\nexport const PurchaseVoucherInputSchema = z.object({\r\n voucherType: z.literal(\"Purchase\"),\r\n ...baseVoucherFields,\r\n /** Sundry Creditor ledger name being paid */\r\n party: z.string().min(1),\r\n items: z.array(lineItemSchema).min(1),\r\n purchaseLedger: z.string().default(\"Purchase\"),\r\n taxes: z.array(taxLedgerSchema).optional(),\r\n});\r\nexport type PurchaseVoucherInput = z.infer<typeof PurchaseVoucherInputSchema>;\r\n\r\nexport const PaymentVoucherInputSchema = z.object({\r\n voucherType: z.literal(\"Payment\"),\r\n ...baseVoucherFields,\r\n /** Ledger being debited — typically an expense or a creditor being paid off */\r\n debitLedger: z.string().min(1),\r\n /** Bank or Cash ledger being credited */\r\n creditLedger: z.string().min(1),\r\n amount: z.number().positive(),\r\n});\r\nexport type PaymentVoucherInput = z.infer<typeof PaymentVoucherInputSchema>;\r\n\r\nexport const ReceiptVoucherInputSchema = z.object({\r\n voucherType: z.literal(\"Receipt\"),\r\n ...baseVoucherFields,\r\n /** Bank or Cash ledger being debited */\r\n debitLedger: z.string().min(1),\r\n /** Ledger being credited — typically the debtor paying you */\r\n creditLedger: z.string().min(1),\r\n amount: z.number().positive(),\r\n});\r\nexport type ReceiptVoucherInput = z.infer<typeof ReceiptVoucherInputSchema>;\r\n\r\nconst journalEntrySchema = z.object({\r\n ledger: z.string().min(1),\r\n type: z.enum([\"Debit\", \"Credit\"]),\r\n amount: z.number().positive(),\r\n});\r\n\r\nexport const JournalVoucherInputSchema = z\r\n .object({\r\n voucherType: z.literal(\"Journal\"),\r\n ...baseVoucherFields,\r\n entries: z.array(journalEntrySchema).min(2),\r\n })\r\n .refine(\r\n (v) => {\r\n const debit = v.entries\r\n .filter((e) => e.type === \"Debit\")\r\n .reduce((s, e) => s + e.amount, 0);\r\n const credit = v.entries\r\n .filter((e) => e.type === \"Credit\")\r\n .reduce((s, e) => s + e.amount, 0);\r\n // float-safe equality\r\n return Math.abs(debit - credit) < 0.005;\r\n },\r\n { message: \"Journal voucher debit and credit totals must balance\" },\r\n );\r\nexport type JournalVoucherInput = z.infer<typeof JournalVoucherInputSchema>;\r\n\r\nexport const VoucherInputSchema = z.discriminatedUnion(\"voucherType\", [\r\n SalesVoucherInputSchema,\r\n PurchaseVoucherInputSchema,\r\n PaymentVoucherInputSchema,\r\n ReceiptVoucherInputSchema,\r\n // Journal isn't included directly here because z.discriminatedUnion can't\r\n // take a refined (ZodEffects) member — see VoucherInput union type below\r\n // and validateVoucherInput() in client.ts, which validates Journal\r\n // separately via JournalVoucherInputSchema.\r\n]);\r\n\r\nexport type VoucherInput =\r\n | SalesVoucherInput\r\n | PurchaseVoucherInput\r\n | PaymentVoucherInput\r\n | ReceiptVoucherInput\r\n | JournalVoucherInput;\r\n\r\n/** Exhaustiveness helper: pass an unreachable VoucherInput here in a\r\n * `default` switch branch — if a new voucher type is added to the union\r\n * without updating the builder, this fails to compile instead of failing at\r\n * runtime in front of a customer. */\r\nexport function assertNever(x: never): never {\r\n throw new Error(`Unhandled voucher type: ${JSON.stringify(x)}`);\r\n}\r\n\r\nexport interface VoucherCreateResult {\r\n voucherNumber: string;\r\n guid: string;\r\n alteredOn: Date;\r\n}\r\n","/**\r\n * Tally's XML is XML-shaped but not XML-clean. Two encoding quirks matter\r\n * enough to centralize here rather than handle ad hoc in every builder:\r\n *\r\n * 1. Standard XML entities (&, <, >, \", ') still need escaping — Tally's\r\n * parser is otherwise normal on that front.\r\n * 2. Tally has its own non-standard \"empty but present\" marker, &#4;, used\r\n * in some master-import contexts to distinguish \"field omitted\" from\r\n * \"field explicitly cleared\". We expose escapeXml() for normal text and\r\n * leave &#4; as an explicit opt-in (EMPTY_MARKER) so builders don't emit\r\n * it by accident.\r\n */\r\n\r\nexport const EMPTY_MARKER = \"&#4;\";\r\n\r\nexport function escapeXml(value: string): string {\r\n return value\r\n .replace(/&/g, \"&amp;\")\r\n .replace(/</g, \"&lt;\")\r\n .replace(/>/g, \"&gt;\")\r\n .replace(/\"/g, \"&quot;\")\r\n .replace(/'/g, \"&apos;\");\r\n}\r\n\r\n/** Tally dates are YYYYMMDD with no separators, always. */\r\nexport function formatTallyDate(date: Date): string {\r\n const y = date.getFullYear();\r\n const m = String(date.getMonth() + 1).padStart(2, \"0\");\r\n const d = String(date.getDate()).padStart(2, \"0\");\r\n return `${y}${m}${d}`;\r\n}\r\n\r\n/**\r\n * Tally renders negative ledger amounts as a sign on the number, but which\r\n * sign means debit vs credit flips depending on whether you're looking at a\r\n * Sales-side or Purchase-side ledger entry. Rather than push that\r\n * ambiguity onto every builder, callers pass an explicit `isDebit` flag and\r\n * this function produces the signed string Tally expects: debit entries are\r\n * positive, credit entries are negative, full stop, at the wire level.\r\n */\r\nexport function formatSignedAmount(amount: number, isDebit: boolean): string {\r\n const magnitude = Math.abs(amount).toFixed(2);\r\n return isDebit ? magnitude : `-${magnitude}`;\r\n}\r\n\r\nexport type EnvelopeRequestType = \"Import Data\" | \"Export Data\";\r\n\r\nexport interface EnvelopeOptions {\r\n requestType: EnvelopeRequestType;\r\n /** \"Vouchers\" | \"Masters\" | \"Collection\" | \"Company\" — Tally's REPORTNAME/ID context */\r\n id: string;\r\n company?: string;\r\n staticVariables?: Record<string, string>;\r\n}\r\n\r\n/**\r\n * Wraps an inner payload in Tally's outer envelope. This is the one place\r\n * both sublanguages meet — everything sublanguage-specific lives in the\r\n * builders that call this, not in here.\r\n *\r\n * Import (write) requests use <IMPORTDATA> and carry the actual master/\r\n * voucher XML inside <REQUESTDATA>. Export (read/collection) requests use\r\n * <EXPORTDATA> and have no REQUESTDATA section at all — the field list comes\r\n * from the report/collection definition Tally already knows about via\r\n * REPORTNAME, not from anything we send. Passing bodyXml on an export\r\n * request is a no-op by design, not an oversight.\r\n */\r\nexport function buildEnvelope(\r\n options: EnvelopeOptions,\r\n bodyXml?: string,\r\n): string {\r\n const staticVars = {\r\n ...(options.company ? { SVCURRENTCOMPANY: options.company } : {}),\r\n ...(options.staticVariables ?? {}),\r\n };\r\n\r\n const staticVarsXml = Object.entries(staticVars)\r\n .map(([key, value]) => `<${key}>${escapeXml(value)}</${key}>`)\r\n .join(\"\");\r\n\r\n const isImport = options.requestType === \"Import Data\";\r\n const sectionTag = isImport ? \"IMPORTDATA\" : \"EXPORTDATA\";\r\n\r\n return (\r\n `<ENVELOPE>` +\r\n `<HEADER><TALLYREQUEST>${escapeXml(options.requestType)}</TALLYREQUEST></HEADER>` +\r\n `<BODY>` +\r\n `<${sectionTag}>` +\r\n `<REQUESTDESC>` +\r\n `<REPORTNAME>${escapeXml(options.id)}</REPORTNAME>` +\r\n (staticVarsXml\r\n ? `<STATICVARIABLES>${staticVarsXml}</STATICVARIABLES>`\r\n : \"\") +\r\n `</REQUESTDESC>` +\r\n (isImport && bodyXml ? `<REQUESTDATA>${bodyXml}</REQUESTDATA>` : \"\") +\r\n `</${sectionTag}>` +\r\n `</BODY>` +\r\n `</ENVELOPE>`\r\n );\r\n}\r\n","import type { LedgerInput, StockItemInput } from \"../../types/ledger.js\";\r\nimport { escapeXml } from \"../envelope.js\";\r\n\r\n/**\r\n * Tally master imports are wrapped in a TALLYMESSAGE envelope, with the\r\n * object's NAME duplicated as both an XML attribute on the tag (how Tally\r\n * identifies *which* object this is, for upsert-by-name semantics) and as a\r\n * <NAME> child element (how Tally reads the field value). Forgetting either\r\n * one is a common hand-rolled-XML bug this builder exists to make\r\n * impossible.\r\n */\r\nexport function buildCreateLedgerXml(input: LedgerInput): string {\r\n const addressXml = (input.address ?? [])\r\n .map((line) => `<ADDRESS>${escapeXml(line)}</ADDRESS>`)\r\n .join(\"\");\r\n\r\n const openingBalanceXml =\r\n input.openingBalance != null\r\n ? `<OPENINGBALANCE>${\r\n input.openingBalanceType === \"Credit\" ? \"-\" : \"\"\r\n }${Math.abs(input.openingBalance).toFixed(2)}</OPENINGBALANCE>`\r\n : \"\";\r\n\r\n return (\r\n `<TALLYMESSAGE xmlns:UDF=\"TallyUDF\">` +\r\n `<LEDGER NAME=\"${escapeXml(input.name)}\" ACTION=\"Create\">` +\r\n `<NAME>${escapeXml(input.name)}</NAME>` +\r\n `<PARENT>${escapeXml(input.group)}</PARENT>` +\r\n (input.gstin ? `<GSTIN>${escapeXml(input.gstin)}</GSTIN>` : \"\") +\r\n (input.state\r\n ? `<LEDSTATENAME>${escapeXml(input.state)}</LEDSTATENAME>`\r\n : \"\") +\r\n (input.pincode ? `<PINCODE>${escapeXml(input.pincode)}</PINCODE>` : \"\") +\r\n openingBalanceXml +\r\n addressXml +\r\n (input.email ? `<EMAIL>${escapeXml(input.email)}</EMAIL>` : \"\") +\r\n (input.phone\r\n ? `<LEDGERPHONE>${escapeXml(input.phone)}</LEDGERPHONE>`\r\n : \"\") +\r\n `</LEDGER>` +\r\n `</TALLYMESSAGE>`\r\n );\r\n}\r\n\r\nexport function buildCreateStockItemXml(input: StockItemInput): string {\r\n const openingXml =\r\n input.openingQty != null\r\n ? `<OPENINGBALANCE>${input.openingQty} ${escapeXml(input.unit)}</OPENINGBALANCE>` +\r\n (input.openingRate != null\r\n ? `<OPENINGRATE>${input.openingRate.toFixed(2)}/${escapeXml(input.unit)}</OPENINGRATE>` +\r\n `<OPENINGVALUE>${(input.openingQty * input.openingRate).toFixed(2)}</OPENINGVALUE>`\r\n : \"\")\r\n : \"\";\r\n\r\n return (\r\n `<TALLYMESSAGE xmlns:UDF=\"TallyUDF\">` +\r\n `<STOCKITEM NAME=\"${escapeXml(input.name)}\" ACTION=\"Create\">` +\r\n `<NAME>${escapeXml(input.name)}</NAME>` +\r\n `<PARENT>${escapeXml(input.group)}</PARENT>` +\r\n `<BASEUNITS>${escapeXml(input.unit)}</BASEUNITS>` +\r\n (input.hsnCode ? `<HSNCODE>${escapeXml(input.hsnCode)}</HSNCODE>` : \"\") +\r\n (input.gstRate != null ? `<GSTRATE>${input.gstRate}</GSTRATE>` : \"\") +\r\n openingXml +\r\n `</STOCKITEM>` +\r\n `</TALLYMESSAGE>`\r\n );\r\n}\r\n","import type {\r\n VoucherInput,\r\n SalesVoucherInput,\r\n PurchaseVoucherInput,\r\n PaymentVoucherInput,\r\n ReceiptVoucherInput,\r\n JournalVoucherInput,\r\n LineItem,\r\n} from \"../../types/voucher.js\";\r\nimport { assertNever } from \"../../types/voucher.js\";\r\nimport { escapeXml, formatTallyDate, formatSignedAmount } from \"../envelope.js\";\r\n\r\nfunction lineItemAmount(item: LineItem): number {\r\n return item.amount ?? item.quantity * item.rate;\r\n}\r\n\r\nfunction buildInventoryEntryXml(item: LineItem, isDebit: boolean): string {\r\n // Inventory entries carry both the ledger-side signed AMOUNT and the\r\n // physical ACTUALQTY/BILLEDQTY — these are allowed to diverge (e.g. free\r\n // samples), but for the common case they're the same quantity.\r\n const qty = `${item.quantity}`;\r\n return (\r\n `<ALLINVENTORYENTRIES.LIST>` +\r\n `<STOCKITEMNAME>${escapeXml(item.stockItem)}</STOCKITEMNAME>` +\r\n `<ISDEEMEDPOSITIVE>${isDebit ? \"Yes\" : \"No\"}</ISDEEMEDPOSITIVE>` +\r\n `<RATE>${item.rate.toFixed(2)}</RATE>` +\r\n `<AMOUNT>${formatSignedAmount(lineItemAmount(item), isDebit)}</AMOUNT>` +\r\n `<ACTUALQTY>${qty}</ACTUALQTY>` +\r\n `<BILLEDQTY>${qty}</BILLEDQTY>` +\r\n `</ALLINVENTORYENTRIES.LIST>`\r\n );\r\n}\r\n\r\nfunction buildLedgerEntryXml(\r\n ledgerName: string,\r\n amount: number,\r\n isDebit: boolean,\r\n): string {\r\n return (\r\n `<ALLLEDGERENTRIES.LIST>` +\r\n `<LEDGERNAME>${escapeXml(ledgerName)}</LEDGERNAME>` +\r\n `<ISDEEMEDPOSITIVE>${isDebit ? \"Yes\" : \"No\"}</ISDEEMEDPOSITIVE>` +\r\n `<AMOUNT>${formatSignedAmount(amount, isDebit)}</AMOUNT>` +\r\n `</ALLLEDGERENTRIES.LIST>`\r\n );\r\n}\r\n\r\nfunction buildSalesXml(input: SalesVoucherInput): string {\r\n const itemsTotal = input.items.reduce(\r\n (sum, item) => sum + lineItemAmount(item),\r\n 0,\r\n );\r\n const taxTotal = (input.taxes ?? []).reduce((sum, t) => sum + t.amount, 0);\r\n const partyTotal = itemsTotal + taxTotal;\r\n\r\n // Party ledger: debit, total including tax.\r\n // Sales ledger: credit, items subtotal — carries the inventory allocations.\r\n // Tax ledgers: credit, one per tax line (CGST/SGST/IGST).\r\n const partyEntry = buildLedgerEntryXml(input.party, partyTotal, true);\r\n const salesEntry =\r\n `<ALLLEDGERENTRIES.LIST>` +\r\n `<LEDGERNAME>${escapeXml(input.salesLedger)}</LEDGERNAME>` +\r\n `<ISDEEMEDPOSITIVE>No</ISDEEMEDPOSITIVE>` +\r\n `<AMOUNT>${formatSignedAmount(itemsTotal, false)}</AMOUNT>` +\r\n input.items.map((item) => buildInventoryEntryXml(item, false)).join(\"\") +\r\n `</ALLLEDGERENTRIES.LIST>`;\r\n const taxEntries = (input.taxes ?? [])\r\n .map((t) => buildLedgerEntryXml(t.ledger, t.amount, false))\r\n .join(\"\");\r\n\r\n return buildVoucherEnvelope({\r\n voucherTypeName: \"Sales\",\r\n date: input.date,\r\n narration: input.narration,\r\n voucherNumber: input.voucherNumber,\r\n reference: input.reference,\r\n isInvoice: true,\r\n partyName: input.party,\r\n body: partyEntry + salesEntry + taxEntries,\r\n });\r\n}\r\n\r\nfunction buildPurchaseXml(input: PurchaseVoucherInput): string {\r\n const itemsTotal = input.items.reduce(\r\n (sum, item) => sum + lineItemAmount(item),\r\n 0,\r\n );\r\n const taxTotal = (input.taxes ?? []).reduce((sum, t) => sum + t.amount, 0);\r\n const partyTotal = itemsTotal + taxTotal;\r\n\r\n // Mirror image of Sales: party is credited, purchase ledger is debited.\r\n const partyEntry = buildLedgerEntryXml(input.party, partyTotal, false);\r\n const purchaseEntry =\r\n `<ALLLEDGERENTRIES.LIST>` +\r\n `<LEDGERNAME>${escapeXml(input.purchaseLedger)}</LEDGERNAME>` +\r\n `<ISDEEMEDPOSITIVE>Yes</ISDEEMEDPOSITIVE>` +\r\n `<AMOUNT>${formatSignedAmount(itemsTotal, true)}</AMOUNT>` +\r\n input.items.map((item) => buildInventoryEntryXml(item, true)).join(\"\") +\r\n `</ALLLEDGERENTRIES.LIST>`;\r\n const taxEntries = (input.taxes ?? [])\r\n .map((t) => buildLedgerEntryXml(t.ledger, t.amount, true))\r\n .join(\"\");\r\n\r\n return buildVoucherEnvelope({\r\n voucherTypeName: \"Purchase\",\r\n date: input.date,\r\n narration: input.narration,\r\n voucherNumber: input.voucherNumber,\r\n reference: input.reference,\r\n isInvoice: true,\r\n partyName: input.party,\r\n body: partyEntry + purchaseEntry + taxEntries,\r\n });\r\n}\r\n\r\nfunction buildPaymentXml(input: PaymentVoucherInput): string {\r\n const body =\r\n buildLedgerEntryXml(input.debitLedger, input.amount, true) +\r\n buildLedgerEntryXml(input.creditLedger, input.amount, false);\r\n return buildVoucherEnvelope({\r\n voucherTypeName: \"Payment\",\r\n date: input.date,\r\n narration: input.narration,\r\n voucherNumber: input.voucherNumber,\r\n reference: input.reference,\r\n isInvoice: false,\r\n body,\r\n });\r\n}\r\n\r\nfunction buildReceiptXml(input: ReceiptVoucherInput): string {\r\n const body =\r\n buildLedgerEntryXml(input.debitLedger, input.amount, true) +\r\n buildLedgerEntryXml(input.creditLedger, input.amount, false);\r\n return buildVoucherEnvelope({\r\n voucherTypeName: \"Receipt\",\r\n date: input.date,\r\n narration: input.narration,\r\n voucherNumber: input.voucherNumber,\r\n reference: input.reference,\r\n isInvoice: false,\r\n body,\r\n });\r\n}\r\n\r\nfunction buildJournalXml(input: JournalVoucherInput): string {\r\n const body = input.entries\r\n .map((e) => buildLedgerEntryXml(e.ledger, e.amount, e.type === \"Debit\"))\r\n .join(\"\");\r\n return buildVoucherEnvelope({\r\n voucherTypeName: \"Journal\",\r\n date: input.date,\r\n narration: input.narration,\r\n voucherNumber: input.voucherNumber,\r\n reference: input.reference,\r\n isInvoice: false,\r\n body,\r\n });\r\n}\r\n\r\ninterface VoucherEnvelopeOptions {\r\n voucherTypeName: string;\r\n date: Date;\r\n narration?: string;\r\n voucherNumber?: string;\r\n reference?: string;\r\n /** Sales/Purchase render as \"invoice\" voucher class in Tally (affects\r\n * whether ALLINVENTORYENTRIES are expected) — Payment/Receipt/Journal don't. */\r\n isInvoice: boolean;\r\n partyName?: string;\r\n body: string;\r\n}\r\n\r\nfunction buildVoucherEnvelope(opts: VoucherEnvelopeOptions): string {\r\n return (\r\n `<TALLYMESSAGE xmlns:UDF=\"TallyUDF\">` +\r\n `<VOUCHER VCHTYPE=\"${escapeXml(opts.voucherTypeName)}\" ACTION=\"Create\"` +\r\n (opts.isInvoice ? ` ISINVOICE=\"Yes\"` : \"\") +\r\n `>` +\r\n `<DATE>${formatTallyDate(opts.date)}</DATE>` +\r\n `<VOUCHERTYPENAME>${escapeXml(opts.voucherTypeName)}</VOUCHERTYPENAME>` +\r\n (opts.voucherNumber\r\n ? `<VOUCHERNUMBER>${escapeXml(opts.voucherNumber)}</VOUCHERNUMBER>`\r\n : \"\") +\r\n (opts.partyName\r\n ? `<PARTYLEDGERNAME>${escapeXml(opts.partyName)}</PARTYLEDGERNAME>`\r\n : \"\") +\r\n (opts.reference\r\n ? `<REFERENCE>${escapeXml(opts.reference)}</REFERENCE>`\r\n : \"\") +\r\n (opts.narration\r\n ? `<NARRATION>${escapeXml(opts.narration)}</NARRATION>`\r\n : \"\") +\r\n opts.body +\r\n `</VOUCHER>` +\r\n `</TALLYMESSAGE>`\r\n );\r\n}\r\n\r\n/**\r\n * The exhaustive switch: TypeScript will refuse to compile this file if a\r\n * sixth voucher type is added to VoucherInput without a matching case here —\r\n * that's the whole point of routing every variant through assertNever in\r\n * the default branch instead of leaving it untyped.\r\n */\r\nexport function buildVoucherXml(input: VoucherInput): string {\r\n switch (input.voucherType) {\r\n case \"Sales\":\r\n return buildSalesXml(input);\r\n case \"Purchase\":\r\n return buildPurchaseXml(input);\r\n case \"Payment\":\r\n return buildPaymentXml(input);\r\n case \"Receipt\":\r\n return buildReceiptXml(input);\r\n case \"Journal\":\r\n return buildJournalXml(input);\r\n default:\r\n return assertNever(input);\r\n }\r\n}\r\n","import { buildEnvelope } from \"../envelope.js\";\r\n\r\n/**\r\n * Export requests don't carry a request body the way imports do — the field\r\n * list comes from Tally's built-in report/collection names. We pin to\r\n * Tally's native report names rather than hand-rolling TDL collection\r\n * definitions, which keeps this builder simple at the cost of being unable\r\n * to add custom fields. (A custom-TDL collection layer is a reasonable\r\n * Phase 2 addition once the basic reads are solid.)\r\n */\r\n\r\nexport function buildGetCompaniesXml(): string {\r\n return buildEnvelope({ requestType: \"Export Data\", id: \"List of Companies\" });\r\n}\r\n\r\nexport function buildGetLedgersXml(company?: string): string {\r\n return buildEnvelope({\r\n requestType: \"Export Data\",\r\n id: \"List of Ledgers\",\r\n company,\r\n staticVariables: { SVEXPORTFORMAT: \"$$SysName:XML\" },\r\n });\r\n}\r\n\r\nexport function buildGetStockItemsXml(company?: string): string {\r\n return buildEnvelope({\r\n requestType: \"Export Data\",\r\n id: \"List of Stock Items\",\r\n company,\r\n staticVariables: { SVEXPORTFORMAT: \"$$SysName:XML\" },\r\n });\r\n}\r\n\r\nexport function buildGetOutstandingXml(company?: string): string {\r\n return buildEnvelope({\r\n requestType: \"Export Data\",\r\n id: \"Bills Receivable\", // swap to \"Bills Payable\" for AP outstanding\r\n company,\r\n staticVariables: { SVEXPORTFORMAT: \"$$SysName:XML\" },\r\n });\r\n}\r\n\r\nexport function buildPingXml(): string {\r\n // Tally has no dedicated health-check endpoint; the cheapest real request\r\n // that proves the HTTP-XML server is alive and a company is loaded is a\r\n // company list export, so ping() reuses this builder rather than\r\n // round-tripping a fake malformed request and hoping for a fast failure.\r\n return buildGetCompaniesXml();\r\n}\r\n","import { XMLParser } from \"fast-xml-parser\";\r\nimport type { VoucherCreateResult } from \"../../types/voucher.js\";\r\nimport {\r\n ok,\r\n err,\r\n tallyError,\r\n type Result,\r\n type TallyError,\r\n} from \"../../types/result.js\";\r\n\r\nconst parser = new XMLParser({\r\n ignoreAttributes: false,\r\n attributeNamePrefix: \"@_\",\r\n // Tally repeats sibling tags (LINEERROR, etc.) without warning when there's\r\n // more than one — force these into arrays unconditionally so downstream\r\n // code never has to special-case \"string vs array of one\".\r\n isArray: (tagName) => [\"LINEERROR\", \"TALLYMESSAGE\"].includes(tagName),\r\n // Tally emits &#4; as an empty-but-present marker on some master fields;\r\n // fast-xml-parser decodes numeric entities by default, which turns it into\r\n // an unprintable control character rather than throwing — we normalize it\r\n // back to an empty string post-parse instead of fighting the entity\r\n // decoder.\r\n});\r\n\r\ninterface RawImportResponse {\r\n ENVELOPE?: {\r\n HEADER?: { STATUS?: string | number };\r\n BODY?: {\r\n DATA?: {\r\n IMPORTRESULT?: {\r\n CREATED?: string | number;\r\n ALTERED?: string | number;\r\n LASTVCHID?: string | number;\r\n LASTMID?: string | number;\r\n ERRORS?: string | number;\r\n };\r\n };\r\n // LINEERROR sometimes appears directly under BODY rather than nested\r\n // under DATA, depending on Tally version — checked at both paths below.\r\n LINEERROR?: string[];\r\n };\r\n };\r\n}\r\n\r\n/**\r\n * Parses a response to an Import Data request (createLedger, createVoucher,\r\n * etc). Two-pass by design: first parse the XML unconditionally, then\r\n * inspect the parsed tree for error markers. We never string-match on raw\r\n * XML for \"LINEERROR\" — that breaks the moment Tally changes whitespace or\r\n * attribute order, which it does between versions.\r\n */\r\nexport function parseImportResponse(\r\n rawXml: string,\r\n): Result<VoucherCreateResult, TallyError> {\r\n let parsed: RawImportResponse;\r\n try {\r\n parsed = parser.parse(rawXml) as RawImportResponse;\r\n } catch (cause) {\r\n return err(\r\n tallyError(\"PARSE_ERROR\", \"Could not parse Tally's response as XML\", {\r\n responseXml: rawXml,\r\n cause,\r\n }),\r\n );\r\n }\r\n\r\n const body = parsed.ENVELOPE?.BODY;\r\n const lineErrors = body?.LINEERROR;\r\n\r\n if (lineErrors && lineErrors.length > 0) {\r\n return err(\r\n tallyError(\"TALLY_REJECTED\", \"Tally rejected the request\", {\r\n tallyMessage: lineErrors.join(\"; \"),\r\n responseXml: rawXml,\r\n }),\r\n );\r\n }\r\n\r\n const result = body?.DATA?.IMPORTRESULT;\r\n const created = Number(result?.CREATED ?? 0);\r\n const altered = Number(result?.ALTERED ?? 0);\r\n const errors = Number(result?.ERRORS ?? 0);\r\n\r\n if (errors > 0) {\r\n return err(\r\n tallyError(\r\n \"TALLY_REJECTED\",\r\n `Tally reported ${errors} error(s) during import`,\r\n {\r\n responseXml: rawXml,\r\n },\r\n ),\r\n );\r\n }\r\n\r\n if (created === 0 && altered === 0) {\r\n // Not necessarily fatal (e.g. an idempotent re-create of an identical\r\n // object can legitimately report 0/0), but it's surprising enough that\r\n // callers should see it as a distinct, named outcome rather than a\r\n // silent success that looks identical to \"created: 1\".\r\n return err(\r\n tallyError(\r\n \"PARSE_ERROR\",\r\n \"Tally returned no CREATED/ALTERED count and no error — unexpected response shape\",\r\n {\r\n responseXml: rawXml,\r\n },\r\n ),\r\n );\r\n }\r\n\r\n return ok({\r\n voucherNumber: String(result?.LASTVCHID ?? \"\"),\r\n guid: String(result?.LASTMID ?? \"\"),\r\n alteredOn: new Date(),\r\n });\r\n}\r\n","import { XMLParser } from \"fast-xml-parser\";\r\nimport type {\r\n Ledger,\r\n StockItem,\r\n Company,\r\n OutstandingEntry,\r\n} from \"../../types/ledger.js\";\r\nimport {\r\n ok,\r\n err,\r\n tallyError,\r\n type Result,\r\n type TallyError,\r\n} from \"../../types/result.js\";\r\n\r\n/**\r\n * The classic XML-to-JSON trap: when a collection has exactly one matching\r\n * record, most XML parsers (including fast-xml-parser without isArray\r\n * hints) collapse `<LEDGER>...</LEDGER>` into a bare object instead of a\r\n * one-element array, because nothing in the XML itself says \"this is a\r\n * repeatable element\" — that's structural knowledge, not something the\r\n * parser can infer from a single instance.\r\n *\r\n * We force every collection tag we read into an array via isArray, so\r\n * \"zero, one, or many results\" is always one shape (T[]) at the call site\r\n * instead of three (undefined | T | T[]).\r\n */\r\nconst COLLECTION_TAGS = [\"LEDGER\", \"STOCKITEM\", \"COMPANY\", \"BILLOUTSTANDING\"];\r\n\r\nconst parser = new XMLParser({\r\n ignoreAttributes: false,\r\n attributeNamePrefix: \"@_\",\r\n isArray: (tagName) => COLLECTION_TAGS.includes(tagName),\r\n});\r\n\r\nfunction parseTallyNumber(raw: unknown): number | undefined {\r\n if (raw == null) return undefined;\r\n // Tally renders negative numbers in collection exports with a trailing\r\n // \" Cr\"/\" Dr\" suffix on some reports and a leading \"-\" on others,\r\n // depending on report type — strip both and let the sign survive.\r\n const cleaned = String(raw)\r\n .replace(/\\s*(Cr|Dr)\\s*$/i, \"\")\r\n .replace(/,/g, \"\")\r\n .trim();\r\n const n = Number(cleaned);\r\n return Number.isFinite(n) ? n : undefined;\r\n}\r\n\r\nfunction safeParse<T>(\r\n rawXml: string,\r\n extract: (parsed: unknown) => T,\r\n): Result<T, TallyError> {\r\n try {\r\n const parsed = parser.parse(rawXml);\r\n return ok(extract(parsed));\r\n } catch (cause) {\r\n return err(\r\n tallyError(\"PARSE_ERROR\", \"Could not parse Tally's collection response\", {\r\n responseXml: rawXml,\r\n cause,\r\n }),\r\n );\r\n }\r\n}\r\n\r\n// Loose shape — Tally's export XML nesting varies by version/report, so we\r\n// reach for fields defensively (?. everywhere) rather than asserting a rigid\r\n// interface that breaks on the next Tally point release.\r\ntype LooseTree = Record<string, any>;\r\n\r\nfunction findCollectionRoot(parsed: LooseTree): LooseTree {\r\n return (\r\n parsed?.ENVELOPE?.BODY?.DATA?.COLLECTION ??\r\n parsed?.ENVELOPE?.BODY?.DATA ??\r\n {}\r\n );\r\n}\r\n\r\nexport function parseLedgerCollection(\r\n rawXml: string,\r\n): Result<Ledger[], TallyError> {\r\n return safeParse(rawXml, (parsed) => {\r\n const root = findCollectionRoot(parsed as LooseTree);\r\n const ledgers: LooseTree[] = root.LEDGER ?? [];\r\n return ledgers.map((l) => ({\r\n name: String(l[\"@_NAME\"] ?? l.NAME ?? \"\"),\r\n guid: String(l.GUID ?? \"\"),\r\n group: String(l.PARENT ?? \"\"),\r\n gstin: l.GSTIN ? String(l.GSTIN) : undefined,\r\n closingBalance: parseTallyNumber(l.CLOSINGBALANCE),\r\n state: l.LEDSTATENAME ? String(l.LEDSTATENAME) : undefined,\r\n }));\r\n });\r\n}\r\n\r\nexport function parseStockItemCollection(\r\n rawXml: string,\r\n): Result<StockItem[], TallyError> {\r\n return safeParse(rawXml, (parsed) => {\r\n const root = findCollectionRoot(parsed as LooseTree);\r\n const items: LooseTree[] = root.STOCKITEM ?? [];\r\n return items.map((s) => ({\r\n name: String(s[\"@_NAME\"] ?? s.NAME ?? \"\"),\r\n guid: String(s.GUID ?? \"\"),\r\n unit: String(s.BASEUNITS ?? \"\"),\r\n closingQty: parseTallyNumber(s.CLOSINGBALANCE),\r\n closingValue: parseTallyNumber(s.CLOSINGVALUE),\r\n hsnCode: s.HSNCODE ? String(s.HSNCODE) : undefined,\r\n gstRate: parseTallyNumber(s.GSTRATE),\r\n }));\r\n });\r\n}\r\n\r\nexport function parseCompanyCollection(\r\n rawXml: string,\r\n): Result<Company[], TallyError> {\r\n return safeParse(rawXml, (parsed) => {\r\n const root = findCollectionRoot(parsed as LooseTree);\r\n const companies: LooseTree[] = root.COMPANY ?? [];\r\n return companies.map((c) => ({\r\n name: String(c[\"@_NAME\"] ?? c.NAME ?? \"\"),\r\n guid: String(c.GUID ?? \"\"),\r\n startingFrom: c.STARTINGFROM ? String(c.STARTINGFROM) : undefined,\r\n endingAt: c.ENDINGAT ? String(c.ENDINGAT) : undefined,\r\n }));\r\n });\r\n}\r\n\r\nexport function parseOutstandingCollection(\r\n rawXml: string,\r\n): Result<OutstandingEntry[], TallyError> {\r\n return safeParse(rawXml, (parsed) => {\r\n const root = findCollectionRoot(parsed as LooseTree);\r\n const bills: LooseTree[] = root.BILLOUTSTANDING ?? [];\r\n return bills.map((b) => ({\r\n ledgerName: String(b.LEDGERNAME ?? \"\"),\r\n voucherNumber: String(b.VOUCHERNUMBER ?? \"\"),\r\n voucherDate: new Date(String(b.VOUCHERDATE ?? \"\")),\r\n dueDate: b.DUEDATE ? new Date(String(b.DUEDATE)) : undefined,\r\n pendingAmount: parseTallyNumber(b.PENDINGAMOUNT) ?? 0,\r\n overdueDays: b.OVERDUEDAYS != null ? Number(b.OVERDUEDAYS) : undefined,\r\n }));\r\n });\r\n}\r\n","import type { Result, TallyConfig, TallyError } from \"../types/result.js\";\r\nimport { ok, err, tallyError } from \"../types/result.js\";\r\n\r\n/**\r\n * Tally's HTTP-XML server takes every request as a raw XML POST body to the\r\n * root path — there's no REST routing, no headers carrying semantics, just\r\n * \"post some XML, get some XML back\". That makes this transport layer\r\n * unusually thin: its only real job is turning network-level failures\r\n * (DNS, connection refused, timeout) into typed errors and retrying *only*\r\n * those — never retrying a request that reached Tally and got a real\r\n * response, because Tally-side rejections aren't transient.\r\n */\r\nexport class TallyTransport {\r\n private readonly retries: number;\r\n\r\n constructor(private readonly config: TallyConfig) {\r\n this.retries = config.retries ?? 1;\r\n }\r\n\r\n async send(requestXml: string): Promise<Result<string, TallyError>> {\r\n let lastError: TallyError | undefined;\r\n\r\n const protocol = this.config.https ? \"https\" : \"http\";\r\n const url = `${protocol}://${this.config.host}:${this.config.port}/`;\r\n\r\n for (let attempt = 0; attempt <= this.retries; attempt++) {\r\n try {\r\n const response = await fetch(url, {\r\n method: \"POST\",\r\n headers: {\r\n \"Content-Type\": \"text/xml\",\r\n },\r\n body: requestXml,\r\n signal: AbortSignal.timeout(this.config.timeoutMs ?? 15_000),\r\n });\r\n\r\n const responseText = await response.text();\r\n\r\n // Tally responded with something (even HTTP error status) —\r\n // that's a real response, hand it back rather than retrying.\r\n return ok(responseText);\r\n } catch (cause) {\r\n if (cause instanceof Error) {\r\n if (cause.name === \"TimeoutError\" || cause.name === \"AbortError\") {\r\n lastError = tallyError(\r\n \"TIMEOUT\",\r\n `Request to Tally timed out after ${\r\n this.config.timeoutMs ?? 15_000\r\n }ms`,\r\n {\r\n requestXml,\r\n cause,\r\n },\r\n );\r\n\r\n // Timeouts are ambiguous (the voucher may have been created\r\n // server-side even though we never saw the response) — still\r\n // retryable for read operations, but callers doing writes\r\n // should treat a TIMEOUT differently from a clean NETWORK_ERROR.\r\n continue;\r\n }\r\n\r\n // No response at all = connection refused, DNS failure, Tally\r\n // not running, wrong port — genuinely safe to retry.\r\n if (cause instanceof TypeError) {\r\n lastError = tallyError(\r\n \"NETWORK_ERROR\",\r\n `Could not reach Tally at ${this.config.host}:${this.config.port}`,\r\n {\r\n requestXml,\r\n cause,\r\n },\r\n );\r\n continue;\r\n }\r\n }\r\n\r\n lastError = tallyError(\r\n \"UNKNOWN\",\r\n \"Unexpected error sending request to Tally\",\r\n {\r\n requestXml,\r\n cause,\r\n },\r\n );\r\n\r\n break;\r\n }\r\n }\r\n\r\n return err(\r\n lastError ??\r\n tallyError(\"UNKNOWN\", \"Request failed with no captured error\"),\r\n );\r\n }\r\n}\r\n","import { z } from \"zod\";\r\nimport type { TallyConfig, Result, TallyError } from \"../types/result.js\";\r\nimport { ok, err, tallyError } from \"../types/result.js\";\r\nimport {\r\n buildCreateLedgerXml,\r\n buildCreateStockItemXml,\r\n buildVoucherXml,\r\n buildGetCompaniesXml,\r\n buildGetLedgersXml,\r\n buildGetStockItemsXml,\r\n buildGetOutstandingXml,\r\n buildPingXml,\r\n parseImportResponse,\r\n parseLedgerCollection,\r\n parseStockItemCollection,\r\n parseCompanyCollection,\r\n parseOutstandingCollection,\r\n} from \"../xml/index.js\";\r\nimport { TallyTransport } from \"./transport.js\";\r\nimport {\r\n JournalVoucherInputSchema,\r\n PaymentVoucherInputSchema,\r\n PurchaseVoucherInputSchema,\r\n ReceiptVoucherInputSchema,\r\n SalesVoucherInputSchema,\r\n type SalesVoucherInput,\r\n type VoucherCreateResult,\r\n type VoucherInput,\r\n} from \"../types/voucher.js\";\r\nimport {\r\n LedgerInputSchema,\r\n StockItemInputSchema,\r\n type Company,\r\n type Ledger,\r\n type LedgerInput,\r\n type OutstandingEntry,\r\n type StockItem,\r\n type StockItemInput,\r\n} from \"../types/ledger.js\";\r\n\r\n/**\r\n * Voucher validation can't go through a single z.discriminatedUnion the way\r\n * Ledger/StockItem can, because JournalVoucherInputSchema is a refined\r\n * (ZodEffects) schema and Zod's discriminatedUnion only accepts plain\r\n * object schemas as members. Switching on voucherType first and validating\r\n * against the matching schema gets the same guarantee — nothing reaches the\r\n * XML builder unvalidated — without fighting Zod's type constraints.\r\n */\r\nfunction validateVoucherInput(\r\n input: VoucherInput,\r\n): Result<VoucherInput, TallyError> {\r\n const schema = {\r\n Sales: SalesVoucherInputSchema,\r\n Purchase: PurchaseVoucherInputSchema,\r\n Payment: PaymentVoucherInputSchema,\r\n Receipt: ReceiptVoucherInputSchema,\r\n Journal: JournalVoucherInputSchema,\r\n }[input.voucherType];\r\n\r\n const parsed = schema.safeParse(input);\r\n if (!parsed.success) {\r\n return err(\r\n tallyError(\r\n \"VALIDATION_ERROR\",\r\n `Invalid ${input.voucherType} voucher input`,\r\n {\r\n cause: parsed.error,\r\n },\r\n ),\r\n );\r\n }\r\n return ok(parsed.data as VoucherInput);\r\n}\r\n\r\nexport class Tally {\r\n private readonly transport: TallyTransport;\r\n private readonly company?: string;\r\n\r\n constructor(config: TallyConfig) {\r\n this.transport = new TallyTransport(config);\r\n this.company = config.company;\r\n }\r\n\r\n // ---- Connection -------------------------------------------------------\r\n\r\n async ping(): Promise<Result<true, TallyError>> {\r\n const result = await this.transport.send(buildPingXml());\r\n if (!result.ok) return result;\r\n // A real Tally instance always echoes back a well-formed ENVELOPE, even\r\n // for an empty company list — so \"did this parse as XML at all\" is a\r\n // sufficient liveness check without needing a dedicated builder.\r\n if (!result.value.includes(\"<ENVELOPE>\")) {\r\n return err(\r\n tallyError(\r\n \"PARSE_ERROR\",\r\n \"Response did not look like a Tally ENVELOPE\",\r\n { responseXml: result.value },\r\n ),\r\n );\r\n }\r\n return ok(true);\r\n }\r\n\r\n // ---- Reads --------------------------------------------------------------\r\n\r\n async getCompanies(): Promise<Result<Company[], TallyError>> {\r\n const res = await this.transport.send(buildGetCompaniesXml());\r\n if (!res.ok) return res;\r\n return parseCompanyCollection(res.value);\r\n }\r\n\r\n async getLedgers(): Promise<Result<Ledger[], TallyError>> {\r\n const res = await this.transport.send(buildGetLedgersXml(this.company));\r\n if (!res.ok) return res;\r\n return parseLedgerCollection(res.value);\r\n }\r\n\r\n /** Alias matching the original product sketch's naming. */\r\n async getCustomers(): Promise<Result<Ledger[], TallyError>> {\r\n const res = await this.getLedgers();\r\n if (!res.ok) return res;\r\n return ok(res.value.filter((l) => l.group === \"Sundry Debtors\"));\r\n }\r\n\r\n async getStockItems(): Promise<Result<StockItem[], TallyError>> {\r\n const res = await this.transport.send(buildGetStockItemsXml(this.company));\r\n if (!res.ok) return res;\r\n return parseStockItemCollection(res.value);\r\n }\r\n\r\n async getOutstanding(): Promise<Result<OutstandingEntry[], TallyError>> {\r\n const res = await this.transport.send(buildGetOutstandingXml(this.company));\r\n if (!res.ok) return res;\r\n return parseOutstandingCollection(res.value);\r\n }\r\n\r\n // ---- Writes -------------------------------------------------------------\r\n\r\n async createLedger(\r\n input: LedgerInput,\r\n ): Promise<Result<VoucherCreateResult, TallyError>> {\r\n const parsed = LedgerInputSchema.safeParse(input);\r\n if (!parsed.success) {\r\n return err(\r\n tallyError(\"VALIDATION_ERROR\", \"Invalid ledger input\", {\r\n cause: parsed.error,\r\n }),\r\n );\r\n }\r\n const xml = buildCreateLedgerXml(parsed.data);\r\n const res = await this.transport.send(xml);\r\n if (!res.ok) return res;\r\n return parseImportResponse(res.value);\r\n }\r\n\r\n async createStockItem(\r\n input: StockItemInput,\r\n ): Promise<Result<VoucherCreateResult, TallyError>> {\r\n const parsed = StockItemInputSchema.safeParse(input);\r\n if (!parsed.success) {\r\n return err(\r\n tallyError(\"VALIDATION_ERROR\", \"Invalid stock item input\", {\r\n cause: parsed.error,\r\n }),\r\n );\r\n }\r\n const xml = buildCreateStockItemXml(parsed.data);\r\n const res = await this.transport.send(xml);\r\n if (!res.ok) return res;\r\n return parseImportResponse(res.value);\r\n }\r\n\r\n async createVoucher(\r\n input: VoucherInput,\r\n ): Promise<Result<VoucherCreateResult, TallyError>> {\r\n const validated = validateVoucherInput(input);\r\n if (!validated.ok) return validated;\r\n const xml = buildVoucherXml(validated.value);\r\n const res = await this.transport.send(xml);\r\n if (!res.ok) return res;\r\n return parseImportResponse(res.value);\r\n }\r\n\r\n /**\r\n * Convenience wrapper matching the original sketch's `createInvoice()`\r\n * signature — expands into a full SalesVoucherInput (voucherType: \"Sales\")\r\n * before going through the same validated path as createVoucher(). Kept\r\n * separate from createVoucher() because \"invoice\" maps to a Sales voucher\r\n * specifically, and spelling that out here means callers coming from\r\n * other invoicing tools (Stripe, Zoho) don't need to know Tally's\r\n * voucherType vocabulary at all.\r\n */\r\n async createInvoice(input: {\r\n customer: string;\r\n date: Date;\r\n items: SalesVoucherInput[\"items\"];\r\n salesLedger?: string;\r\n taxes?: SalesVoucherInput[\"taxes\"];\r\n reference?: string;\r\n narration?: string;\r\n }): Promise<Result<VoucherCreateResult, TallyError>> {\r\n return this.createVoucher({\r\n voucherType: \"Sales\",\r\n date: input.date,\r\n party: input.customer,\r\n items: input.items,\r\n salesLedger: input.salesLedger ?? \"Sales\",\r\n taxes: input.taxes,\r\n reference: input.reference,\r\n narration: input.narration,\r\n });\r\n }\r\n\r\n // ---- AI agent integration ------------------------------------------------\r\n\r\n /**\r\n * Returns JSON-Schema-shaped tool definitions (derived from the same Zod\r\n * schemas used for validation, so the agent-facing contract can never\r\n * drift from what the SDK actually accepts) for OpenAI-style function\r\n * calling, LangGraph, Mastra, or a hand-rolled MCP server. Each `handler`\r\n * closes over `this`, so a caller can wire these straight into an agent\r\n * framework's tool registry without writing adapter glue.\r\n */\r\n tools() {\r\n return [\r\n {\r\n name: \"getCustomers\",\r\n description:\r\n \"List all Sundry Debtor ledgers (customers) in the active Tally company.\",\r\n parameters: z.object({}),\r\n handler: () => this.getCustomers(),\r\n },\r\n {\r\n name: \"getOutstanding\",\r\n description:\r\n \"Get outstanding (unpaid) receivable bills across all customers.\",\r\n parameters: z.object({}),\r\n handler: () => this.getOutstanding(),\r\n },\r\n {\r\n name: \"createInvoice\",\r\n description:\r\n \"Create a sales invoice for a customer with one or more line items.\",\r\n parameters: z.object({\r\n customer: z.string(),\r\n date: z.coerce.date(),\r\n items: z.array(\r\n z.object({\r\n stockItem: z.string(),\r\n quantity: z.number(),\r\n rate: z.number(),\r\n }),\r\n ),\r\n }),\r\n handler: (args: {\r\n customer: string;\r\n date: Date;\r\n items: SalesVoucherInput[\"items\"];\r\n }) => this.createInvoice(args),\r\n },\r\n {\r\n name: \"createLedger\",\r\n description:\r\n \"Create a new ledger account (e.g. a new customer or supplier) in Tally.\",\r\n parameters: LedgerInputSchema,\r\n handler: (args: LedgerInput) => this.createLedger(args),\r\n },\r\n ] as const;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"sources":["../src/types/result.ts","../src/types/ledger.ts","../src/types/voucher.ts","../src/xml/envelope.ts","../src/xml/builders/ledger.ts","../src/xml/builders/voucher.ts","../src/xml/builders/collection.ts","../src/xml/parsers/response-parser.ts","../src/xml/parsers/collection-parser.ts","../src/tally/transport.ts","../src/tally/client.ts"],"names":["err","z","parser","XMLParser"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Tally's HTTP layer is not a reliable signal of success. A failed voucher\r\n * import still comes back as HTTP 200 with a <LINEERROR> buried in the body.\r\n * Network failures, XML parse failures, and Tally-side rejections are three\r\n * different failure classes with three different recovery strategies (retry,\r\n * fix-your-builder-bug, fix-your-data) — so we keep them as distinct codes\r\n * instead of collapsing everything into a generic Error.\r\n */\r\nexport type TallyErrorCode =\r\n | \"NETWORK_ERROR\" // request never reached Tally, or Tally never responded — safe to retry\r\n | \"TIMEOUT\" // request sent, no response within the configured window — retry with caution (may have applied)\r\n | \"PARSE_ERROR\" // Tally responded, but the XML didn't match any known shape — SDK bug or Tally version drift\r\n | \"TALLY_REJECTED\" // Tally understood the request and rejected it (LINEERROR) — do not retry as-is\r\n | \"VALIDATION_ERROR\" // the input never left the process — caught by the Zod schema before XML was built\r\n | \"NOT_FOUND\" // a get-by-name lookup returned no matching object\r\n | \"UNKNOWN\";\r\n\r\nexport interface TallyError {\r\n code: TallyErrorCode;\r\n message: string;\r\n /** Raw <LINEERROR> text from Tally, when code === \"TALLY_REJECTED\" */\r\n tallyMessage?: string;\r\n /** The XML request body that produced this error, kept for debugging/logging */\r\n requestXml?: string;\r\n /** The raw XML response body, when one was received */\r\n responseXml?: string;\r\n /** Underlying cause (e.g. an AxiosError, a ZodError), for stack traces */\r\n cause?: unknown;\r\n}\r\n\r\nexport type Result<T, E = TallyError> =\r\n | { ok: true; value: T }\r\n | { ok: false; error: E };\r\n\r\nexport function ok<T>(value: T): Result<T, never> {\r\n return { ok: true, value };\r\n}\r\n\r\nexport function err<E = TallyError>(error: E): Result<never, E> {\r\n return { ok: false, error };\r\n}\r\n\r\nexport function tallyError(\r\n code: TallyErrorCode,\r\n message: string,\r\n extra?: Partial<Omit<TallyError, \"code\" | \"message\">>\r\n): TallyError {\r\n return { code, message, ...extra };\r\n}\r\n\r\n/** Narrow a Result to its value, or throw — for callers who'd rather not\r\n * thread Result through their own code. Named unwrap (not \"get\") so misuse\r\n * is obvious at the call site. */\r\nexport function unwrap<T>(result: Result<T, TallyError>): T {\r\n if (result.ok) return result.value;\r\n const err = result.error;\r\n const e = new Error(`[${err.code}] ${err.message}`);\r\n (e as Error & { cause?: unknown }).cause = err.cause ?? err;\r\n throw e;\r\n}\r\n\r\nexport interface TallyConfig {\r\n host: string;\r\n port: number;\r\n /** Defaults to false; set true only for instances behind TLS termination */\r\n https?: boolean;\r\n /** Defaults to the active company in Tally if omitted */\r\n company?: string;\r\n /** Request timeout in ms; Tally can be slow on large COLLECTION exports */\r\n timeoutMs?: number;\r\n /** Retries on NETWORK_ERROR/TIMEOUT only — never on TALLY_REJECTED */\r\n retries?: number;\r\n}","import { z } from \"zod\";\r\n\r\n/**\r\n * GSTIN format check is intentionally loose (Tally itself doesn't hard-reject\r\n * malformed GSTINs on import, it just stores what you give it) — we validate\r\n * shape, not checksum, to avoid the SDK rejecting valid-but-unusual entries\r\n * (e.g. SEZ/UN body GSTINs) that a strict regex would choke on.\r\n */\r\nconst gstinSchema = z\r\n .string()\r\n .regex(\r\n /^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z]{1}[1-9A-Z]{1}Z[0-9A-Z]{1}$/,\r\n \"Invalid GSTIN format\",\r\n )\r\n .optional();\r\n\r\nexport const LedgerInputSchema = z.object({\r\n name: z.string().min(1),\r\n /** Tally group name, e.g. \"Sundry Debtors\", \"Sundry Creditors\", \"Bank Accounts\" */\r\n group: z.string().min(1),\r\n gstin: gstinSchema,\r\n openingBalance: z.number().optional(),\r\n /** \"Debit\" | \"Credit\" — required by Tally when openingBalance is set */\r\n openingBalanceType: z.enum([\"Debit\", \"Credit\"]).optional(),\r\n address: z.array(z.string()).optional(),\r\n state: z.string().optional(),\r\n pincode: z.string().optional(),\r\n email: z.string().email().optional(),\r\n phone: z.string().optional(),\r\n});\r\nexport type LedgerInput = z.infer<typeof LedgerInputSchema>;\r\n\r\nexport const LedgerSchema = z.object({\r\n name: z.string(),\r\n guid: z.string(),\r\n group: z.string(),\r\n gstin: z.string().optional(),\r\n /** Signed: positive = debit balance, negative = credit balance (normalized\r\n * at the parser layer — Tally's raw XML encodes sign via a separate\r\n * DR/CR-style attribute, never as a literal minus on the export). */\r\n closingBalance: z.number().optional(),\r\n state: z.string().optional(),\r\n});\r\nexport type Ledger = z.infer<typeof LedgerSchema>;\r\n\r\nexport const StockItemSchema = z.object({\r\n name: z.string(),\r\n guid: z.string(),\r\n unit: z.string(),\r\n closingQty: z.number().optional(),\r\n closingValue: z.number().optional(),\r\n /** HSN/SAC code, when GST is enabled in the company */\r\n hsnCode: z.string().optional(),\r\n gstRate: z.number().optional(),\r\n});\r\nexport type StockItem = z.infer<typeof StockItemSchema>;\r\n\r\nexport const StockItemInputSchema = z.object({\r\n name: z.string().min(1),\r\n /** Tally stock group name, e.g. \"Primary\" */\r\n group: z.string().default(\"Primary\"),\r\n unit: z.string().min(1),\r\n hsnCode: z.string().optional(),\r\n gstRate: z.number().optional(),\r\n openingQty: z.number().optional(),\r\n openingRate: z.number().optional(),\r\n});\r\nexport type StockItemInput = z.infer<typeof StockItemInputSchema>;\r\n\r\nexport const CompanySchema = z.object({\r\n name: z.string(),\r\n guid: z.string(),\r\n startingFrom: z.string().optional(),\r\n endingAt: z.string().optional(),\r\n});\r\nexport type Company = z.infer<typeof CompanySchema>;\r\n\r\nexport const OutstandingEntrySchema = z.object({\r\n ledgerName: z.string(),\r\n voucherNumber: z.string(),\r\n voucherDate: z.coerce.date(),\r\n dueDate: z.coerce.date().optional(),\r\n /** Positive = they owe you, negative = you owe them */\r\n pendingAmount: z.number(),\r\n overdueDays: z.number().optional(),\r\n});\r\nexport type OutstandingEntry = z.infer<typeof OutstandingEntrySchema>;\r\n","import { z } from \"zod\";\r\n\r\n/**\r\n * Tally treats \"voucher\" as one umbrella concept, but Sales/Purchase vouchers\r\n * are item+ledger hybrids (stock movement AND money movement) while\r\n * Payment/Receipt/Journal are pure ledger-to-ledger entries. Modeling all\r\n * five as one flat object either makes every field optional (so TypeScript\r\n * can't catch \"Sales voucher missing items\") or forces five near-duplicate\r\n * interfaces with no shared base.\r\n *\r\n * Instead: a shared base schema for fields every voucher has, extended by a\r\n * discriminated union on `voucherType` so each variant only carries the\r\n * fields that are actually valid for it, and the XML builder's switch\r\n * statement gets exhaustiveness-checked by the compiler (see\r\n * packages/xml/src/builders/voucher.ts).\r\n */\r\n\r\nconst baseVoucherFields = {\r\n date: z.coerce.date(),\r\n narration: z.string().optional(),\r\n /** Tally auto-numbers if omitted; only set this if you're syncing from an\r\n * external system that owns numbering (e.g. an e-invoice generator). */\r\n voucherNumber: z.string().optional(),\r\n reference: z.string().optional(),\r\n};\r\n\r\nconst lineItemSchema = z.object({\r\n /** Must match an existing Tally stock item name exactly (case-sensitive) */\r\n stockItem: z.string().min(1),\r\n quantity: z.number().positive(),\r\n rate: z.number().nonnegative(),\r\n /** Defaults to quantity * rate; pass explicitly to override rounding */\r\n amount: z.number().optional(),\r\n});\r\nexport type LineItem = z.infer<typeof lineItemSchema>;\r\n\r\nconst taxLedgerSchema = z.object({\r\n /** e.g. \"Output CGST\", \"Output SGST\", \"Output IGST\" — must exist in Tally */\r\n ledger: z.string().min(1),\r\n amount: z.number(),\r\n});\r\n\r\nexport const SalesVoucherInputSchema = z.object({\r\n voucherType: z.literal(\"Sales\"),\r\n ...baseVoucherFields,\r\n /** Sundry Debtor ledger name being billed */\r\n party: z.string().min(1),\r\n items: z.array(lineItemSchema).min(1),\r\n /** Sales/revenue ledger to credit; defaults to \"Sales\" */\r\n salesLedger: z.string().default(\"Sales\"),\r\n taxes: z.array(taxLedgerSchema).optional(),\r\n});\r\nexport type SalesVoucherInput = z.infer<typeof SalesVoucherInputSchema>;\r\n\r\nexport const PurchaseVoucherInputSchema = z.object({\r\n voucherType: z.literal(\"Purchase\"),\r\n ...baseVoucherFields,\r\n /** Sundry Creditor ledger name being paid */\r\n party: z.string().min(1),\r\n items: z.array(lineItemSchema).min(1),\r\n purchaseLedger: z.string().default(\"Purchase\"),\r\n taxes: z.array(taxLedgerSchema).optional(),\r\n});\r\nexport type PurchaseVoucherInput = z.infer<typeof PurchaseVoucherInputSchema>;\r\n\r\nexport const PaymentVoucherInputSchema = z.object({\r\n voucherType: z.literal(\"Payment\"),\r\n ...baseVoucherFields,\r\n /** Ledger being debited — typically an expense or a creditor being paid off */\r\n debitLedger: z.string().min(1),\r\n /** Bank or Cash ledger being credited */\r\n creditLedger: z.string().min(1),\r\n amount: z.number().positive(),\r\n});\r\nexport type PaymentVoucherInput = z.infer<typeof PaymentVoucherInputSchema>;\r\n\r\nexport const ReceiptVoucherInputSchema = z.object({\r\n voucherType: z.literal(\"Receipt\"),\r\n ...baseVoucherFields,\r\n /** Bank or Cash ledger being debited */\r\n debitLedger: z.string().min(1),\r\n /** Ledger being credited — typically the debtor paying you */\r\n creditLedger: z.string().min(1),\r\n amount: z.number().positive(),\r\n});\r\nexport type ReceiptVoucherInput = z.infer<typeof ReceiptVoucherInputSchema>;\r\n\r\nconst journalEntrySchema = z.object({\r\n ledger: z.string().min(1),\r\n type: z.enum([\"Debit\", \"Credit\"]),\r\n amount: z.number().positive(),\r\n});\r\n\r\nexport const JournalVoucherInputSchema = z\r\n .object({\r\n voucherType: z.literal(\"Journal\"),\r\n ...baseVoucherFields,\r\n entries: z.array(journalEntrySchema).min(2),\r\n })\r\n .refine(\r\n (v) => {\r\n const debit = v.entries\r\n .filter((e) => e.type === \"Debit\")\r\n .reduce((s, e) => s + e.amount, 0);\r\n const credit = v.entries\r\n .filter((e) => e.type === \"Credit\")\r\n .reduce((s, e) => s + e.amount, 0);\r\n // float-safe equality\r\n return Math.abs(debit - credit) < 0.005;\r\n },\r\n { message: \"Journal voucher debit and credit totals must balance\" },\r\n );\r\nexport type JournalVoucherInput = z.infer<typeof JournalVoucherInputSchema>;\r\n\r\nexport const VoucherInputSchema = z.discriminatedUnion(\"voucherType\", [\r\n SalesVoucherInputSchema,\r\n PurchaseVoucherInputSchema,\r\n PaymentVoucherInputSchema,\r\n ReceiptVoucherInputSchema,\r\n // Journal isn't included directly here because z.discriminatedUnion can't\r\n // take a refined (ZodEffects) member — see VoucherInput union type below\r\n // and validateVoucherInput() in client.ts, which validates Journal\r\n // separately via JournalVoucherInputSchema.\r\n]);\r\n\r\nexport type VoucherInput =\r\n | SalesVoucherInput\r\n | PurchaseVoucherInput\r\n | PaymentVoucherInput\r\n | ReceiptVoucherInput\r\n | JournalVoucherInput;\r\n\r\n/** Exhaustiveness helper: pass an unreachable VoucherInput here in a\r\n * `default` switch branch — if a new voucher type is added to the union\r\n * without updating the builder, this fails to compile instead of failing at\r\n * runtime in front of a customer. */\r\nexport function assertNever(x: never): never {\r\n throw new Error(`Unhandled voucher type: ${JSON.stringify(x)}`);\r\n}\r\n\r\nexport interface VoucherCreateResult {\r\n voucherNumber: string;\r\n guid: string;\r\n alteredOn: Date;\r\n}\r\n","/**\r\n * Tally's XML is XML-shaped but not XML-clean. Two encoding quirks matter\r\n * enough to centralize here rather than handle ad hoc in every builder:\r\n *\r\n * 1. Standard XML entities (&, <, >, \", ') still need escaping — Tally's\r\n * parser is otherwise normal on that front.\r\n * 2. Tally has its own non-standard \"empty but present\" marker, &#4;, used\r\n * in some master-import contexts to distinguish \"field omitted\" from\r\n * \"field explicitly cleared\". We expose escapeXml() for normal text and\r\n * leave &#4; as an explicit opt-in (EMPTY_MARKER) so builders don't emit\r\n * it by accident.\r\n */\r\n\r\nexport const EMPTY_MARKER = \"&#4;\";\r\n\r\nexport function escapeXml(value: string): string {\r\n return value\r\n .replace(/&/g, \"&amp;\")\r\n .replace(/</g, \"&lt;\")\r\n .replace(/>/g, \"&gt;\")\r\n .replace(/\"/g, \"&quot;\")\r\n .replace(/'/g, \"&apos;\");\r\n}\r\n\r\n/** Tally dates are YYYYMMDD with no separators, always. */\r\nexport function formatTallyDate(date: Date): string {\r\n const y = date.getFullYear();\r\n const m = String(date.getMonth() + 1).padStart(2, \"0\");\r\n const d = String(date.getDate()).padStart(2, \"0\");\r\n return `${y}${m}${d}`;\r\n}\r\n\r\n/**\r\n * Tally renders negative ledger amounts as a sign on the number, but which\r\n * sign means debit vs credit flips depending on whether you're looking at a\r\n * Sales-side or Purchase-side ledger entry. Rather than push that\r\n * ambiguity onto every builder, callers pass an explicit `isDebit` flag and\r\n * this function produces the signed string Tally expects: debit entries are\r\n * positive, credit entries are negative, full stop, at the wire level.\r\n */\r\nexport function formatSignedAmount(amount: number, isDebit: boolean): string {\r\n const magnitude = Math.abs(amount).toFixed(2);\r\n return isDebit ? magnitude : `-${magnitude}`;\r\n}\r\n\r\nexport type EnvelopeRequestType = \"Import Data\" | \"Export Data\";\r\n\r\nexport interface EnvelopeOptions {\r\n requestType: EnvelopeRequestType;\r\n /** \"Vouchers\" | \"Masters\" | \"Collection\" | \"Company\" — Tally's REPORTNAME/ID context */\r\n id: string;\r\n company?: string;\r\n staticVariables?: Record<string, string>;\r\n}\r\n\r\n/**\r\n * Wraps an inner payload in Tally's outer envelope. This is the one place\r\n * both sublanguages meet — everything sublanguage-specific lives in the\r\n * builders that call this, not in here.\r\n *\r\n * Import (write) requests use <IMPORTDATA> and carry the actual master/\r\n * voucher XML inside <REQUESTDATA>. Export (read/collection) requests use\r\n * <EXPORTDATA> and have no REQUESTDATA section at all — the field list comes\r\n * from the report/collection definition Tally already knows about via\r\n * REPORTNAME, not from anything we send. Passing bodyXml on an export\r\n * request is a no-op by design, not an oversight.\r\n *\r\n * IMPORTANT: this only works for requests where REPORTNAME refers to a\r\n * report Tally already has registered (e.g. \"Vouchers\", \"All Masters\",\r\n * \"Trial Balance\", \"Bills Receivable\" — confirmed against a live instance).\r\n * It does NOT support inline TDL for ad-hoc field lists — for that, use\r\n * buildCollectionEnvelope() below.\r\n */\r\nexport function buildEnvelope(\r\n options: EnvelopeOptions,\r\n bodyXml?: string,\r\n): string {\r\n const staticVars = {\r\n ...(options.company ? { SVCURRENTCOMPANY: options.company } : {}),\r\n ...(options.staticVariables ?? {}),\r\n };\r\n\r\n const staticVarsXml = Object.entries(staticVars)\r\n .map(([key, value]) => `<${key}>${escapeXml(value)}</${key}>`)\r\n .join(\"\");\r\n\r\n const isImport = options.requestType === \"Import Data\";\r\n const sectionTag = isImport ? \"IMPORTDATA\" : \"EXPORTDATA\";\r\n\r\n return (\r\n `<ENVELOPE>` +\r\n `<HEADER><TALLYREQUEST>${escapeXml(options.requestType)}</TALLYREQUEST></HEADER>` +\r\n `<BODY>` +\r\n `<${sectionTag}>` +\r\n `<REQUESTDESC>` +\r\n `<REPORTNAME>${escapeXml(options.id)}</REPORTNAME>` +\r\n (staticVarsXml\r\n ? `<STATICVARIABLES>${staticVarsXml}</STATICVARIABLES>`\r\n : \"\") +\r\n `</REQUESTDESC>` +\r\n (isImport && bodyXml ? `<REQUESTDATA>${bodyXml}</REQUESTDATA>` : \"\") +\r\n `</${sectionTag}>` +\r\n `</BODY>` +\r\n `</ENVELOPE>`\r\n );\r\n}\r\n\r\nexport interface CollectionEnvelopeOptions {\r\n /**\r\n * Both the TDL <COLLECTION NAME=\"...\"> and the <ID> Tally resolves the\r\n * request by — these must be identical, since Tally looks the inline\r\n * definition up by this name within the same request.\r\n */\r\n name: string;\r\n /** Tally's internal object type the collection walks — e.g. \"Ledger\",\r\n * \"StockItem\", \"Company\", \"Group\", \"VoucherType\". Verified against\r\n * Tally's own Developer Reference (Case Study I) and a live TallyXML\r\n * Postman collection for Ledger/Company specifically. */\r\n type: string;\r\n company?: string;\r\n /**\r\n * Native field names to pull per record (become <NATIVEMETHOD> entries).\r\n * \"*\" is a valid Tally wildcard for \"everything natively available\" —\r\n * it's included by default *alongside* explicit names, because in\r\n * practice \"*\" alone has been observed to omit fields that explicit\r\n * NATIVEMETHOD entries still return. Defensive, not just decorative.\r\n */\r\n fields?: string[];\r\n /** Extra STATICVARIABLES beyond SVEXPORTFORMAT/SVCURRENTCOMPANY — e.g.\r\n * SVFROMDATE/SVTODATE for period-scoped collections. */\r\n staticVariables?: Record<string, string>;\r\n}\r\n\r\n/**\r\n * Builds a TYPE=Collection export request with an inline TDL <COLLECTION>\r\n * definition. This is Tally's documented mechanism for pulling arbitrary\r\n * entity lists (ledgers, stock items, companies, ...) — unlike\r\n * buildEnvelope()'s REPORTNAME path, it does not depend on Tally already\r\n * having a report by that name; the shape is defined entirely in the\r\n * request itself, so it works the same way regardless of Tally version or\r\n * which UI reports happen to be registered locally.\r\n *\r\n * Source: Tally Developer Reference, \"Case Study I – XML Request and\r\n * Response Formats\" → Request to Export Collection & Corresponding\r\n * Response. Field-list behavior (NATIVEMETHOD, \"*\") cross-checked against\r\n * a published Tally XML Postman collection using this exact shape for\r\n * \"List of Companies\" and \"Ledgers\".\r\n */\r\nexport function buildCollectionEnvelope(\r\n options: CollectionEnvelopeOptions,\r\n): string {\r\n const staticVars = {\r\n SVEXPORTFORMAT: \"$$SysName:XML\",\r\n ...(options.company ? { SVCURRENTCOMPANY: options.company } : {}),\r\n ...(options.staticVariables ?? {}),\r\n };\r\n\r\n const staticVarsXml = Object.entries(staticVars)\r\n .map(([key, value]) => `<${key}>${escapeXml(value)}</${key}>`)\r\n .join(\"\");\r\n\r\n const fields =\r\n options.fields && options.fields.length > 0 ? options.fields : [\"*\"];\r\n const nativeMethodsXml = fields\r\n .map((f) => `<NATIVEMETHOD>${escapeXml(f)}</NATIVEMETHOD>`)\r\n .join(\"\");\r\n\r\n const safeName = escapeXml(options.name);\r\n\r\n return (\r\n `<ENVELOPE>` +\r\n `<HEADER>` +\r\n `<VERSION>1</VERSION>` +\r\n `<TALLYREQUEST>Export</TALLYREQUEST>` +\r\n `<TYPE>Collection</TYPE>` +\r\n `<ID>${safeName}</ID>` +\r\n `</HEADER>` +\r\n `<BODY>` +\r\n `<DESC>` +\r\n `<STATICVARIABLES>${staticVarsXml}</STATICVARIABLES>` +\r\n `<TDL><TDLMESSAGE>` +\r\n `<COLLECTION NAME=\"${safeName}\" ISMODIFY=\"No\" ISFIXED=\"No\" ISINITIALIZE=\"Yes\" ISOPTION=\"No\" ISINTERNAL=\"No\">` +\r\n `<TYPE>${escapeXml(options.type)}</TYPE>` +\r\n nativeMethodsXml +\r\n `</COLLECTION>` +\r\n `</TDLMESSAGE></TDL>` +\r\n `</DESC>` +\r\n `</BODY>` +\r\n `</ENVELOPE>`\r\n );\r\n}\r\n","import type { LedgerInput, StockItemInput } from \"../../types/ledger.js\";\r\nimport { escapeXml } from \"../envelope.js\";\r\n\r\n/**\r\n * Tally master imports are wrapped in a TALLYMESSAGE envelope, with the\r\n * object's NAME duplicated as both an XML attribute on the tag (how Tally\r\n * identifies *which* object this is, for upsert-by-name semantics) and as a\r\n * <NAME> child element (how Tally reads the field value). Forgetting either\r\n * one is a common hand-rolled-XML bug this builder exists to make\r\n * impossible.\r\n */\r\nexport function buildCreateLedgerXml(input: LedgerInput): string {\r\n const addressXml = (input.address ?? [])\r\n .map((line) => `<ADDRESS>${escapeXml(line)}</ADDRESS>`)\r\n .join(\"\");\r\n\r\n const openingBalanceXml =\r\n input.openingBalance != null\r\n ? `<OPENINGBALANCE>${\r\n input.openingBalanceType === \"Credit\" ? \"-\" : \"\"\r\n }${Math.abs(input.openingBalance).toFixed(2)}</OPENINGBALANCE>`\r\n : \"\";\r\n\r\n return (\r\n `<TALLYMESSAGE xmlns:UDF=\"TallyUDF\">` +\r\n `<LEDGER NAME=\"${escapeXml(input.name)}\" ACTION=\"Create\">` +\r\n `<NAME>${escapeXml(input.name)}</NAME>` +\r\n `<PARENT>${escapeXml(input.group)}</PARENT>` +\r\n (input.gstin ? `<GSTIN>${escapeXml(input.gstin)}</GSTIN>` : \"\") +\r\n (input.state\r\n ? `<LEDSTATENAME>${escapeXml(input.state)}</LEDSTATENAME>`\r\n : \"\") +\r\n (input.pincode ? `<PINCODE>${escapeXml(input.pincode)}</PINCODE>` : \"\") +\r\n openingBalanceXml +\r\n addressXml +\r\n (input.email ? `<EMAIL>${escapeXml(input.email)}</EMAIL>` : \"\") +\r\n (input.phone\r\n ? `<LEDGERPHONE>${escapeXml(input.phone)}</LEDGERPHONE>`\r\n : \"\") +\r\n `</LEDGER>` +\r\n `</TALLYMESSAGE>`\r\n );\r\n}\r\n\r\nexport function buildCreateStockItemXml(input: StockItemInput): string {\r\n const openingXml =\r\n input.openingQty != null\r\n ? `<OPENINGBALANCE>${input.openingQty} ${escapeXml(input.unit)}</OPENINGBALANCE>` +\r\n (input.openingRate != null\r\n ? `<OPENINGRATE>${input.openingRate.toFixed(2)}/${escapeXml(input.unit)}</OPENINGRATE>` +\r\n `<OPENINGVALUE>${(input.openingQty * input.openingRate).toFixed(2)}</OPENINGVALUE>`\r\n : \"\")\r\n : \"\";\r\n\r\n return (\r\n `<TALLYMESSAGE xmlns:UDF=\"TallyUDF\">` +\r\n `<STOCKITEM NAME=\"${escapeXml(input.name)}\" ACTION=\"Create\">` +\r\n `<NAME>${escapeXml(input.name)}</NAME>` +\r\n `<PARENT>${escapeXml(input.group)}</PARENT>` +\r\n `<BASEUNITS>${escapeXml(input.unit)}</BASEUNITS>` +\r\n (input.hsnCode ? `<HSNCODE>${escapeXml(input.hsnCode)}</HSNCODE>` : \"\") +\r\n (input.gstRate != null ? `<GSTRATE>${input.gstRate}</GSTRATE>` : \"\") +\r\n openingXml +\r\n `</STOCKITEM>` +\r\n `</TALLYMESSAGE>`\r\n );\r\n}\r\n","import type {\r\n VoucherInput,\r\n SalesVoucherInput,\r\n PurchaseVoucherInput,\r\n PaymentVoucherInput,\r\n ReceiptVoucherInput,\r\n JournalVoucherInput,\r\n LineItem,\r\n} from \"../../types/voucher.js\";\r\nimport { assertNever } from \"../../types/voucher.js\";\r\nimport { escapeXml, formatTallyDate, formatSignedAmount } from \"../envelope.js\";\r\n\r\nfunction lineItemAmount(item: LineItem): number {\r\n return item.amount ?? item.quantity * item.rate;\r\n}\r\n\r\nfunction buildInventoryEntryXml(item: LineItem, isDebit: boolean): string {\r\n // Inventory entries carry both the ledger-side signed AMOUNT and the\r\n // physical ACTUALQTY/BILLEDQTY — these are allowed to diverge (e.g. free\r\n // samples), but for the common case they're the same quantity.\r\n const qty = `${item.quantity}`;\r\n return (\r\n `<ALLINVENTORYENTRIES.LIST>` +\r\n `<STOCKITEMNAME>${escapeXml(item.stockItem)}</STOCKITEMNAME>` +\r\n `<ISDEEMEDPOSITIVE>${isDebit ? \"Yes\" : \"No\"}</ISDEEMEDPOSITIVE>` +\r\n `<RATE>${item.rate.toFixed(2)}</RATE>` +\r\n `<AMOUNT>${formatSignedAmount(lineItemAmount(item), isDebit)}</AMOUNT>` +\r\n `<ACTUALQTY>${qty}</ACTUALQTY>` +\r\n `<BILLEDQTY>${qty}</BILLEDQTY>` +\r\n `</ALLINVENTORYENTRIES.LIST>`\r\n );\r\n}\r\n\r\nfunction buildLedgerEntryXml(\r\n ledgerName: string,\r\n amount: number,\r\n isDebit: boolean,\r\n): string {\r\n return (\r\n `<ALLLEDGERENTRIES.LIST>` +\r\n `<LEDGERNAME>${escapeXml(ledgerName)}</LEDGERNAME>` +\r\n `<ISDEEMEDPOSITIVE>${isDebit ? \"Yes\" : \"No\"}</ISDEEMEDPOSITIVE>` +\r\n `<AMOUNT>${formatSignedAmount(amount, isDebit)}</AMOUNT>` +\r\n `</ALLLEDGERENTRIES.LIST>`\r\n );\r\n}\r\n\r\nfunction buildSalesXml(input: SalesVoucherInput): string {\r\n const itemsTotal = input.items.reduce(\r\n (sum, item) => sum + lineItemAmount(item),\r\n 0,\r\n );\r\n const taxTotal = (input.taxes ?? []).reduce((sum, t) => sum + t.amount, 0);\r\n const partyTotal = itemsTotal + taxTotal;\r\n\r\n // Party ledger: debit, total including tax.\r\n // Sales ledger: credit, items subtotal — carries the inventory allocations.\r\n // Tax ledgers: credit, one per tax line (CGST/SGST/IGST).\r\n const partyEntry = buildLedgerEntryXml(input.party, partyTotal, true);\r\n const salesEntry =\r\n `<ALLLEDGERENTRIES.LIST>` +\r\n `<LEDGERNAME>${escapeXml(input.salesLedger)}</LEDGERNAME>` +\r\n `<ISDEEMEDPOSITIVE>No</ISDEEMEDPOSITIVE>` +\r\n `<AMOUNT>${formatSignedAmount(itemsTotal, false)}</AMOUNT>` +\r\n input.items.map((item) => buildInventoryEntryXml(item, false)).join(\"\") +\r\n `</ALLLEDGERENTRIES.LIST>`;\r\n const taxEntries = (input.taxes ?? [])\r\n .map((t) => buildLedgerEntryXml(t.ledger, t.amount, false))\r\n .join(\"\");\r\n\r\n return buildVoucherEnvelope({\r\n voucherTypeName: \"Sales\",\r\n date: input.date,\r\n narration: input.narration,\r\n voucherNumber: input.voucherNumber,\r\n reference: input.reference,\r\n isInvoice: true,\r\n partyName: input.party,\r\n body: partyEntry + salesEntry + taxEntries,\r\n });\r\n}\r\n\r\nfunction buildPurchaseXml(input: PurchaseVoucherInput): string {\r\n const itemsTotal = input.items.reduce(\r\n (sum, item) => sum + lineItemAmount(item),\r\n 0,\r\n );\r\n const taxTotal = (input.taxes ?? []).reduce((sum, t) => sum + t.amount, 0);\r\n const partyTotal = itemsTotal + taxTotal;\r\n\r\n // Mirror image of Sales: party is credited, purchase ledger is debited.\r\n const partyEntry = buildLedgerEntryXml(input.party, partyTotal, false);\r\n const purchaseEntry =\r\n `<ALLLEDGERENTRIES.LIST>` +\r\n `<LEDGERNAME>${escapeXml(input.purchaseLedger)}</LEDGERNAME>` +\r\n `<ISDEEMEDPOSITIVE>Yes</ISDEEMEDPOSITIVE>` +\r\n `<AMOUNT>${formatSignedAmount(itemsTotal, true)}</AMOUNT>` +\r\n input.items.map((item) => buildInventoryEntryXml(item, true)).join(\"\") +\r\n `</ALLLEDGERENTRIES.LIST>`;\r\n const taxEntries = (input.taxes ?? [])\r\n .map((t) => buildLedgerEntryXml(t.ledger, t.amount, true))\r\n .join(\"\");\r\n\r\n return buildVoucherEnvelope({\r\n voucherTypeName: \"Purchase\",\r\n date: input.date,\r\n narration: input.narration,\r\n voucherNumber: input.voucherNumber,\r\n reference: input.reference,\r\n isInvoice: true,\r\n partyName: input.party,\r\n body: partyEntry + purchaseEntry + taxEntries,\r\n });\r\n}\r\n\r\nfunction buildPaymentXml(input: PaymentVoucherInput): string {\r\n const body =\r\n buildLedgerEntryXml(input.debitLedger, input.amount, true) +\r\n buildLedgerEntryXml(input.creditLedger, input.amount, false);\r\n return buildVoucherEnvelope({\r\n voucherTypeName: \"Payment\",\r\n date: input.date,\r\n narration: input.narration,\r\n voucherNumber: input.voucherNumber,\r\n reference: input.reference,\r\n isInvoice: false,\r\n body,\r\n });\r\n}\r\n\r\nfunction buildReceiptXml(input: ReceiptVoucherInput): string {\r\n const body =\r\n buildLedgerEntryXml(input.debitLedger, input.amount, true) +\r\n buildLedgerEntryXml(input.creditLedger, input.amount, false);\r\n return buildVoucherEnvelope({\r\n voucherTypeName: \"Receipt\",\r\n date: input.date,\r\n narration: input.narration,\r\n voucherNumber: input.voucherNumber,\r\n reference: input.reference,\r\n isInvoice: false,\r\n body,\r\n });\r\n}\r\n\r\nfunction buildJournalXml(input: JournalVoucherInput): string {\r\n const body = input.entries\r\n .map((e) => buildLedgerEntryXml(e.ledger, e.amount, e.type === \"Debit\"))\r\n .join(\"\");\r\n return buildVoucherEnvelope({\r\n voucherTypeName: \"Journal\",\r\n date: input.date,\r\n narration: input.narration,\r\n voucherNumber: input.voucherNumber,\r\n reference: input.reference,\r\n isInvoice: false,\r\n body,\r\n });\r\n}\r\n\r\ninterface VoucherEnvelopeOptions {\r\n voucherTypeName: string;\r\n date: Date;\r\n narration?: string;\r\n voucherNumber?: string;\r\n reference?: string;\r\n /** Sales/Purchase render as \"invoice\" voucher class in Tally (affects\r\n * whether ALLINVENTORYENTRIES are expected) — Payment/Receipt/Journal don't. */\r\n isInvoice: boolean;\r\n partyName?: string;\r\n body: string;\r\n}\r\n\r\nfunction buildVoucherEnvelope(opts: VoucherEnvelopeOptions): string {\r\n return (\r\n `<TALLYMESSAGE xmlns:UDF=\"TallyUDF\">` +\r\n `<VOUCHER VCHTYPE=\"${escapeXml(opts.voucherTypeName)}\" ACTION=\"Create\"` +\r\n (opts.isInvoice ? ` ISINVOICE=\"Yes\"` : \"\") +\r\n `>` +\r\n `<DATE>${formatTallyDate(opts.date)}</DATE>` +\r\n `<VOUCHERTYPENAME>${escapeXml(opts.voucherTypeName)}</VOUCHERTYPENAME>` +\r\n (opts.voucherNumber\r\n ? `<VOUCHERNUMBER>${escapeXml(opts.voucherNumber)}</VOUCHERNUMBER>`\r\n : \"\") +\r\n (opts.partyName\r\n ? `<PARTYLEDGERNAME>${escapeXml(opts.partyName)}</PARTYLEDGERNAME>`\r\n : \"\") +\r\n (opts.reference\r\n ? `<REFERENCE>${escapeXml(opts.reference)}</REFERENCE>`\r\n : \"\") +\r\n (opts.narration\r\n ? `<NARRATION>${escapeXml(opts.narration)}</NARRATION>`\r\n : \"\") +\r\n opts.body +\r\n `</VOUCHER>` +\r\n `</TALLYMESSAGE>`\r\n );\r\n}\r\n\r\n/**\r\n * The exhaustive switch: TypeScript will refuse to compile this file if a\r\n * sixth voucher type is added to VoucherInput without a matching case here —\r\n * that's the whole point of routing every variant through assertNever in\r\n * the default branch instead of leaving it untyped.\r\n */\r\nexport function buildVoucherXml(input: VoucherInput): string {\r\n switch (input.voucherType) {\r\n case \"Sales\":\r\n return buildSalesXml(input);\r\n case \"Purchase\":\r\n return buildPurchaseXml(input);\r\n case \"Payment\":\r\n return buildPaymentXml(input);\r\n case \"Receipt\":\r\n return buildReceiptXml(input);\r\n case \"Journal\":\r\n return buildJournalXml(input);\r\n default:\r\n return assertNever(input);\r\n }\r\n}\r\n","import {\r\n buildEnvelope,\r\n buildCollectionEnvelope,\r\n formatTallyDate,\r\n} from \"../envelope.js\";\r\n\r\n/**\r\n * Earlier version of this file guessed free-text REPORTNAME values\r\n * (\"List of Companies\", \"List of Ledgers\", \"List of Stock Items\") against\r\n * buildEnvelope(). Confirmed live against a real TallyPrime instance that\r\n * those names aren't registered reports — Tally returned a bare\r\n * <RESPONSE><LINEERROR>Could not find Report '...'!</LINEERROR></RESPONSE>\r\n * for all three.\r\n *\r\n * Entity lists now go through buildCollectionEnvelope(), Tally's documented\r\n * TYPE=Collection + inline TDL mechanism, which doesn't depend on a\r\n * pre-registered report existing at all — the shape is fully self-describing\r\n * in the request. buildEnvelope()'s REPORTNAME path is kept for\r\n * getOutstanding(), since \"Bills Receivable\" *is* a real registered report\r\n * (confirmed: no LINEERROR), it just needs a static-variable fix (below).\r\n */\r\n\r\nexport function buildGetCompaniesXml(): string {\r\n return buildCollectionEnvelope({\r\n name: \"List of Companies\",\r\n type: \"Company\",\r\n fields: [\"Name\", \"Guid\", \"StartingFrom\", \"BooksFrom\", \"*\"],\r\n // Newer TallyPrime releases distinguish \"Simple\" companies from full\r\n // ones; without this some installs omit Simple companies from the\r\n // collection. Harmless no-op on installs that don't have the concept.\r\n staticVariables: { SVIsSimpleCompany: \"No\" },\r\n });\r\n}\r\n\r\nexport function buildGetLedgersXml(company?: string): string {\r\n return buildCollectionEnvelope({\r\n name: \"Ledgers\",\r\n type: \"Ledger\",\r\n company,\r\n fields: [\r\n \"Name\",\r\n \"Parent\",\r\n \"OpeningBalance\",\r\n \"ClosingBalance\",\r\n \"GSTIN\",\r\n \"LedStateName\",\r\n \"*\",\r\n ],\r\n });\r\n}\r\n\r\nexport function buildGetStockItemsXml(company?: string): string {\r\n return buildCollectionEnvelope({\r\n name: \"StockItems\",\r\n type: \"StockItem\",\r\n company,\r\n fields: [\r\n \"Name\",\r\n \"Guid\",\r\n \"BaseUnits\",\r\n \"ClosingBalance\",\r\n \"ClosingValue\",\r\n \"HSNCode\",\r\n \"GSTRate\",\r\n \"*\",\r\n ],\r\n });\r\n}\r\n\r\n/**\r\n * \"Bills Receivable\" is confirmed as a real registered report (no\r\n * LINEERROR), but came back as an empty <ENVELOPE></ENVELOPE> in testing —\r\n * most likely because, without an explicit date range, Tally fell back to\r\n * a default period with nothing in it. Pass `dateRange` to scope it\r\n * explicitly. UNVERIFIED beyond this reasoning — confirm against your\r\n * instance with the updated raw-test script before relying on it; if it's\r\n * still empty with a date range supplied, this report may need to be\r\n * queried as its own TDL Collection rather than as a named report at all.\r\n */\r\nexport function buildGetOutstandingXml(\r\n company?: string,\r\n dateRange?: { from: Date; to: Date },\r\n): string {\r\n return buildEnvelope({\r\n requestType: \"Export Data\",\r\n id: \"Bills Receivable\", // swap to \"Bills Payable\" for AP outstanding\r\n company,\r\n staticVariables: {\r\n SVEXPORTFORMAT: \"$$SysName:XML\",\r\n ...(dateRange\r\n ? {\r\n SVFROMDATE: formatTallyDate(dateRange.from),\r\n SVTODATE: formatTallyDate(dateRange.to),\r\n }\r\n : {}),\r\n },\r\n });\r\n}\r\n\r\nexport function buildPingXml(): string {\r\n // Tally has no dedicated health-check endpoint; the cheapest real request\r\n // that proves the HTTP-XML server is alive and a company is loaded is a\r\n // company list export, so ping() reuses this builder rather than\r\n // round-tripping a fake malformed request and hoping for a fast failure.\r\n return buildGetCompaniesXml();\r\n}\r\n","import { XMLParser } from \"fast-xml-parser\";\r\nimport type { VoucherCreateResult } from \"../../types/voucher.js\";\r\nimport {\r\n ok,\r\n err,\r\n tallyError,\r\n type Result,\r\n type TallyError,\r\n} from \"../../types/result.js\";\r\n\r\nconst parser = new XMLParser({\r\n ignoreAttributes: false,\r\n attributeNamePrefix: \"@_\",\r\n // Tally repeats sibling tags (LINEERROR, etc.) without warning when there's\r\n // more than one — force these into arrays unconditionally so downstream\r\n // code never has to special-case \"string vs array of one\".\r\n isArray: (tagName) => [\"LINEERROR\", \"TALLYMESSAGE\"].includes(tagName),\r\n // Tally emits &#4; as an empty-but-present marker on some master fields;\r\n // fast-xml-parser decodes numeric entities by default, which turns it into\r\n // an unprintable control character rather than throwing — we normalize it\r\n // back to an empty string post-parse instead of fighting the entity\r\n // decoder.\r\n});\r\n\r\ninterface RawImportResponse {\r\n RESPONSE?: { LINEERROR?: string[] };\r\n ENVELOPE?: {\r\n HEADER?: { STATUS?: string | number };\r\n BODY?: {\r\n DATA?: {\r\n IMPORTRESULT?: {\r\n CREATED?: string | number;\r\n ALTERED?: string | number;\r\n LASTVCHID?: string | number;\r\n LASTMID?: string | number;\r\n ERRORS?: string | number;\r\n };\r\n };\r\n // LINEERROR sometimes appears directly under BODY rather than nested\r\n // under DATA, depending on Tally version — checked at both paths below.\r\n LINEERROR?: string[];\r\n };\r\n };\r\n}\r\n\r\n/**\r\n * Parses a response to an Import Data request (createLedger, createVoucher,\r\n * etc). Two-pass by design: first parse the XML unconditionally, then\r\n * inspect the parsed tree for error markers. We never string-match on raw\r\n * XML for \"LINEERROR\" — that breaks the moment Tally changes whitespace or\r\n * attribute order, which it does between versions.\r\n */\r\nexport function parseImportResponse(\r\n rawXml: string,\r\n): Result<VoucherCreateResult, TallyError> {\r\n let parsed: RawImportResponse;\r\n try {\r\n parsed = parser.parse(rawXml) as RawImportResponse;\r\n } catch (cause) {\r\n return err(\r\n tallyError(\"PARSE_ERROR\", \"Could not parse Tally's response as XML\", {\r\n responseXml: rawXml,\r\n cause,\r\n }),\r\n );\r\n }\r\n\r\n // Tally signals \"could not resolve this report/request\" with a bare\r\n // <RESPONSE><LINEERROR>...</LINEERROR></RESPONSE> root — no <ENVELOPE> at\r\n // all. Confirmed live against a real instance. Checked first, before the\r\n // ENVELOPE-wrapped path below.\r\n const bareLineErrors = parsed.RESPONSE?.LINEERROR;\r\n if (bareLineErrors && bareLineErrors.length > 0) {\r\n return err(\r\n tallyError(\"TALLY_REJECTED\", \"Tally rejected the request\", {\r\n tallyMessage: bareLineErrors.join(\"; \"),\r\n responseXml: rawXml,\r\n }),\r\n );\r\n }\r\n\r\n const body = parsed.ENVELOPE?.BODY;\r\n const lineErrors = body?.LINEERROR;\r\n\r\n if (lineErrors && lineErrors.length > 0) {\r\n return err(\r\n tallyError(\"TALLY_REJECTED\", \"Tally rejected the request\", {\r\n tallyMessage: lineErrors.join(\"; \"),\r\n responseXml: rawXml,\r\n }),\r\n );\r\n }\r\n\r\n const result = body?.DATA?.IMPORTRESULT;\r\n const created = Number(result?.CREATED ?? 0);\r\n const altered = Number(result?.ALTERED ?? 0);\r\n const errors = Number(result?.ERRORS ?? 0);\r\n\r\n if (errors > 0) {\r\n return err(\r\n tallyError(\r\n \"TALLY_REJECTED\",\r\n `Tally reported ${errors} error(s) during import`,\r\n {\r\n responseXml: rawXml,\r\n },\r\n ),\r\n );\r\n }\r\n\r\n if (created === 0 && altered === 0) {\r\n // Not necessarily fatal (e.g. an idempotent re-create of an identical\r\n // object can legitimately report 0/0), but it's surprising enough that\r\n // callers should see it as a distinct, named outcome rather than a\r\n // silent success that looks identical to \"created: 1\".\r\n return err(\r\n tallyError(\r\n \"PARSE_ERROR\",\r\n \"Tally returned no CREATED/ALTERED count and no error — unexpected response shape\",\r\n {\r\n responseXml: rawXml,\r\n },\r\n ),\r\n );\r\n }\r\n\r\n return ok({\r\n voucherNumber: String(result?.LASTVCHID ?? \"\"),\r\n guid: String(result?.LASTMID ?? \"\"),\r\n alteredOn: new Date(),\r\n });\r\n}\r\n","import { XMLParser } from \"fast-xml-parser\";\r\nimport type {\r\n Ledger,\r\n StockItem,\r\n Company,\r\n OutstandingEntry,\r\n} from \"../../types/ledger.js\";\r\nimport {\r\n ok,\r\n err,\r\n tallyError,\r\n type Result,\r\n type TallyError,\r\n} from \"../../types/result.js\";\r\n\r\n/**\r\n * The classic XML-to-JSON trap: when a collection has exactly one matching\r\n * record, most XML parsers (including fast-xml-parser without isArray\r\n * hints) collapse `<LEDGER>...</LEDGER>` into a bare object instead of a\r\n * one-element array, because nothing in the XML itself says \"this is a\r\n * repeatable element\" — that's structural knowledge, not something the\r\n * parser can infer from a single instance.\r\n *\r\n * We force every collection tag we read into an array via isArray, so\r\n * \"zero, one, or many results\" is always one shape (T[]) at the call site\r\n * instead of three (undefined | T | T[]).\r\n */\r\nconst COLLECTION_TAGS = [\"LEDGER\", \"STOCKITEM\", \"COMPANY\", \"BILLOUTSTANDING\"];\r\n\r\nconst parser = new XMLParser({\r\n ignoreAttributes: false,\r\n attributeNamePrefix: \"@_\",\r\n isArray: (tagName) => COLLECTION_TAGS.includes(tagName),\r\n});\r\n\r\nfunction parseTallyNumber(raw: unknown): number | undefined {\r\n if (raw == null) return undefined;\r\n // Tally renders negative numbers in collection exports with a trailing\r\n // \" Cr\"/\" Dr\" suffix on some reports and a leading \"-\" on others,\r\n // depending on report type — strip both and let the sign survive.\r\n const cleaned = String(raw)\r\n .replace(/\\s*(Cr|Dr)\\s*$/i, \"\")\r\n .replace(/,/g, \"\")\r\n .trim();\r\n const n = Number(cleaned);\r\n return Number.isFinite(n) ? n : undefined;\r\n}\r\n\r\nfunction safeParse<T>(\r\n rawXml: string,\r\n extract: (parsed: unknown) => T,\r\n): Result<T, TallyError> {\r\n try {\r\n const parsed = parser.parse(rawXml);\r\n return ok(extract(parsed));\r\n } catch (cause) {\r\n return err(\r\n tallyError(\"PARSE_ERROR\", \"Could not parse Tally's collection response\", {\r\n responseXml: rawXml,\r\n cause,\r\n }),\r\n );\r\n }\r\n}\r\n\r\n// Loose shape — Tally's export XML nesting varies by version/report, so we\r\n// reach for fields defensively (?. everywhere) rather than asserting a rigid\r\n// interface that breaks on the next Tally point release.\r\ntype LooseTree = Record<string, any>;\r\n\r\nfunction findCollectionRoot(parsed: LooseTree): LooseTree {\r\n return (\r\n parsed?.ENVELOPE?.BODY?.DATA?.COLLECTION ??\r\n parsed?.ENVELOPE?.BODY?.DATA ??\r\n {}\r\n );\r\n}\r\n\r\nexport function parseLedgerCollection(\r\n rawXml: string,\r\n): Result<Ledger[], TallyError> {\r\n return safeParse(rawXml, (parsed) => {\r\n const root = findCollectionRoot(parsed as LooseTree);\r\n const ledgers: LooseTree[] = root.LEDGER ?? [];\r\n return ledgers.map((l) => ({\r\n name: String(l[\"@_NAME\"] ?? l.NAME ?? \"\"),\r\n guid: String(l.GUID ?? \"\"),\r\n group: String(l.PARENT ?? \"\"),\r\n gstin: l.GSTIN ? String(l.GSTIN) : undefined,\r\n closingBalance: parseTallyNumber(l.CLOSINGBALANCE),\r\n state: l.LEDSTATENAME ? String(l.LEDSTATENAME) : undefined,\r\n }));\r\n });\r\n}\r\n\r\nexport function parseStockItemCollection(\r\n rawXml: string,\r\n): Result<StockItem[], TallyError> {\r\n return safeParse(rawXml, (parsed) => {\r\n const root = findCollectionRoot(parsed as LooseTree);\r\n const items: LooseTree[] = root.STOCKITEM ?? [];\r\n return items.map((s) => ({\r\n name: String(s[\"@_NAME\"] ?? s.NAME ?? \"\"),\r\n guid: String(s.GUID ?? \"\"),\r\n unit: String(s.BASEUNITS ?? \"\"),\r\n closingQty: parseTallyNumber(s.CLOSINGBALANCE),\r\n closingValue: parseTallyNumber(s.CLOSINGVALUE),\r\n hsnCode: s.HSNCODE ? String(s.HSNCODE) : undefined,\r\n gstRate: parseTallyNumber(s.GSTRATE),\r\n }));\r\n });\r\n}\r\n\r\nexport function parseCompanyCollection(\r\n rawXml: string,\r\n): Result<Company[], TallyError> {\r\n return safeParse(rawXml, (parsed) => {\r\n const root = findCollectionRoot(parsed as LooseTree);\r\n const companies: LooseTree[] = root.COMPANY ?? [];\r\n return companies.map((c) => ({\r\n name: String(c[\"@_NAME\"] ?? c.NAME ?? \"\"),\r\n guid: String(c.GUID ?? \"\"),\r\n startingFrom: c.STARTINGFROM ? String(c.STARTINGFROM) : undefined,\r\n endingAt: c.ENDINGAT ? String(c.ENDINGAT) : undefined,\r\n }));\r\n });\r\n}\r\n\r\nexport function parseOutstandingCollection(\r\n rawXml: string,\r\n): Result<OutstandingEntry[], TallyError> {\r\n return safeParse(rawXml, (parsed) => {\r\n const root = findCollectionRoot(parsed as LooseTree);\r\n const bills: LooseTree[] = root.BILLOUTSTANDING ?? [];\r\n return bills.map((b) => ({\r\n ledgerName: String(b.LEDGERNAME ?? \"\"),\r\n voucherNumber: String(b.VOUCHERNUMBER ?? \"\"),\r\n voucherDate: new Date(String(b.VOUCHERDATE ?? \"\")),\r\n dueDate: b.DUEDATE ? new Date(String(b.DUEDATE)) : undefined,\r\n pendingAmount: parseTallyNumber(b.PENDINGAMOUNT) ?? 0,\r\n overdueDays: b.OVERDUEDAYS != null ? Number(b.OVERDUEDAYS) : undefined,\r\n }));\r\n });\r\n}\r\n","import type { Result, TallyConfig, TallyError } from \"../types/result.js\";\r\nimport { ok, err, tallyError } from \"../types/result.js\";\r\n\r\n/**\r\n * Tally's HTTP-XML server takes every request as a raw XML POST body to the\r\n * root path — there's no REST routing, no headers carrying semantics, just\r\n * \"post some XML, get some XML back\". That makes this transport layer\r\n * unusually thin: its only real job is turning network-level failures\r\n * (DNS, connection refused, timeout) into typed errors and retrying *only*\r\n * those — never retrying a request that reached Tally and got a real\r\n * response, because Tally-side rejections aren't transient.\r\n */\r\nexport class TallyTransport {\r\n private readonly retries: number;\r\n\r\n constructor(private readonly config: TallyConfig) {\r\n this.retries = config.retries ?? 1;\r\n }\r\n\r\n async send(requestXml: string): Promise<Result<string, TallyError>> {\r\n let lastError: TallyError | undefined;\r\n\r\n const protocol = this.config.https ? \"https\" : \"http\";\r\n const url = `${protocol}://${this.config.host}:${this.config.port}/`;\r\n\r\n for (let attempt = 0; attempt <= this.retries; attempt++) {\r\n try {\r\n const response = await fetch(url, {\r\n method: \"POST\",\r\n headers: {\r\n \"Content-Type\": \"text/xml\",\r\n },\r\n body: requestXml,\r\n signal: AbortSignal.timeout(this.config.timeoutMs ?? 15_000),\r\n });\r\n\r\n const responseText = await response.text();\r\n\r\n // Tally responded with something (even HTTP error status) —\r\n // that's a real response, hand it back rather than retrying.\r\n return ok(responseText);\r\n } catch (cause) {\r\n if (cause instanceof Error) {\r\n if (cause.name === \"TimeoutError\" || cause.name === \"AbortError\") {\r\n lastError = tallyError(\r\n \"TIMEOUT\",\r\n `Request to Tally timed out after ${\r\n this.config.timeoutMs ?? 15_000\r\n }ms`,\r\n {\r\n requestXml,\r\n cause,\r\n },\r\n );\r\n\r\n // Timeouts are ambiguous (the voucher may have been created\r\n // server-side even though we never saw the response) — still\r\n // retryable for read operations, but callers doing writes\r\n // should treat a TIMEOUT differently from a clean NETWORK_ERROR.\r\n continue;\r\n }\r\n\r\n // No response at all = connection refused, DNS failure, Tally\r\n // not running, wrong port — genuinely safe to retry.\r\n if (cause instanceof TypeError) {\r\n lastError = tallyError(\r\n \"NETWORK_ERROR\",\r\n `Could not reach Tally at ${this.config.host}:${this.config.port}`,\r\n {\r\n requestXml,\r\n cause,\r\n },\r\n );\r\n continue;\r\n }\r\n }\r\n\r\n lastError = tallyError(\r\n \"UNKNOWN\",\r\n \"Unexpected error sending request to Tally\",\r\n {\r\n requestXml,\r\n cause,\r\n },\r\n );\r\n\r\n break;\r\n }\r\n }\r\n\r\n return err(\r\n lastError ??\r\n tallyError(\"UNKNOWN\", \"Request failed with no captured error\"),\r\n );\r\n }\r\n}\r\n","import { z } from \"zod\";\r\nimport type { TallyConfig, Result, TallyError } from \"../types/result.js\";\r\nimport { ok, err, tallyError } from \"../types/result.js\";\r\nimport {\r\n buildCreateLedgerXml,\r\n buildCreateStockItemXml,\r\n buildVoucherXml,\r\n buildGetCompaniesXml,\r\n buildGetLedgersXml,\r\n buildGetStockItemsXml,\r\n buildGetOutstandingXml,\r\n buildPingXml,\r\n parseImportResponse,\r\n parseLedgerCollection,\r\n parseStockItemCollection,\r\n parseCompanyCollection,\r\n parseOutstandingCollection,\r\n} from \"../xml/index.js\";\r\nimport { TallyTransport } from \"./transport.js\";\r\nimport {\r\n JournalVoucherInputSchema,\r\n PaymentVoucherInputSchema,\r\n PurchaseVoucherInputSchema,\r\n ReceiptVoucherInputSchema,\r\n SalesVoucherInputSchema,\r\n type SalesVoucherInput,\r\n type VoucherCreateResult,\r\n type VoucherInput,\r\n} from \"../types/voucher.js\";\r\nimport {\r\n LedgerInputSchema,\r\n StockItemInputSchema,\r\n type Company,\r\n type Ledger,\r\n type LedgerInput,\r\n type OutstandingEntry,\r\n type StockItem,\r\n type StockItemInput,\r\n} from \"../types/ledger.js\";\r\n\r\n/**\r\n * Voucher validation can't go through a single z.discriminatedUnion the way\r\n * Ledger/StockItem can, because JournalVoucherInputSchema is a refined\r\n * (ZodEffects) schema and Zod's discriminatedUnion only accepts plain\r\n * object schemas as members. Switching on voucherType first and validating\r\n * against the matching schema gets the same guarantee — nothing reaches the\r\n * XML builder unvalidated — without fighting Zod's type constraints.\r\n */\r\nfunction validateVoucherInput(\r\n input: VoucherInput,\r\n): Result<VoucherInput, TallyError> {\r\n const schema = {\r\n Sales: SalesVoucherInputSchema,\r\n Purchase: PurchaseVoucherInputSchema,\r\n Payment: PaymentVoucherInputSchema,\r\n Receipt: ReceiptVoucherInputSchema,\r\n Journal: JournalVoucherInputSchema,\r\n }[input.voucherType];\r\n\r\n const parsed = schema.safeParse(input);\r\n if (!parsed.success) {\r\n return err(\r\n tallyError(\r\n \"VALIDATION_ERROR\",\r\n `Invalid ${input.voucherType} voucher input`,\r\n {\r\n cause: parsed.error,\r\n },\r\n ),\r\n );\r\n }\r\n return ok(parsed.data as VoucherInput);\r\n}\r\n\r\nexport class Tally {\r\n private readonly transport: TallyTransport;\r\n private readonly company?: string;\r\n\r\n constructor(config: TallyConfig) {\r\n this.transport = new TallyTransport(config);\r\n this.company = config.company;\r\n }\r\n\r\n // ---- Connection -------------------------------------------------------\r\n\r\n async ping(): Promise<Result<true, TallyError>> {\r\n const result = await this.transport.send(buildPingXml());\r\n if (!result.ok) return result;\r\n // A real Tally instance always echoes back a well-formed ENVELOPE, even\r\n // for an empty company list — so \"did this parse as XML at all\" is a\r\n // sufficient liveness check without needing a dedicated builder.\r\n if (!result.value.includes(\"<ENVELOPE>\")) {\r\n return err(\r\n tallyError(\r\n \"PARSE_ERROR\",\r\n \"Response did not look like a Tally ENVELOPE\",\r\n { responseXml: result.value },\r\n ),\r\n );\r\n }\r\n return ok(true);\r\n }\r\n\r\n // ---- Reads --------------------------------------------------------------\r\n\r\n async getCompanies(): Promise<Result<Company[], TallyError>> {\r\n const res = await this.transport.send(buildGetCompaniesXml());\r\n if (!res.ok) return res;\r\n return parseCompanyCollection(res.value);\r\n }\r\n\r\n async getLedgers(): Promise<Result<Ledger[], TallyError>> {\r\n const res = await this.transport.send(buildGetLedgersXml(this.company));\r\n if (!res.ok) return res;\r\n return parseLedgerCollection(res.value);\r\n }\r\n\r\n /** Alias matching the original product sketch's naming. */\r\n async getCustomers(): Promise<Result<Ledger[], TallyError>> {\r\n const res = await this.getLedgers();\r\n if (!res.ok) return res;\r\n return ok(res.value.filter((l) => l.group === \"Sundry Debtors\"));\r\n }\r\n\r\n async getStockItems(): Promise<Result<StockItem[], TallyError>> {\r\n const res = await this.transport.send(buildGetStockItemsXml(this.company));\r\n if (!res.ok) return res;\r\n return parseStockItemCollection(res.value);\r\n }\r\n\r\n async getOutstanding(dateRange?: {\r\n from: Date;\r\n to: Date;\r\n }): Promise<Result<OutstandingEntry[], TallyError>> {\r\n const res = await this.transport.send(\r\n buildGetOutstandingXml(this.company, dateRange),\r\n );\r\n if (!res.ok) return res;\r\n return parseOutstandingCollection(res.value);\r\n }\r\n\r\n // ---- Writes -------------------------------------------------------------\r\n\r\n async createLedger(\r\n input: LedgerInput,\r\n ): Promise<Result<VoucherCreateResult, TallyError>> {\r\n const parsed = LedgerInputSchema.safeParse(input);\r\n if (!parsed.success) {\r\n return err(\r\n tallyError(\"VALIDATION_ERROR\", \"Invalid ledger input\", {\r\n cause: parsed.error,\r\n }),\r\n );\r\n }\r\n const xml = buildCreateLedgerXml(parsed.data);\r\n const res = await this.transport.send(xml);\r\n if (!res.ok) return res;\r\n return parseImportResponse(res.value);\r\n }\r\n\r\n async createStockItem(\r\n input: StockItemInput,\r\n ): Promise<Result<VoucherCreateResult, TallyError>> {\r\n const parsed = StockItemInputSchema.safeParse(input);\r\n if (!parsed.success) {\r\n return err(\r\n tallyError(\"VALIDATION_ERROR\", \"Invalid stock item input\", {\r\n cause: parsed.error,\r\n }),\r\n );\r\n }\r\n const xml = buildCreateStockItemXml(parsed.data);\r\n const res = await this.transport.send(xml);\r\n if (!res.ok) return res;\r\n return parseImportResponse(res.value);\r\n }\r\n\r\n async createVoucher(\r\n input: VoucherInput,\r\n ): Promise<Result<VoucherCreateResult, TallyError>> {\r\n const validated = validateVoucherInput(input);\r\n if (!validated.ok) return validated;\r\n const xml = buildVoucherXml(validated.value);\r\n const res = await this.transport.send(xml);\r\n if (!res.ok) return res;\r\n return parseImportResponse(res.value);\r\n }\r\n\r\n /**\r\n * Convenience wrapper matching the original sketch's `createInvoice()`\r\n * signature — expands into a full SalesVoucherInput (voucherType: \"Sales\")\r\n * before going through the same validated path as createVoucher(). Kept\r\n * separate from createVoucher() because \"invoice\" maps to a Sales voucher\r\n * specifically, and spelling that out here means callers coming from\r\n * other invoicing tools (Stripe, Zoho) don't need to know Tally's\r\n * voucherType vocabulary at all.\r\n */\r\n async createInvoice(input: {\r\n customer: string;\r\n date: Date;\r\n items: SalesVoucherInput[\"items\"];\r\n salesLedger?: string;\r\n taxes?: SalesVoucherInput[\"taxes\"];\r\n reference?: string;\r\n narration?: string;\r\n }): Promise<Result<VoucherCreateResult, TallyError>> {\r\n return this.createVoucher({\r\n voucherType: \"Sales\",\r\n date: input.date,\r\n party: input.customer,\r\n items: input.items,\r\n salesLedger: input.salesLedger ?? \"Sales\",\r\n taxes: input.taxes,\r\n reference: input.reference,\r\n narration: input.narration,\r\n });\r\n }\r\n\r\n // ---- AI agent integration ------------------------------------------------\r\n\r\n /**\r\n * Returns JSON-Schema-shaped tool definitions (derived from the same Zod\r\n * schemas used for validation, so the agent-facing contract can never\r\n * drift from what the SDK actually accepts) for OpenAI-style function\r\n * calling, LangGraph, Mastra, or a hand-rolled MCP server. Each `handler`\r\n * closes over `this`, so a caller can wire these straight into an agent\r\n * framework's tool registry without writing adapter glue.\r\n */\r\n tools() {\r\n return [\r\n {\r\n name: \"getCustomers\",\r\n description:\r\n \"List all Sundry Debtor ledgers (customers) in the active Tally company.\",\r\n parameters: z.object({}),\r\n handler: () => this.getCustomers(),\r\n },\r\n {\r\n name: \"getOutstanding\",\r\n description:\r\n \"Get outstanding (unpaid) receivable bills across all customers.\",\r\n parameters: z.object({}),\r\n handler: () => this.getOutstanding(),\r\n },\r\n {\r\n name: \"createInvoice\",\r\n description:\r\n \"Create a sales invoice for a customer with one or more line items.\",\r\n parameters: z.object({\r\n customer: z.string(),\r\n date: z.coerce.date(),\r\n items: z.array(\r\n z.object({\r\n stockItem: z.string(),\r\n quantity: z.number(),\r\n rate: z.number(),\r\n }),\r\n ),\r\n }),\r\n handler: (args: {\r\n customer: string;\r\n date: Date;\r\n items: SalesVoucherInput[\"items\"];\r\n }) => this.createInvoice(args),\r\n },\r\n {\r\n name: \"createLedger\",\r\n description:\r\n \"Create a new ledger account (e.g. a new customer or supplier) in Tally.\",\r\n parameters: LedgerInputSchema,\r\n handler: (args: LedgerInput) => this.createLedger(args),\r\n },\r\n ] as const;\r\n }\r\n}\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paprflare/tally",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "module": "index.ts",
5
5
  "type": "module",
6
6
  "private": false,