@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.
- package/README.md +75 -3
- package/dist/index.d.ts +323 -175
- package/dist/index.js +441 -386
- package/dist/index.js.map +1 -1
- package/package.json +1 -2
- package/src/client.ts +0 -293
- package/src/errors.ts +0 -136
- package/src/http.test.ts +0 -374
- package/src/http.ts +0 -390
- package/src/index.ts +0 -564
- package/src/resources/admin.ts +0 -359
- package/src/resources/analytics.ts +0 -60
- package/src/resources/api-keys.ts +0 -135
- package/src/resources/audit-log.ts +0 -64
- package/src/resources/benchmarks.ts +0 -104
- package/src/resources/builder-sessions.ts +0 -75
- package/src/resources/channels.ts +0 -143
- package/src/resources/checkpoints.ts +0 -225
- package/src/resources/command-center.ts +0 -73
- package/src/resources/community.ts +0 -103
- package/src/resources/completions.ts +0 -104
- package/src/resources/computer-auto-stop.ts +0 -43
- package/src/resources/computer-env.ts +0 -76
- package/src/resources/computer-logs.ts +0 -50
- package/src/resources/computer-osa.ts +0 -76
- package/src/resources/computer-ports.ts +0 -91
- package/src/resources/computer-terminal.ts +0 -61
- package/src/resources/computer-volumes.ts +0 -64
- package/src/resources/computer.ts +0 -551
- package/src/resources/computers.ts +0 -75
- package/src/resources/credits.ts +0 -43
- package/src/resources/cron-jobs.ts +0 -191
- package/src/resources/custom_domains.ts +0 -123
- package/src/resources/dashboard.ts +0 -49
- package/src/resources/databases.ts +0 -218
- package/src/resources/deployments.test.ts +0 -194
- package/src/resources/deployments.ts +0 -1060
- package/src/resources/desktop.ts +0 -134
- package/src/resources/docker-deploy.test.ts +0 -102
- package/src/resources/docker-deploy.ts +0 -183
- package/src/resources/egress.test.ts +0 -318
- package/src/resources/egressAudit.ts +0 -245
- package/src/resources/egressNetwork.ts +0 -450
- package/src/resources/egressSecrets.ts +0 -577
- package/src/resources/email.ts +0 -212
- package/src/resources/embeddings.ts +0 -36
- package/src/resources/events.ts +0 -296
- package/src/resources/exec.ts +0 -319
- package/src/resources/external-keys.ts +0 -79
- package/src/resources/files.test.ts +0 -339
- package/src/resources/files.ts +0 -220
- package/src/resources/flat-custom-domains.ts +0 -127
- package/src/resources/functions.ts +0 -178
- package/src/resources/governance.test.ts +0 -355
- package/src/resources/governance.ts +0 -528
- package/src/resources/health-checks.ts +0 -165
- package/src/resources/integrations.ts +0 -183
- package/src/resources/mcp.ts +0 -70
- package/src/resources/models.ts +0 -45
- package/src/resources/network_policy.ts +0 -73
- package/src/resources/open-computers/agents.ts +0 -91
- package/src/resources/open-computers/apps.ts +0 -102
- package/src/resources/open-computers/clusters.ts +0 -88
- package/src/resources/open-computers/desktop.ts +0 -34
- package/src/resources/open-computers/files.ts +0 -97
- package/src/resources/open-computers/hosts.ts +0 -85
- package/src/resources/open-computers/index.ts +0 -98
- package/src/resources/open-computers/jobs.ts +0 -75
- package/src/resources/open-computers/open_computers.test.ts +0 -288
- package/src/resources/open-computers/secrets.ts +0 -115
- package/src/resources/open-computers/terminal.ts +0 -33
- package/src/resources/open-computers/tunnels.ts +0 -87
- package/src/resources/open-computers/types.ts +0 -343
- package/src/resources/open-computers/workspaces.ts +0 -135
- package/src/resources/org-invites.ts +0 -189
- package/src/resources/phase1.test.ts +0 -187
- package/src/resources/project-auth.ts +0 -142
- package/src/resources/project-integrations.ts +0 -133
- package/src/resources/provider-defaults.ts +0 -89
- package/src/resources/quotas.ts +0 -77
- package/src/resources/regions.ts +0 -94
- package/src/resources/sandbox-processes.ts +0 -112
- package/src/resources/sandbox-shares.ts +0 -83
- package/src/resources/sandbox-templates.ts +0 -195
- package/src/resources/sandboxes.live.test.ts +0 -92
- package/src/resources/sandboxes.test.ts +0 -653
- package/src/resources/sandboxes.ts +0 -1433
- package/src/resources/settings.ts +0 -143
- package/src/resources/snapshots-standalone.ts +0 -51
- package/src/resources/storage.ts +0 -221
- package/src/resources/tenant-events.ts +0 -32
- package/src/resources/tenant.ts +0 -148
- package/src/resources/usage.ts +0 -85
- package/src/resources/volumes.ts +0 -117
- package/src/resources/webhooks.ts +0 -224
- package/src/resources/workspace-invites.ts +0 -188
- package/src/resources/workspace-members.test.ts +0 -121
- package/src/resources/workspace-members.ts +0 -143
- package/src/resources/workspaces.ts +0 -285
- package/src/types.ts +0 -463
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CronJobs resource — scheduled work.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { randomUUID } from "node:crypto";
|
|
6
|
-
|
|
7
|
-
import type { HttpClient } from "../http.js";
|
|
8
|
-
|
|
9
|
-
// ── Branded IDs ──────────────────────────────────────────────────────────────
|
|
10
|
-
|
|
11
|
-
export type CronJobId = string & { readonly __brand: "CronJobId" };
|
|
12
|
-
export type CronJobExecutionId = string & {
|
|
13
|
-
readonly __brand: "CronJobExecutionId";
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
// ── Resource shapes ──────────────────────────────────────────────────────────
|
|
17
|
-
|
|
18
|
-
export interface CronJobData {
|
|
19
|
-
id: CronJobId;
|
|
20
|
-
tenant_id: string;
|
|
21
|
-
name: string;
|
|
22
|
-
schedule: string;
|
|
23
|
-
state?: string;
|
|
24
|
-
paused?: boolean;
|
|
25
|
-
last_run_at?: string | null;
|
|
26
|
-
next_run_at?: string | null;
|
|
27
|
-
created_at?: string;
|
|
28
|
-
updated_at?: string;
|
|
29
|
-
[key: string]: unknown;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface CronJobExecutionData {
|
|
33
|
-
id: CronJobExecutionId;
|
|
34
|
-
cron_job_id: CronJobId;
|
|
35
|
-
state?: string;
|
|
36
|
-
started_at?: string | null;
|
|
37
|
-
finished_at?: string | null;
|
|
38
|
-
duration_ms?: number | null;
|
|
39
|
-
exit_code?: number | null;
|
|
40
|
-
error?: string | null;
|
|
41
|
-
created_at?: string;
|
|
42
|
-
[key: string]: unknown;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// ── Request payloads ─────────────────────────────────────────────────────────
|
|
46
|
-
|
|
47
|
-
export interface CronJobListParams {
|
|
48
|
-
limit?: number;
|
|
49
|
-
cursor?: string;
|
|
50
|
-
state?: string;
|
|
51
|
-
[key: string]: string | number | boolean | undefined;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export interface CronJobCreateParams {
|
|
55
|
-
name: string;
|
|
56
|
-
schedule: string;
|
|
57
|
-
idempotencyKey?: string;
|
|
58
|
-
[key: string]: unknown;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export interface CronJobUpdateParams {
|
|
62
|
-
name?: string;
|
|
63
|
-
schedule?: string;
|
|
64
|
-
[key: string]: unknown;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
68
|
-
|
|
69
|
-
function unwrap<T>(payload: unknown): T {
|
|
70
|
-
if (payload && typeof payload === "object" && "data" in (payload as object)) {
|
|
71
|
-
return (payload as { data: T }).data;
|
|
72
|
-
}
|
|
73
|
-
return payload as T;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function listItems<T>(
|
|
77
|
-
payload: unknown,
|
|
78
|
-
candidateKeys: string[] = ["data", "cron_jobs", "executions", "items"],
|
|
79
|
-
): T[] {
|
|
80
|
-
if (Array.isArray(payload)) return payload;
|
|
81
|
-
if (!payload || typeof payload !== "object") return [];
|
|
82
|
-
const p = payload as Record<string, unknown>;
|
|
83
|
-
if (Array.isArray(p.data)) return p.data as T[];
|
|
84
|
-
for (const key of candidateKeys) {
|
|
85
|
-
if (Array.isArray(p[key])) return p[key] as T[];
|
|
86
|
-
}
|
|
87
|
-
return [];
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function stripUndefined(
|
|
91
|
-
input: Record<string, unknown>,
|
|
92
|
-
): Record<string, unknown> {
|
|
93
|
-
return Object.fromEntries(
|
|
94
|
-
Object.entries(input).filter(([, v]) => v !== undefined),
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function idempotencyKey(key?: string): string {
|
|
99
|
-
return key ?? randomUUID();
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// ── Main resource ─────────────────────────────────────────────────────────────
|
|
103
|
-
|
|
104
|
-
export class CronJobs {
|
|
105
|
-
constructor(private readonly http: HttpClient) {}
|
|
106
|
-
|
|
107
|
-
async list(params: CronJobListParams = {}): Promise<CronJobData[]> {
|
|
108
|
-
const query = stripUndefined({ ...params }) as Record<
|
|
109
|
-
string,
|
|
110
|
-
string | number | boolean | undefined
|
|
111
|
-
>;
|
|
112
|
-
const data = await this.http.get<unknown>("/cron-jobs", query);
|
|
113
|
-
return listItems<CronJobData>(data);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
async get(jobId: string): Promise<CronJobData> {
|
|
117
|
-
const data = await this.http.get<unknown>(`/cron-jobs/${jobId}`);
|
|
118
|
-
return unwrap<CronJobData>(data);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
async create(params: CronJobCreateParams): Promise<CronJobData> {
|
|
122
|
-
const { idempotencyKey: ikey, ...rest } = params;
|
|
123
|
-
const body = stripUndefined(rest as Record<string, unknown>);
|
|
124
|
-
const data = await this.http.request<unknown>("/cron-jobs", {
|
|
125
|
-
method: "POST",
|
|
126
|
-
body,
|
|
127
|
-
headers: { "Idempotency-Key": idempotencyKey(ikey) },
|
|
128
|
-
});
|
|
129
|
-
return unwrap<CronJobData>(data);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
async update(
|
|
133
|
-
jobId: string,
|
|
134
|
-
params: CronJobUpdateParams,
|
|
135
|
-
): Promise<CronJobData> {
|
|
136
|
-
const body = stripUndefined(params as Record<string, unknown>);
|
|
137
|
-
const data = await this.http.patch<unknown>(`/cron-jobs/${jobId}`, body);
|
|
138
|
-
return unwrap<CronJobData>(data);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
async delete(jobId: string): Promise<void> {
|
|
142
|
-
await this.http.delete<unknown>(`/cron-jobs/${jobId}`);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// ── Control ────────────────────────────────────────────────────────────────
|
|
146
|
-
|
|
147
|
-
async pause(jobId: string): Promise<CronJobData> {
|
|
148
|
-
const data = await this.http.post<unknown>(`/cron-jobs/${jobId}/pause`);
|
|
149
|
-
return unwrap<CronJobData>(data);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
async resume(jobId: string): Promise<CronJobData> {
|
|
153
|
-
const data = await this.http.post<unknown>(`/cron-jobs/${jobId}/resume`);
|
|
154
|
-
return unwrap<CronJobData>(data);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
async runNow(
|
|
158
|
-
jobId: string,
|
|
159
|
-
opts: { idempotencyKey?: string } = {},
|
|
160
|
-
): Promise<CronJobData> {
|
|
161
|
-
const data = await this.http.request<unknown>(
|
|
162
|
-
`/cron-jobs/${jobId}/run-now`,
|
|
163
|
-
{
|
|
164
|
-
method: "POST",
|
|
165
|
-
headers: { "Idempotency-Key": idempotencyKey(opts.idempotencyKey) },
|
|
166
|
-
},
|
|
167
|
-
);
|
|
168
|
-
return unwrap<CronJobData>(data);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// ── Execution history ──────────────────────────────────────────────────────
|
|
172
|
-
|
|
173
|
-
async listExecutions(jobId: string): Promise<CronJobExecutionData[]> {
|
|
174
|
-
const data = await this.http.get<unknown>(`/cron-jobs/${jobId}/executions`);
|
|
175
|
-
return listItems<CronJobExecutionData>(data, [
|
|
176
|
-
"data",
|
|
177
|
-
"executions",
|
|
178
|
-
"items",
|
|
179
|
-
]);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
async getExecution(
|
|
183
|
-
jobId: string,
|
|
184
|
-
executionId: string,
|
|
185
|
-
): Promise<CronJobExecutionData> {
|
|
186
|
-
const data = await this.http.get<unknown>(
|
|
187
|
-
`/cron-jobs/${jobId}/executions/${executionId}`,
|
|
188
|
-
);
|
|
189
|
-
return unwrap<CronJobExecutionData>(data);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import type { HttpClient } from "../http.js";
|
|
2
|
-
|
|
3
|
-
// ─── Custom Domains ───────────────────────────────────────────────────────────
|
|
4
|
-
|
|
5
|
-
export type CustomDomainStatus =
|
|
6
|
-
| "pending"
|
|
7
|
-
| "verified"
|
|
8
|
-
| "active"
|
|
9
|
-
| "failed"
|
|
10
|
-
| "removed";
|
|
11
|
-
|
|
12
|
-
export interface CustomDomainData {
|
|
13
|
-
id: string;
|
|
14
|
-
computer_id: string;
|
|
15
|
-
tenant_id: string;
|
|
16
|
-
fqdn: string;
|
|
17
|
-
status: CustomDomainStatus;
|
|
18
|
-
/** The CNAME target the user must point their DNS record at. */
|
|
19
|
-
verification_target: string;
|
|
20
|
-
/** Human-readable DNS setup instructions. */
|
|
21
|
-
instructions: string;
|
|
22
|
-
verified_at: string | null;
|
|
23
|
-
tls_issued_at: string | null;
|
|
24
|
-
created_at: string;
|
|
25
|
-
updated_at: string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export interface CustomDomainRegisterParams {
|
|
29
|
-
fqdn: string;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// ─── CustomDomains resource ──────────────────────────────────────────────────
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Custom domain management for a Computer.
|
|
36
|
-
*
|
|
37
|
-
* Accessed via `computer.domains`.
|
|
38
|
-
*
|
|
39
|
-
* ## Workflow
|
|
40
|
-
* ```ts
|
|
41
|
-
* // 1. Register the domain
|
|
42
|
-
* const domain = await computer.domains.register("app.example.com");
|
|
43
|
-
* console.log(domain.instructions);
|
|
44
|
-
* // => "Add a CNAME record: app.example.com → <slug>.sandbox.miosa.ai"
|
|
45
|
-
*
|
|
46
|
-
* // 2. Add the CNAME in your DNS registrar, then...
|
|
47
|
-
*
|
|
48
|
-
* // 3. Verify ownership
|
|
49
|
-
* const verified = await computer.domains.verify(domain.id);
|
|
50
|
-
* // Caddy auto-issues a TLS certificate after this point.
|
|
51
|
-
* ```
|
|
52
|
-
*/
|
|
53
|
-
export class CustomDomains {
|
|
54
|
-
private readonly http: HttpClient;
|
|
55
|
-
private readonly computerId: string;
|
|
56
|
-
|
|
57
|
-
constructor(http: HttpClient, computerId: string) {
|
|
58
|
-
this.http = http;
|
|
59
|
-
this.computerId = computerId;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
private base(): string {
|
|
63
|
-
return `/computers/${this.computerId}/domains`;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Register a custom FQDN for this computer.
|
|
68
|
-
*
|
|
69
|
-
* Returns the domain record with `verification_target` and `instructions`
|
|
70
|
-
* showing which CNAME record to add. The domain starts in `pending` status.
|
|
71
|
-
*
|
|
72
|
-
* @param fqdn - The fully-qualified domain name to register
|
|
73
|
-
* (e.g. `"app.example.com"`). Must be lowercase RFC 1123, ≤ 253 chars,
|
|
74
|
-
* and must NOT end with `miosa.ai`.
|
|
75
|
-
*/
|
|
76
|
-
async register(fqdn: string): Promise<CustomDomainData> {
|
|
77
|
-
const resp = await this.http.post<{ data: CustomDomainData }>(this.base(), {
|
|
78
|
-
fqdn,
|
|
79
|
-
});
|
|
80
|
-
return resp.data;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* List all custom domains registered for this computer.
|
|
85
|
-
*/
|
|
86
|
-
async list(): Promise<CustomDomainData[]> {
|
|
87
|
-
const resp = await this.http.get<{ data: CustomDomainData[] }>(this.base());
|
|
88
|
-
return resp.data;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Verify DNS ownership of a registered domain.
|
|
93
|
-
*
|
|
94
|
-
* The control plane resolves the domain's CNAME and confirms it points to
|
|
95
|
-
* the expected `verification_target`. On success the domain transitions to
|
|
96
|
-
* `verified` status and Caddy will auto-issue a TLS certificate on the next
|
|
97
|
-
* inbound request.
|
|
98
|
-
*
|
|
99
|
-
* @param id - The custom domain record id (from `register()` or `list()`).
|
|
100
|
-
* @throws `ApiError` with code `CNAME_MISMATCH` if the CNAME doesn't match.
|
|
101
|
-
* @throws `ApiError` with code `DNS_LOOKUP_FAILED` if DNS is unreachable.
|
|
102
|
-
*/
|
|
103
|
-
async verify(id: string): Promise<CustomDomainData> {
|
|
104
|
-
const resp = await this.http.post<{ data: CustomDomainData }>(
|
|
105
|
-
`${this.base()}/${id}/verify`,
|
|
106
|
-
);
|
|
107
|
-
return resp.data;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Delete a custom domain mapping.
|
|
112
|
-
*
|
|
113
|
-
* The domain is immediately removed from the routing cache and Caddy will
|
|
114
|
-
* stop serving it on the next cert renewal cycle.
|
|
115
|
-
*
|
|
116
|
-
* @param id - The custom domain record id.
|
|
117
|
-
*/
|
|
118
|
-
async delete(id: string): Promise<void> {
|
|
119
|
-
await this.http.delete<{ id: string; deleted: boolean }>(
|
|
120
|
-
`${this.base()}/${id}`,
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dashboard — aggregated platform overview.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import type { HttpClient } from "../http.js";
|
|
6
|
-
|
|
7
|
-
// ── Resource shapes ──────────────────────────────────────────────────────────
|
|
8
|
-
|
|
9
|
-
export interface DashboardSummary {
|
|
10
|
-
computers?: unknown;
|
|
11
|
-
sandboxes?: unknown;
|
|
12
|
-
credits?: unknown;
|
|
13
|
-
[key: string]: unknown;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface OverviewData {
|
|
17
|
-
status?: string;
|
|
18
|
-
[key: string]: unknown;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
22
|
-
|
|
23
|
-
function unwrap<T>(payload: unknown): T {
|
|
24
|
-
if (payload && typeof payload === "object") {
|
|
25
|
-
const p = payload as Record<string, unknown>;
|
|
26
|
-
for (const k of ["data", "dashboard", "overview", "items"]) {
|
|
27
|
-
if (k in p) return p[k] as T;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return payload as T;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// ── Main resource ─────────────────────────────────────────────────────────────
|
|
34
|
-
|
|
35
|
-
export class Dashboard {
|
|
36
|
-
constructor(private readonly http: HttpClient) {}
|
|
37
|
-
|
|
38
|
-
/** Aggregated user dashboard payload. */
|
|
39
|
-
async summary(): Promise<DashboardSummary> {
|
|
40
|
-
const data = await this.http.get<unknown>("/dashboard");
|
|
41
|
-
return unwrap<DashboardSummary>(data);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/** Status / health overview (public endpoint). */
|
|
45
|
-
async overview(): Promise<OverviewData> {
|
|
46
|
-
const data = await this.http.get<unknown>("/overview");
|
|
47
|
-
return unwrap<OverviewData>(data);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Databases resource — managed Postgres / databases.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { randomUUID } from "node:crypto";
|
|
6
|
-
|
|
7
|
-
import type { HttpClient } from "../http.js";
|
|
8
|
-
|
|
9
|
-
// ── Branded IDs ──────────────────────────────────────────────────────────────
|
|
10
|
-
|
|
11
|
-
export type DatabaseId = string & { readonly __brand: "DatabaseId" };
|
|
12
|
-
|
|
13
|
-
// ── Resource shapes ──────────────────────────────────────────────────────────
|
|
14
|
-
|
|
15
|
-
export interface DatabaseData {
|
|
16
|
-
id: DatabaseId;
|
|
17
|
-
tenant_id: string;
|
|
18
|
-
name: string;
|
|
19
|
-
state?: string;
|
|
20
|
-
engine?: string;
|
|
21
|
-
engine_version?: string;
|
|
22
|
-
version?: string;
|
|
23
|
-
cpu_count?: number;
|
|
24
|
-
memory_mb?: number;
|
|
25
|
-
storage_mb?: number;
|
|
26
|
-
host?: string | null;
|
|
27
|
-
port?: number | null;
|
|
28
|
-
created_at?: string;
|
|
29
|
-
updated_at?: string;
|
|
30
|
-
[key: string]: unknown;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export interface DatabaseCredentials {
|
|
34
|
-
url?: string;
|
|
35
|
-
host?: string;
|
|
36
|
-
port?: number;
|
|
37
|
-
user?: string;
|
|
38
|
-
username?: string;
|
|
39
|
-
password?: string;
|
|
40
|
-
database?: string;
|
|
41
|
-
[key: string]: unknown;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export interface DatabaseLogsResult {
|
|
45
|
-
lines?: string[];
|
|
46
|
-
logs?: string[];
|
|
47
|
-
[key: string]: unknown;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// ── Request payloads ─────────────────────────────────────────────────────────
|
|
51
|
-
|
|
52
|
-
export interface DatabaseListParams {
|
|
53
|
-
limit?: number;
|
|
54
|
-
cursor?: string;
|
|
55
|
-
state?: string;
|
|
56
|
-
[key: string]: string | number | boolean | undefined;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export interface DatabaseCreateParams {
|
|
60
|
-
name: string;
|
|
61
|
-
engine?: string;
|
|
62
|
-
engine_version?: string;
|
|
63
|
-
cpu_count?: number;
|
|
64
|
-
memory_mb?: number;
|
|
65
|
-
storage_mb?: number;
|
|
66
|
-
external_workspace_id?: string;
|
|
67
|
-
external_user_id?: string;
|
|
68
|
-
external_project_id?: string;
|
|
69
|
-
metadata?: Record<string, unknown>;
|
|
70
|
-
/** @deprecated use engine_version. */
|
|
71
|
-
version?: string;
|
|
72
|
-
/** @deprecated use cpu_count/memory_mb/storage_mb. */
|
|
73
|
-
size?: string;
|
|
74
|
-
region?: string;
|
|
75
|
-
idempotencyKey?: string;
|
|
76
|
-
idempotency_key?: string;
|
|
77
|
-
[key: string]: unknown;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export interface DatabaseLogsParams {
|
|
81
|
-
lines?: number;
|
|
82
|
-
since?: string;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
86
|
-
|
|
87
|
-
function unwrap<T>(payload: unknown): T {
|
|
88
|
-
if (payload && typeof payload === "object" && "data" in (payload as object)) {
|
|
89
|
-
return (payload as { data: T }).data;
|
|
90
|
-
}
|
|
91
|
-
return payload as T;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function listItems<T>(
|
|
95
|
-
payload: unknown,
|
|
96
|
-
candidateKeys: string[] = ["data", "databases", "items"],
|
|
97
|
-
): T[] {
|
|
98
|
-
if (Array.isArray(payload)) return payload;
|
|
99
|
-
if (!payload || typeof payload !== "object") return [];
|
|
100
|
-
const p = payload as Record<string, unknown>;
|
|
101
|
-
if (Array.isArray(p.data)) return p.data as T[];
|
|
102
|
-
for (const key of candidateKeys) {
|
|
103
|
-
if (Array.isArray(p[key])) return p[key] as T[];
|
|
104
|
-
}
|
|
105
|
-
return [];
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function stripUndefined(
|
|
109
|
-
input: Record<string, unknown>,
|
|
110
|
-
): Record<string, unknown> {
|
|
111
|
-
return Object.fromEntries(
|
|
112
|
-
Object.entries(input).filter(([, v]) => v !== undefined),
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function idempotencyKey(key?: string): string {
|
|
117
|
-
return key ?? randomUUID();
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// ── Main resource ─────────────────────────────────────────────────────────────
|
|
121
|
-
|
|
122
|
-
export class Databases {
|
|
123
|
-
constructor(private readonly http: HttpClient) {}
|
|
124
|
-
|
|
125
|
-
async list(params: DatabaseListParams = {}): Promise<DatabaseData[]> {
|
|
126
|
-
const query = stripUndefined({ ...params }) as Record<
|
|
127
|
-
string,
|
|
128
|
-
string | number | boolean | undefined
|
|
129
|
-
>;
|
|
130
|
-
const data = await this.http.get<unknown>("/databases", query);
|
|
131
|
-
return listItems<DatabaseData>(data);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
async get(databaseId: string): Promise<DatabaseData> {
|
|
135
|
-
const data = await this.http.get<unknown>(`/databases/${databaseId}`);
|
|
136
|
-
return unwrap<DatabaseData>(data);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
async create(params: DatabaseCreateParams): Promise<DatabaseData> {
|
|
140
|
-
const {
|
|
141
|
-
idempotencyKey: camelIdempotencyKey,
|
|
142
|
-
idempotency_key: snakeIdempotencyKey,
|
|
143
|
-
version,
|
|
144
|
-
engine_version,
|
|
145
|
-
size: _deprecatedSize,
|
|
146
|
-
...rest
|
|
147
|
-
} = params;
|
|
148
|
-
|
|
149
|
-
const body = stripUndefined({
|
|
150
|
-
...rest,
|
|
151
|
-
engine_version: engine_version ?? version,
|
|
152
|
-
} as Record<string, unknown>);
|
|
153
|
-
|
|
154
|
-
const data = await this.http.request<unknown>("/databases", {
|
|
155
|
-
method: "POST",
|
|
156
|
-
body,
|
|
157
|
-
headers: {
|
|
158
|
-
"Idempotency-Key": idempotencyKey(
|
|
159
|
-
camelIdempotencyKey ?? snakeIdempotencyKey,
|
|
160
|
-
),
|
|
161
|
-
},
|
|
162
|
-
});
|
|
163
|
-
return unwrap<DatabaseData>(data);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
async delete(databaseId: string): Promise<void> {
|
|
167
|
-
await this.http.delete<unknown>(`/databases/${databaseId}`);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// ── Lifecycle ──────────────────────────────────────────────────────────────
|
|
171
|
-
|
|
172
|
-
async start(databaseId: string): Promise<DatabaseData> {
|
|
173
|
-
const data = await this.http.post<unknown>(
|
|
174
|
-
`/databases/${databaseId}/start`,
|
|
175
|
-
);
|
|
176
|
-
return unwrap<DatabaseData>(data);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
async stop(databaseId: string): Promise<DatabaseData> {
|
|
180
|
-
const data = await this.http.post<unknown>(`/databases/${databaseId}/stop`);
|
|
181
|
-
return unwrap<DatabaseData>(data);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
async restart(databaseId: string): Promise<DatabaseData> {
|
|
185
|
-
const data = await this.http.post<unknown>(
|
|
186
|
-
`/databases/${databaseId}/restart`,
|
|
187
|
-
);
|
|
188
|
-
return unwrap<DatabaseData>(data);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
// ── Credentials + logs ────────────────────────────────────────────────────
|
|
192
|
-
|
|
193
|
-
async credentials(databaseId: string): Promise<DatabaseCredentials> {
|
|
194
|
-
const data = await this.http.get<unknown>(
|
|
195
|
-
`/databases/${databaseId}/credentials`,
|
|
196
|
-
);
|
|
197
|
-
return unwrap<DatabaseCredentials>(data);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
async logs(
|
|
201
|
-
databaseId: string,
|
|
202
|
-
params: DatabaseLogsParams = {},
|
|
203
|
-
): Promise<DatabaseLogsResult> {
|
|
204
|
-
const query = stripUndefined({
|
|
205
|
-
lines: params.lines,
|
|
206
|
-
since: params.since,
|
|
207
|
-
}) as Record<string, string | number | boolean | undefined>;
|
|
208
|
-
const data = await this.http.get<unknown>(
|
|
209
|
-
`/databases/${databaseId}/logs`,
|
|
210
|
-
query,
|
|
211
|
-
);
|
|
212
|
-
return data as DatabaseLogsResult;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
streamLogs(databaseId: string): AsyncIterableIterator<unknown> {
|
|
216
|
-
return this.http.stream<unknown>(`/databases/${databaseId}/logs/stream`);
|
|
217
|
-
}
|
|
218
|
-
}
|