mbase-sdk 0.0.2
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/LICENSE +21 -0
- package/README.md +497 -0
- package/dist/index.cjs +714 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +717 -0
- package/dist/index.d.ts +717 -0
- package/dist/index.js +698 -0
- package/dist/index.js.map +1 -0
- package/package.json +76 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,717 @@
|
|
|
1
|
+
type MeterbaseOptions = {
|
|
2
|
+
/** A secret key. It names its own workspace. */
|
|
3
|
+
apiKey: string;
|
|
4
|
+
/** Defaults to the hosted engine. */
|
|
5
|
+
baseUrl?: string;
|
|
6
|
+
/** Per attempt, not per call. */
|
|
7
|
+
timeout?: number;
|
|
8
|
+
maxRetries?: number;
|
|
9
|
+
fetch?: typeof globalThis.fetch;
|
|
10
|
+
};
|
|
11
|
+
type RequestOptions = {
|
|
12
|
+
signal?: AbortSignal;
|
|
13
|
+
timeout?: number;
|
|
14
|
+
maxRetries?: number;
|
|
15
|
+
};
|
|
16
|
+
type HttpMethod = "GET" | "POST" | "PATCH" | "DELETE";
|
|
17
|
+
type Request = RequestOptions & {
|
|
18
|
+
method: HttpMethod;
|
|
19
|
+
path: string;
|
|
20
|
+
query?: Record<string, string | number | boolean | undefined>;
|
|
21
|
+
body?: unknown;
|
|
22
|
+
/**
|
|
23
|
+
* Replay this call even though its method is not safe. Only a route that
|
|
24
|
+
* carries an idempotency key may set it, and the key has to be fixed before
|
|
25
|
+
* `request` is called — the loop re-sends one body, so a key generated
|
|
26
|
+
* per attempt would count the same usage twice.
|
|
27
|
+
*/
|
|
28
|
+
idempotent?: boolean;
|
|
29
|
+
};
|
|
30
|
+
declare class Client {
|
|
31
|
+
#private;
|
|
32
|
+
constructor(options: MeterbaseOptions);
|
|
33
|
+
request<T>(req: Request): Promise<T>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Enveloped so pagination can arrive without breaking callers. */
|
|
37
|
+
type List<T> = {
|
|
38
|
+
data: T[];
|
|
39
|
+
};
|
|
40
|
+
type Meter = {
|
|
41
|
+
id: string;
|
|
42
|
+
workspace_id: string;
|
|
43
|
+
key: string;
|
|
44
|
+
name: string;
|
|
45
|
+
description: string;
|
|
46
|
+
unit: string;
|
|
47
|
+
value: string;
|
|
48
|
+
/** Usage-alert percents for this meter. `null` inherits the workspace's
|
|
49
|
+
* defaults; `[]` turns alerts off for the meter. A customer's own list
|
|
50
|
+
* beats this one. */
|
|
51
|
+
thresholds: number[] | null;
|
|
52
|
+
created_at: string;
|
|
53
|
+
updated_at: string;
|
|
54
|
+
archived_at: string | null;
|
|
55
|
+
};
|
|
56
|
+
type MeterCreateParams = {
|
|
57
|
+
key: string;
|
|
58
|
+
name: string;
|
|
59
|
+
description?: string;
|
|
60
|
+
unit?: string;
|
|
61
|
+
value?: string;
|
|
62
|
+
/** Whole percents, 1–1000, at most 32 of them; a mark over 100 is an
|
|
63
|
+
* overage alert. Omitted, the meter inherits the workspace's. */
|
|
64
|
+
thresholds?: number[];
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* An omitted field is left alone; `""` clears an optional one.
|
|
68
|
+
*
|
|
69
|
+
* `thresholds` is the exception on both counts: `null` is a value there, not
|
|
70
|
+
* silence. Omit it to keep the stored list, send `null` to inherit the
|
|
71
|
+
* workspace's again, send `[]` to turn alerts off for this meter.
|
|
72
|
+
*/
|
|
73
|
+
type MeterUpdateParams = {
|
|
74
|
+
key?: string;
|
|
75
|
+
name?: string;
|
|
76
|
+
description?: string;
|
|
77
|
+
unit?: string;
|
|
78
|
+
value?: string;
|
|
79
|
+
thresholds?: number[] | null;
|
|
80
|
+
};
|
|
81
|
+
type MeterListParams = {
|
|
82
|
+
include_archived?: boolean;
|
|
83
|
+
};
|
|
84
|
+
type Customer = {
|
|
85
|
+
id: string;
|
|
86
|
+
workspace_id: string;
|
|
87
|
+
external_id: string;
|
|
88
|
+
name: string;
|
|
89
|
+
metadata: Record<string, unknown>;
|
|
90
|
+
/** Usage-alert percents for this customer. `null` inherits — the meter's
|
|
91
|
+
* list, then the workspace's. `[]` turns alerts off for this customer.
|
|
92
|
+
* The most specific of the three, and it always wins. */
|
|
93
|
+
thresholds: number[] | null;
|
|
94
|
+
created_at: string;
|
|
95
|
+
updated_at: string;
|
|
96
|
+
deleted_at: string | null;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* A plan as a customer read embeds it: the plan itself, flattened onto the
|
|
100
|
+
* assignment that named it.
|
|
101
|
+
*
|
|
102
|
+
* `id` is the **plan's**. The assignment's own id is on
|
|
103
|
+
* `customers.plan.retrieve`, which is where instructions are identified;
|
|
104
|
+
* what a reader wants from an embed is which plan. `cycle` is here because
|
|
105
|
+
* `anchor_at` fixes a period only alongside its stride.
|
|
106
|
+
*/
|
|
107
|
+
type EmbeddedPlan = {
|
|
108
|
+
id: string;
|
|
109
|
+
key: string;
|
|
110
|
+
name: string;
|
|
111
|
+
cycle: PlanCycle;
|
|
112
|
+
/** When this instruction takes effect — ahead of now on `pending_plan`. */
|
|
113
|
+
effective_at: string;
|
|
114
|
+
/** What the customer's periods are measured from. */
|
|
115
|
+
anchor_at: string;
|
|
116
|
+
effective: ApplyMode;
|
|
117
|
+
reconciliation: RecordedReconciliation;
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* A single-customer read. The plan travels with the customer because a caller
|
|
121
|
+
* holding one almost always goes on to ask what it is entitled to.
|
|
122
|
+
*
|
|
123
|
+
* `plan` is the one in force now and `pending_plan` the change waiting to
|
|
124
|
+
* land, each `null` when there is none — holding no plan is a default deny,
|
|
125
|
+
* not a failure. `customers.list`, `create`, `update` and `delete` answer a
|
|
126
|
+
* plain `Customer`: a listing does not embed, where the same read would run
|
|
127
|
+
* per row for an answer most callers of a list do not want.
|
|
128
|
+
*/
|
|
129
|
+
type CustomerWithPlan = Customer & {
|
|
130
|
+
plan: EmbeddedPlan | null;
|
|
131
|
+
pending_plan: EmbeddedPlan | null;
|
|
132
|
+
};
|
|
133
|
+
type CustomerCreateParams = {
|
|
134
|
+
external_id: string;
|
|
135
|
+
name?: string;
|
|
136
|
+
metadata?: Record<string, unknown>;
|
|
137
|
+
/** Whole percents, 1–1000, at most 32 of them; a mark over 100 is an
|
|
138
|
+
* overage alert. Omitted, the customer inherits. */
|
|
139
|
+
thresholds?: number[];
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* An omitted field is left alone. `external_id` cannot be cleared, and
|
|
143
|
+
* `metadata` is replaced wholesale rather than merged.
|
|
144
|
+
*
|
|
145
|
+
* `thresholds` reads `null` as a value, not as silence: omit it to keep the
|
|
146
|
+
* stored list, send `null` to go back to inheriting the meter's or the
|
|
147
|
+
* workspace's, send `[]` to turn alerts off for this customer alone.
|
|
148
|
+
*/
|
|
149
|
+
type CustomerUpdateParams = {
|
|
150
|
+
external_id?: string;
|
|
151
|
+
name?: string;
|
|
152
|
+
metadata?: Record<string, unknown>;
|
|
153
|
+
thresholds?: number[] | null;
|
|
154
|
+
};
|
|
155
|
+
type CustomerListParams = {
|
|
156
|
+
include_deleted?: boolean;
|
|
157
|
+
};
|
|
158
|
+
/** `customer_id` is the tenant's own external id and `meter_id` the meter's
|
|
159
|
+
* key: an SDK never holds Meterbase uuids. */
|
|
160
|
+
type CheckParams = {
|
|
161
|
+
customer_id: string;
|
|
162
|
+
meter_id: string;
|
|
163
|
+
/** What is about to be consumed, `1 … 100000000000`. Defaults to `1`, which
|
|
164
|
+
* asks whether there is any capacity at all. */
|
|
165
|
+
quantity?: number;
|
|
166
|
+
};
|
|
167
|
+
type CheckResult = {
|
|
168
|
+
allowed: boolean;
|
|
169
|
+
/** Unlimited for this meter. `available` is `null`. */
|
|
170
|
+
no_cap: boolean;
|
|
171
|
+
/**
|
|
172
|
+
* The whole capacity: the plan's unused entitlement for the current period,
|
|
173
|
+
* floored at 0, plus every open grant. `null` under `no_cap`, where capacity
|
|
174
|
+
* is not a number.
|
|
175
|
+
*
|
|
176
|
+
* One figure and no breakdown: `check` answers from a single cached integer,
|
|
177
|
+
* and itemising where the capacity came from would cost it that. For the
|
|
178
|
+
* per-grant detail, read `customers.allowances.list`.
|
|
179
|
+
*/
|
|
180
|
+
available: number | null;
|
|
181
|
+
};
|
|
182
|
+
/**
|
|
183
|
+
* `track` records work that already happened, so it never refuses on capacity
|
|
184
|
+
* — the gate is `check`, which runs before the work. A quantity beyond the
|
|
185
|
+
* customer's capacity is recorded, drives `available` to 0, and the next
|
|
186
|
+
* `check` says no.
|
|
187
|
+
*/
|
|
188
|
+
type TrackParams = {
|
|
189
|
+
customer_id: string;
|
|
190
|
+
meter_id: string;
|
|
191
|
+
/** Integer, `1 … 100000000000`. Defaults to `1`, which is what a counting
|
|
192
|
+
* meter sends. */
|
|
193
|
+
quantity?: number;
|
|
194
|
+
/**
|
|
195
|
+
* The engine requires one; the SDK generates one per call when it is
|
|
196
|
+
* omitted, and reuses it across that call's retries. Supply your own when
|
|
197
|
+
* the caller already has an id for the work — a job id, a request id — so a
|
|
198
|
+
* retry from further out replays rather than counts twice.
|
|
199
|
+
*/
|
|
200
|
+
idempotency_key?: string;
|
|
201
|
+
};
|
|
202
|
+
/** Enveloped, like the list reads, so the receipt can grow a sibling field
|
|
203
|
+
* without breaking callers. */
|
|
204
|
+
type TrackResult = {
|
|
205
|
+
event: UsageEvent;
|
|
206
|
+
};
|
|
207
|
+
/**
|
|
208
|
+
* A receipt. The same shape whether the event is new or a replay — no capacity
|
|
209
|
+
* figures, no nullable fields, nothing to branch on.
|
|
210
|
+
*/
|
|
211
|
+
type UsageEvent = {
|
|
212
|
+
/** Meterbase's id for the event. A retry of the same key returns this same
|
|
213
|
+
* id. */
|
|
214
|
+
id: string;
|
|
215
|
+
customer_id: string;
|
|
216
|
+
meter_id: string;
|
|
217
|
+
quantity: number;
|
|
218
|
+
/** When Meterbase stored it, which chooses the period the event counts
|
|
219
|
+
* against. */
|
|
220
|
+
occurred_at: string;
|
|
221
|
+
/** The same instant as `occurred_at`. Both are on the wire so a reader of
|
|
222
|
+
* either keeps working. */
|
|
223
|
+
recorded_at: string;
|
|
224
|
+
idempotency_key: string;
|
|
225
|
+
/** `true` when this key had already been recorded: nothing was written, and
|
|
226
|
+
* this is the original event. */
|
|
227
|
+
replayed: boolean;
|
|
228
|
+
};
|
|
229
|
+
/**
|
|
230
|
+
* A plan's billing period. Every recurring allowance it holds is measured
|
|
231
|
+
* against it, and it is fixed when the plan is created. `one_time` is not
|
|
232
|
+
* among them: that is a kind of allowance, not a period.
|
|
233
|
+
*/
|
|
234
|
+
type PlanCycle = "daily" | "weekly" | "monthly" | "quarterly" | "half_yearly" | "yearly";
|
|
235
|
+
type Plan = {
|
|
236
|
+
id: string;
|
|
237
|
+
workspace_id: string;
|
|
238
|
+
key: string;
|
|
239
|
+
name: string;
|
|
240
|
+
description: string;
|
|
241
|
+
cycle: PlanCycle;
|
|
242
|
+
created_at: string;
|
|
243
|
+
updated_at: string;
|
|
244
|
+
archived_at: string | null;
|
|
245
|
+
};
|
|
246
|
+
type PlanCreateParams = {
|
|
247
|
+
key: string;
|
|
248
|
+
name: string;
|
|
249
|
+
description?: string;
|
|
250
|
+
cycle: PlanCycle;
|
|
251
|
+
};
|
|
252
|
+
/**
|
|
253
|
+
* An omitted field is left alone; `""` clears the description. There is no
|
|
254
|
+
* `cycle`: moving a plan's period would re-date every period its customers
|
|
255
|
+
* were already measured against, so a different cadence is a different plan.
|
|
256
|
+
*/
|
|
257
|
+
type PlanUpdateParams = {
|
|
258
|
+
key?: string;
|
|
259
|
+
name?: string;
|
|
260
|
+
description?: string;
|
|
261
|
+
};
|
|
262
|
+
type PlanListParams = {
|
|
263
|
+
include_archived?: boolean;
|
|
264
|
+
};
|
|
265
|
+
/**
|
|
266
|
+
* Which of a `(plan, meter)` pair's two lineages a version belongs to. Each
|
|
267
|
+
* numbers itself separately.
|
|
268
|
+
*/
|
|
269
|
+
type PlanAllowanceKind = "recurring" | "one_time";
|
|
270
|
+
type ApplyMode = "immediate" | "next_cycle";
|
|
271
|
+
/**
|
|
272
|
+
* What an `immediate` plan change does with the period it lands in: `none`
|
|
273
|
+
* lets the new plan's amount govern the whole period, `prorate` weights the
|
|
274
|
+
* two plans by the fraction each was held for, and `reset` closes the period
|
|
275
|
+
* at the change and opens a fresh one — moving the customer's anchor, and so
|
|
276
|
+
* their renewal day.
|
|
277
|
+
*/
|
|
278
|
+
type Reconciliation = "none" | "prorate" | "reset";
|
|
279
|
+
/**
|
|
280
|
+
* Reconciliation as a stored row may read it. The plan history is append-only,
|
|
281
|
+
* so a mode the API has since stopped accepting — `rebalance` — survives in
|
|
282
|
+
* rows written while it did. Responses widen to this; requests do not.
|
|
283
|
+
*/
|
|
284
|
+
type RecordedReconciliation = Reconciliation | "rebalance";
|
|
285
|
+
/**
|
|
286
|
+
* How long a one-time grant lives once minted. Months are kept apart from
|
|
287
|
+
* days because they are not the same length: three months from Jan 31 dies
|
|
288
|
+
* Apr 30, ninety days dies May 1.
|
|
289
|
+
*/
|
|
290
|
+
type Validity = {
|
|
291
|
+
months: number;
|
|
292
|
+
days: number;
|
|
293
|
+
};
|
|
294
|
+
type PlanAllowance = {
|
|
295
|
+
id: string;
|
|
296
|
+
workspace_id: string;
|
|
297
|
+
plan_id: string;
|
|
298
|
+
meter_id: string;
|
|
299
|
+
/** 1, 2, 3… per lineage. Assigned by the engine, never by the caller. */
|
|
300
|
+
version: number;
|
|
301
|
+
/** Units per period. `0` is legal and grants nothing. `null` under no_cap. */
|
|
302
|
+
amount: number | null;
|
|
303
|
+
no_cap: boolean;
|
|
304
|
+
kind: PlanAllowanceKind;
|
|
305
|
+
/** `one_time` only; `null` is a grant that never expires. */
|
|
306
|
+
valid_for: Validity | null;
|
|
307
|
+
effective_from: string;
|
|
308
|
+
apply_mode: ApplyMode;
|
|
309
|
+
created_at: string;
|
|
310
|
+
};
|
|
311
|
+
/**
|
|
312
|
+
* An allowance says how much, never how often: the period is the plan's
|
|
313
|
+
* cycle. Give exactly one of `amount` or `no_cap`.
|
|
314
|
+
*/
|
|
315
|
+
type PlanAllowanceSetParams = {
|
|
316
|
+
meter_id: string;
|
|
317
|
+
amount?: number;
|
|
318
|
+
no_cap?: boolean;
|
|
319
|
+
/** Defaults to `recurring`. */
|
|
320
|
+
kind?: PlanAllowanceKind;
|
|
321
|
+
/** `one_time` only. */
|
|
322
|
+
valid_for?: Validity;
|
|
323
|
+
/** Defaults to `next_cycle`, except `one_time` which is always immediate. */
|
|
324
|
+
apply_mode?: ApplyMode;
|
|
325
|
+
};
|
|
326
|
+
type PlanAllowanceListParams = {
|
|
327
|
+
meter_id?: string;
|
|
328
|
+
};
|
|
329
|
+
type Assignment = {
|
|
330
|
+
id: string;
|
|
331
|
+
workspace_id: string;
|
|
332
|
+
customer_id: string;
|
|
333
|
+
plan_id: string;
|
|
334
|
+
/** Ahead of now for a change that has not landed yet. */
|
|
335
|
+
effective_at: string;
|
|
336
|
+
/** As recorded, which is not always as asked: a first plan starts at once. */
|
|
337
|
+
effective: ApplyMode;
|
|
338
|
+
/** Widened for history: a row written under an older engine may name a mode
|
|
339
|
+
* the API no longer takes. */
|
|
340
|
+
reconciliation: RecordedReconciliation;
|
|
341
|
+
/** What periods are measured from. A plan change inherits it, so a
|
|
342
|
+
* customer's renewal day never moves under them — `reconciliation: "reset"`
|
|
343
|
+
* is the one thing that moves it. */
|
|
344
|
+
anchor_at: string;
|
|
345
|
+
/** Set when a newer instruction replaced this one before it took effect. */
|
|
346
|
+
superseded_at: string | null;
|
|
347
|
+
created_at: string;
|
|
348
|
+
};
|
|
349
|
+
/** Assigning and changing are one operation: the history is append-only. */
|
|
350
|
+
type AssignPlanParams = {
|
|
351
|
+
plan_id: string;
|
|
352
|
+
/** Defaults to `next_cycle` on a change, and is forced to `immediate` on a
|
|
353
|
+
* customer's first plan: there is no period to wait out. */
|
|
354
|
+
effective?: ApplyMode;
|
|
355
|
+
/** `immediate` only; the engine refuses it beside `next_cycle`. */
|
|
356
|
+
reconciliation?: Reconciliation;
|
|
357
|
+
/** The customer's first assignment only, and the one chance to stagger
|
|
358
|
+
* their billing day. Defaults to the instant it lands. Refused beside
|
|
359
|
+
* `reconciliation: "reset"`, which anchors at the change instant itself. */
|
|
360
|
+
cycle_anchor?: string;
|
|
361
|
+
};
|
|
362
|
+
/**
|
|
363
|
+
* The plan-change helpers name the plan `plan` rather than `plan_id`: they sit
|
|
364
|
+
* a layer above the wire, where the engine's own `assign` still mirrors it
|
|
365
|
+
* field for field.
|
|
366
|
+
*/
|
|
367
|
+
type PlanChangeParams = {
|
|
368
|
+
/** The plan to move to, by its Meterbase id. */
|
|
369
|
+
plan: string;
|
|
370
|
+
/** Defaults to `next_cycle`. */
|
|
371
|
+
effective?: ApplyMode;
|
|
372
|
+
/** `immediate` only. Defaults to `none`. */
|
|
373
|
+
reconciliation?: Reconciliation;
|
|
374
|
+
};
|
|
375
|
+
/** `effective` is fixed to `immediate`; what is left to choose is the fold. */
|
|
376
|
+
type PlanChangeNowParams = Omit<PlanChangeParams, "effective">;
|
|
377
|
+
/** Neither `effective` nor `reconciliation` is open: the call names both. */
|
|
378
|
+
type PlanMoveParams = Pick<PlanChangeParams, "plan">;
|
|
379
|
+
/** `plan` is not accepted on a grant: the engine mints those itself when a
|
|
380
|
+
* plan is assigned. */
|
|
381
|
+
type AllowanceSource = "purchased" | "bonus" | "manual";
|
|
382
|
+
type Allowance = {
|
|
383
|
+
id: string;
|
|
384
|
+
workspace_id: string;
|
|
385
|
+
customer_id: string;
|
|
386
|
+
meter_id: string;
|
|
387
|
+
amount: number | null;
|
|
388
|
+
no_cap: boolean;
|
|
389
|
+
consumed: number;
|
|
390
|
+
/** `null` under no_cap. */
|
|
391
|
+
remaining: number | null;
|
|
392
|
+
source: AllowanceSource | "plan";
|
|
393
|
+
metadata: Record<string, unknown>;
|
|
394
|
+
effective_at: string;
|
|
395
|
+
expires_at: string | null;
|
|
396
|
+
revoked_at: string | null;
|
|
397
|
+
exhausted_at: string | null;
|
|
398
|
+
created_at: string;
|
|
399
|
+
/** Null unless `source` is `plan`. Together they answer where the grant
|
|
400
|
+
* came from and why it went away. */
|
|
401
|
+
plan_allowance_version_id: string | null;
|
|
402
|
+
assignment_id: string | null;
|
|
403
|
+
cancelled_at: string | null;
|
|
404
|
+
};
|
|
405
|
+
/** Give exactly one of `amount` or `no_cap`. Unlike a plan allowance, a grant
|
|
406
|
+
* of 0 is refused: a grant that gives nothing is a no-op, not a state. */
|
|
407
|
+
type AllowanceGrantParams = {
|
|
408
|
+
meter_id: string;
|
|
409
|
+
/** At least 1. */
|
|
410
|
+
amount?: number;
|
|
411
|
+
no_cap?: boolean;
|
|
412
|
+
/** Required: the engine will not guess why capacity was handed out. */
|
|
413
|
+
source: AllowanceSource;
|
|
414
|
+
metadata?: Record<string, unknown>;
|
|
415
|
+
/** Defaults to now. Dated ahead, the grant is inert until then. */
|
|
416
|
+
effective_at?: string;
|
|
417
|
+
expires_at?: string;
|
|
418
|
+
};
|
|
419
|
+
type AllowanceListParams = {
|
|
420
|
+
meter_id?: string;
|
|
421
|
+
/** Revoked, expired and exhausted grants as well as open ones. */
|
|
422
|
+
include_closed?: boolean;
|
|
423
|
+
};
|
|
424
|
+
type WhoAmI = {
|
|
425
|
+
workspace: string;
|
|
426
|
+
caller: string;
|
|
427
|
+
kind: "api_key" | "service";
|
|
428
|
+
};
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Capacity handed to one customer on top of their plan. A grant with
|
|
432
|
+
* `source: "plan"` is the engine's own, minted when a plan is assigned, and
|
|
433
|
+
* cannot be created here.
|
|
434
|
+
*/
|
|
435
|
+
declare class CustomerAllowances {
|
|
436
|
+
#private;
|
|
437
|
+
constructor(client: Client);
|
|
438
|
+
grant(customerId: string, params: AllowanceGrantParams, options?: RequestOptions): Promise<Allowance>;
|
|
439
|
+
/** Open grants only, unless `include_closed`. */
|
|
440
|
+
list(customerId: string, params?: AllowanceListParams, options?: RequestOptions): Promise<List<Allowance>>;
|
|
441
|
+
retrieve(customerId: string, allowanceId: string, options?: RequestOptions): Promise<Allowance>;
|
|
442
|
+
/** Withdraws what is left without erasing what was consumed. Idempotent. */
|
|
443
|
+
revoke(customerId: string, allowanceId: string, options?: RequestOptions): Promise<Allowance>;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Which plan a customer holds. The history is append-only: there is no patch
|
|
448
|
+
* and no delete, and moving a customer to a different plan is the same call as
|
|
449
|
+
* their first.
|
|
450
|
+
*
|
|
451
|
+
* `assign` is that call, mirroring the wire. The rest name the four moves a
|
|
452
|
+
* caller actually makes — later, now, now-and-start-over, and never mind — so
|
|
453
|
+
* that picking one does not mean knowing what `effective` and `reconciliation`
|
|
454
|
+
* do to a half-used period.
|
|
455
|
+
*/
|
|
456
|
+
declare class CustomerPlan {
|
|
457
|
+
#private;
|
|
458
|
+
constructor(client: Client);
|
|
459
|
+
/**
|
|
460
|
+
* Put a customer on a plan. This is the wire call, and the only one that
|
|
461
|
+
* takes `cycle_anchor` — a first assignment's one chance to put their
|
|
462
|
+
* periods on a date they already have.
|
|
463
|
+
*
|
|
464
|
+
* Returns the instruction as recorded, which is not always as asked: a first
|
|
465
|
+
* plan is recorded `immediate` whatever `effective` said.
|
|
466
|
+
*/
|
|
467
|
+
assign(customerId: string, params: AssignPlanParams, options?: RequestOptions): Promise<Assignment>;
|
|
468
|
+
/**
|
|
469
|
+
* Move a customer to a different plan, with both knobs in the open.
|
|
470
|
+
* `effective` defaults to `next_cycle`; `reconciliation` applies only to an
|
|
471
|
+
* `immediate` change and defaults to `none`.
|
|
472
|
+
*
|
|
473
|
+
* Reach for `changeAtNextCycle`, `changeNow` or `restart` when one of them
|
|
474
|
+
* says what you mean — this is the form to fall back to when the two are
|
|
475
|
+
* chosen at runtime.
|
|
476
|
+
*/
|
|
477
|
+
change(customerId: string, params: PlanChangeParams, options?: RequestOptions): Promise<Assignment>;
|
|
478
|
+
/**
|
|
479
|
+
* Schedule the move for the end of the period they are in: they keep the
|
|
480
|
+
* plan they are paying for until it runs out, and the new one starts at
|
|
481
|
+
* their next boundary. Nothing is pro-rated, because nothing is split.
|
|
482
|
+
*
|
|
483
|
+
* Two plans on different cycles share no boundary, and this answers
|
|
484
|
+
* `CycleChangeRequiresResetError` — use `restart` for that move.
|
|
485
|
+
*/
|
|
486
|
+
changeAtNextCycle(customerId: string, params: PlanMoveParams, options?: RequestOptions): Promise<Assignment>;
|
|
487
|
+
/**
|
|
488
|
+
* Move them now, inside the period already running. Their renewal day does
|
|
489
|
+
* not move; what changes is this period's cap, and `reconciliation` says
|
|
490
|
+
* how:
|
|
491
|
+
*
|
|
492
|
+
* - `none` (the default) — the new plan's amount governs the whole period.
|
|
493
|
+
* Usage already spent still counts, so a downgrade can deny until the
|
|
494
|
+
* period ends.
|
|
495
|
+
* - `prorate` — each plan's amount weighted by the fraction of the period it
|
|
496
|
+
* was held for. Refused between plans on different cycles, which share no
|
|
497
|
+
* period to weight.
|
|
498
|
+
*
|
|
499
|
+
* To have the period itself start over instead, use `restart`.
|
|
500
|
+
*/
|
|
501
|
+
changeNow(customerId: string, params: PlanChangeNowParams, options?: RequestOptions): Promise<Assignment>;
|
|
502
|
+
/**
|
|
503
|
+
* Move them now and start a fresh period today: the period they were in
|
|
504
|
+
* closes where the change lands, keeping the usage it had, and the new
|
|
505
|
+
* plan's full amount opens immediately.
|
|
506
|
+
*
|
|
507
|
+
* This moves the customer's anchor, so their renewal day becomes today. It
|
|
508
|
+
* is the move for a customer starting over — a new contract, a re-signup —
|
|
509
|
+
* and the only one that can take a customer between plans whose cycles
|
|
510
|
+
* differ.
|
|
511
|
+
*/
|
|
512
|
+
restart(customerId: string, params: PlanMoveParams, options?: RequestOptions): Promise<Assignment>;
|
|
513
|
+
/**
|
|
514
|
+
* Call off a change that has not landed yet, leaving the customer on the
|
|
515
|
+
* plan they hold. Naming the plan already held is what supersedes a pending
|
|
516
|
+
* instruction, so this reads the plan in force and names it back.
|
|
517
|
+
*
|
|
518
|
+
* Returns the assignment still in force, or `null` for a customer holding no
|
|
519
|
+
* plan — who can have nothing pending, since a first assignment always lands
|
|
520
|
+
* at once.
|
|
521
|
+
*/
|
|
522
|
+
cancelScheduledChange(customerId: string, options?: RequestOptions): Promise<Assignment | null>;
|
|
523
|
+
/**
|
|
524
|
+
* The plan in force now, which is not always the newest instruction: a
|
|
525
|
+
* change dated ahead does not govern yet.
|
|
526
|
+
*
|
|
527
|
+
* `null` when the customer holds no plan. That is a default deny rather than
|
|
528
|
+
* a failure — they are entitled to nothing — so it is an answer here and not
|
|
529
|
+
* a thrown `NotFoundError`. A customer who does not exist at all still
|
|
530
|
+
* throws one.
|
|
531
|
+
*/
|
|
532
|
+
retrieve(customerId: string, options?: RequestOptions): Promise<Assignment | null>;
|
|
533
|
+
/**
|
|
534
|
+
* The change waiting to land, or `null` when none is. At most one is ever
|
|
535
|
+
* live: a newer instruction supersedes the one before it.
|
|
536
|
+
*
|
|
537
|
+
* Read against the assignment in force rather than against the local clock,
|
|
538
|
+
* so a change landing seconds from now is not reported as already governing.
|
|
539
|
+
*/
|
|
540
|
+
pending(customerId: string, options?: RequestOptions): Promise<Assignment | null>;
|
|
541
|
+
/** Every instruction, superseded ones included: it is the whole trail. */
|
|
542
|
+
history(customerId: string, options?: RequestOptions): Promise<List<Assignment>>;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
declare class Customers {
|
|
546
|
+
#private;
|
|
547
|
+
/** The plan they hold, and the trail of instructions that got them there. */
|
|
548
|
+
readonly plan: CustomerPlan;
|
|
549
|
+
/** Grants, which sit on top of whatever the plan gives. */
|
|
550
|
+
readonly allowances: CustomerAllowances;
|
|
551
|
+
constructor(client: Client);
|
|
552
|
+
create(params: CustomerCreateParams, options?: RequestOptions): Promise<Customer>;
|
|
553
|
+
/** Lean: a listing does not embed the plan. Read one customer for that. */
|
|
554
|
+
list(params?: CustomerListParams, options?: RequestOptions): Promise<List<Customer>>;
|
|
555
|
+
/**
|
|
556
|
+
* One customer, with the plan they hold. `plan` is the one in force now and
|
|
557
|
+
* `pending_plan` the change waiting to land, each `null` when there is
|
|
558
|
+
* none — so knowing what a customer is on costs no second request.
|
|
559
|
+
*/
|
|
560
|
+
retrieve(id: string, options?: RequestOptions): Promise<CustomerWithPlan>;
|
|
561
|
+
/**
|
|
562
|
+
* Resolves the tenant's own identifier, or null, embedding the plan the way
|
|
563
|
+
* `retrieve` does. The engine answers this as a filtered list, so a miss is
|
|
564
|
+
* an empty collection rather than a 404.
|
|
565
|
+
*/
|
|
566
|
+
retrieveByExternalId(externalId: string, options?: RequestOptions): Promise<CustomerWithPlan | null>;
|
|
567
|
+
update(id: string, params: CustomerUpdateParams, options?: RequestOptions): Promise<Customer>;
|
|
568
|
+
/** Soft delete: usage and assignments keep referencing the customer. */
|
|
569
|
+
delete(id: string, options?: RequestOptions): Promise<Customer>;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
declare class Meters {
|
|
573
|
+
#private;
|
|
574
|
+
constructor(client: Client);
|
|
575
|
+
create(params: MeterCreateParams, options?: RequestOptions): Promise<Meter>;
|
|
576
|
+
list(params?: MeterListParams, options?: RequestOptions): Promise<List<Meter>>;
|
|
577
|
+
retrieve(id: string, options?: RequestOptions): Promise<Meter>;
|
|
578
|
+
update(id: string, params: MeterUpdateParams, options?: RequestOptions): Promise<Meter>;
|
|
579
|
+
/** Soft delete: plans and usage keep referencing the meter. Idempotent. */
|
|
580
|
+
archive(id: string, options?: RequestOptions): Promise<Meter>;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* A plan's entitlement, versioned. There is no update and no delete: an edit
|
|
585
|
+
* appends the next version, so which amount applied when stays derivable.
|
|
586
|
+
*/
|
|
587
|
+
declare class PlanAllowances {
|
|
588
|
+
#private;
|
|
589
|
+
constructor(client: Client);
|
|
590
|
+
set(planId: string, params: PlanAllowanceSetParams, options?: RequestOptions): Promise<PlanAllowance>;
|
|
591
|
+
/** Every version of every meter, newest first — history, not just current. */
|
|
592
|
+
list(planId: string, params?: PlanAllowanceListParams, options?: RequestOptions): Promise<List<PlanAllowance>>;
|
|
593
|
+
}
|
|
594
|
+
declare class Plans {
|
|
595
|
+
#private;
|
|
596
|
+
readonly allowances: PlanAllowances;
|
|
597
|
+
constructor(client: Client);
|
|
598
|
+
/** A new plan grants nothing; attach entitlement with `allowances.set`. */
|
|
599
|
+
create(params: PlanCreateParams, options?: RequestOptions): Promise<Plan>;
|
|
600
|
+
list(params?: PlanListParams, options?: RequestOptions): Promise<List<Plan>>;
|
|
601
|
+
retrieve(id: string, options?: RequestOptions): Promise<Plan>;
|
|
602
|
+
update(id: string, params: PlanUpdateParams, options?: RequestOptions): Promise<Plan>;
|
|
603
|
+
/**
|
|
604
|
+
* Stops new assignments without withdrawing capacity from anyone already on
|
|
605
|
+
* the plan, which is why an archived plan still resolves by id. Idempotent.
|
|
606
|
+
*/
|
|
607
|
+
archive(id: string, options?: RequestOptions): Promise<Plan>;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
declare class MeterbaseError extends Error {
|
|
611
|
+
constructor(message: string, options?: {
|
|
612
|
+
cause?: unknown;
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
declare class APIError extends MeterbaseError {
|
|
616
|
+
readonly status: number;
|
|
617
|
+
readonly code: string;
|
|
618
|
+
/** From `X-Request-Id`, when the engine sends one. */
|
|
619
|
+
readonly requestId: string | undefined;
|
|
620
|
+
readonly body: unknown;
|
|
621
|
+
constructor(args: {
|
|
622
|
+
status: number;
|
|
623
|
+
code: string;
|
|
624
|
+
message: string;
|
|
625
|
+
requestId?: string | undefined;
|
|
626
|
+
body?: unknown;
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
declare class AuthenticationError extends APIError {
|
|
630
|
+
}
|
|
631
|
+
declare class PermissionDeniedError extends APIError {
|
|
632
|
+
}
|
|
633
|
+
declare class NotFoundError extends APIError {
|
|
634
|
+
}
|
|
635
|
+
declare class ConflictError extends APIError {
|
|
636
|
+
}
|
|
637
|
+
/**
|
|
638
|
+
* `409 idempotency_conflict`: the key is in use for a different meter or
|
|
639
|
+
* quantity. A caller told their key is taken asks what it recorded next, so
|
|
640
|
+
* the engine names the original and this carries it.
|
|
641
|
+
*
|
|
642
|
+
* A `ConflictError` still, so `catch (e) { if (e instanceof ConflictError) }`
|
|
643
|
+
* keeps working.
|
|
644
|
+
*/
|
|
645
|
+
declare class IdempotencyConflictError extends ConflictError {
|
|
646
|
+
/** The event that key already recorded. Undefined only if the engine sent a
|
|
647
|
+
* body this could not be read out of. */
|
|
648
|
+
readonly existingEventId: string | undefined;
|
|
649
|
+
constructor(args: ConstructorParameters<typeof APIError>[0]);
|
|
650
|
+
}
|
|
651
|
+
declare class InvalidRequestError extends APIError {
|
|
652
|
+
}
|
|
653
|
+
/**
|
|
654
|
+
* `422 cycle_change_requires_reset`: the two plans measure different cycles,
|
|
655
|
+
* so a `next_cycle` change has no shared boundary to wait for and a `prorate`
|
|
656
|
+
* no shared period to weight. The move is `customers.plan.restart`, which
|
|
657
|
+
* closes the current period and opens a fresh one on the new cycle — or
|
|
658
|
+
* `changeNow` with the default `reconciliation: "none"` to keep the period
|
|
659
|
+
* that is running. The engine's `message` says as much.
|
|
660
|
+
*
|
|
661
|
+
* An `InvalidRequestError` still, so an existing `catch` keeps working.
|
|
662
|
+
*/
|
|
663
|
+
declare class CycleChangeRequiresResetError extends InvalidRequestError {
|
|
664
|
+
}
|
|
665
|
+
declare class RateLimitError extends APIError {
|
|
666
|
+
/** Seconds to wait, from `Retry-After`, when the engine sends one. */
|
|
667
|
+
readonly retryAfter: number | undefined;
|
|
668
|
+
constructor(args: ConstructorParameters<typeof APIError>[0] & {
|
|
669
|
+
retryAfter?: number | undefined;
|
|
670
|
+
});
|
|
671
|
+
}
|
|
672
|
+
declare class ServerError extends APIError {
|
|
673
|
+
}
|
|
674
|
+
declare class ConnectionError extends MeterbaseError {
|
|
675
|
+
}
|
|
676
|
+
declare class TimeoutError extends ConnectionError {
|
|
677
|
+
}
|
|
678
|
+
declare function errorFromResponse(args: {
|
|
679
|
+
status: number;
|
|
680
|
+
code: string;
|
|
681
|
+
message: string;
|
|
682
|
+
requestId?: string | undefined;
|
|
683
|
+
retryAfter?: number | undefined;
|
|
684
|
+
body?: unknown;
|
|
685
|
+
}): APIError;
|
|
686
|
+
|
|
687
|
+
declare class Meterbase {
|
|
688
|
+
#private;
|
|
689
|
+
readonly customers: Customers;
|
|
690
|
+
readonly meters: Meters;
|
|
691
|
+
readonly plans: Plans;
|
|
692
|
+
constructor(options: MeterbaseOptions);
|
|
693
|
+
/**
|
|
694
|
+
* Asks whether a customer may consume `quantity` of a meter, named by the
|
|
695
|
+
* tenant's own external id and the meter's key. Absence of entitlement is
|
|
696
|
+
* not permission: a customer with no plan and no grant is denied.
|
|
697
|
+
*
|
|
698
|
+
* This is the gate, and the only call that ever refuses. Run it before the
|
|
699
|
+
* work; record the work with `track` afterwards.
|
|
700
|
+
*/
|
|
701
|
+
check(params: CheckParams, options?: RequestOptions): Promise<CheckResult>;
|
|
702
|
+
/**
|
|
703
|
+
* Records usage that already happened — the tokens were spent, the image
|
|
704
|
+
* was generated — so it never refuses on capacity. A quantity beyond the
|
|
705
|
+
* customer's capacity is recorded, drives `available` to 0, and the next
|
|
706
|
+
* `check` says no. The answer is a receipt, not a verdict.
|
|
707
|
+
*
|
|
708
|
+
* `idempotency_key` is generated when omitted, so retrying this call — the
|
|
709
|
+
* SDK's own retries included — replays the original rather than counting
|
|
710
|
+
* the same work twice.
|
|
711
|
+
*/
|
|
712
|
+
track(params: TrackParams, options?: RequestOptions): Promise<TrackResult>;
|
|
713
|
+
/** Reports which workspace this key acts for. */
|
|
714
|
+
whoami(options?: RequestOptions): Promise<WhoAmI>;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
export { APIError, type Allowance, type AllowanceGrantParams, type AllowanceListParams, type AllowanceSource, type ApplyMode, type AssignPlanParams, type Assignment, AuthenticationError, type CheckParams, type CheckResult, ConflictError, ConnectionError, type Customer, CustomerAllowances, type CustomerCreateParams, type CustomerListParams, CustomerPlan, type CustomerUpdateParams, type CustomerWithPlan, Customers, CycleChangeRequiresResetError, type EmbeddedPlan, IdempotencyConflictError, InvalidRequestError, type List, type Meter, type MeterCreateParams, type MeterListParams, type MeterUpdateParams, Meterbase, MeterbaseError, type MeterbaseOptions, Meters, NotFoundError, PermissionDeniedError, type Plan, type PlanAllowance, type PlanAllowanceKind, type PlanAllowanceListParams, type PlanAllowanceSetParams, PlanAllowances, type PlanChangeNowParams, type PlanChangeParams, type PlanCreateParams, type PlanCycle, type PlanListParams, type PlanMoveParams, type PlanUpdateParams, Plans, RateLimitError, type Reconciliation, type RecordedReconciliation, type RequestOptions, ServerError, TimeoutError, type TrackParams, type TrackResult, type UsageEvent, type Validity, type WhoAmI, errorFromResponse };
|