{"_id":"@ejosterberg/opensalestax-square","_rev":"5-f5638cb027850be705a20f5c30655773","name":"@ejosterberg/opensalestax-square","dist-tags":{"alpha":"0.1.0-alpha.1","latest":"0.1.2"},"versions":{"0.1.0-alpha.1":{"name":"@ejosterberg/opensalestax-square","version":"0.1.0-alpha.1","keywords":["square","square-api","tax","sales-tax","us-tax","opensalestax","tax-calculation","library"],"author":{"name":"Eric Osterberg","email":"ejosterberg@gmail.com"},"license":"Apache-2.0","_id":"@ejosterberg/opensalestax-square@0.1.0-alpha.1","maintainers":[{"name":"ejosterberg","email":"ejosterberg@gmail.com"}],"homepage":"https://github.com/ejosterberg/opensalestax-square","bugs":{"url":"https://github.com/ejosterberg/opensalestax-square/issues"},"dist":{"shasum":"31759265c7d4af13f6a59984f1e88aa043f2c0dd","tarball":"https://registry.npmjs.org/@ejosterberg/opensalestax-square/-/opensalestax-square-0.1.0-alpha.1.tgz","fileCount":29,"integrity":"sha512-wPrwRyMGwQtZF87Em+S9MfqGVwzDyyqUuTVr61zt/9CsECJtDEmdCsCP9d+7dZLyMCoiGqAidyNCI9vPpW1JtQ==","signatures":[{"sig":"MEUCIQDFDkDBXfWC3Zf+bXAaDi3VxxEy0aI1CGfCZDAF/TdvygIgZueC0z27XeiBpcoLMszHIbIW8rW+UZEgVvFMy1J0CE0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":79703},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=20"},"gitHead":"6abbe59cef3db6f196985acb902d0c9bbc6e681e","scripts":{"lint":"eslint .","test":"jest","audit":"npm audit --omit=dev --audit-level=high","build":"tsc -p tsconfig.build.json","check":"npm run lint && npm run typecheck && npm test && npm run audit","clean":"rimraf dist coverage .scannerwork","smoke":"ts-node tools/smoke-engine.ts","format":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\" \"tools/**/*.ts\"","lint:fix":"eslint . --fix","typecheck":"tsc --noEmit","format:check":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\" \"tools/**/*.ts\"","test:coverage":"jest --coverage","prepublishOnly":"npm run check && npm run build"},"_npmUser":{"name":"ejosterberg","email":"ejosterberg@gmail.com"},"repository":{"url":"git+https://github.com/ejosterberg/opensalestax-square.git","type":"git"},"_npmVersion":"11.4.2","description":"Server-side TypeScript library that computes destination-based US sales tax for Square Orders and Invoices via the self-hosted OpenSalesTax engine.","directories":{},"_nodeVersion":"22.17.0","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","nock":"^14.0.15","eslint":"^8.57.1","rimraf":"^5.0.10","ts-jest":"^29.2.5","ts-node":"^10.9.2","prettier":"^3.4.2","typescript":"^5.6.3","@types/jest":"^29.5.14","@types/node":"^20.19.0","eslint-config-prettier":"^9.1.0","@typescript-eslint/parser":"^7.18.0","@typescript-eslint/eslint-plugin":"^7.18.0"},"_npmOperationalInternal":{"tmp":"tmp/opensalestax-square_0.1.0-alpha.1_1778729225734_0.04772608907002773","host":"s3://npm-registry-packages-npm-production"}},"0.1.0-alpha.2":{"name":"@ejosterberg/opensalestax-square","version":"0.1.0-alpha.2","keywords":["square","square-api","tax","sales-tax","us-tax","opensalestax","tax-calculation","library"],"author":{"name":"Eric Osterberg","email":"ejosterberg@gmail.com"},"license":"Apache-2.0","_id":"@ejosterberg/opensalestax-square@0.1.0-alpha.2","maintainers":[{"name":"ejosterberg","email":"ejosterberg@gmail.com"}],"homepage":"https://github.com/ejosterberg/opensalestax-square","bugs":{"url":"https://github.com/ejosterberg/opensalestax-square/issues"},"dist":{"shasum":"fa20f705ac84de267738bb3b76ccad832ceb856e","tarball":"https://registry.npmjs.org/@ejosterberg/opensalestax-square/-/opensalestax-square-0.1.0-alpha.2.tgz","fileCount":29,"integrity":"sha512-hnKAkpmgWL6UEjsS2kqfOp88kvcfwrxiNqlcpJw7fup4y6lMrsQuE/BEbyh/APvsNgEe0PROzqBNfIhVb1LDZQ==","signatures":[{"sig":"MEYCIQCEGtElx1mfIY6YlxJxpqi1Pd8r2UbcD+KmVSdfar1s7wIhALlvSzQwcc1fPad82f+5wUMUsPSYpZ50nVgVpzeutK7q","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":83008},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=20"},"gitHead":"0ff0b6196e9b3837b31f197224e91e9ca81b1951","scripts":{"lint":"eslint .","test":"jest","audit":"npm audit --omit=dev --audit-level=high","build":"tsc -p tsconfig.build.json","check":"npm run lint && npm run typecheck && npm test && npm run audit","clean":"rimraf dist coverage .scannerwork","smoke":"ts-node tools/smoke-engine.ts","format":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\" \"tools/**/*.ts\"","lint:fix":"eslint . --fix","typecheck":"tsc --noEmit","format:check":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\" \"tools/**/*.ts\"","test:coverage":"jest --coverage","prepublishOnly":"npm run check && npm run build"},"_npmUser":{"name":"ejosterberg","email":"ejosterberg@gmail.com"},"repository":{"url":"git+https://github.com/ejosterberg/opensalestax-square.git","type":"git"},"_npmVersion":"11.4.2","description":"Server-side TypeScript library that computes destination-based US sales tax for Square Orders and Invoices via the self-hosted OpenSalesTax engine.","directories":{},"_nodeVersion":"22.17.0","dependencies":{"@ejosterberg/opensalestax":"^0.1.0"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","nock":"^14.0.15","eslint":"^8.57.1","rimraf":"^5.0.10","ts-jest":"^29.2.5","ts-node":"^10.9.2","prettier":"^3.4.2","typescript":"^5.6.3","@types/jest":"^29.5.14","@types/node":"^20.19.0","eslint-config-prettier":"^9.1.0","@typescript-eslint/parser":"^7.18.0","@typescript-eslint/eslint-plugin":"^7.18.0"},"_npmOperationalInternal":{"tmp":"tmp/opensalestax-square_0.1.0-alpha.2_1778857533994_0.5874802764301437","host":"s3://npm-registry-packages-npm-production"}},"0.1.0":{"name":"@ejosterberg/opensalestax-square","version":"0.1.0","keywords":["square","square-api","tax","sales-tax","us-tax","opensalestax","tax-calculation","library"],"author":{"name":"Eric Osterberg","email":"ejosterberg@gmail.com"},"license":"Apache-2.0","_id":"@ejosterberg/opensalestax-square@0.1.0","maintainers":[{"name":"ejosterberg","email":"ejosterberg@gmail.com"}],"homepage":"https://github.com/ejosterberg/opensalestax-square","bugs":{"url":"https://github.com/ejosterberg/opensalestax-square/issues"},"dist":{"shasum":"7f951396eddcadfa36dceaca350f3ca46a4ddb40","tarball":"https://registry.npmjs.org/@ejosterberg/opensalestax-square/-/opensalestax-square-0.1.0.tgz","fileCount":29,"integrity":"sha512-EYUV1xkmeRADAowFoxaFo3eIS2zhoUXHbKvJBgn87Iji/nPcNNHwAVGVwMj3jsj3mg1a+f7orspHVH6DD5jFWQ==","signatures":[{"sig":"MEUCIDhK4fbRaYgGVw/+VID9W0FbiEjKUq8ogfUcOUKjCtznAiEA0KIvK3b3MBc1/sHzAtX6Qwl/+RUtRj6d8PFzklNZOAI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":83678},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=20"},"gitHead":"73168cb3665c1b9391533f0a7b26a8a643a5af7b","scripts":{"lint":"eslint .","test":"jest","audit":"npm audit --omit=dev --audit-level=high","build":"tsc -p tsconfig.build.json","check":"npm run lint && npm run typecheck && npm test && npm run audit","clean":"rimraf dist coverage .scannerwork","smoke":"ts-node tools/smoke-engine.ts","format":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\" \"tools/**/*.ts\"","lint:fix":"eslint . --fix","typecheck":"tsc --noEmit","format:check":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\" \"tools/**/*.ts\"","test:coverage":"jest --coverage","prepublishOnly":"npm run check && npm run build"},"_npmUser":{"name":"ejosterberg","email":"ejosterberg@gmail.com"},"repository":{"url":"git+https://github.com/ejosterberg/opensalestax-square.git","type":"git"},"_npmVersion":"11.4.2","description":"Server-side TypeScript library that computes destination-based US sales tax for Square Orders and Invoices via the self-hosted OpenSalesTax engine.","directories":{},"_nodeVersion":"22.17.0","dependencies":{"@ejosterberg/opensalestax":"^0.1.0"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","nock":"^14.0.15","eslint":"^8.57.1","rimraf":"^5.0.10","ts-jest":"^29.2.5","ts-node":"^10.9.2","prettier":"^3.4.2","typescript":"^5.6.3","@types/jest":"^29.5.14","@types/node":"^20.19.0","eslint-config-prettier":"^9.1.0","@typescript-eslint/parser":"^7.18.0","@typescript-eslint/eslint-plugin":"^7.18.0"},"_npmOperationalInternal":{"tmp":"tmp/opensalestax-square_0.1.0_1778870582592_0.6648211745077302","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@ejosterberg/opensalestax-square","version":"0.1.1","keywords":["square","square-api","tax","sales-tax","us-tax","opensalestax","tax-calculation","library"],"author":{"name":"Eric Osterberg","email":"ejosterberg@gmail.com"},"license":"(Apache-2.0 OR GPL-2.0-or-later)","_id":"@ejosterberg/opensalestax-square@0.1.1","maintainers":[{"name":"ejosterberg","email":"ejosterberg@gmail.com"}],"homepage":"https://github.com/ejosterberg/opensalestax-square","bugs":{"url":"https://github.com/ejosterberg/opensalestax-square/issues"},"dist":{"shasum":"a629d3ea6b03e5d310a46f62faa4e54266974089","tarball":"https://registry.npmjs.org/@ejosterberg/opensalestax-square/-/opensalestax-square-0.1.1.tgz","fileCount":25,"integrity":"sha512-TdXcL+PSt4DRdMRfL74FD5FLs6khNF4G0kQRXDaglkWslNp+MP6gTpWT/d+ciIm4aYbcWZVX+eKPP389vYgBvA==","signatures":[{"sig":"MEQCIC3s4TwzgxUlt9c2SmuX9dEEREgzE+u/FSU76ZqwvY/IAiBTEAPxlmA8FPLGfUUTjm7XutvLFpWs7/+kq5t9lK6q4A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@ejosterberg%2fopensalestax-square@0.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":64318},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=20"},"gitHead":"00f3bb092b317cb0658a9d76b44cab6df097a3e3","scripts":{"lint":"eslint .","test":"jest","audit":"npm audit --omit=dev --audit-level=high","build":"tsc -p tsconfig.build.json","check":"npm run lint && npm run typecheck && npm test && npm run audit","clean":"rimraf dist coverage .scannerwork","smoke":"ts-node tools/smoke-engine.ts","format":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\" \"tools/**/*.ts\"","lint:fix":"eslint . --fix","typecheck":"tsc --noEmit","format:check":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\" \"tools/**/*.ts\"","test:coverage":"jest --coverage","prepublishOnly":"npm run check && npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f0d3d0be-419a-4d44-8c9d-61680a730c0d"}},"repository":{"url":"git+https://github.com/ejosterberg/opensalestax-square.git","type":"git"},"_npmVersion":"11.12.1","description":"Server-side TypeScript library that computes destination-based US sales tax for Square Orders and Invoices via the self-hosted OpenSalesTax engine.","directories":{},"_nodeVersion":"24.15.0","dependencies":{"@ejosterberg/opensalestax":"^0.1.0"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","nock":"^14.0.15","eslint":"^8.57.1","rimraf":"^5.0.10","ts-jest":"^29.2.5","ts-node":"^10.9.2","prettier":"^3.4.2","typescript":"^5.6.3","@types/jest":"^29.5.14","@types/node":"^20.19.0","eslint-config-prettier":"^9.1.0","@typescript-eslint/parser":"^7.18.0","@typescript-eslint/eslint-plugin":"^7.18.0"},"_npmOperationalInternal":{"tmp":"tmp/opensalestax-square_0.1.1_1779039776261_0.7015457243395926","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@ejosterberg/opensalestax-square","version":"0.1.2","description":"Server-side TypeScript library that computes destination-based US sales tax for Square Orders and Invoices via the self-hosted OpenSalesTax engine.","license":"(Apache-2.0 OR GPL-2.0-or-later)","author":{"name":"Eric Osterberg","email":"ejosterberg@gmail.com"},"homepage":"https://github.com/ejosterberg/opensalestax-square","repository":{"type":"git","url":"git+https://github.com/ejosterberg/opensalestax-square.git"},"bugs":{"url":"https://github.com/ejosterberg/opensalestax-square/issues"},"keywords":["square","square-api","tax","sales-tax","us-tax","opensalestax","tax-calculation","library"],"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=20"},"dependencies":{"@ejosterberg/opensalestax":"^0.2.0"},"scripts":{"build":"tsc -p tsconfig.build.json","clean":"rimraf dist coverage .scannerwork","lint":"eslint .","lint:fix":"eslint . --fix","format":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\" \"tools/**/*.ts\"","format:check":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\" \"tools/**/*.ts\"","typecheck":"tsc --noEmit","test":"jest","test:coverage":"jest --coverage","audit":"npm audit --omit=dev --audit-level=high","smoke":"ts-node tools/smoke-engine.ts","check":"npm run lint && npm run typecheck && npm test && npm run audit","prepublishOnly":"npm run check && npm run build"},"devDependencies":{"@types/jest":"^29.5.14","@types/node":"^20.19.0","@typescript-eslint/eslint-plugin":"^7.18.0","@typescript-eslint/parser":"^7.18.0","eslint":"^8.57.1","eslint-config-prettier":"^9.1.0","jest":"^29.7.0","nock":"^14.0.15","prettier":"^3.4.2","rimraf":"^5.0.10","ts-jest":"^29.2.5","ts-node":"^10.9.2","typescript":"^5.6.3"},"gitHead":"0d1e581a033559ba389941907cc97af4432f3fc7","_id":"@ejosterberg/opensalestax-square@0.1.2","_nodeVersion":"24.15.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-Sbpq/btkTsyOtQ+vQVbanoXqi1HyHald/W32gNqTVs5p60qz9coK5dTuNLHtCd88RAue4ckXiXLjfSxOngQXqA==","shasum":"2a3517a82a24ea601a49b817ae5f42afaae9645d","tarball":"https://registry.npmjs.org/@ejosterberg/opensalestax-square/-/opensalestax-square-0.1.2.tgz","fileCount":25,"unpackedSize":64780,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@ejosterberg%2fopensalestax-square@0.1.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIGktJPuhtL2vPmuqF8tUqk4U8mwhXyizR8t3AkznMqyAAiEA//Pugl/63QPPPK0k1Xmf0I8aJmdwe48OksTLy+WCxwA="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f0d3d0be-419a-4d44-8c9d-61680a730c0d"}},"directories":{},"maintainers":[{"name":"ejosterberg","email":"ejosterberg@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/opensalestax-square_0.1.2_1779167328877_0.27835527309180663"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-14T03:27:05.623Z","modified":"2026-05-19T05:08:49.319Z","0.1.0-alpha.1":"2026-05-14T03:27:05.925Z","0.1.0-alpha.2":"2026-05-15T15:05:34.163Z","0.1.0":"2026-05-15T18:43:02.753Z","0.1.1":"2026-05-17T17:42:56.414Z","0.1.2":"2026-05-19T05:08:49.058Z"},"bugs":{"url":"https://github.com/ejosterberg/opensalestax-square/issues"},"author":{"name":"Eric Osterberg","email":"ejosterberg@gmail.com"},"license":"(Apache-2.0 OR GPL-2.0-or-later)","homepage":"https://github.com/ejosterberg/opensalestax-square","keywords":["square","square-api","tax","sales-tax","us-tax","opensalestax","tax-calculation","library"],"repository":{"type":"git","url":"git+https://github.com/ejosterberg/opensalestax-square.git"},"description":"Server-side TypeScript library that computes destination-based US sales tax for Square Orders and Invoices via the self-hosted OpenSalesTax engine.","maintainers":[{"name":"ejosterberg","email":"ejosterberg@gmail.com"}],"readme":"# @ejosterberg/opensalestax-square\n\n[![ci](https://github.com/ejosterberg/opensalestax-square/actions/workflows/ci.yml/badge.svg)](https://github.com/ejosterberg/opensalestax-square/actions/workflows/ci.yml)\n[![npm](https://img.shields.io/npm/v/@ejosterberg/opensalestax-square.svg)](https://www.npmjs.com/package/@ejosterberg/opensalestax-square)\n[![License: Apache-2.0 OR GPL-2.0-or-later](https://img.shields.io/badge/License-Apache_2.0_OR_GPL_2.0--or--later-blue.svg)](LICENSE)\n\nServer-side TypeScript library that computes **destination-based US sales tax**\nfor **Square Orders and Invoices** via the self-hosted\n[OpenSalesTax](https://github.com/ejosterberg/opensalestax) engine. No SaaS,\nno per-transaction fees, no third-party API keys.\n\n- Pure server-side functions — `calculateForSquareOrder` and\n  `calculateForSquareInvoice` take an already-fetched Square object\n  plus an engine client, and return a structured tax breakdown.\n- **USD-only / US-only.** Non-USD or non-US orders return a zero-tax\n  result with `skippedReason` populated; the caller falls through to\n  whatever default behavior they like.\n- **Fail-soft default.** If the OpenSalesTax engine is unreachable,\n  the library returns zero tax + an `engineError` string. Opt into\n  fail-hard via `options.failHard`.\n- **No inbound HTTP surface.** Pure outbound calls to the configured\n  engine URL. The library runs in the merchant's own process.\n- **No `squareup` SDK dependency.** Library types Square shapes via\n  hand-rolled interfaces — bring your own Square SDK or REST client.\n\n> Tax calculations are provided as-is for convenience. The merchant is\n> solely responsible for tax-collection accuracy and remittance to the\n> appropriate jurisdictions. Verify against your state Department of\n> Revenue before remitting.\n\n## Compatibility\n\n| Library | Square REST API | OST engine | Node |\n|---------|-----------------|-----------|------|\n| 0.1.x   | 2024-x+         | 0.22+ (v1 API) | 20+ |\n\n## Install\n\n```bash\nnpm install @ejosterberg/opensalestax-square\n```\n\n## Quickstart\n\n```ts\nimport {\n  calculateForSquareOrder,\n  OpenSalesTaxClient,\n  type SquareOrder,\n} from '@ejosterberg/opensalestax-square';\n\n// 1. Build a client. The constructor enforces a scheme allowlist\n//    (http: / https:) and blocks loopback / RFC-1918 hosts unless\n//    you explicitly opt in with `allowPrivate: true`.\nconst ostClient = new OpenSalesTaxClient({\n  baseUrl: process.env.OSTAX_API_URL!, // e.g. \"https://ost.your-domain.com\"\n  // apiKey: process.env.OSTAX_API_TOKEN, // optional X-API-Key\n  // timeoutMs: 5000,                     // optional per-request timeout\n});\n\n// 2. Fetch the order via Square's SDK (or REST directly).\n//    The shape below is illustrative; you'll typically just hand off\n//    the SDK-returned object.\nconst order: SquareOrder = {\n  id: 'ORDER_ID',\n  line_items: [\n    { uid: 'line_1', quantity: '1', total_money: { amount: 10000, currency: 'USD' } },\n  ],\n  fulfillments: [\n    {\n      type: 'SHIPMENT',\n      shipment_details: {\n        recipient: {\n          address: { country: 'US', postal_code: '55401' },\n        },\n      },\n    },\n  ],\n  total_money: { amount: 10000, currency: 'USD' },\n};\n\n// 3. Calculate.\nconst result = await calculateForSquareOrder(order, ostClient);\n\n// 4. Apply to Square's order via UpdateOrder.\n// result.taxTotal, result.lines[i].jurisdictions[j], etc.\n```\n\nFor Square Invoices:\n\n```ts\nimport { calculateForSquareInvoice } from '@ejosterberg/opensalestax-square';\n\nconst result = await calculateForSquareInvoice(invoice, ostClient, {\n  // Optional — only needed if invoice.order isn't pre-attached.\n  fetchOrder: async (id) => squareSdk.ordersApi.retrieveOrder(id).then((r) => r.order),\n});\n```\n\n## Configuration\n\n```ts\nnew OpenSalesTaxClient({\n  baseUrl: 'https://ost.your-domain.com', // required, scheme allowlist enforced\n  apiKey: 'optional-x-api-key',\n  timeoutMs: 5000,                         // per-request, default 5000\n  allowPrivate: false,                     // permit RFC-1918 / loopback, default false\n});\n\nawait calculateForSquareOrder(order, client, {\n  defaultCategory: 'general',              // default category when no mapping matches\n  categoryByCatalogObjectId: {\n    cat_id_shirt: 'clothing',\n    cat_id_book:  'general',\n  },\n  failHard: false,                          // throw on engine errors instead of fail-soft\n  cache: true,                              // true | false | CacheLike (default true)\n});\n```\n\n## How it works\n\n1. **Address resolution.** Reads the destination ZIP from the order's\n   first SHIPMENT fulfillment (`Order.fulfillments[i].shipment_details.recipient.address`).\n   For invoices, falls back to `Invoice.primary_recipient.address` if the\n   linked order has no shipping fulfillment.\n2. **Gating.** USD / US country / ZIP regex `^\\d{5}(-\\d{4})?$`. Any\n   gate failure → zero-tax `TaxCalculationResult` with `skippedReason`.\n3. **Line extraction.** Reads each `line_items[i].total_money.amount`\n   (preferred), else `base_price_money.amount * quantity`. Lines with\n   no resolvable amount are skipped. Any non-USD line currency aborts\n   with `NonUSDError`.\n4. **Engine call.** Single `POST /v1/calculate` per order. The\n   response carries per-line and per-jurisdiction breakdowns.\n5. **Caching.** In-memory LRU keyed on ZIP + line bundle; 24h TTL by\n   default. Set `cache: false` to disable, or pass `cache: { get, set }`\n   to plug in Redis / Memcached.\n\n## Square POS in-person tax (origin-based)\n\nThe library uses **destination-based** tax — appropriate for online\norders and shipped goods. In-person Square POS transactions in some\nstates (TX, CA, IL) follow **origin-based** tax sourced from the seller\nlocation, not the destination. v0.1 does not handle this case; if your\nbusiness is brick-and-mortar POS exclusively, this library may not be\nthe right fit. v0.2+ may add origin-mode support — open an issue if\nyou want it.\n\n## What this library does NOT do\n\nBy design (engine constitution §13 + this repo's spec):\n\n- **Filing or remittance.** It computes tax. You file.\n- **Address validation.** Bring your own / use Square's SDK.\n- **Non-USD currencies / non-US jurisdictions.** Returns\n  zero-tax + `skippedReason`.\n- **Webhook handling.** Square's `order.created` / `invoice.created`\n  webhooks → tax-write-back flow is deferred to v0.2. Until then,\n  call the library yourself from your order-finalization or\n  invoice-issue code.\n- **Square POS origin-based tax** (see above).\n- **Calling Square's API.** The library reads caller-supplied\n  Square objects; the caller is responsible for fetching them and\n  writing tax results back via Square's `UpdateOrder` or\n  `UpdateInvoice` endpoints.\n\n## Security\n\nThe library exposes **no inbound HTTP routes**. The trust boundary is\nyour own process; whatever code imports this library is already\ntrusted.\n\n`baseUrl` is validated at client construction time: URL parse + scheme\nallowlist (`http:` / `https:`) + private-network blocklist (loopback,\nRFC-1918, IPv6 link-local) unless you opt in with `allowPrivate: true`.\n\nThe library never logs customer addresses, line item descriptions,\nproduct names, or customer emails. See [`docs/SECURITY-REVIEW.md`](docs/SECURITY-REVIEW.md)\nfor the full threat model.\n\nReporting vulnerabilities: see [`SECURITY.md`](SECURITY.md).\n\n## Contributing\n\nDCO sign-off mandatory on every commit (`git commit -s`). See\n[`CONTRIBUTING.md`](CONTRIBUTING.md). Dual-licensed under your choice of Apache-2.0 OR GPL-2.0-or-later. See [`LICENSE`](LICENSE).\n\n## Related projects\n\n| Connector | Stack | Repo |\n|-----------|-------|------|\n| OpenSalesTax engine | Python | [opensalestax](https://github.com/ejosterberg/opensalestax) |\n| Stripe (PHP)         | PHP | [opensalestax-stripe-php](https://github.com/ejosterberg/opensalestax-stripe-php) |\n| Medusa v2            | TypeScript | [opensalestax-medusa](https://github.com/ejosterberg/opensalestax-medusa) |\n| Vendure              | TypeScript | [opensalestax-vendure](https://github.com/ejosterberg/opensalestax-vendure) |\n| Square               | TypeScript | **this repo** |\n","readmeFilename":"README.md"}