@clocknext/sdk 0.17.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -561,7 +561,8 @@ await cnk.customers.unitBalance(customerId, { unitName: "Seats" });
561
561
  let cursor: string | undefined;
562
562
  do {
563
563
  const page = await cnk.signals.usageLog({ customerId, limit: 50, cursor });
564
- // page.usageLogs — each row has a `kind`: credit | outcome | unit | wallet | composite
564
+ // page.usageLogs — each row has a `type`: credit | outcome | unit | wallet | composite,
565
+ // and `custom`: the `custom` object sent on the signal (or null)
565
566
  cursor = page.nextCursor ?? undefined;
566
567
  } while (cursor);
567
568
  ```
@@ -774,6 +775,42 @@ await cnk.units.unarchive(unit.id); // and bring it back
774
775
  Models are enabled in the ClockNext dashboard. A bundle line names its model by
775
776
  `modelId` — the same id you send as `usage.model` on a signal.
776
777
 
778
+ ## Taxes
779
+
780
+ `cnk.taxes` manages the tax rates charged to your customers by billing country
781
+ — the same rates as **Settings → Taxes** in the dashboard. Every active tax for
782
+ a customer's country is applied to their invoices and portal purchases
783
+ automatically; a customer with no country is charged no tax.
784
+
785
+ It has four calls: `list()`, `get(id)`, `create(input)` and `update(id, input)`.
786
+
787
+ - **`behavior` is lower case:** `"inclusive"` (already inside the price) or
788
+ `"exclusive"` (added on top).
789
+ - **`countryCode`** is a 2-letter ISO code (`"IN"`, `"GB"`); lower case is
790
+ accepted, a country name is refused.
791
+ - **No duplicates:** two active taxes can't share a name (ignoring case) in the
792
+ same country — that's a `ConflictError`.
793
+ - **`update()` is partial**, and only affects invoices issued afterwards —
794
+ issued invoices keep the tax they were issued with.
795
+ - **Archiving is dashboard-only.** There is no `archive()` / `unarchive()` /
796
+ `delete()`; an archived tax reads back with `isActive: false` and can still
797
+ be updated.
798
+
799
+ ```ts
800
+ const gst = await cnk.taxes.create({
801
+ name: "GST",
802
+ percentage: 18,
803
+ countryCode: "IN",
804
+ behavior: "exclusive",
805
+ description: "India GST",
806
+ });
807
+
808
+ const active = await cnk.taxes.list({ active: true }); // omit for archived ones too
809
+ const one = await cnk.taxes.get(gst.id);
810
+
811
+ await cnk.taxes.update(gst.id, { percentage: 12 }); // only the percentage changes
812
+ ```
813
+
777
814
  ## Customer portal
778
815
 
779
816
  ```ts
package/dist/index.cjs CHANGED
@@ -333,7 +333,7 @@ function sleep(ms) {
333
333
  }
334
334
 
335
335
  // src/http.ts
336
- var SDK_VERSION = "0.17.0" ;
336
+ var SDK_VERSION = "0.18.0" ;
337
337
  var Transport = class {
338
338
  constructor(cfg) {
339
339
  this.cfg = cfg;
@@ -1441,7 +1441,6 @@ var Signals = class {
1441
1441
  customerId: params.customerId,
1442
1442
  limit: params.limit,
1443
1443
  cursor: params.cursor,
1444
- period: params.period,
1445
1444
  from: params.from,
1446
1445
  to: params.to
1447
1446
  }
@@ -1513,6 +1512,54 @@ var Units = class {
1513
1512
  }
1514
1513
  };
1515
1514
 
1515
+ // src/resources/taxes.ts
1516
+ var Taxes = class {
1517
+ constructor(transport) {
1518
+ this.transport = transport;
1519
+ }
1520
+ transport;
1521
+ /** List them, oldest first. `{ active: true }` returns only active ones,
1522
+ * `{ active: false }` only archived ones; omit it for both. */
1523
+ async list(params = {}) {
1524
+ const res = await this.transport.request({
1525
+ method: "GET",
1526
+ path: "/api/v1/taxes",
1527
+ query: { active: activeQuery(params.active) }
1528
+ });
1529
+ return filterByActive(res.taxes, params.active);
1530
+ }
1531
+ /** One tax. */
1532
+ async get(id) {
1533
+ const res = await this.transport.request({
1534
+ method: "GET",
1535
+ path: `/api/v1/taxes/${encodeURIComponent(id)}`
1536
+ });
1537
+ return res.tax;
1538
+ }
1539
+ /** Create one. It starts active. Two active taxes can't share a name
1540
+ * (ignoring case) in the same country — that's a `ConflictError`. Not
1541
+ * retried on failure — a retry could create a second row. */
1542
+ async create(input) {
1543
+ const res = await this.transport.request({
1544
+ method: "POST",
1545
+ path: "/api/v1/taxes",
1546
+ body: input
1547
+ });
1548
+ return res.tax;
1549
+ }
1550
+ /** PARTIAL update: only the fields you send change. Archived taxes can be
1551
+ * edited and stay archived. Only invoices issued afterwards use the new
1552
+ * values. */
1553
+ async update(id, input) {
1554
+ const res = await this.transport.request({
1555
+ method: "PATCH",
1556
+ path: `/api/v1/taxes/${encodeURIComponent(id)}`,
1557
+ body: input
1558
+ });
1559
+ return res.tax;
1560
+ }
1561
+ };
1562
+
1516
1563
  // src/client.ts
1517
1564
  var ClockNext = class {
1518
1565
  /** Record usage signals (credit / wallet / outcome / unit) and read the usage log. */
@@ -1529,6 +1576,8 @@ var ClockNext = class {
1529
1576
  units;
1530
1577
  /** Composites: list, get, create, update, archive, unarchive (no delete). */
1531
1578
  composites;
1579
+ /** Tax rates by country: list, get, create, update (archive in the dashboard). */
1580
+ taxes;
1532
1581
  /** Subscribe customers to plans (purchases). */
1533
1582
  purchases;
1534
1583
  /** Read invoices and mint hosted pay links. */
@@ -1555,6 +1604,7 @@ var ClockNext = class {
1555
1604
  this.outcomes = new Outcomes(transport);
1556
1605
  this.units = new Units(transport);
1557
1606
  this.composites = new Composites(transport);
1607
+ this.taxes = new Taxes(transport);
1558
1608
  this.purchases = new Purchases(transport);
1559
1609
  this.invoices = new Invoices(transport);
1560
1610
  this.payments = new Payments(transport);