@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 +38 -1
- package/dist/index.cjs +52 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +82 -14
- package/dist/index.d.ts +82 -14
- package/dist/index.js +52 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +4 -0
- package/src/index.ts +5 -1
- package/src/resources/signals.ts +0 -1
- package/src/resources/taxes.ts +59 -0
- package/src/types.ts +55 -14
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { Portal } from "./resources/portal.js";
|
|
|
12
12
|
import { Purchases } from "./resources/purchases.js";
|
|
13
13
|
import { Signals } from "./resources/signals.js";
|
|
14
14
|
import { Units } from "./resources/units.js";
|
|
15
|
+
import { Taxes } from "./resources/taxes.js";
|
|
15
16
|
import type { ClockNextConfig, ResolvedConfig } from "./types.js";
|
|
16
17
|
|
|
17
18
|
/**
|
|
@@ -46,6 +47,8 @@ export class ClockNext {
|
|
|
46
47
|
readonly units: Units;
|
|
47
48
|
/** Composites: list, get, create, update, archive, unarchive (no delete). */
|
|
48
49
|
readonly composites: Composites;
|
|
50
|
+
/** Tax rates by country: list, get, create, update (archive in the dashboard). */
|
|
51
|
+
readonly taxes: Taxes;
|
|
49
52
|
/** Subscribe customers to plans (purchases). */
|
|
50
53
|
readonly purchases: Purchases;
|
|
51
54
|
/** Read invoices and mint hosted pay links. */
|
|
@@ -76,6 +79,7 @@ export class ClockNext {
|
|
|
76
79
|
this.outcomes = new Outcomes(transport);
|
|
77
80
|
this.units = new Units(transport);
|
|
78
81
|
this.composites = new Composites(transport);
|
|
82
|
+
this.taxes = new Taxes(transport);
|
|
79
83
|
this.purchases = new Purchases(transport);
|
|
80
84
|
this.invoices = new Invoices(transport);
|
|
81
85
|
this.payments = new Payments(transport);
|
package/src/index.ts
CHANGED
|
@@ -56,7 +56,6 @@ export type {
|
|
|
56
56
|
CompositeCompletionInput,
|
|
57
57
|
CompositeCompletionResult,
|
|
58
58
|
SerializedUnitUsage,
|
|
59
|
-
UsageLogPeriod,
|
|
60
59
|
UsageLogListParams,
|
|
61
60
|
UsageLogAppliedRule,
|
|
62
61
|
UsageLogOutcomeAttribution,
|
|
@@ -114,6 +113,11 @@ export type {
|
|
|
114
113
|
Unit,
|
|
115
114
|
CreateUnitInput,
|
|
116
115
|
UpdateUnitInput,
|
|
116
|
+
// taxes
|
|
117
|
+
TaxBehavior,
|
|
118
|
+
Tax,
|
|
119
|
+
CreateTaxInput,
|
|
120
|
+
UpdateTaxInput,
|
|
117
121
|
CompositeItem,
|
|
118
122
|
Composite,
|
|
119
123
|
CreateCompositeInput,
|
package/src/resources/signals.ts
CHANGED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { activeQuery, filterByActive } from "../filters.js";
|
|
2
|
+
import type { Transport } from "../http.js";
|
|
3
|
+
import type { CreateTaxInput, Tax, UpdateTaxInput } from "../types.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The `taxes` resource — the tax rates charged to customers by billing
|
|
7
|
+
* country (the same rates as Settings → Taxes). `/api/v1/taxes`.
|
|
8
|
+
*
|
|
9
|
+
* Every active tax for a customer's country is applied to their invoices and
|
|
10
|
+
* portal purchases automatically. There is no `delete()`, `archive()` or
|
|
11
|
+
* `unarchive()` — archiving and restoring a tax is done in the dashboard.
|
|
12
|
+
*/
|
|
13
|
+
export class Taxes {
|
|
14
|
+
constructor(private readonly transport: Transport) {}
|
|
15
|
+
|
|
16
|
+
/** List them, oldest first. `{ active: true }` returns only active ones,
|
|
17
|
+
* `{ active: false }` only archived ones; omit it for both. */
|
|
18
|
+
async list(params: { active?: boolean } = {}): Promise<Tax[]> {
|
|
19
|
+
const res = await this.transport.request<{ taxes: Tax[] }>({
|
|
20
|
+
method: "GET",
|
|
21
|
+
path: "/api/v1/taxes",
|
|
22
|
+
query: { active: activeQuery(params.active) },
|
|
23
|
+
});
|
|
24
|
+
return filterByActive(res.taxes, params.active);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** One tax. */
|
|
28
|
+
async get(id: string): Promise<Tax> {
|
|
29
|
+
const res = await this.transport.request<{ tax: Tax }>({
|
|
30
|
+
method: "GET",
|
|
31
|
+
path: `/api/v1/taxes/${encodeURIComponent(id)}`,
|
|
32
|
+
});
|
|
33
|
+
return res.tax;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Create one. It starts active. Two active taxes can't share a name
|
|
37
|
+
* (ignoring case) in the same country — that's a `ConflictError`. Not
|
|
38
|
+
* retried on failure — a retry could create a second row. */
|
|
39
|
+
async create(input: CreateTaxInput): Promise<Tax> {
|
|
40
|
+
const res = await this.transport.request<{ created: true; tax: Tax }>({
|
|
41
|
+
method: "POST",
|
|
42
|
+
path: "/api/v1/taxes",
|
|
43
|
+
body: input,
|
|
44
|
+
});
|
|
45
|
+
return res.tax;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** PARTIAL update: only the fields you send change. Archived taxes can be
|
|
49
|
+
* edited and stay archived. Only invoices issued afterwards use the new
|
|
50
|
+
* values. */
|
|
51
|
+
async update(id: string, input: UpdateTaxInput): Promise<Tax> {
|
|
52
|
+
const res = await this.transport.request<{ updated: true; tax: Tax }>({
|
|
53
|
+
method: "PATCH",
|
|
54
|
+
path: `/api/v1/taxes/${encodeURIComponent(id)}`,
|
|
55
|
+
body: input,
|
|
56
|
+
});
|
|
57
|
+
return res.tax;
|
|
58
|
+
}
|
|
59
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -383,9 +383,6 @@ export interface TrackResult {
|
|
|
383
383
|
// Usage log (mirrors GET /api/v1/signal/usage-log)
|
|
384
384
|
// ---------------------------------------------------------------------------
|
|
385
385
|
|
|
386
|
-
/** A preset time window, or `"custom"` for an explicit `from`/`to` range. */
|
|
387
|
-
export type UsageLogPeriod = "all" | "today" | "7d" | "30d" | "90d" | "custom";
|
|
388
|
-
|
|
389
386
|
export interface UsageLogListParams {
|
|
390
387
|
customerId: string;
|
|
391
388
|
/** Default 50, max 200. */
|
|
@@ -393,11 +390,11 @@ export interface UsageLogListParams {
|
|
|
393
390
|
/** Pass back a previous page's `nextCursor` to fetch the next page. Omit for
|
|
394
391
|
* the first page. */
|
|
395
392
|
cursor?: string;
|
|
396
|
-
/**
|
|
397
|
-
|
|
398
|
-
/** `YYYY-MM-DD`, only used when `period` is `"custom"`. */
|
|
393
|
+
/** First day to include, `YYYY-MM-DD` (UTC). The whole day is included.
|
|
394
|
+
* Keep sending the same value while paging with `cursor`. */
|
|
399
395
|
from?: string;
|
|
400
|
-
/** `YYYY-MM-DD
|
|
396
|
+
/** Last day to include, `YYYY-MM-DD` (UTC). The whole day is included.
|
|
397
|
+
* Must not be before `from`. */
|
|
401
398
|
to?: string;
|
|
402
399
|
}
|
|
403
400
|
|
|
@@ -426,13 +423,14 @@ export interface UsageLogOutcomeAttribution {
|
|
|
426
423
|
* One row of a customer's usage history, merged from every meter kind
|
|
427
424
|
* (`UsageLog`, `UnitUsageLog`, completed composite occurrences) into one
|
|
428
425
|
* feed and sorted by time — the same rows the customer portal's own "Usage
|
|
429
|
-
* logs" table shows. `
|
|
430
|
-
*
|
|
426
|
+
* logs" table shows. `credit`, `outcome`, `unit` and `composite` are each
|
|
427
|
+
* `null` unless `type` matches that group.
|
|
431
428
|
*/
|
|
432
429
|
export interface UsageLogEntry {
|
|
433
430
|
id: string;
|
|
434
431
|
createdAt: string;
|
|
435
|
-
|
|
432
|
+
/** Which meter this row is. */
|
|
433
|
+
type: "credit" | "outcome" | "unit" | "wallet" | "composite";
|
|
436
434
|
status: SignalStatus;
|
|
437
435
|
typeName: string | null;
|
|
438
436
|
member: string | null;
|
|
@@ -447,16 +445,19 @@ export interface UsageLogEntry {
|
|
|
447
445
|
};
|
|
448
446
|
/** Formatted USD strings (e.g. `"$0.0064"`). */
|
|
449
447
|
cost: { providedCost: string; customerCost: string };
|
|
450
|
-
/** Populated only when `
|
|
448
|
+
/** Populated only when `type === "credit"`. `amount` is a formatted credit
|
|
451
449
|
* value, honouring the org's credit-decimals display setting. */
|
|
452
450
|
credit: { amount: string; appliedRules: UsageLogAppliedRule[] } | null;
|
|
453
|
-
/** Populated only when `
|
|
451
|
+
/** Populated only when `type === "outcome"`. */
|
|
454
452
|
outcome: UsageLogOutcomeAttribution | null;
|
|
455
|
-
/** Populated only when `
|
|
453
|
+
/** Populated only when `type === "unit"`. `quantity` is formatted. */
|
|
456
454
|
unit: { quantity: string } | null;
|
|
457
|
-
/** Populated only when `
|
|
455
|
+
/** Populated only when `type === "composite"`. `amount` is a formatted USD
|
|
458
456
|
* price — the composite's flat price, read live, not stored per row. */
|
|
459
457
|
composite: { amount: string } | null;
|
|
458
|
+
/** The `custom` object sent on the signal, as sent. `null` when none was
|
|
459
|
+
* sent, and always `null` for unit and composite rows. */
|
|
460
|
+
custom: Record<string, unknown> | null;
|
|
460
461
|
}
|
|
461
462
|
|
|
462
463
|
export interface UsageLogPage {
|
|
@@ -963,6 +964,46 @@ export interface CreateUnitInput {
|
|
|
963
964
|
/** `units.update()` body — PARTIAL. `tiers`, when sent, is the complete list. */
|
|
964
965
|
export type UpdateUnitInput = Partial<CreateUnitInput>;
|
|
965
966
|
|
|
967
|
+
/** How a tax applies: `"inclusive"` — already inside the price;
|
|
968
|
+
* `"exclusive"` — added on top. Lower case only. */
|
|
969
|
+
export type TaxBehavior = "inclusive" | "exclusive";
|
|
970
|
+
|
|
971
|
+
/** A tax rate, charged to customers whose billing country matches. */
|
|
972
|
+
export interface Tax {
|
|
973
|
+
id: string;
|
|
974
|
+
/** Shown on invoices. Unique among active taxes in the same country,
|
|
975
|
+
* ignoring case. */
|
|
976
|
+
name: string;
|
|
977
|
+
/** A note for your team; not shown to customers. */
|
|
978
|
+
description: string | null;
|
|
979
|
+
/** 0–100. */
|
|
980
|
+
percentage: number;
|
|
981
|
+
/** ISO 3166-1 alpha-2, upper case (e.g. `"IN"`). */
|
|
982
|
+
countryCode: string;
|
|
983
|
+
behavior: TaxBehavior;
|
|
984
|
+
/** `false` once archived in the dashboard (Settings → Taxes): it no longer
|
|
985
|
+
* applies to new invoices. */
|
|
986
|
+
isActive: boolean;
|
|
987
|
+
createdAt: string;
|
|
988
|
+
updatedAt: string;
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
/** `taxes.create()` body. */
|
|
992
|
+
export interface CreateTaxInput {
|
|
993
|
+
/** 1–100 characters. */
|
|
994
|
+
name: string;
|
|
995
|
+
/** 0–100. */
|
|
996
|
+
percentage: number;
|
|
997
|
+
/** ISO 3166-1 alpha-2 (lower case is accepted). A country name is refused. */
|
|
998
|
+
countryCode: string;
|
|
999
|
+
behavior: TaxBehavior;
|
|
1000
|
+
/** Up to 500 characters. */
|
|
1001
|
+
description?: string | null;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
/** `taxes.update()` body — PARTIAL: only the fields you send change. */
|
|
1005
|
+
export type UpdateTaxInput = Partial<CreateTaxInput>;
|
|
1006
|
+
|
|
966
1007
|
/** A catalogue item a composite wraps. */
|
|
967
1008
|
export interface CompositeItem {
|
|
968
1009
|
id: string;
|