@iteradian-rpc/sdk 1.0.1 → 1.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/README.md +106 -17
- package/dist/index.d.mts +151 -10
- package/dist/index.d.ts +151 -10
- package/dist/index.js +81 -9
- package/dist/index.mjs +81 -9
- package/package.json +5 -13
package/README.md
CHANGED
|
@@ -166,11 +166,15 @@ client.clearAccessToken();
|
|
|
166
166
|
// Login (token set automatically)
|
|
167
167
|
const tokens = await client.auth.login({ email: "...", password: "..." });
|
|
168
168
|
|
|
169
|
-
// Register
|
|
170
|
-
|
|
169
|
+
// Register — does NOT sign in. Answers { message, email } and emails a
|
|
170
|
+
// confirmation link; log in once the address is confirmed.
|
|
171
|
+
// acceptedTerms is required: pass true only after the user agreed to the
|
|
172
|
+
// Terms of Service, Privacy Policy and DPA (https://iteradian.com/terms,
|
|
173
|
+
// /privacy, /dpa). The server rejects registration (400) otherwise.
|
|
174
|
+
const { message } = await client.auth.register({
|
|
171
175
|
email: "...",
|
|
172
176
|
password: "...",
|
|
173
|
-
|
|
177
|
+
acceptedTerms: true,
|
|
174
178
|
});
|
|
175
179
|
|
|
176
180
|
// Refresh token
|
|
@@ -184,7 +188,7 @@ const setup = await client.auth.enable2FA({ password: "..." });
|
|
|
184
188
|
console.log(`Secret: ${setup.secret}`);
|
|
185
189
|
console.log(`QR Code: ${setup.qrCode}`);
|
|
186
190
|
await client.auth.verify2FA({ code: "123456" });
|
|
187
|
-
await client.auth.disable2FA(
|
|
191
|
+
await client.auth.disable2FA("password", "123456"); // password + current 6-digit TOTP code
|
|
188
192
|
|
|
189
193
|
// Magic Link
|
|
190
194
|
await client.auth.sendMagicLink({ email: "user@example.com" });
|
|
@@ -208,11 +212,23 @@ await client.organizations.delete(orgId);
|
|
|
208
212
|
|
|
209
213
|
// Members
|
|
210
214
|
const members = await client.organizations.listMembers(orgId);
|
|
211
|
-
const member = await client.organizations.inviteMember(orgId, {
|
|
212
|
-
email: "user@example.com",
|
|
213
|
-
role: "member",
|
|
214
|
-
});
|
|
215
215
|
await client.organizations.removeMember(orgId, memberId);
|
|
216
|
+
|
|
217
|
+
// Invitations — inviting creates a pending invite; the invitee becomes a
|
|
218
|
+
// member only after accepting it (signed in, verified email).
|
|
219
|
+
const invite = await client.organizations.inviteMember(orgId, {
|
|
220
|
+
email: "user@example.com",
|
|
221
|
+
role: "developer",
|
|
222
|
+
}); // { id, email, role, status: "pending", expiresAt, createdAt }
|
|
223
|
+
const open = await client.organizations.listInvites(orgId);
|
|
224
|
+
await client.organizations.revokeInvite(orgId, invite.id);
|
|
225
|
+
|
|
226
|
+
// As the invitee
|
|
227
|
+
const { invites } = await client.organizations.listMyInvites();
|
|
228
|
+
await client.organizations.acceptInvite(invites[0].id); // or declineInvite()
|
|
229
|
+
// A user who has not accepted the current terms version gets 403
|
|
230
|
+
// (TERMS_ACCEPTANCE_REQUIRED); once they agree, accept with:
|
|
231
|
+
await client.organizations.acceptInvite(invites[0].id, { acceptedTerms: true });
|
|
216
232
|
```
|
|
217
233
|
|
|
218
234
|
### API Keys (`client.apiKeys`)
|
|
@@ -321,7 +337,11 @@ const stats = await client.logs.getStats(orgId, { period: "24h" });
|
|
|
321
337
|
|
|
322
338
|
```typescript
|
|
323
339
|
const sub = await client.subscriptions.get(orgId);
|
|
324
|
-
|
|
340
|
+
// The caller confirms the user accepted the plan-change billing terms; the
|
|
341
|
+
// server rejects the change (400) unless acceptedTerms is true.
|
|
342
|
+
const updated = await client.subscriptions.changePlan(orgId, "pro", {
|
|
343
|
+
acceptedTerms: true,
|
|
344
|
+
});
|
|
325
345
|
const cancelled = await client.subscriptions.cancel(orgId);
|
|
326
346
|
const reactivated = await client.subscriptions.reactivate(orgId);
|
|
327
347
|
const invoices = await client.subscriptions.getInvoices(orgId);
|
|
@@ -365,7 +385,8 @@ All types are exported from the package and defined in `src/types.ts` (538 lines
|
|
|
365
385
|
| Type | Fields |
|
|
366
386
|
| ----------------- | ------------------------------------- |
|
|
367
387
|
| `LoginRequest` | `email`, `password`, `twoFactorCode?` |
|
|
368
|
-
| `RegisterRequest` | `email`, `password
|
|
388
|
+
| `RegisterRequest` | `email`, `password` |
|
|
389
|
+
| `RegisterResponse` | `message`, `email` (no tokens) |
|
|
369
390
|
| `AuthTokens` | `accessToken`, `refreshToken`, `user` |
|
|
370
391
|
| `TwoFASetup` | `secret`, `qrCode` |
|
|
371
392
|
|
|
@@ -377,6 +398,9 @@ All types are exported from the package and defined in `src/types.ts` (538 lines
|
|
|
377
398
|
| `OrgMember` | `id`, `userId`, `email`, `role`, `joinedAt` |
|
|
378
399
|
| `CreateOrgRequest` | `name`, `slug` |
|
|
379
400
|
| `InviteMemberRequest` | `email`, `role` |
|
|
401
|
+
| `OrgInvite` | `id`, `email`, `role`, `status`, `expiresAt`, `createdAt`, `invitedBy?` |
|
|
402
|
+
| `MyInvites` | `emailVerified`, `invites` (`MyInvite[]`) |
|
|
403
|
+
| `InviteAcceptance` | `organizationId`, `membershipId`, `role` |
|
|
380
404
|
|
|
381
405
|
### API Key Types
|
|
382
406
|
|
|
@@ -449,6 +473,16 @@ try {
|
|
|
449
473
|
}
|
|
450
474
|
```
|
|
451
475
|
|
|
476
|
+
### Terms acceptance (403 `TERMS_ACCEPTANCE_REQUIRED`)
|
|
477
|
+
|
|
478
|
+
After Iteradian publishes a new version of the Terms of Service, Privacy
|
|
479
|
+
Policy or DPA, any write (POST/PUT/PATCH/DELETE) made with a user JWT may
|
|
480
|
+
answer `IteradianError` with `statusCode` 403 until the user accepts the new
|
|
481
|
+
version in the dashboard (the response body carries
|
|
482
|
+
`code: "TERMS_ACCEPTANCE_REQUIRED"`, `termsVersion` and `termsUrl`). API keys
|
|
483
|
+
and agent tokens are unaffected. `organizations.acceptInvite(id, {
|
|
484
|
+
acceptedTerms: true })` records the acceptance as part of joining.
|
|
485
|
+
|
|
452
486
|
On a gateway call the same error also carries the JSON-RPC detail, which is how
|
|
453
487
|
you tell "wait a second" from "you are out of quota until the period rolls
|
|
454
488
|
over":
|
|
@@ -465,6 +499,9 @@ try {
|
|
|
465
499
|
if (err instanceof IteradianError) {
|
|
466
500
|
if (err.isRateLimited) {
|
|
467
501
|
// -32005. Wait err.retryAfter seconds and try again.
|
|
502
|
+
} else if (err.isDailyLimitReached) {
|
|
503
|
+
// -32008. This API key's daily limit is used up. err.data carries
|
|
504
|
+
// { dailyLimit, used, cost, resetsAt }; resetsAt is the next 00:00 UTC.
|
|
468
505
|
} else if (err.isQuotaExhausted) {
|
|
469
506
|
// -32006 or -32007. Retrying will not help: err.data.resetsAt says when
|
|
470
507
|
// the allowance returns, and the cap needs a plan change.
|
|
@@ -489,8 +526,9 @@ The SDK automatically retries:
|
|
|
489
526
|
- **5xx Server Errors** — with exponential backoff
|
|
490
527
|
- **429 Too Many Requests**, but **only** `-32005` (rate or concurrency limit).
|
|
491
528
|
`-32006` (monthly quota exhausted) and `-32007` (overage spend cap) do not
|
|
492
|
-
recover until the billing period rolls over,
|
|
493
|
-
|
|
529
|
+
recover until the billing period rolls over, and `-32008` (per-API-key daily
|
|
530
|
+
limit) not until `error.data.resetsAt` (the next 00:00 UTC), so retrying
|
|
531
|
+
them burns your time for a guaranteed 429.
|
|
494
532
|
|
|
495
533
|
Backoff formula: `min(1000 * 2^(attempt-1), 10000)` ms, or the gateway's own
|
|
496
534
|
`retryAfter` hint when it gives one — capped at 30 seconds either way.
|
|
@@ -622,10 +660,61 @@ This SDK takes both, and defaults the gateway to `https://rpc.iteradian.com`.
|
|
|
622
660
|
organization holds. Creating more keys does not raise them.
|
|
623
661
|
- The gateway returns HTTP 429 with a JSON-RPC error body:
|
|
624
662
|
`-32005` rate limited (retry after `error.data.retryAfter`), `-32006` monthly
|
|
625
|
-
quota exhausted, `-32007` overage spend cap reached
|
|
626
|
-
|
|
663
|
+
quota exhausted, `-32007` overage spend cap reached, `-32008` the API key's
|
|
664
|
+
own daily limit reached (`error.data = { dailyLimit, used, cost, resetsAt }`).
|
|
665
|
+
None of the last three recover before `resetsAt` (the billing period roll-over,
|
|
666
|
+
or the next 00:00 UTC for `-32008`), so retrying them is wasted work.
|
|
667
|
+
|
|
668
|
+
Plans (defaults; an admin can change them): Free 25 rps / 3M per month with no
|
|
669
|
+
overage (requests stop at the quota, no card needed), Developer 100 rps / 5M
|
|
670
|
+
with overage at $6 per million, Professional 500 rps / 30M at $4.50 per million,
|
|
671
|
+
Dedicated per contract from $4 per million. Trials are offered on Developer
|
|
672
|
+
only; a trial that ends unpaid falls back to Free. See `sdks/SDK_CONTRACT.md`
|
|
673
|
+
for the full table.
|
|
674
|
+
|
|
675
|
+
### WebSocket
|
|
676
|
+
|
|
677
|
+
The gateway also serves JSON-RPC over WebSocket at
|
|
678
|
+
`wss://rpc.iteradian.com/ws/v1/{network}`. This SDK does not wrap it on
|
|
679
|
+
purpose: connect with any WebSocket client, such as ethers
|
|
680
|
+
`WebSocketProvider`, viem's `webSocket()` transport, or the built-in
|
|
681
|
+
`WebSocket` in browsers and Node 22+. Authenticate with the
|
|
682
|
+
`X-Api-Key` header, `Authorization: Bearer <key>`, or `?apiKey=<key>` on the
|
|
683
|
+
URL (browsers cannot set headers on a WebSocket).
|
|
627
684
|
|
|
628
|
-
|
|
629
|
-
|
|
685
|
+
```typescript
|
|
686
|
+
const ws = new WebSocket(
|
|
687
|
+
"wss://rpc.iteradian.com/ws/v1/eth-mainnet?apiKey=itrd_live_...",
|
|
688
|
+
);
|
|
689
|
+
|
|
690
|
+
ws.addEventListener("open", () => {
|
|
691
|
+
ws.send(JSON.stringify({
|
|
692
|
+
jsonrpc: "2.0", id: 1, method: "eth_subscribe", params: ["newHeads"],
|
|
693
|
+
}));
|
|
694
|
+
});
|
|
695
|
+
|
|
696
|
+
ws.addEventListener("message", (event) => {
|
|
697
|
+
const msg = JSON.parse(event.data);
|
|
698
|
+
if (msg.method === "eth_subscription") {
|
|
699
|
+
console.log("new head", msg.params.result.number);
|
|
700
|
+
}
|
|
701
|
+
});
|
|
702
|
+
|
|
703
|
+
ws.addEventListener("close", (event) => {
|
|
704
|
+
// 1012: node restarted, reconnect and re-subscribe. 4003: key revoked, stop.
|
|
705
|
+
console.log("closed", event.code);
|
|
706
|
+
});
|
|
707
|
+
```
|
|
630
708
|
|
|
631
|
-
|
|
709
|
+
- Each message you send is charged like an HTTP request (a batch of N costs N).
|
|
710
|
+
Subscription notifications pushed to you are not charged.
|
|
711
|
+
- A message refused by a limit gets an ordinary JSON-RPC error under that
|
|
712
|
+
call's `id`, with the same codes as above (`-32005` to `-32008`). The socket
|
|
713
|
+
stays open.
|
|
714
|
+
- An organization can hold `max(5, floor(concurrency / 4))` streams at once;
|
|
715
|
+
past that the upgrade is refused with HTTP 429. Other upgrade failures: 400
|
|
716
|
+
bad path, 401/403 bad key, 404 unknown network, 503 no WebSocket-capable node.
|
|
717
|
+
- Close code `1012` means the upstream node restarted: reconnect and
|
|
718
|
+
re-subscribe. `4003` means the key was revoked or the organization suspended
|
|
719
|
+
(keys are re-checked every 60 s): do not reconnect.
|
|
720
|
+
- The server pings every 30 s. Messages are limited to 1 MB.
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
interface RegisterRequest {
|
|
2
2
|
email: string;
|
|
3
3
|
password: string;
|
|
4
|
+
/**
|
|
5
|
+
* The caller confirms the user agreed to the Terms of Service, Privacy
|
|
6
|
+
* Policy and DPA (https://iteradian.com/terms, /privacy, /dpa). Always
|
|
7
|
+
* sent; the server rejects registration (400) unless this is `true`.
|
|
8
|
+
*/
|
|
9
|
+
acceptedTerms: boolean;
|
|
10
|
+
/** @deprecated Ignored by the API. */
|
|
4
11
|
organizationName?: string;
|
|
5
12
|
}
|
|
6
13
|
interface LoginRequest {
|
|
@@ -9,6 +16,15 @@ interface LoginRequest {
|
|
|
9
16
|
twoFactorCode?: string;
|
|
10
17
|
backupCode?: string;
|
|
11
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* What `POST /auth/register` answers — whether or not the address already has
|
|
21
|
+
* an account (so it cannot be used to probe for accounts). No session is
|
|
22
|
+
* created: the user confirms their address from the email, then logs in.
|
|
23
|
+
*/
|
|
24
|
+
interface RegisterResponse {
|
|
25
|
+
message: string;
|
|
26
|
+
email: string;
|
|
27
|
+
}
|
|
12
28
|
interface AuthTokens {
|
|
13
29
|
accessToken: string;
|
|
14
30
|
refreshToken: string;
|
|
@@ -49,6 +65,53 @@ interface OrgMember {
|
|
|
49
65
|
role: OrgRole;
|
|
50
66
|
joinedAt: string;
|
|
51
67
|
}
|
|
68
|
+
/** An invitation to join an organization, as its owners/admins see it. */
|
|
69
|
+
interface OrgInvite {
|
|
70
|
+
id: string;
|
|
71
|
+
email: string;
|
|
72
|
+
role: OrgRole;
|
|
73
|
+
/** "expired" invitations stay listed until revoked or re-sent. */
|
|
74
|
+
status: "pending" | "expired";
|
|
75
|
+
expiresAt: string;
|
|
76
|
+
createdAt: string;
|
|
77
|
+
/** Email of the member who sent it. */
|
|
78
|
+
invitedBy?: string | null;
|
|
79
|
+
}
|
|
80
|
+
/** An invitation addressed to the signed-in user. */
|
|
81
|
+
interface MyInvite {
|
|
82
|
+
id: string;
|
|
83
|
+
role: OrgRole;
|
|
84
|
+
expiresAt: string;
|
|
85
|
+
createdAt: string;
|
|
86
|
+
invitedBy: string | null;
|
|
87
|
+
organization: {
|
|
88
|
+
id: string;
|
|
89
|
+
name: string;
|
|
90
|
+
avatarUrl?: string | null;
|
|
91
|
+
avatarUrlDark?: string | null;
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
interface MyInvites {
|
|
95
|
+
/** Invitations can only be accepted once the user's email is verified. */
|
|
96
|
+
emailVerified: boolean;
|
|
97
|
+
invites: MyInvite[];
|
|
98
|
+
}
|
|
99
|
+
/** The membership created by accepting an invitation. */
|
|
100
|
+
/** Options for `organizations.acceptInvite`. */
|
|
101
|
+
interface AcceptInviteOptions {
|
|
102
|
+
/**
|
|
103
|
+
* The caller confirms the user agreed to the current Terms of Service,
|
|
104
|
+
* Privacy Policy and DPA. Only needed when the user has not accepted the
|
|
105
|
+
* current terms version yet; without it the API answers 403
|
|
106
|
+
* `TERMS_ACCEPTANCE_REQUIRED`. Sent only when given.
|
|
107
|
+
*/
|
|
108
|
+
acceptedTerms?: boolean;
|
|
109
|
+
}
|
|
110
|
+
interface InviteAcceptance {
|
|
111
|
+
organizationId: string;
|
|
112
|
+
membershipId: string;
|
|
113
|
+
role: OrgRole;
|
|
114
|
+
}
|
|
52
115
|
interface UserPermissions {
|
|
53
116
|
role: OrgRole;
|
|
54
117
|
roleLabel: string;
|
|
@@ -349,6 +412,14 @@ interface LogQueryParams {
|
|
|
349
412
|
sortBy?: "timestamp" | "latencyMs" | "statusCode";
|
|
350
413
|
sortOrder?: "asc" | "desc";
|
|
351
414
|
}
|
|
415
|
+
/** Options for `subscriptions.changePlan`. */
|
|
416
|
+
interface ChangePlanOptions {
|
|
417
|
+
/**
|
|
418
|
+
* The caller confirms the user accepted the plan-change billing terms.
|
|
419
|
+
* The server rejects the change (400) unless this is `true`.
|
|
420
|
+
*/
|
|
421
|
+
acceptedTerms: boolean;
|
|
422
|
+
}
|
|
352
423
|
interface Subscription {
|
|
353
424
|
id: string;
|
|
354
425
|
organizationId: string;
|
|
@@ -377,7 +448,21 @@ interface PlanLimits {
|
|
|
377
448
|
endpoints: number;
|
|
378
449
|
teamMembers: number;
|
|
379
450
|
logRetentionDays: number;
|
|
380
|
-
|
|
451
|
+
/**
|
|
452
|
+
* Limits sold as something other than a plain number, keyed by the API's
|
|
453
|
+
* limit name (`rps`, `concurrency`, `maxApiKeys`, `monthlyRequests`,
|
|
454
|
+
* `overageRatePer1k`, `overageCapUsd`). `"unlimited"`: not enforced per
|
|
455
|
+
* plan. `"custom"`: negotiated per contract. Such a limit carries no number.
|
|
456
|
+
* Absent on plans where every limit is a number.
|
|
457
|
+
*/
|
|
458
|
+
limitModes?: Partial<Record<PlanLimitKey, PlanLimitMode>>;
|
|
459
|
+
/** Display text for those limits, e.g. "Quoted per contract". */
|
|
460
|
+
limitLabels?: Partial<Record<PlanLimitKey, string>>;
|
|
461
|
+
}
|
|
462
|
+
/** How a plan limit is sold. Absent from `limitModes` means a plain number. */
|
|
463
|
+
type PlanLimitMode = "unlimited" | "custom";
|
|
464
|
+
/** Limit names that may appear in `PlanLimits.limitModes`. */
|
|
465
|
+
type PlanLimitKey = "rps" | "concurrency" | "maxApiKeys" | "monthlyRequests" | "overageRatePer1k" | "overageCapUsd";
|
|
381
466
|
interface Invoice {
|
|
382
467
|
id: string;
|
|
383
468
|
amount: number;
|
|
@@ -482,6 +567,8 @@ declare class IteradianError extends Error {
|
|
|
482
567
|
* -32005 rate limit or concurrency limit exceeded (retry shortly)
|
|
483
568
|
* -32006 monthly quota exhausted (retrying will not help until `resetsAt`)
|
|
484
569
|
* -32007 overage spend limit reached (same — needs a plan change)
|
|
570
|
+
* -32008 per-API-key daily limit reached (no retry until `data.resetsAt`,
|
|
571
|
+
* the next 00:00 UTC)
|
|
485
572
|
*/
|
|
486
573
|
readonly rpcCode?: number;
|
|
487
574
|
/** Seconds to wait before retrying, when the gateway supplied one. */
|
|
@@ -493,8 +580,18 @@ declare class IteradianError extends Error {
|
|
|
493
580
|
retryAfter?: number;
|
|
494
581
|
data?: Record<string, unknown>;
|
|
495
582
|
});
|
|
496
|
-
/**
|
|
583
|
+
/**
|
|
584
|
+
* True when the request failed because an allowance is used up and retrying
|
|
585
|
+
* will not help until it resets: the subscription quota (-32006), the
|
|
586
|
+
* overage spend cap (-32007) or the API key's daily limit (-32008).
|
|
587
|
+
*/
|
|
497
588
|
get isQuotaExhausted(): boolean;
|
|
589
|
+
/**
|
|
590
|
+
* True when the API key's own daily limit is reached (-32008). `data` then
|
|
591
|
+
* carries `{ dailyLimit, used, cost, resetsAt }`; `resetsAt` is the next
|
|
592
|
+
* 00:00 UTC.
|
|
593
|
+
*/
|
|
594
|
+
get isDailyLimitReached(): boolean;
|
|
498
595
|
/** True when the request was throttled and is worth retrying. */
|
|
499
596
|
get isRateLimited(): boolean;
|
|
500
597
|
}
|
|
@@ -530,8 +627,18 @@ declare class HttpClient {
|
|
|
530
627
|
declare class AuthResource {
|
|
531
628
|
private http;
|
|
532
629
|
constructor(http: HttpClient);
|
|
533
|
-
/**
|
|
534
|
-
|
|
630
|
+
/**
|
|
631
|
+
* Register a new user account. Does not sign in: the API answers
|
|
632
|
+
* `{ message, email }` (the same for an address that already has an
|
|
633
|
+
* account) and emails a confirmation link. Call `login()` once the address
|
|
634
|
+
* is confirmed.
|
|
635
|
+
*
|
|
636
|
+
* The server rejects registration (400) unless the user agreed to the
|
|
637
|
+
* Terms of Service, Privacy Policy and DPA, so `data.acceptedTerms` is
|
|
638
|
+
* required and always sent. Pass `acceptedTerms: true` only after the user
|
|
639
|
+
* has ticked the agreement.
|
|
640
|
+
*/
|
|
641
|
+
register(data: RegisterRequest): Promise<RegisterResponse>;
|
|
535
642
|
/** Login with email/password (optionally with 2FA code) */
|
|
536
643
|
login(data: LoginRequest): Promise<AuthTokens>;
|
|
537
644
|
/** Logout current session */
|
|
@@ -587,11 +694,37 @@ declare class OrganizationsResource {
|
|
|
587
694
|
leave(orgId: string): Promise<void>;
|
|
588
695
|
/** List organization members */
|
|
589
696
|
listMembers(orgId: string): Promise<OrgMember[]>;
|
|
590
|
-
/**
|
|
697
|
+
/**
|
|
698
|
+
* Invite someone to the organization by email. Creates (or refreshes) a
|
|
699
|
+
* pending invitation — nobody becomes a member until the invitee accepts
|
|
700
|
+
* it while signed in with a verified address.
|
|
701
|
+
*/
|
|
591
702
|
inviteMember(orgId: string, data: {
|
|
592
703
|
email: string;
|
|
593
704
|
role: string;
|
|
594
|
-
}): Promise<
|
|
705
|
+
}): Promise<OrgInvite>;
|
|
706
|
+
/** Open invitations of the organization (owner/admin) */
|
|
707
|
+
listInvites(orgId: string): Promise<OrgInvite[]>;
|
|
708
|
+
/** Revoke an open invitation (owner/admin) */
|
|
709
|
+
revokeInvite(orgId: string, inviteId: string): Promise<{
|
|
710
|
+
message: string;
|
|
711
|
+
}>;
|
|
712
|
+
/** Invitations addressed to the signed-in user */
|
|
713
|
+
listMyInvites(): Promise<MyInvites>;
|
|
714
|
+
/**
|
|
715
|
+
* Accept an invitation addressed to the signed-in user.
|
|
716
|
+
*
|
|
717
|
+
* If the user has not accepted the current terms version yet, the API
|
|
718
|
+
* answers 403 (`TERMS_ACCEPTANCE_REQUIRED`) unless
|
|
719
|
+
* `{ acceptedTerms: true }` is passed — only after the user agreed to the
|
|
720
|
+
* Terms of Service, Privacy Policy and DPA. `acceptedTerms` is sent only
|
|
721
|
+
* when given.
|
|
722
|
+
*/
|
|
723
|
+
acceptInvite(inviteId: string, options?: AcceptInviteOptions): Promise<InviteAcceptance>;
|
|
724
|
+
/** Decline an invitation addressed to the signed-in user */
|
|
725
|
+
declineInvite(inviteId: string): Promise<{
|
|
726
|
+
message: string;
|
|
727
|
+
}>;
|
|
595
728
|
/** Update a member's role */
|
|
596
729
|
updateMemberRole(orgId: string, memberId: string, role: string): Promise<OrgMember>;
|
|
597
730
|
/** Remove a member from the organization */
|
|
@@ -741,8 +874,15 @@ declare class SubscriptionsResource {
|
|
|
741
874
|
constructor(http: HttpClient);
|
|
742
875
|
/** Get current subscription */
|
|
743
876
|
get(orgId: string): Promise<Subscription>;
|
|
744
|
-
/**
|
|
745
|
-
|
|
877
|
+
/**
|
|
878
|
+
* Change subscription plan.
|
|
879
|
+
*
|
|
880
|
+
* The server rejects a plan change unless the caller confirms the
|
|
881
|
+
* plan-change billing terms, so `options.acceptedTerms` is required and
|
|
882
|
+
* always sent. Pass `{ acceptedTerms: true }` only after the user has
|
|
883
|
+
* accepted the terms.
|
|
884
|
+
*/
|
|
885
|
+
changePlan(orgId: string, planId: string, options: ChangePlanOptions): Promise<Subscription>;
|
|
746
886
|
/** Cancel subscription */
|
|
747
887
|
cancel(orgId: string): Promise<Subscription>;
|
|
748
888
|
/** Reactivate a cancelled subscription */
|
|
@@ -837,7 +977,7 @@ declare class RpcResource {
|
|
|
837
977
|
*
|
|
838
978
|
* @example
|
|
839
979
|
* ```typescript
|
|
840
|
-
* import { IteradianClient } from '@iteradian/sdk';
|
|
980
|
+
* import { IteradianClient } from '@iteradian-rpc/sdk';
|
|
841
981
|
*
|
|
842
982
|
* const client = new IteradianClient({
|
|
843
983
|
* baseUrl: 'https://api.iteradian.com/api/v1',
|
|
@@ -890,4 +1030,5 @@ declare class IteradianClient {
|
|
|
890
1030
|
clearAccessToken(): void;
|
|
891
1031
|
}
|
|
892
1032
|
|
|
893
|
-
export {
|
|
1033
|
+
export { AlertsResource, ApiKeysResource, AuthResource, DashboardResource, EndpointsResource, IteradianClient, IteradianError, LogsResource, OrganizationsResource, PlansResource, RpcResource, SubscriptionsResource, SupportResource, UsageResource };
|
|
1034
|
+
export type { AcceptInviteOptions, Alert, AlertChannel, AlertCondition, AlertMetric, AlertRule, AlertSeverity, AlertStatus, ApiError, ApiKey, ApiKeyAnalytics, ApiKeyWithSecret, ApiResponse, AuthTokens, ChangePlanOptions, CreateAlertChannelRequest, CreateAlertRuleRequest, CreateApiKeyRequest, CreateEndpointRequest, CreateTicketRequest, DailyUsage, DashboardData, DataPoint, Endpoint, EndpointMetric, EndpointRegion, EndpointStatus, HealthStatus, InviteAcceptance, Invoice, IteradianConfig, JsonRpcError, JsonRpcRequest, JsonRpcResponse, LogFilterOptions, LogQueryParams, LogStatus, LoginRequest, LogsResponse, Membership, MyInvite, MyInvites, Network, NetworkType, OrgInvite, OrgMember, OrgRole, Organization, PaginatedResponse, Plan, PlanLimitKey, PlanLimitMode, PlanLimits, QuickStats, RegisterRequest, RegisterResponse, RequestLog, Subscription, SupportTicket, TicketCategory, TicketMessage, TicketPriority, TicketStatus, TwoFASetup, UpdateApiKeyRequest, UpdateEndpointRequest, UsageByMethod, UsageByNetwork, UsageByRegion, UsageSummary, User, UserPermissions };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
interface RegisterRequest {
|
|
2
2
|
email: string;
|
|
3
3
|
password: string;
|
|
4
|
+
/**
|
|
5
|
+
* The caller confirms the user agreed to the Terms of Service, Privacy
|
|
6
|
+
* Policy and DPA (https://iteradian.com/terms, /privacy, /dpa). Always
|
|
7
|
+
* sent; the server rejects registration (400) unless this is `true`.
|
|
8
|
+
*/
|
|
9
|
+
acceptedTerms: boolean;
|
|
10
|
+
/** @deprecated Ignored by the API. */
|
|
4
11
|
organizationName?: string;
|
|
5
12
|
}
|
|
6
13
|
interface LoginRequest {
|
|
@@ -9,6 +16,15 @@ interface LoginRequest {
|
|
|
9
16
|
twoFactorCode?: string;
|
|
10
17
|
backupCode?: string;
|
|
11
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* What `POST /auth/register` answers — whether or not the address already has
|
|
21
|
+
* an account (so it cannot be used to probe for accounts). No session is
|
|
22
|
+
* created: the user confirms their address from the email, then logs in.
|
|
23
|
+
*/
|
|
24
|
+
interface RegisterResponse {
|
|
25
|
+
message: string;
|
|
26
|
+
email: string;
|
|
27
|
+
}
|
|
12
28
|
interface AuthTokens {
|
|
13
29
|
accessToken: string;
|
|
14
30
|
refreshToken: string;
|
|
@@ -49,6 +65,53 @@ interface OrgMember {
|
|
|
49
65
|
role: OrgRole;
|
|
50
66
|
joinedAt: string;
|
|
51
67
|
}
|
|
68
|
+
/** An invitation to join an organization, as its owners/admins see it. */
|
|
69
|
+
interface OrgInvite {
|
|
70
|
+
id: string;
|
|
71
|
+
email: string;
|
|
72
|
+
role: OrgRole;
|
|
73
|
+
/** "expired" invitations stay listed until revoked or re-sent. */
|
|
74
|
+
status: "pending" | "expired";
|
|
75
|
+
expiresAt: string;
|
|
76
|
+
createdAt: string;
|
|
77
|
+
/** Email of the member who sent it. */
|
|
78
|
+
invitedBy?: string | null;
|
|
79
|
+
}
|
|
80
|
+
/** An invitation addressed to the signed-in user. */
|
|
81
|
+
interface MyInvite {
|
|
82
|
+
id: string;
|
|
83
|
+
role: OrgRole;
|
|
84
|
+
expiresAt: string;
|
|
85
|
+
createdAt: string;
|
|
86
|
+
invitedBy: string | null;
|
|
87
|
+
organization: {
|
|
88
|
+
id: string;
|
|
89
|
+
name: string;
|
|
90
|
+
avatarUrl?: string | null;
|
|
91
|
+
avatarUrlDark?: string | null;
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
interface MyInvites {
|
|
95
|
+
/** Invitations can only be accepted once the user's email is verified. */
|
|
96
|
+
emailVerified: boolean;
|
|
97
|
+
invites: MyInvite[];
|
|
98
|
+
}
|
|
99
|
+
/** The membership created by accepting an invitation. */
|
|
100
|
+
/** Options for `organizations.acceptInvite`. */
|
|
101
|
+
interface AcceptInviteOptions {
|
|
102
|
+
/**
|
|
103
|
+
* The caller confirms the user agreed to the current Terms of Service,
|
|
104
|
+
* Privacy Policy and DPA. Only needed when the user has not accepted the
|
|
105
|
+
* current terms version yet; without it the API answers 403
|
|
106
|
+
* `TERMS_ACCEPTANCE_REQUIRED`. Sent only when given.
|
|
107
|
+
*/
|
|
108
|
+
acceptedTerms?: boolean;
|
|
109
|
+
}
|
|
110
|
+
interface InviteAcceptance {
|
|
111
|
+
organizationId: string;
|
|
112
|
+
membershipId: string;
|
|
113
|
+
role: OrgRole;
|
|
114
|
+
}
|
|
52
115
|
interface UserPermissions {
|
|
53
116
|
role: OrgRole;
|
|
54
117
|
roleLabel: string;
|
|
@@ -349,6 +412,14 @@ interface LogQueryParams {
|
|
|
349
412
|
sortBy?: "timestamp" | "latencyMs" | "statusCode";
|
|
350
413
|
sortOrder?: "asc" | "desc";
|
|
351
414
|
}
|
|
415
|
+
/** Options for `subscriptions.changePlan`. */
|
|
416
|
+
interface ChangePlanOptions {
|
|
417
|
+
/**
|
|
418
|
+
* The caller confirms the user accepted the plan-change billing terms.
|
|
419
|
+
* The server rejects the change (400) unless this is `true`.
|
|
420
|
+
*/
|
|
421
|
+
acceptedTerms: boolean;
|
|
422
|
+
}
|
|
352
423
|
interface Subscription {
|
|
353
424
|
id: string;
|
|
354
425
|
organizationId: string;
|
|
@@ -377,7 +448,21 @@ interface PlanLimits {
|
|
|
377
448
|
endpoints: number;
|
|
378
449
|
teamMembers: number;
|
|
379
450
|
logRetentionDays: number;
|
|
380
|
-
|
|
451
|
+
/**
|
|
452
|
+
* Limits sold as something other than a plain number, keyed by the API's
|
|
453
|
+
* limit name (`rps`, `concurrency`, `maxApiKeys`, `monthlyRequests`,
|
|
454
|
+
* `overageRatePer1k`, `overageCapUsd`). `"unlimited"`: not enforced per
|
|
455
|
+
* plan. `"custom"`: negotiated per contract. Such a limit carries no number.
|
|
456
|
+
* Absent on plans where every limit is a number.
|
|
457
|
+
*/
|
|
458
|
+
limitModes?: Partial<Record<PlanLimitKey, PlanLimitMode>>;
|
|
459
|
+
/** Display text for those limits, e.g. "Quoted per contract". */
|
|
460
|
+
limitLabels?: Partial<Record<PlanLimitKey, string>>;
|
|
461
|
+
}
|
|
462
|
+
/** How a plan limit is sold. Absent from `limitModes` means a plain number. */
|
|
463
|
+
type PlanLimitMode = "unlimited" | "custom";
|
|
464
|
+
/** Limit names that may appear in `PlanLimits.limitModes`. */
|
|
465
|
+
type PlanLimitKey = "rps" | "concurrency" | "maxApiKeys" | "monthlyRequests" | "overageRatePer1k" | "overageCapUsd";
|
|
381
466
|
interface Invoice {
|
|
382
467
|
id: string;
|
|
383
468
|
amount: number;
|
|
@@ -482,6 +567,8 @@ declare class IteradianError extends Error {
|
|
|
482
567
|
* -32005 rate limit or concurrency limit exceeded (retry shortly)
|
|
483
568
|
* -32006 monthly quota exhausted (retrying will not help until `resetsAt`)
|
|
484
569
|
* -32007 overage spend limit reached (same — needs a plan change)
|
|
570
|
+
* -32008 per-API-key daily limit reached (no retry until `data.resetsAt`,
|
|
571
|
+
* the next 00:00 UTC)
|
|
485
572
|
*/
|
|
486
573
|
readonly rpcCode?: number;
|
|
487
574
|
/** Seconds to wait before retrying, when the gateway supplied one. */
|
|
@@ -493,8 +580,18 @@ declare class IteradianError extends Error {
|
|
|
493
580
|
retryAfter?: number;
|
|
494
581
|
data?: Record<string, unknown>;
|
|
495
582
|
});
|
|
496
|
-
/**
|
|
583
|
+
/**
|
|
584
|
+
* True when the request failed because an allowance is used up and retrying
|
|
585
|
+
* will not help until it resets: the subscription quota (-32006), the
|
|
586
|
+
* overage spend cap (-32007) or the API key's daily limit (-32008).
|
|
587
|
+
*/
|
|
497
588
|
get isQuotaExhausted(): boolean;
|
|
589
|
+
/**
|
|
590
|
+
* True when the API key's own daily limit is reached (-32008). `data` then
|
|
591
|
+
* carries `{ dailyLimit, used, cost, resetsAt }`; `resetsAt` is the next
|
|
592
|
+
* 00:00 UTC.
|
|
593
|
+
*/
|
|
594
|
+
get isDailyLimitReached(): boolean;
|
|
498
595
|
/** True when the request was throttled and is worth retrying. */
|
|
499
596
|
get isRateLimited(): boolean;
|
|
500
597
|
}
|
|
@@ -530,8 +627,18 @@ declare class HttpClient {
|
|
|
530
627
|
declare class AuthResource {
|
|
531
628
|
private http;
|
|
532
629
|
constructor(http: HttpClient);
|
|
533
|
-
/**
|
|
534
|
-
|
|
630
|
+
/**
|
|
631
|
+
* Register a new user account. Does not sign in: the API answers
|
|
632
|
+
* `{ message, email }` (the same for an address that already has an
|
|
633
|
+
* account) and emails a confirmation link. Call `login()` once the address
|
|
634
|
+
* is confirmed.
|
|
635
|
+
*
|
|
636
|
+
* The server rejects registration (400) unless the user agreed to the
|
|
637
|
+
* Terms of Service, Privacy Policy and DPA, so `data.acceptedTerms` is
|
|
638
|
+
* required and always sent. Pass `acceptedTerms: true` only after the user
|
|
639
|
+
* has ticked the agreement.
|
|
640
|
+
*/
|
|
641
|
+
register(data: RegisterRequest): Promise<RegisterResponse>;
|
|
535
642
|
/** Login with email/password (optionally with 2FA code) */
|
|
536
643
|
login(data: LoginRequest): Promise<AuthTokens>;
|
|
537
644
|
/** Logout current session */
|
|
@@ -587,11 +694,37 @@ declare class OrganizationsResource {
|
|
|
587
694
|
leave(orgId: string): Promise<void>;
|
|
588
695
|
/** List organization members */
|
|
589
696
|
listMembers(orgId: string): Promise<OrgMember[]>;
|
|
590
|
-
/**
|
|
697
|
+
/**
|
|
698
|
+
* Invite someone to the organization by email. Creates (or refreshes) a
|
|
699
|
+
* pending invitation — nobody becomes a member until the invitee accepts
|
|
700
|
+
* it while signed in with a verified address.
|
|
701
|
+
*/
|
|
591
702
|
inviteMember(orgId: string, data: {
|
|
592
703
|
email: string;
|
|
593
704
|
role: string;
|
|
594
|
-
}): Promise<
|
|
705
|
+
}): Promise<OrgInvite>;
|
|
706
|
+
/** Open invitations of the organization (owner/admin) */
|
|
707
|
+
listInvites(orgId: string): Promise<OrgInvite[]>;
|
|
708
|
+
/** Revoke an open invitation (owner/admin) */
|
|
709
|
+
revokeInvite(orgId: string, inviteId: string): Promise<{
|
|
710
|
+
message: string;
|
|
711
|
+
}>;
|
|
712
|
+
/** Invitations addressed to the signed-in user */
|
|
713
|
+
listMyInvites(): Promise<MyInvites>;
|
|
714
|
+
/**
|
|
715
|
+
* Accept an invitation addressed to the signed-in user.
|
|
716
|
+
*
|
|
717
|
+
* If the user has not accepted the current terms version yet, the API
|
|
718
|
+
* answers 403 (`TERMS_ACCEPTANCE_REQUIRED`) unless
|
|
719
|
+
* `{ acceptedTerms: true }` is passed — only after the user agreed to the
|
|
720
|
+
* Terms of Service, Privacy Policy and DPA. `acceptedTerms` is sent only
|
|
721
|
+
* when given.
|
|
722
|
+
*/
|
|
723
|
+
acceptInvite(inviteId: string, options?: AcceptInviteOptions): Promise<InviteAcceptance>;
|
|
724
|
+
/** Decline an invitation addressed to the signed-in user */
|
|
725
|
+
declineInvite(inviteId: string): Promise<{
|
|
726
|
+
message: string;
|
|
727
|
+
}>;
|
|
595
728
|
/** Update a member's role */
|
|
596
729
|
updateMemberRole(orgId: string, memberId: string, role: string): Promise<OrgMember>;
|
|
597
730
|
/** Remove a member from the organization */
|
|
@@ -741,8 +874,15 @@ declare class SubscriptionsResource {
|
|
|
741
874
|
constructor(http: HttpClient);
|
|
742
875
|
/** Get current subscription */
|
|
743
876
|
get(orgId: string): Promise<Subscription>;
|
|
744
|
-
/**
|
|
745
|
-
|
|
877
|
+
/**
|
|
878
|
+
* Change subscription plan.
|
|
879
|
+
*
|
|
880
|
+
* The server rejects a plan change unless the caller confirms the
|
|
881
|
+
* plan-change billing terms, so `options.acceptedTerms` is required and
|
|
882
|
+
* always sent. Pass `{ acceptedTerms: true }` only after the user has
|
|
883
|
+
* accepted the terms.
|
|
884
|
+
*/
|
|
885
|
+
changePlan(orgId: string, planId: string, options: ChangePlanOptions): Promise<Subscription>;
|
|
746
886
|
/** Cancel subscription */
|
|
747
887
|
cancel(orgId: string): Promise<Subscription>;
|
|
748
888
|
/** Reactivate a cancelled subscription */
|
|
@@ -837,7 +977,7 @@ declare class RpcResource {
|
|
|
837
977
|
*
|
|
838
978
|
* @example
|
|
839
979
|
* ```typescript
|
|
840
|
-
* import { IteradianClient } from '@iteradian/sdk';
|
|
980
|
+
* import { IteradianClient } from '@iteradian-rpc/sdk';
|
|
841
981
|
*
|
|
842
982
|
* const client = new IteradianClient({
|
|
843
983
|
* baseUrl: 'https://api.iteradian.com/api/v1',
|
|
@@ -890,4 +1030,5 @@ declare class IteradianClient {
|
|
|
890
1030
|
clearAccessToken(): void;
|
|
891
1031
|
}
|
|
892
1032
|
|
|
893
|
-
export {
|
|
1033
|
+
export { AlertsResource, ApiKeysResource, AuthResource, DashboardResource, EndpointsResource, IteradianClient, IteradianError, LogsResource, OrganizationsResource, PlansResource, RpcResource, SubscriptionsResource, SupportResource, UsageResource };
|
|
1034
|
+
export type { AcceptInviteOptions, Alert, AlertChannel, AlertCondition, AlertMetric, AlertRule, AlertSeverity, AlertStatus, ApiError, ApiKey, ApiKeyAnalytics, ApiKeyWithSecret, ApiResponse, AuthTokens, ChangePlanOptions, CreateAlertChannelRequest, CreateAlertRuleRequest, CreateApiKeyRequest, CreateEndpointRequest, CreateTicketRequest, DailyUsage, DashboardData, DataPoint, Endpoint, EndpointMetric, EndpointRegion, EndpointStatus, HealthStatus, InviteAcceptance, Invoice, IteradianConfig, JsonRpcError, JsonRpcRequest, JsonRpcResponse, LogFilterOptions, LogQueryParams, LogStatus, LoginRequest, LogsResponse, Membership, MyInvite, MyInvites, Network, NetworkType, OrgInvite, OrgMember, OrgRole, Organization, PaginatedResponse, Plan, PlanLimitKey, PlanLimitMode, PlanLimits, QuickStats, RegisterRequest, RegisterResponse, RequestLog, Subscription, SupportTicket, TicketCategory, TicketMessage, TicketPriority, TicketStatus, TwoFASetup, UpdateApiKeyRequest, UpdateEndpointRequest, UsageByMethod, UsageByNetwork, UsageByRegion, UsageSummary, User, UserPermissions };
|
package/dist/index.js
CHANGED
|
@@ -48,9 +48,21 @@ var IteradianError = class extends Error {
|
|
|
48
48
|
this.retryAfter = rpc?.retryAfter;
|
|
49
49
|
this.data = rpc?.data;
|
|
50
50
|
}
|
|
51
|
-
/**
|
|
51
|
+
/**
|
|
52
|
+
* True when the request failed because an allowance is used up and retrying
|
|
53
|
+
* will not help until it resets: the subscription quota (-32006), the
|
|
54
|
+
* overage spend cap (-32007) or the API key's daily limit (-32008).
|
|
55
|
+
*/
|
|
52
56
|
get isQuotaExhausted() {
|
|
53
|
-
return this.rpcCode === -32006 || this.rpcCode === -32007;
|
|
57
|
+
return this.rpcCode === -32006 || this.rpcCode === -32007 || this.rpcCode === -32008;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* True when the API key's own daily limit is reached (-32008). `data` then
|
|
61
|
+
* carries `{ dailyLimit, used, cost, resetsAt }`; `resetsAt` is the next
|
|
62
|
+
* 00:00 UTC.
|
|
63
|
+
*/
|
|
64
|
+
get isDailyLimitReached() {
|
|
65
|
+
return this.rpcCode === -32008;
|
|
54
66
|
}
|
|
55
67
|
/** True when the request was throttled and is worth retrying. */
|
|
56
68
|
get isRateLimited() {
|
|
@@ -150,7 +162,7 @@ var HttpClient = class {
|
|
|
150
162
|
const rpc = errorBody?.error;
|
|
151
163
|
const rpcCode = typeof rpc?.code === "number" ? rpc.code : void 0;
|
|
152
164
|
const retryAfter = typeof rpc?.data?.retryAfter === "number" ? rpc.data.retryAfter : void 0;
|
|
153
|
-
const worthRetrying = response.status >= 500 || response.status === 429 && rpcCode !== -32006 && rpcCode !== -32007;
|
|
165
|
+
const worthRetrying = response.status >= 500 || response.status === 429 && rpcCode !== -32006 && rpcCode !== -32007 && rpcCode !== -32008;
|
|
154
166
|
if (this.retry && attempt < this.maxRetries && worthRetrying && isReplayableBody(body) && !controller.signal.aborted) {
|
|
155
167
|
const backoff = Math.min(1e3 * 2 ** (attempt - 1), 1e4);
|
|
156
168
|
const delay = Math.min(
|
|
@@ -236,9 +248,22 @@ var AuthResource = class {
|
|
|
236
248
|
constructor(http) {
|
|
237
249
|
this.http = http;
|
|
238
250
|
}
|
|
239
|
-
/**
|
|
251
|
+
/**
|
|
252
|
+
* Register a new user account. Does not sign in: the API answers
|
|
253
|
+
* `{ message, email }` (the same for an address that already has an
|
|
254
|
+
* account) and emails a confirmation link. Call `login()` once the address
|
|
255
|
+
* is confirmed.
|
|
256
|
+
*
|
|
257
|
+
* The server rejects registration (400) unless the user agreed to the
|
|
258
|
+
* Terms of Service, Privacy Policy and DPA, so `data.acceptedTerms` is
|
|
259
|
+
* required and always sent. Pass `acceptedTerms: true` only after the user
|
|
260
|
+
* has ticked the agreement.
|
|
261
|
+
*/
|
|
240
262
|
register(data) {
|
|
241
|
-
return this.http.post("/auth/register",
|
|
263
|
+
return this.http.post("/auth/register", {
|
|
264
|
+
...data,
|
|
265
|
+
acceptedTerms: data?.acceptedTerms === true
|
|
266
|
+
});
|
|
242
267
|
}
|
|
243
268
|
/** Login with email/password (optionally with 2FA code) */
|
|
244
269
|
async login(data) {
|
|
@@ -337,10 +362,47 @@ var OrganizationsResource = class {
|
|
|
337
362
|
listMembers(orgId) {
|
|
338
363
|
return this.http.get(`/orgs/${orgId}/members`);
|
|
339
364
|
}
|
|
340
|
-
/**
|
|
365
|
+
/**
|
|
366
|
+
* Invite someone to the organization by email. Creates (or refreshes) a
|
|
367
|
+
* pending invitation — nobody becomes a member until the invitee accepts
|
|
368
|
+
* it while signed in with a verified address.
|
|
369
|
+
*/
|
|
341
370
|
inviteMember(orgId, data) {
|
|
342
371
|
return this.http.post(`/orgs/${orgId}/members`, data);
|
|
343
372
|
}
|
|
373
|
+
/** Open invitations of the organization (owner/admin) */
|
|
374
|
+
listInvites(orgId) {
|
|
375
|
+
return this.http.get(`/orgs/${orgId}/invites`);
|
|
376
|
+
}
|
|
377
|
+
/** Revoke an open invitation (owner/admin) */
|
|
378
|
+
revokeInvite(orgId, inviteId) {
|
|
379
|
+
return this.http.delete(`/orgs/${orgId}/invites/${inviteId}`);
|
|
380
|
+
}
|
|
381
|
+
/** Invitations addressed to the signed-in user */
|
|
382
|
+
listMyInvites() {
|
|
383
|
+
return this.http.get("/invites");
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Accept an invitation addressed to the signed-in user.
|
|
387
|
+
*
|
|
388
|
+
* If the user has not accepted the current terms version yet, the API
|
|
389
|
+
* answers 403 (`TERMS_ACCEPTANCE_REQUIRED`) unless
|
|
390
|
+
* `{ acceptedTerms: true }` is passed — only after the user agreed to the
|
|
391
|
+
* Terms of Service, Privacy Policy and DPA. `acceptedTerms` is sent only
|
|
392
|
+
* when given.
|
|
393
|
+
*/
|
|
394
|
+
acceptInvite(inviteId, options) {
|
|
395
|
+
if (options?.acceptedTerms !== void 0) {
|
|
396
|
+
return this.http.post(`/invites/${inviteId}/accept`, {
|
|
397
|
+
acceptedTerms: options.acceptedTerms === true
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
return this.http.post(`/invites/${inviteId}/accept`);
|
|
401
|
+
}
|
|
402
|
+
/** Decline an invitation addressed to the signed-in user */
|
|
403
|
+
declineInvite(inviteId) {
|
|
404
|
+
return this.http.post(`/invites/${inviteId}/decline`);
|
|
405
|
+
}
|
|
344
406
|
/** Update a member's role */
|
|
345
407
|
updateMemberRole(orgId, memberId, role) {
|
|
346
408
|
return this.http.put(`/orgs/${orgId}/members/${memberId}`, { role });
|
|
@@ -638,9 +700,19 @@ var SubscriptionsResource = class {
|
|
|
638
700
|
get(orgId) {
|
|
639
701
|
return this.http.get(`/orgs/${orgId}/subscription`);
|
|
640
702
|
}
|
|
641
|
-
/**
|
|
642
|
-
|
|
643
|
-
|
|
703
|
+
/**
|
|
704
|
+
* Change subscription plan.
|
|
705
|
+
*
|
|
706
|
+
* The server rejects a plan change unless the caller confirms the
|
|
707
|
+
* plan-change billing terms, so `options.acceptedTerms` is required and
|
|
708
|
+
* always sent. Pass `{ acceptedTerms: true }` only after the user has
|
|
709
|
+
* accepted the terms.
|
|
710
|
+
*/
|
|
711
|
+
changePlan(orgId, planId, options) {
|
|
712
|
+
return this.http.put(`/orgs/${orgId}/subscription/plan`, {
|
|
713
|
+
planId,
|
|
714
|
+
acceptedTerms: options?.acceptedTerms === true
|
|
715
|
+
});
|
|
644
716
|
}
|
|
645
717
|
/** Cancel subscription */
|
|
646
718
|
cancel(orgId) {
|
package/dist/index.mjs
CHANGED
|
@@ -9,9 +9,21 @@ var IteradianError = class extends Error {
|
|
|
9
9
|
this.retryAfter = rpc?.retryAfter;
|
|
10
10
|
this.data = rpc?.data;
|
|
11
11
|
}
|
|
12
|
-
/**
|
|
12
|
+
/**
|
|
13
|
+
* True when the request failed because an allowance is used up and retrying
|
|
14
|
+
* will not help until it resets: the subscription quota (-32006), the
|
|
15
|
+
* overage spend cap (-32007) or the API key's daily limit (-32008).
|
|
16
|
+
*/
|
|
13
17
|
get isQuotaExhausted() {
|
|
14
|
-
return this.rpcCode === -32006 || this.rpcCode === -32007;
|
|
18
|
+
return this.rpcCode === -32006 || this.rpcCode === -32007 || this.rpcCode === -32008;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* True when the API key's own daily limit is reached (-32008). `data` then
|
|
22
|
+
* carries `{ dailyLimit, used, cost, resetsAt }`; `resetsAt` is the next
|
|
23
|
+
* 00:00 UTC.
|
|
24
|
+
*/
|
|
25
|
+
get isDailyLimitReached() {
|
|
26
|
+
return this.rpcCode === -32008;
|
|
15
27
|
}
|
|
16
28
|
/** True when the request was throttled and is worth retrying. */
|
|
17
29
|
get isRateLimited() {
|
|
@@ -111,7 +123,7 @@ var HttpClient = class {
|
|
|
111
123
|
const rpc = errorBody?.error;
|
|
112
124
|
const rpcCode = typeof rpc?.code === "number" ? rpc.code : void 0;
|
|
113
125
|
const retryAfter = typeof rpc?.data?.retryAfter === "number" ? rpc.data.retryAfter : void 0;
|
|
114
|
-
const worthRetrying = response.status >= 500 || response.status === 429 && rpcCode !== -32006 && rpcCode !== -32007;
|
|
126
|
+
const worthRetrying = response.status >= 500 || response.status === 429 && rpcCode !== -32006 && rpcCode !== -32007 && rpcCode !== -32008;
|
|
115
127
|
if (this.retry && attempt < this.maxRetries && worthRetrying && isReplayableBody(body) && !controller.signal.aborted) {
|
|
116
128
|
const backoff = Math.min(1e3 * 2 ** (attempt - 1), 1e4);
|
|
117
129
|
const delay = Math.min(
|
|
@@ -197,9 +209,22 @@ var AuthResource = class {
|
|
|
197
209
|
constructor(http) {
|
|
198
210
|
this.http = http;
|
|
199
211
|
}
|
|
200
|
-
/**
|
|
212
|
+
/**
|
|
213
|
+
* Register a new user account. Does not sign in: the API answers
|
|
214
|
+
* `{ message, email }` (the same for an address that already has an
|
|
215
|
+
* account) and emails a confirmation link. Call `login()` once the address
|
|
216
|
+
* is confirmed.
|
|
217
|
+
*
|
|
218
|
+
* The server rejects registration (400) unless the user agreed to the
|
|
219
|
+
* Terms of Service, Privacy Policy and DPA, so `data.acceptedTerms` is
|
|
220
|
+
* required and always sent. Pass `acceptedTerms: true` only after the user
|
|
221
|
+
* has ticked the agreement.
|
|
222
|
+
*/
|
|
201
223
|
register(data) {
|
|
202
|
-
return this.http.post("/auth/register",
|
|
224
|
+
return this.http.post("/auth/register", {
|
|
225
|
+
...data,
|
|
226
|
+
acceptedTerms: data?.acceptedTerms === true
|
|
227
|
+
});
|
|
203
228
|
}
|
|
204
229
|
/** Login with email/password (optionally with 2FA code) */
|
|
205
230
|
async login(data) {
|
|
@@ -298,10 +323,47 @@ var OrganizationsResource = class {
|
|
|
298
323
|
listMembers(orgId) {
|
|
299
324
|
return this.http.get(`/orgs/${orgId}/members`);
|
|
300
325
|
}
|
|
301
|
-
/**
|
|
326
|
+
/**
|
|
327
|
+
* Invite someone to the organization by email. Creates (or refreshes) a
|
|
328
|
+
* pending invitation — nobody becomes a member until the invitee accepts
|
|
329
|
+
* it while signed in with a verified address.
|
|
330
|
+
*/
|
|
302
331
|
inviteMember(orgId, data) {
|
|
303
332
|
return this.http.post(`/orgs/${orgId}/members`, data);
|
|
304
333
|
}
|
|
334
|
+
/** Open invitations of the organization (owner/admin) */
|
|
335
|
+
listInvites(orgId) {
|
|
336
|
+
return this.http.get(`/orgs/${orgId}/invites`);
|
|
337
|
+
}
|
|
338
|
+
/** Revoke an open invitation (owner/admin) */
|
|
339
|
+
revokeInvite(orgId, inviteId) {
|
|
340
|
+
return this.http.delete(`/orgs/${orgId}/invites/${inviteId}`);
|
|
341
|
+
}
|
|
342
|
+
/** Invitations addressed to the signed-in user */
|
|
343
|
+
listMyInvites() {
|
|
344
|
+
return this.http.get("/invites");
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Accept an invitation addressed to the signed-in user.
|
|
348
|
+
*
|
|
349
|
+
* If the user has not accepted the current terms version yet, the API
|
|
350
|
+
* answers 403 (`TERMS_ACCEPTANCE_REQUIRED`) unless
|
|
351
|
+
* `{ acceptedTerms: true }` is passed — only after the user agreed to the
|
|
352
|
+
* Terms of Service, Privacy Policy and DPA. `acceptedTerms` is sent only
|
|
353
|
+
* when given.
|
|
354
|
+
*/
|
|
355
|
+
acceptInvite(inviteId, options) {
|
|
356
|
+
if (options?.acceptedTerms !== void 0) {
|
|
357
|
+
return this.http.post(`/invites/${inviteId}/accept`, {
|
|
358
|
+
acceptedTerms: options.acceptedTerms === true
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
return this.http.post(`/invites/${inviteId}/accept`);
|
|
362
|
+
}
|
|
363
|
+
/** Decline an invitation addressed to the signed-in user */
|
|
364
|
+
declineInvite(inviteId) {
|
|
365
|
+
return this.http.post(`/invites/${inviteId}/decline`);
|
|
366
|
+
}
|
|
305
367
|
/** Update a member's role */
|
|
306
368
|
updateMemberRole(orgId, memberId, role) {
|
|
307
369
|
return this.http.put(`/orgs/${orgId}/members/${memberId}`, { role });
|
|
@@ -599,9 +661,19 @@ var SubscriptionsResource = class {
|
|
|
599
661
|
get(orgId) {
|
|
600
662
|
return this.http.get(`/orgs/${orgId}/subscription`);
|
|
601
663
|
}
|
|
602
|
-
/**
|
|
603
|
-
|
|
604
|
-
|
|
664
|
+
/**
|
|
665
|
+
* Change subscription plan.
|
|
666
|
+
*
|
|
667
|
+
* The server rejects a plan change unless the caller confirms the
|
|
668
|
+
* plan-change billing terms, so `options.acceptedTerms` is required and
|
|
669
|
+
* always sent. Pass `{ acceptedTerms: true }` only after the user has
|
|
670
|
+
* accepted the terms.
|
|
671
|
+
*/
|
|
672
|
+
changePlan(orgId, planId, options) {
|
|
673
|
+
return this.http.put(`/orgs/${orgId}/subscription/plan`, {
|
|
674
|
+
planId,
|
|
675
|
+
acceptedTerms: options?.acceptedTerms === true
|
|
676
|
+
});
|
|
605
677
|
}
|
|
606
678
|
/** Cancel subscription */
|
|
607
679
|
cancel(orgId) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iteradian-rpc/sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Official Iteradian Control Plane SDK for JavaScript/TypeScript",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
21
21
|
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
22
22
|
"lint": "tsc --noEmit",
|
|
23
|
-
"test": "
|
|
23
|
+
"test": "node --test test/account.test.mjs"
|
|
24
24
|
},
|
|
25
25
|
"keywords": [
|
|
26
26
|
"iteradian",
|
|
@@ -33,22 +33,14 @@
|
|
|
33
33
|
"author": "Iteradian",
|
|
34
34
|
"license": "MIT",
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"tsup": "^
|
|
36
|
+
"tsup": "^9.0.0",
|
|
37
37
|
"typescript": "^6.0.3",
|
|
38
|
-
"@types/node": "^
|
|
38
|
+
"@types/node": "^26.6.5"
|
|
39
39
|
},
|
|
40
40
|
"engines": {
|
|
41
41
|
"node": ">=16.0.0"
|
|
42
42
|
},
|
|
43
|
-
"
|
|
44
|
-
"type": "git",
|
|
45
|
-
"url": "git+https://github.com/IteRaDian-RPC/iteradian-control-plane.git",
|
|
46
|
-
"directory": "sdks/typescript"
|
|
47
|
-
},
|
|
48
|
-
"homepage": "https://github.com/IteRaDian-RPC/iteradian-control-plane/tree/main/sdks/typescript#readme",
|
|
49
|
-
"bugs": {
|
|
50
|
-
"url": "https://github.com/IteRaDian-RPC/iteradian-control-plane/issues"
|
|
51
|
-
},
|
|
43
|
+
"homepage": "https://iteradian.com",
|
|
52
44
|
"publishConfig": {
|
|
53
45
|
"access": "public"
|
|
54
46
|
}
|