@miosa/sdk 1.2.4 → 1.2.6

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.
Files changed (100) hide show
  1. package/README.md +75 -3
  2. package/dist/index.d.ts +323 -175
  3. package/dist/index.js +441 -386
  4. package/dist/index.js.map +1 -1
  5. package/package.json +1 -2
  6. package/src/client.ts +0 -293
  7. package/src/errors.ts +0 -136
  8. package/src/http.test.ts +0 -374
  9. package/src/http.ts +0 -390
  10. package/src/index.ts +0 -564
  11. package/src/resources/admin.ts +0 -359
  12. package/src/resources/analytics.ts +0 -60
  13. package/src/resources/api-keys.ts +0 -135
  14. package/src/resources/audit-log.ts +0 -64
  15. package/src/resources/benchmarks.ts +0 -104
  16. package/src/resources/builder-sessions.ts +0 -75
  17. package/src/resources/channels.ts +0 -143
  18. package/src/resources/checkpoints.ts +0 -225
  19. package/src/resources/command-center.ts +0 -73
  20. package/src/resources/community.ts +0 -103
  21. package/src/resources/completions.ts +0 -104
  22. package/src/resources/computer-auto-stop.ts +0 -43
  23. package/src/resources/computer-env.ts +0 -76
  24. package/src/resources/computer-logs.ts +0 -50
  25. package/src/resources/computer-osa.ts +0 -76
  26. package/src/resources/computer-ports.ts +0 -91
  27. package/src/resources/computer-terminal.ts +0 -61
  28. package/src/resources/computer-volumes.ts +0 -64
  29. package/src/resources/computer.ts +0 -551
  30. package/src/resources/computers.ts +0 -75
  31. package/src/resources/credits.ts +0 -43
  32. package/src/resources/cron-jobs.ts +0 -191
  33. package/src/resources/custom_domains.ts +0 -123
  34. package/src/resources/dashboard.ts +0 -49
  35. package/src/resources/databases.ts +0 -218
  36. package/src/resources/deployments.test.ts +0 -194
  37. package/src/resources/deployments.ts +0 -1060
  38. package/src/resources/desktop.ts +0 -134
  39. package/src/resources/docker-deploy.test.ts +0 -102
  40. package/src/resources/docker-deploy.ts +0 -183
  41. package/src/resources/egress.test.ts +0 -318
  42. package/src/resources/egressAudit.ts +0 -245
  43. package/src/resources/egressNetwork.ts +0 -450
  44. package/src/resources/egressSecrets.ts +0 -577
  45. package/src/resources/email.ts +0 -212
  46. package/src/resources/embeddings.ts +0 -36
  47. package/src/resources/events.ts +0 -296
  48. package/src/resources/exec.ts +0 -319
  49. package/src/resources/external-keys.ts +0 -79
  50. package/src/resources/files.test.ts +0 -339
  51. package/src/resources/files.ts +0 -220
  52. package/src/resources/flat-custom-domains.ts +0 -127
  53. package/src/resources/functions.ts +0 -178
  54. package/src/resources/governance.test.ts +0 -355
  55. package/src/resources/governance.ts +0 -528
  56. package/src/resources/health-checks.ts +0 -165
  57. package/src/resources/integrations.ts +0 -183
  58. package/src/resources/mcp.ts +0 -70
  59. package/src/resources/models.ts +0 -45
  60. package/src/resources/network_policy.ts +0 -73
  61. package/src/resources/open-computers/agents.ts +0 -91
  62. package/src/resources/open-computers/apps.ts +0 -102
  63. package/src/resources/open-computers/clusters.ts +0 -88
  64. package/src/resources/open-computers/desktop.ts +0 -34
  65. package/src/resources/open-computers/files.ts +0 -97
  66. package/src/resources/open-computers/hosts.ts +0 -85
  67. package/src/resources/open-computers/index.ts +0 -98
  68. package/src/resources/open-computers/jobs.ts +0 -75
  69. package/src/resources/open-computers/open_computers.test.ts +0 -288
  70. package/src/resources/open-computers/secrets.ts +0 -115
  71. package/src/resources/open-computers/terminal.ts +0 -33
  72. package/src/resources/open-computers/tunnels.ts +0 -87
  73. package/src/resources/open-computers/types.ts +0 -343
  74. package/src/resources/open-computers/workspaces.ts +0 -135
  75. package/src/resources/org-invites.ts +0 -189
  76. package/src/resources/phase1.test.ts +0 -187
  77. package/src/resources/project-auth.ts +0 -142
  78. package/src/resources/project-integrations.ts +0 -133
  79. package/src/resources/provider-defaults.ts +0 -89
  80. package/src/resources/quotas.ts +0 -77
  81. package/src/resources/regions.ts +0 -94
  82. package/src/resources/sandbox-processes.ts +0 -112
  83. package/src/resources/sandbox-shares.ts +0 -83
  84. package/src/resources/sandbox-templates.ts +0 -195
  85. package/src/resources/sandboxes.live.test.ts +0 -92
  86. package/src/resources/sandboxes.test.ts +0 -653
  87. package/src/resources/sandboxes.ts +0 -1433
  88. package/src/resources/settings.ts +0 -143
  89. package/src/resources/snapshots-standalone.ts +0 -51
  90. package/src/resources/storage.ts +0 -221
  91. package/src/resources/tenant-events.ts +0 -32
  92. package/src/resources/tenant.ts +0 -148
  93. package/src/resources/usage.ts +0 -85
  94. package/src/resources/volumes.ts +0 -117
  95. package/src/resources/webhooks.ts +0 -224
  96. package/src/resources/workspace-invites.ts +0 -188
  97. package/src/resources/workspace-members.test.ts +0 -121
  98. package/src/resources/workspace-members.ts +0 -143
  99. package/src/resources/workspaces.ts +0 -285
  100. package/src/types.ts +0 -463
@@ -1,528 +0,0 @@
1
- /**
2
- * Phase 6 governance resources — policy, members, workspaces, bulk ops,
3
- * billing, impersonation, and scoped API keys.
4
- */
5
-
6
- import type { HttpClient } from "../http.js";
7
-
8
- // ── Types ──────────────────────────────────────────────────────────────────────
9
-
10
- export type PolicyDoc = Record<string, unknown>;
11
-
12
- export interface BulkJobResponse {
13
- queued: number;
14
- job_id: string;
15
- [key: string]: unknown;
16
- }
17
-
18
- export interface BulkJobStatus {
19
- id: string;
20
- status: "queued" | "running" | "completed" | "failed";
21
- processed?: number;
22
- errors?: unknown[];
23
- [key: string]: unknown;
24
- }
25
-
26
- export interface MemberRecord {
27
- id: string;
28
- email?: string;
29
- role: string;
30
- [key: string]: unknown;
31
- }
32
-
33
- export interface Invoice {
34
- id: string;
35
- amount: number;
36
- [key: string]: unknown;
37
- }
38
-
39
- export interface PaymentMethod {
40
- id: string;
41
- brand: string;
42
- last4: string;
43
- [key: string]: unknown;
44
- }
45
-
46
- // ── Effective policy typed accessors ─────────────────────────────────────────
47
-
48
- export interface EffectivePolicyField<T = unknown> {
49
- value: T;
50
- source: "user" | "workspace" | "tenant" | "platform";
51
- }
52
-
53
- export interface EffectiveLifecycle {
54
- default_idle_timeout_sec?: EffectivePolicyField<number>;
55
- default_timeout_sec?: EffectivePolicyField<number>;
56
- default_always_on?: EffectivePolicyField<boolean>;
57
- [key: string]: EffectivePolicyField | undefined;
58
- }
59
-
60
- export interface EffectiveQuotas {
61
- max_sandboxes?: EffectivePolicyField<number>;
62
- max_concurrent_sandboxes?: EffectivePolicyField<number>;
63
- max_computers?: EffectivePolicyField<number>;
64
- [key: string]: EffectivePolicyField | undefined;
65
- }
66
-
67
- export interface EffectivePolicyDoc {
68
- lifecycle: Record<string, EffectivePolicyField>;
69
- quotas: Record<string, EffectivePolicyField>;
70
- sizing?: Record<string, EffectivePolicyField>;
71
- features?: Record<string, EffectivePolicyField>;
72
- egress?: Record<string, EffectivePolicyField>;
73
- [key: string]: Record<string, EffectivePolicyField> | undefined;
74
- }
75
-
76
- // ── Policy sub-resources ──────────────────────────────────────────────────────
77
-
78
- export class TenantPolicy {
79
- constructor(private readonly http: HttpClient) {}
80
-
81
- async get(): Promise<PolicyDoc> {
82
- const r = await this.http.get<{ data?: PolicyDoc }>("/tenant/policy");
83
- return (r as { data?: PolicyDoc }).data ?? (r as PolicyDoc);
84
- }
85
-
86
- async set(policy: PolicyDoc): Promise<PolicyDoc> {
87
- const r = await this.http.put<{ data?: PolicyDoc }>(
88
- "/tenant/policy",
89
- policy,
90
- );
91
- return (r as { data?: PolicyDoc }).data ?? (r as PolicyDoc);
92
- }
93
-
94
- async delete(): Promise<void> {
95
- await this.http.delete<unknown>("/tenant/policy");
96
- }
97
- }
98
-
99
- export class WorkspacePolicyResource {
100
- constructor(
101
- private readonly http: HttpClient,
102
- private readonly workspaceId: string,
103
- ) {}
104
-
105
- async get(): Promise<PolicyDoc> {
106
- const r = await this.http.get<{ data?: PolicyDoc }>(
107
- `/workspaces/${this.workspaceId}/policy`,
108
- );
109
- return (r as { data?: PolicyDoc }).data ?? (r as PolicyDoc);
110
- }
111
-
112
- async set(policy: PolicyDoc): Promise<PolicyDoc> {
113
- const r = await this.http.put<{ data?: PolicyDoc }>(
114
- `/workspaces/${this.workspaceId}/policy`,
115
- policy,
116
- );
117
- return (r as { data?: PolicyDoc }).data ?? (r as PolicyDoc);
118
- }
119
-
120
- async delete(): Promise<void> {
121
- await this.http.delete<unknown>(`/workspaces/${this.workspaceId}/policy`);
122
- }
123
- }
124
-
125
- export class ExternalUserPolicyResource {
126
- constructor(
127
- private readonly http: HttpClient,
128
- private readonly userId: string,
129
- ) {}
130
-
131
- async get(): Promise<PolicyDoc> {
132
- const r = await this.http.get<{ data?: PolicyDoc }>(
133
- `/external-users/${this.userId}/policy`,
134
- );
135
- return (r as { data?: PolicyDoc }).data ?? (r as PolicyDoc);
136
- }
137
-
138
- async set(policy: PolicyDoc): Promise<PolicyDoc> {
139
- const r = await this.http.put<{ data?: PolicyDoc }>(
140
- `/external-users/${this.userId}/policy`,
141
- policy,
142
- );
143
- return (r as { data?: PolicyDoc }).data ?? (r as PolicyDoc);
144
- }
145
-
146
- async delete(): Promise<void> {
147
- await this.http.delete<unknown>(`/external-users/${this.userId}/policy`);
148
- }
149
-
150
- async effective(): Promise<EffectivePolicyDoc> {
151
- const r = await this.http.get<unknown>(
152
- `/external-users/${this.userId}/effective-policy`,
153
- );
154
- const data =
155
- (r as { data?: EffectivePolicyDoc }).data ?? (r as EffectivePolicyDoc);
156
- return data as EffectivePolicyDoc;
157
- }
158
- }
159
-
160
- // ── ExternalUsers proxy ───────────────────────────────────────────────────────
161
-
162
- export class ExternalUserProxy {
163
- readonly policy: ExternalUserPolicyResource;
164
-
165
- constructor(http: HttpClient, userId: string) {
166
- this.policy = new ExternalUserPolicyResource(http, userId);
167
- }
168
- }
169
-
170
- export class ExternalUsers {
171
- constructor(private readonly http: HttpClient) {}
172
-
173
- call(externalUserId: string): ExternalUserProxy {
174
- return new ExternalUserProxy(this.http, externalUserId);
175
- }
176
- }
177
-
178
- // ── Tenant members ─────────────────────────────────────────────────────────────
179
-
180
- export class TenantMembersResource {
181
- constructor(private readonly http: HttpClient) {}
182
-
183
- async list(): Promise<MemberRecord[]> {
184
- const r = await this.http.get<{ data?: MemberRecord[] }>("/tenant/members");
185
- return (r as { data?: MemberRecord[] }).data ?? (r as MemberRecord[]) ?? [];
186
- }
187
-
188
- async invite(email: string, role: string): Promise<MemberRecord> {
189
- const r = await this.http.post<{ data?: MemberRecord }>("/tenant/members", {
190
- email,
191
- role,
192
- });
193
- return (r as { data?: MemberRecord }).data ?? (r as MemberRecord);
194
- }
195
-
196
- async updateRole(memberId: string, role: string): Promise<MemberRecord> {
197
- const r = await this.http.patch<{ data?: MemberRecord }>(
198
- `/tenant/members/${memberId}/role`,
199
- { role },
200
- );
201
- return (r as { data?: MemberRecord }).data ?? (r as MemberRecord);
202
- }
203
-
204
- async remove(memberId: string): Promise<void> {
205
- await this.http.delete<unknown>(`/tenant/members/${memberId}`);
206
- }
207
-
208
- async transferOwnership(
209
- newOwnerUserId: string,
210
- ): Promise<Record<string, unknown>> {
211
- const r = await this.http.post<{ data?: Record<string, unknown> }>(
212
- "/tenant/transfer-ownership",
213
- { new_owner_user_id: newOwnerUserId },
214
- );
215
- return (
216
- (r as { data?: Record<string, unknown> }).data ??
217
- (r as Record<string, unknown>)
218
- );
219
- }
220
- }
221
-
222
- // ── Tenant events ─────────────────────────────────────────────────────────────
223
-
224
- export interface AdminStreamEvent {
225
- _event_type?: string;
226
- [key: string]: unknown;
227
- }
228
-
229
- export class TenantEventStreamResource {
230
- constructor(private readonly http: HttpClient) {}
231
-
232
- stream(options?: {
233
- types?: string[];
234
- scope?: string;
235
- }): AsyncIterableIterator<AdminStreamEvent> {
236
- const params = new URLSearchParams();
237
- if (options?.types?.length) params.set("types", options.types.join(","));
238
- if (options?.scope) params.set("scope", options.scope);
239
- const qs = params.toString() ? `?${params.toString()}` : "";
240
- return this.http.stream<AdminStreamEvent>(`/tenant/events/stream${qs}`);
241
- }
242
- }
243
-
244
- // ── GovernanceTenant ──────────────────────────────────────────────────────────
245
-
246
- export class GovernanceTenant {
247
- readonly policy: TenantPolicy;
248
- readonly members: TenantMembersResource;
249
- readonly events: TenantEventStreamResource;
250
-
251
- constructor(http: HttpClient) {
252
- this.policy = new TenantPolicy(http);
253
- this.members = new TenantMembersResource(http);
254
- this.events = new TenantEventStreamResource(http);
255
- }
256
-
257
- async current(): Promise<Record<string, unknown>> {
258
- return (await this.policy["http" as never]) as never;
259
- }
260
- }
261
-
262
- // ── Workspace sub-resources ────────────────────────────────────────────────────
263
-
264
- export class WorkspaceMembersResource {
265
- constructor(
266
- private readonly http: HttpClient,
267
- private readonly workspaceId: string,
268
- ) {}
269
-
270
- async list(): Promise<MemberRecord[]> {
271
- const r = await this.http.get<{ data?: MemberRecord[] }>(
272
- `/workspaces/${this.workspaceId}/members`,
273
- );
274
- return (r as { data?: MemberRecord[] }).data ?? (r as MemberRecord[]) ?? [];
275
- }
276
-
277
- async invite(email: string, role: string): Promise<MemberRecord> {
278
- const r = await this.http.post<{ data?: MemberRecord }>(
279
- `/workspaces/${this.workspaceId}/members`,
280
- { email, role },
281
- );
282
- return (r as { data?: MemberRecord }).data ?? (r as MemberRecord);
283
- }
284
-
285
- async updateRole(memberId: string, role: string): Promise<MemberRecord> {
286
- const r = await this.http.patch<{ data?: MemberRecord }>(
287
- `/workspaces/${this.workspaceId}/members/${memberId}/role`,
288
- { role },
289
- );
290
- return (r as { data?: MemberRecord }).data ?? (r as MemberRecord);
291
- }
292
-
293
- async remove(memberId: string): Promise<void> {
294
- await this.http.delete<unknown>(
295
- `/workspaces/${this.workspaceId}/members/${memberId}`,
296
- );
297
- }
298
- }
299
-
300
- export class WorkspaceProxy {
301
- readonly policy: WorkspacePolicyResource;
302
- readonly members: WorkspaceMembersResource;
303
-
304
- constructor(
305
- private readonly http: HttpClient,
306
- private readonly workspaceId: string,
307
- ) {
308
- this.policy = new WorkspacePolicyResource(http, workspaceId);
309
- this.members = new WorkspaceMembersResource(http, workspaceId);
310
- }
311
-
312
- async transfer(
313
- resourceIds: string[],
314
- targetWorkspaceId: string,
315
- ): Promise<Record<string, unknown>> {
316
- const r = await this.http.post<{ data?: Record<string, unknown> }>(
317
- `/workspaces/${this.workspaceId}/transfer`,
318
- { resource_ids: resourceIds, target_workspace_id: targetWorkspaceId },
319
- );
320
- return (
321
- (r as { data?: Record<string, unknown> }).data ??
322
- (r as Record<string, unknown>)
323
- );
324
- }
325
- }
326
-
327
- // ── GovernanceWorkspaces ──────────────────────────────────────────────────────
328
-
329
- export class GovernanceWorkspaces {
330
- constructor(private readonly http: HttpClient) {}
331
-
332
- /** client.workspaces("ws_id") → proxy with .policy, .members, .transfer() */
333
- workspace(workspaceId: string): WorkspaceProxy {
334
- return new WorkspaceProxy(this.http, workspaceId);
335
- }
336
-
337
- async list(): Promise<Record<string, unknown>[]> {
338
- const r = await this.http.get<{ data?: Record<string, unknown>[] }>(
339
- "/workspaces",
340
- );
341
- const items =
342
- (r as { data?: Record<string, unknown>[] }).data ??
343
- (r as Record<string, unknown>[]);
344
- return Array.isArray(items) ? items : [];
345
- }
346
-
347
- async create(
348
- name: string,
349
- opts?: { description?: string; metadata?: Record<string, unknown> },
350
- ): Promise<Record<string, unknown>> {
351
- const r = await this.http.post<{ data?: Record<string, unknown> }>(
352
- "/workspaces",
353
- { name, ...opts },
354
- );
355
- return (
356
- (r as { data?: Record<string, unknown> }).data ??
357
- (r as Record<string, unknown>)
358
- );
359
- }
360
-
361
- async get(workspaceId: string): Promise<Record<string, unknown>> {
362
- const r = await this.http.get<{ data?: Record<string, unknown> }>(
363
- `/workspaces/${workspaceId}`,
364
- );
365
- return (
366
- (r as { data?: Record<string, unknown> }).data ??
367
- (r as Record<string, unknown>)
368
- );
369
- }
370
-
371
- async update(
372
- workspaceId: string,
373
- fields: Record<string, unknown>,
374
- ): Promise<Record<string, unknown>> {
375
- const r = await this.http.patch<{ data?: Record<string, unknown> }>(
376
- `/workspaces/${workspaceId}`,
377
- fields,
378
- );
379
- return (
380
- (r as { data?: Record<string, unknown> }).data ??
381
- (r as Record<string, unknown>)
382
- );
383
- }
384
-
385
- async delete(workspaceId: string): Promise<void> {
386
- await this.http.delete<unknown>(`/workspaces/${workspaceId}`);
387
- }
388
- }
389
-
390
- // ── Bulk ops ──────────────────────────────────────────────────────────────────
391
-
392
- function bulkBody(opts: {
393
- ids?: string[];
394
- filter?: Record<string, unknown>;
395
- }): Record<string, unknown> {
396
- if (opts.ids !== undefined) return { ids: opts.ids };
397
- if (opts.filter !== undefined) return { filter: opts.filter };
398
- throw new Error("Provide either ids or filter");
399
- }
400
-
401
- export class BulkSandboxesResource {
402
- constructor(private readonly http: HttpClient) {}
403
-
404
- async pause(opts: {
405
- ids?: string[];
406
- filter?: Record<string, unknown>;
407
- }): Promise<BulkJobResponse> {
408
- return this.http.post<BulkJobResponse>(
409
- "/bulk/sandboxes/pause",
410
- bulkBody(opts),
411
- );
412
- }
413
-
414
- async resume(opts: {
415
- ids?: string[];
416
- filter?: Record<string, unknown>;
417
- }): Promise<BulkJobResponse> {
418
- return this.http.post<BulkJobResponse>(
419
- "/bulk/sandboxes/resume",
420
- bulkBody(opts),
421
- );
422
- }
423
-
424
- async destroy(opts: {
425
- ids?: string[];
426
- filter?: Record<string, unknown>;
427
- }): Promise<BulkJobResponse> {
428
- return this.http.post<BulkJobResponse>(
429
- "/bulk/sandboxes/destroy",
430
- bulkBody(opts),
431
- );
432
- }
433
- }
434
-
435
- export class BulkPolicyResource {
436
- constructor(private readonly http: HttpClient) {}
437
-
438
- async apply(opts: {
439
- tier: string;
440
- idsOrFilter: string[] | Record<string, unknown>;
441
- policy: PolicyDoc;
442
- }): Promise<BulkJobResponse> {
443
- const body: Record<string, unknown> = {
444
- tier: opts.tier,
445
- policy: opts.policy,
446
- };
447
- if (Array.isArray(opts.idsOrFilter)) {
448
- body["ids"] = opts.idsOrFilter;
449
- } else {
450
- body["filter"] = opts.idsOrFilter;
451
- }
452
- return this.http.post<BulkJobResponse>("/bulk/policy/apply", body);
453
- }
454
- }
455
-
456
- export class BulkJobsResource {
457
- constructor(private readonly http: HttpClient) {}
458
-
459
- async get(jobId: string): Promise<BulkJobStatus> {
460
- const r = await this.http.get<{ data?: BulkJobStatus }>(
461
- `/bulk/jobs/${jobId}`,
462
- );
463
- return (r as { data?: BulkJobStatus }).data ?? (r as BulkJobStatus);
464
- }
465
- }
466
-
467
- export class BulkResource {
468
- readonly sandboxes: BulkSandboxesResource;
469
- readonly policy: BulkPolicyResource;
470
- readonly jobs: BulkJobsResource;
471
-
472
- constructor(http: HttpClient) {
473
- this.sandboxes = new BulkSandboxesResource(http);
474
- this.policy = new BulkPolicyResource(http);
475
- this.jobs = new BulkJobsResource(http);
476
- }
477
- }
478
-
479
- // ── Billing ───────────────────────────────────────────────────────────────────
480
-
481
- export class BillingInvoicesResource {
482
- constructor(private readonly http: HttpClient) {}
483
-
484
- async list(opts?: { limit?: number; cursor?: string }): Promise<Invoice[]> {
485
- const params = new URLSearchParams();
486
- if (opts?.limit !== undefined) params.set("limit", String(opts.limit));
487
- if (opts?.cursor) params.set("cursor", opts.cursor);
488
- const qs = params.toString() ? `?${params.toString()}` : "";
489
- const r = await this.http.get<{ data?: Invoice[] }>(
490
- `/billing/invoices${qs}`,
491
- );
492
- return (r as { data?: Invoice[] }).data ?? (r as Invoice[]) ?? [];
493
- }
494
-
495
- async get(invoiceId: string): Promise<Invoice> {
496
- const r = await this.http.get<{ data?: Invoice }>(
497
- `/billing/invoices/${invoiceId}`,
498
- );
499
- return (r as { data?: Invoice }).data ?? (r as Invoice);
500
- }
501
- }
502
-
503
- export class BillingResource {
504
- readonly invoices: BillingInvoicesResource;
505
-
506
- constructor(private readonly http: HttpClient) {
507
- this.invoices = new BillingInvoicesResource(http);
508
- }
509
-
510
- async paymentMethods(): Promise<PaymentMethod[]> {
511
- const r = await this.http.get<{ data?: PaymentMethod[] }>(
512
- "/billing/payment-methods",
513
- );
514
- return (
515
- (r as { data?: PaymentMethod[] }).data ?? (r as PaymentMethod[]) ?? []
516
- );
517
- }
518
-
519
- async upcoming(): Promise<Record<string, unknown>> {
520
- const r = await this.http.get<{ data?: Record<string, unknown> }>(
521
- "/billing/upcoming",
522
- );
523
- return (
524
- (r as { data?: Record<string, unknown> }).data ??
525
- (r as Record<string, unknown>)
526
- );
527
- }
528
- }
@@ -1,165 +0,0 @@
1
- /**
2
- * HealthChecks resource — uptime monitoring.
3
- */
4
-
5
- import { randomUUID } from "node:crypto";
6
-
7
- import type { HttpClient } from "../http.js";
8
-
9
- // ── Branded IDs ──────────────────────────────────────────────────────────────
10
-
11
- export type HealthCheckId = string & { readonly __brand: "HealthCheckId" };
12
-
13
- // ── Resource shapes ──────────────────────────────────────────────────────────
14
-
15
- export interface HealthCheckData {
16
- id: HealthCheckId;
17
- tenant_id: string;
18
- name: string;
19
- url: string;
20
- state?: string;
21
- interval_sec?: number;
22
- timeout_sec?: number;
23
- method?: string;
24
- expected_status?: number | null;
25
- last_checked_at?: string | null;
26
- last_status?: "up" | "down" | null;
27
- created_at?: string;
28
- updated_at?: string;
29
- [key: string]: unknown;
30
- }
31
-
32
- // ── Request payloads ─────────────────────────────────────────────────────────
33
-
34
- export interface HealthCheckListParams {
35
- limit?: number;
36
- cursor?: string;
37
- state?: string;
38
- [key: string]: string | number | boolean | undefined;
39
- }
40
-
41
- export interface HealthCheckCreateParams {
42
- name: string;
43
- url: string;
44
- interval_sec?: number;
45
- intervalSec?: number;
46
- timeout_sec?: number;
47
- timeoutSec?: number;
48
- method?: string;
49
- expected_status?: number;
50
- expectedStatus?: number;
51
- idempotencyKey?: string;
52
- [key: string]: unknown;
53
- }
54
-
55
- export interface HealthCheckUpdateParams {
56
- name?: string;
57
- url?: string;
58
- interval_sec?: number;
59
- intervalSec?: number;
60
- timeout_sec?: number;
61
- timeoutSec?: number;
62
- method?: string;
63
- expected_status?: number;
64
- expectedStatus?: number;
65
- [key: string]: unknown;
66
- }
67
-
68
- // ── Helpers ───────────────────────────────────────────────────────────────────
69
-
70
- function unwrap<T>(payload: unknown): T {
71
- if (payload && typeof payload === "object" && "data" in (payload as object)) {
72
- return (payload as { data: T }).data;
73
- }
74
- return payload as T;
75
- }
76
-
77
- function listItems<T>(
78
- payload: unknown,
79
- candidateKeys: string[] = ["data", "health_checks", "items"],
80
- ): T[] {
81
- if (Array.isArray(payload)) return payload;
82
- if (!payload || typeof payload !== "object") return [];
83
- const p = payload as Record<string, unknown>;
84
- if (Array.isArray(p.data)) return p.data as T[];
85
- for (const key of candidateKeys) {
86
- if (Array.isArray(p[key])) return p[key] as T[];
87
- }
88
- return [];
89
- }
90
-
91
- function stripUndefined(
92
- input: Record<string, unknown>,
93
- ): Record<string, unknown> {
94
- return Object.fromEntries(
95
- Object.entries(input).filter(([, v]) => v !== undefined),
96
- );
97
- }
98
-
99
- function idempotencyKey(key?: string): string {
100
- return key ?? randomUUID();
101
- }
102
-
103
- // ── Main resource ─────────────────────────────────────────────────────────────
104
-
105
- export class HealthChecks {
106
- constructor(private readonly http: HttpClient) {}
107
-
108
- async list(params: HealthCheckListParams = {}): Promise<HealthCheckData[]> {
109
- const query = stripUndefined({ ...params }) as Record<
110
- string,
111
- string | number | boolean | undefined
112
- >;
113
- const data = await this.http.get<unknown>("/health-checks", query);
114
- return listItems<HealthCheckData>(data);
115
- }
116
-
117
- async get(checkId: string): Promise<HealthCheckData> {
118
- const data = await this.http.get<unknown>(`/health-checks/${checkId}`);
119
- return unwrap<HealthCheckData>(data);
120
- }
121
-
122
- async create(params: HealthCheckCreateParams): Promise<HealthCheckData> {
123
- const {
124
- idempotencyKey: ikey,
125
- intervalSec,
126
- timeoutSec,
127
- expectedStatus,
128
- ...rest
129
- } = params;
130
- const body = stripUndefined({
131
- ...rest,
132
- interval_sec: intervalSec ?? rest.interval_sec,
133
- timeout_sec: timeoutSec ?? rest.timeout_sec,
134
- expected_status: expectedStatus ?? rest.expected_status,
135
- });
136
- const data = await this.http.request<unknown>("/health-checks", {
137
- method: "POST",
138
- body,
139
- headers: { "Idempotency-Key": idempotencyKey(ikey) },
140
- });
141
- return unwrap<HealthCheckData>(data);
142
- }
143
-
144
- async update(
145
- checkId: string,
146
- params: HealthCheckUpdateParams,
147
- ): Promise<HealthCheckData> {
148
- const { intervalSec, timeoutSec, expectedStatus, ...rest } = params;
149
- const body = stripUndefined({
150
- ...rest,
151
- interval_sec: intervalSec ?? rest.interval_sec,
152
- timeout_sec: timeoutSec ?? rest.timeout_sec,
153
- expected_status: expectedStatus ?? rest.expected_status,
154
- });
155
- const data = await this.http.patch<unknown>(
156
- `/health-checks/${checkId}`,
157
- body,
158
- );
159
- return unwrap<HealthCheckData>(data);
160
- }
161
-
162
- async delete(checkId: string): Promise<void> {
163
- await this.http.delete<unknown>(`/health-checks/${checkId}`);
164
- }
165
- }