@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,1060 +0,0 @@
1
- /**
2
- * Deployments resource — sandbox→production publishing surface.
3
- *
4
- * Backend phase status:
5
- * - list / get / create / update / delete / env: repo deployment surface.
6
- * - publish / versions.* / releases.* / rollback / domains.*: live release surface.
7
- * - runtimeInstances.*: dynamic runtime status/log inspection.
8
- * - publishFromSandbox: direct sandbox -> deployment bridge.
9
- *
10
- * See docs/deploy/* for the conceptual model.
11
- */
12
-
13
- import { randomUUID } from "node:crypto";
14
-
15
- import type { HttpClient } from "../http.js";
16
- import type { DockerDeployHostData } from "./docker-deploy.js";
17
-
18
- // ── Branded IDs ─────────────────────────────────────────────────────────────
19
-
20
- export type DeploymentId = string & { readonly __brand: "DeploymentId" };
21
- export type DeploymentVersionId = string & {
22
- readonly __brand: "DeploymentVersionId";
23
- };
24
- export type DeploymentReleaseId = string & {
25
- readonly __brand: "DeploymentReleaseId";
26
- };
27
- export type DeploymentServiceId = string & {
28
- readonly __brand: "DeploymentServiceId";
29
- };
30
- export type RuntimeInstanceId = string & {
31
- readonly __brand: "RuntimeInstanceId";
32
- };
33
-
34
- // ── States / enums ──────────────────────────────────────────────────────────
35
-
36
- export type DeploymentState =
37
- | "pending"
38
- | "building"
39
- | "running"
40
- | "stopped"
41
- | "failed";
42
-
43
- export type DeploymentVersionKind = "static" | "dynamic" | "sandbox_backed";
44
-
45
- export type DeploymentVersionState =
46
- | "created"
47
- | "building"
48
- | "ready"
49
- | "failed"
50
- | "archived";
51
-
52
- export type DeploymentSourceType = "repo" | "sandbox" | "upload";
53
-
54
- export type DeploymentProduct = "miosa_deploy" | "docker_deploy";
55
-
56
- export type DeploymentServiceType =
57
- | "static_web"
58
- | "web"
59
- | "api"
60
- | "function"
61
- | "worker"
62
- | "cron"
63
- | "postgres"
64
- | "redis"
65
- | "bucket"
66
- | "volume";
67
-
68
- export type RuntimeInstanceState =
69
- | "provisioning"
70
- | "starting"
71
- | "healthy"
72
- | "unhealthy"
73
- | "error"
74
- | "stopped"
75
- | "destroyed";
76
-
77
- // ── Shared attribution ──────────────────────────────────────────────────────
78
-
79
- export interface ExternalAttribution {
80
- externalWorkspaceId?: string;
81
- external_workspace_id?: string;
82
- externalUserId?: string;
83
- external_user_id?: string;
84
- externalProjectId?: string;
85
- external_project_id?: string;
86
- }
87
-
88
- // ── Resource shapes ─────────────────────────────────────────────────────────
89
-
90
- export interface DeploymentData {
91
- id: DeploymentId;
92
- tenant_id: string;
93
- owner_id?: string;
94
- name: string;
95
- slug: string;
96
- /**
97
- * @deprecated — repo-based model. New deployments use source_type: "sandbox"
98
- * with `source_sandbox_id` on the version row. Will become nullable.
99
- */
100
- repo_url?: string;
101
- repo_provider?: "github";
102
- branch?: string;
103
- build_command?: string | null;
104
- run_command?: string | null;
105
- runtime_image?: string | null;
106
- current_build_id?: string | null;
107
- active_version_id?: string | null;
108
- source_type?: DeploymentSourceType;
109
- state: DeploymentState;
110
- auto_deploy?: boolean;
111
- custom_domain_id?: string | null;
112
- linked_database_id?: string | null;
113
- deployment_product?: DeploymentProduct | string | null;
114
- docker_deploy_host_id?: string | null;
115
- metadata?: Record<string, unknown>;
116
- external_workspace_id?: string | null;
117
- external_user_id?: string | null;
118
- external_project_id?: string | null;
119
- public_url?: string | null;
120
- created_at?: string;
121
- updated_at?: string;
122
- }
123
-
124
- export interface DockerDeployDoctorCheck {
125
- name: string;
126
- ok: boolean;
127
- message: string;
128
- details?: Record<string, unknown>;
129
- }
130
-
131
- export interface DockerDeployDoctorProbe {
132
- url: string;
133
- ok: boolean;
134
- status?: number;
135
- error?: string;
136
- }
137
-
138
- export interface DockerDeployDoctorResult {
139
- ok: boolean;
140
- deployment: DeploymentData;
141
- host?: DockerDeployHostData;
142
- checks: DockerDeployDoctorCheck[];
143
- probe?: DockerDeployDoctorProbe;
144
- }
145
-
146
- export interface DockerDeployDoctorParams {
147
- probePath?: string;
148
- probe_path?: string;
149
- timeoutMs?: number;
150
- timeout_ms?: number;
151
- }
152
-
153
- export type DeploymentDatabaseRequest =
154
- | boolean
155
- | {
156
- engine?: "postgresql" | "mysql" | "redis" | "qdrant";
157
- size?: "xs" | "small" | "medium" | "large";
158
- storage_mb?: number;
159
- region?: string;
160
- };
161
-
162
- export interface DeploymentVersionData {
163
- id: DeploymentVersionId;
164
- deployment_id: DeploymentId;
165
- tenant_id: string;
166
- created_by?: string | null;
167
- source_sandbox_id?: string | null;
168
- build_id?: string | null;
169
- version_number: number;
170
- kind: DeploymentVersionKind;
171
- state: DeploymentVersionState;
172
- artifact_uri?: string | null;
173
- artifact_manifest?: Record<string, unknown>;
174
- artifact_sha256?: string | null;
175
- runtime_image?: string | null;
176
- runtime_command?: string | null;
177
- runtime_port?: number | null;
178
- health_check_path?: string | null;
179
- build_log_uri?: string | null;
180
- metadata?: Record<string, unknown>;
181
- promoted_at?: string | null;
182
- archived_at?: string | null;
183
- external_workspace_id?: string | null;
184
- external_user_id?: string | null;
185
- external_project_id?: string | null;
186
- created_at?: string;
187
- updated_at?: string;
188
- }
189
-
190
- export interface DeploymentReleaseData {
191
- id: DeploymentReleaseId;
192
- deployment_id?: DeploymentId;
193
- environment_id?: string | null;
194
- deployment_version_id: DeploymentVersionId;
195
- service_id?: DeploymentServiceId | null;
196
- tenant_id: string;
197
- external_workspace_id?: string | null;
198
- external_user_id?: string | null;
199
- external_project_id?: string | null;
200
- source_sandbox_id?: string | null;
201
- build_id?: string | null;
202
- kind: "static" | "oci" | "rootfs" | string;
203
- state?: string;
204
- artifact_uri?: string | null;
205
- artifact_sha256?: string | null;
206
- artifact_manifest?: Record<string, unknown>;
207
- storage_backend?: string | null;
208
- storage_uri?: string;
209
- sha256?: string;
210
- size_bytes?: number;
211
- start_command?: string | null;
212
- port?: number | null;
213
- health_check_path?: string | null;
214
- build_log_uri?: string | null;
215
- metadata?: Record<string, unknown>;
216
- ready_at?: string | null;
217
- archived_at?: string | null;
218
- created_at?: string;
219
- updated_at?: string;
220
- }
221
-
222
- export interface DeploymentServiceData {
223
- id: DeploymentServiceId;
224
- deployment_id: DeploymentId;
225
- environment_id?: string | null;
226
- tenant_id: string;
227
- type: DeploymentServiceType;
228
- name?: string | null;
229
- desired_replicas?: number;
230
- state: string;
231
- metadata?: Record<string, unknown>;
232
- }
233
-
234
- export interface RuntimeInstanceData {
235
- id: RuntimeInstanceId;
236
- deployment_id?: DeploymentId;
237
- environment_id?: string | null;
238
- service_id?: DeploymentServiceId | null;
239
- release_id?: DeploymentReleaseId;
240
- tenant_id: string;
241
- external_workspace_id?: string | null;
242
- external_user_id?: string | null;
243
- external_project_id?: string | null;
244
- host_id?: string | null;
245
- node_id?: string | null;
246
- vm_id?: string | null;
247
- desired_state?: string | null;
248
- state: RuntimeInstanceState;
249
- ip_address?: string | null;
250
- port?: number | null;
251
- health_check_path?: string | null;
252
- last_health_check_at?: string | null;
253
- last_heartbeat_at?: string | null;
254
- started_at?: string | null;
255
- stopped_at?: string | null;
256
- error_message?: string | null;
257
- restart_count?: number;
258
- cpu_limit_millicores?: number | null;
259
- memory_limit_mb?: number | null;
260
- runtime_log_path?: string | null;
261
- metadata?: Record<string, unknown>;
262
- created_at?: string;
263
- updated_at?: string;
264
- }
265
-
266
- export interface DeploymentBuildData {
267
- id: string;
268
- deployment_id: DeploymentId;
269
- commit_sha?: string | null;
270
- commit_message?: string | null;
271
- triggered_by?: string;
272
- state: string;
273
- started_at?: string | null;
274
- finished_at?: string | null;
275
- duration_ms?: number | null;
276
- log_url?: string | null;
277
- image_digest?: string | null;
278
- error_message?: string | null;
279
- external_workspace_id?: string | null;
280
- external_user_id?: string | null;
281
- external_project_id?: string | null;
282
- created_at?: string;
283
- }
284
-
285
- // ── Request / response payloads ─────────────────────────────────────────────
286
-
287
- export interface DeploymentListParams extends ExternalAttribution {
288
- project_id?: string;
289
- projectId?: string;
290
- state?: DeploymentState | string;
291
- limit?: number;
292
- cursor?: string;
293
- }
294
-
295
- export interface DeploymentCreateParams extends ExternalAttribution {
296
- name: string;
297
- /** Current backend create route is repo-backed; project IDs are attribution, not route ownership. */
298
- project_id?: string;
299
- projectId?: string;
300
- /** @deprecated Ignored by the backend create route. Use sandbox.deploy() for sandbox-backed deployments. */
301
- source_type?: DeploymentSourceType;
302
- /** @deprecated Ignored by the backend create route. Use sandbox.deploy() for sandbox-backed deployments. */
303
- sourceType?: DeploymentSourceType;
304
- repo_url?: string;
305
- repoUrl?: string;
306
- branch?: string;
307
- build_command?: string;
308
- buildCommand?: string;
309
- run_command?: string;
310
- runCommand?: string;
311
- auto_deploy?: boolean;
312
- autoDeploy?: boolean;
313
- database?: DeploymentDatabaseRequest;
314
- metadata?: Record<string, unknown>;
315
- idempotencyKey?: string;
316
- }
317
-
318
- export interface DockerDeployCreateParams extends DeploymentCreateParams {}
319
-
320
- export interface DeploymentUpdateParams {
321
- name?: string;
322
- branch?: string;
323
- build_command?: string;
324
- buildCommand?: string;
325
- run_command?: string;
326
- runCommand?: string;
327
- auto_deploy?: boolean;
328
- autoDeploy?: boolean;
329
- }
330
-
331
- export interface PublishParams extends ExternalAttribution {
332
- sourceSandboxId: string;
333
- source_sandbox_id?: string;
334
- name?: string;
335
- deploymentId?: string;
336
- deployment_id?: string;
337
- /** @deprecated Reserved for dynamic runtime publish; ignored by current static publish route. */
338
- kind?: "auto" | "static" | "dynamic";
339
- /** @deprecated Reserved for deployment environments; ignored by current static publish route. */
340
- environment?: "production" | "staging" | string;
341
- outputPath?: string;
342
- output_path?: string;
343
- /** @deprecated Current /deployments/:id/publish snapshots /workspace internally. */
344
- sourceSnapshotPath?: string;
345
- /** @deprecated Current /deployments/:id/publish snapshots /workspace internally. */
346
- source_snapshot_path?: string;
347
- entrypoint?: string;
348
- promote?: boolean;
349
- domain?: string;
350
- customDomain?: string;
351
- custom_domain?: string;
352
- /** @deprecated Reserved for dynamic runtime publish. */
353
- buildCommand?: string;
354
- /** @deprecated Reserved for dynamic runtime publish. */
355
- build_command?: string;
356
- /** @deprecated Reserved for dynamic runtime publish. */
357
- runCommand?: string;
358
- /** @deprecated Reserved for dynamic runtime publish. */
359
- run_command?: string;
360
- /** @deprecated Reserved for dynamic runtime publish. */
361
- port?: number;
362
- /** @deprecated Reserved for dynamic runtime publish. */
363
- healthCheckPath?: string;
364
- /** @deprecated Reserved for dynamic runtime publish. */
365
- health_check_path?: string;
366
- /** @deprecated Reserved for managed data-service binding. */
367
- dataServices?: string[];
368
- /** @deprecated Reserved for managed data-service binding. */
369
- data_services?: string[];
370
- idempotencyKey?: string;
371
- }
372
-
373
- export interface PublishResult {
374
- deployment: DeploymentData;
375
- version: DeploymentVersionData;
376
- release?: DeploymentReleaseData;
377
- services?: DeploymentServiceData[];
378
- promoted: boolean;
379
- }
380
-
381
- export type PublishFromSandboxParams = Omit<
382
- PublishParams,
383
- "sourceSandboxId" | "source_sandbox_id"
384
- > & {
385
- sourceSandboxId?: string;
386
- source_sandbox_id?: string;
387
- };
388
-
389
- export interface RollbackParams {
390
- versionId?: string;
391
- version_id?: string;
392
- idempotencyKey?: string;
393
- }
394
-
395
- export interface VersionListParams extends ExternalAttribution {
396
- state?: DeploymentVersionState | string;
397
- limit?: number;
398
- cursor?: string;
399
- }
400
-
401
- export interface RuntimeLogsResult {
402
- runtime_instance_id?: string;
403
- deployment_id?: string;
404
- log_path?: string;
405
- logs: string;
406
- }
407
-
408
- export interface AddDomainParams extends ExternalAttribution {
409
- redirectPolicy?: "none" | "www_to_apex" | "apex_to_www";
410
- redirect_policy?: "none" | "www_to_apex" | "apex_to_www";
411
- idempotencyKey?: string;
412
- }
413
-
414
- // ── Helpers ────────────────────────────────────────────────────────────────
415
-
416
- function attributionBody(p: ExternalAttribution): Record<string, unknown> {
417
- const out: Record<string, unknown> = {};
418
- const ws = p.externalWorkspaceId ?? p.external_workspace_id;
419
- const usr = p.externalUserId ?? p.external_user_id;
420
- const proj = p.externalProjectId ?? p.external_project_id;
421
- if (ws !== undefined) out.external_workspace_id = ws;
422
- if (usr !== undefined) out.external_user_id = usr;
423
- if (proj !== undefined) out.external_project_id = proj;
424
- return out;
425
- }
426
-
427
- function idempotencyKey(key?: string): string {
428
- return key ?? randomUUID();
429
- }
430
-
431
- function unwrap<T>(payload: { data?: T } | T): T {
432
- if (payload && typeof payload === "object" && "data" in (payload as object)) {
433
- return (payload as { data: T }).data;
434
- }
435
- return payload as T;
436
- }
437
-
438
- function listItems<T>(
439
- payload: { data?: T[] } | { items?: T[] } | T[] | unknown,
440
- candidateKeys: string[] = ["items", "deployments", "versions", "domains"],
441
- ): T[] {
442
- if (Array.isArray(payload)) return payload;
443
- if (!payload || typeof payload !== "object") return [];
444
- const p = payload as Record<string, unknown>;
445
- if (Array.isArray(p.data)) return p.data as T[];
446
- for (const key of candidateKeys) {
447
- if (Array.isArray(p[key])) return p[key] as T[];
448
- }
449
- return [];
450
- }
451
-
452
- function stripUndefined(
453
- input: Record<string, unknown>,
454
- ): Record<string, unknown> {
455
- return Object.fromEntries(
456
- Object.entries(input).filter(([, v]) => v !== undefined),
457
- );
458
- }
459
-
460
- function dockerDeployMetadata(
461
- metadata: Record<string, unknown> | undefined,
462
- ): Record<string, unknown> {
463
- return {
464
- ...(metadata ?? {}),
465
- deployment_product: "docker_deploy",
466
- };
467
- }
468
-
469
- function dockerDeployProduct(deployment: DeploymentData): unknown {
470
- return (
471
- deployment.deployment_product ??
472
- deployment.metadata?.["deployment_product"]
473
- );
474
- }
475
-
476
- function dockerDeployHostId(deployment: DeploymentData): string | null {
477
- const metadataHost = deployment.metadata?.["docker_deploy_host_id"];
478
- return (
479
- deployment.docker_deploy_host_id ??
480
- (typeof metadataHost === "string" ? metadataHost : null)
481
- );
482
- }
483
-
484
- function dockerDeployApp(deployment: DeploymentData): Record<string, unknown> | null {
485
- const app = deployment.metadata?.["docker_deploy"];
486
- if (!app || typeof app !== "object" || Array.isArray(app)) return null;
487
- return app as Record<string, unknown>;
488
- }
489
-
490
- function dockerDeployAppPort(app: Record<string, unknown> | null): number | null {
491
- const url = app?.["url"];
492
- if (typeof url !== "string") return null;
493
-
494
- try {
495
- const parsed = new URL(url);
496
- const port = Number.parseInt(parsed.port, 10);
497
- return Number.isInteger(port) ? port : null;
498
- } catch {
499
- return null;
500
- }
501
- }
502
-
503
- function addDoctorCheck(
504
- checks: DockerDeployDoctorCheck[],
505
- name: string,
506
- ok: boolean,
507
- message: string,
508
- details?: Record<string, unknown>,
509
- ): void {
510
- checks.push({ name, ok, message, ...(details ? { details } : {}) });
511
- }
512
-
513
- function hostHealthy(host: DockerDeployHostData | undefined): boolean {
514
- return Boolean(
515
- host && host.status === "active" && host.appliance_status === "healthy",
516
- );
517
- }
518
-
519
- function probeUrl(publicUrl: string, probePath: string): string {
520
- const url = new URL(publicUrl);
521
- url.pathname = probePath.startsWith("/") ? probePath : `/${probePath}`;
522
- return url.toString();
523
- }
524
-
525
- // ── Sub-resources ──────────────────────────────────────────────────────────
526
-
527
- export class DeploymentVersions {
528
- constructor(
529
- private readonly http: HttpClient,
530
- private readonly deploymentId: string,
531
- ) {}
532
-
533
- async list(params: VersionListParams = {}): Promise<DeploymentVersionData[]> {
534
- const query = stripUndefined({
535
- state: params.state,
536
- limit: params.limit,
537
- cursor: params.cursor,
538
- ...attributionBody(params),
539
- });
540
- const data = await this.http.get<unknown>(
541
- `/deployments/${this.deploymentId}/versions`,
542
- query as Record<string, string | number | boolean | undefined>,
543
- );
544
- return listItems<DeploymentVersionData>(data);
545
- }
546
-
547
- async get(versionId: string): Promise<DeploymentVersionData> {
548
- const data = await this.http.get<unknown>(
549
- `/deployments/${this.deploymentId}/versions/${versionId}`,
550
- );
551
- return unwrap(data) as DeploymentVersionData;
552
- }
553
-
554
- async promote(
555
- versionId: string,
556
- opts: { environment?: string; idempotencyKey?: string } = {},
557
- ): Promise<DeploymentData> {
558
- const body = stripUndefined({ environment: opts.environment });
559
- const data = await this.http.request<unknown>(
560
- `/deployments/${this.deploymentId}/versions/${versionId}/promote`,
561
- {
562
- method: "POST",
563
- body,
564
- headers: { "Idempotency-Key": idempotencyKey(opts.idempotencyKey) },
565
- },
566
- );
567
- return unwrap(data) as DeploymentData;
568
- }
569
- }
570
-
571
- export class DeploymentReleases {
572
- constructor(
573
- private readonly http: HttpClient,
574
- private readonly deploymentId: string,
575
- ) {}
576
-
577
- async list(): Promise<DeploymentReleaseData[]> {
578
- const data = await this.http.get<unknown>(
579
- `/deployments/${this.deploymentId}/releases`,
580
- );
581
- return listItems<DeploymentReleaseData>(data, ["releases"]);
582
- }
583
-
584
- async get(releaseId: string): Promise<DeploymentReleaseData> {
585
- const data = await this.http.get<unknown>(
586
- `/deployments/${this.deploymentId}/releases/${releaseId}`,
587
- );
588
- return unwrap(data) as DeploymentReleaseData;
589
- }
590
- }
591
-
592
- export class DeploymentRuntimeInstances {
593
- constructor(
594
- private readonly http: HttpClient,
595
- private readonly deploymentId: string,
596
- ) {}
597
-
598
- async list(): Promise<RuntimeInstanceData[]> {
599
- const data = await this.http.get<unknown>(
600
- `/deployments/${this.deploymentId}/runtime-instances`,
601
- );
602
- return listItems<RuntimeInstanceData>(data, ["runtime_instances"]);
603
- }
604
-
605
- async get(instanceId: string): Promise<RuntimeInstanceData> {
606
- const data = await this.http.get<unknown>(
607
- `/deployments/${this.deploymentId}/runtime-instances/${instanceId}`,
608
- );
609
- return unwrap(data) as RuntimeInstanceData;
610
- }
611
-
612
- async logs(instanceId: string, lines = 100): Promise<RuntimeLogsResult> {
613
- const data = await this.http.get<unknown>(
614
- `/deployments/${this.deploymentId}/runtime-instances/${instanceId}/logs`,
615
- { lines },
616
- );
617
- const unwrapped = unwrap(data) as Record<string, unknown>;
618
- const result: RuntimeLogsResult = { logs: String(unwrapped.logs ?? "") };
619
- if (typeof unwrapped.runtime_instance_id === "string") {
620
- result.runtime_instance_id = unwrapped.runtime_instance_id;
621
- }
622
- if (typeof unwrapped.deployment_id === "string") {
623
- result.deployment_id = unwrapped.deployment_id;
624
- }
625
- if (typeof unwrapped.log_path === "string") {
626
- result.log_path = unwrapped.log_path;
627
- }
628
- return result;
629
- }
630
- }
631
-
632
- export class DeploymentDomains {
633
- constructor(
634
- private readonly http: HttpClient,
635
- private readonly deploymentId: string,
636
- ) {}
637
-
638
- async add(
639
- domain: string,
640
- params: AddDomainParams = {},
641
- ): Promise<Record<string, unknown>> {
642
- const body = {
643
- domain,
644
- redirect_policy: params.redirectPolicy ?? params.redirect_policy,
645
- ...attributionBody(params),
646
- };
647
- const data = await this.http.request<unknown>(
648
- `/deployments/${this.deploymentId}/domains`,
649
- {
650
- method: "POST",
651
- body: stripUndefined(body),
652
- headers: { "Idempotency-Key": idempotencyKey(params.idempotencyKey) },
653
- },
654
- );
655
- return unwrap(data) as Record<string, unknown>;
656
- }
657
-
658
- async list(
659
- filters: ExternalAttribution = {},
660
- ): Promise<Record<string, unknown>[]> {
661
- const data = await this.http.get<unknown>(
662
- `/deployments/${this.deploymentId}/domains`,
663
- attributionBody(filters) as Record<
664
- string,
665
- string | number | boolean | undefined
666
- >,
667
- );
668
- return listItems<Record<string, unknown>>(data);
669
- }
670
-
671
- async verify(domainId: string): Promise<Record<string, unknown>> {
672
- const data = await this.http.post<unknown>(
673
- `/deployments/${this.deploymentId}/domains/${domainId}/verify`,
674
- );
675
- return unwrap(data) as Record<string, unknown>;
676
- }
677
-
678
- async delete(domainId: string): Promise<void> {
679
- await this.http.delete<unknown>(
680
- `/deployments/${this.deploymentId}/domains/${domainId}`,
681
- );
682
- }
683
- }
684
-
685
- // ── Main resource ──────────────────────────────────────────────────────────
686
-
687
- export class Deployments {
688
- constructor(private readonly http: HttpClient) {}
689
-
690
- async list(params: DeploymentListParams = {}): Promise<DeploymentData[]> {
691
- const projectId = params.projectId ?? params.project_id;
692
- const query = stripUndefined({
693
- project_id: projectId,
694
- state: params.state,
695
- limit: params.limit,
696
- cursor: params.cursor,
697
- ...attributionBody(params),
698
- });
699
- const data = await this.http.get<unknown>(
700
- "/deployments",
701
- query as Record<string, string | number | boolean | undefined>,
702
- );
703
- return listItems<DeploymentData>(data);
704
- }
705
-
706
- async get(deploymentId: string): Promise<DeploymentData> {
707
- const data = await this.http.get<unknown>(`/deployments/${deploymentId}`);
708
- return unwrap(data) as DeploymentData;
709
- }
710
-
711
- async create(params: DeploymentCreateParams): Promise<DeploymentData> {
712
- const body = stripUndefined({
713
- name: params.name,
714
- repo_url: params.repoUrl ?? params.repo_url,
715
- branch: params.branch,
716
- build_command: params.buildCommand ?? params.build_command,
717
- run_command: params.runCommand ?? params.run_command,
718
- auto_deploy: params.autoDeploy ?? params.auto_deploy,
719
- database: params.database,
720
- metadata: params.metadata,
721
- ...attributionBody(params),
722
- });
723
- const data = await this.http.request<unknown>("/deployments", {
724
- method: "POST",
725
- body,
726
- headers: { "Idempotency-Key": idempotencyKey(params.idempotencyKey) },
727
- });
728
- return unwrap(data) as DeploymentData;
729
- }
730
-
731
- /**
732
- * Create a deployment that runs on the workspace's dedicated Docker Deploy
733
- * runtime. It uses the same /deployments API as MIOSA Deploy, but marks the
734
- * deployment so the control plane attaches it to the workspace Docker host.
735
- */
736
- async createDockerDeploy(
737
- params: DockerDeployCreateParams,
738
- ): Promise<DeploymentData> {
739
- return this.create({
740
- ...params,
741
- metadata: dockerDeployMetadata(params.metadata),
742
- });
743
- }
744
-
745
- /**
746
- * Verify a Docker Deploy deployment before telling a user or agent it is
747
- * live. Checks product markers, appliance host health, route metadata, and
748
- * optionally probes the public URL.
749
- */
750
- async doctorDockerDeploy(
751
- deploymentId: string,
752
- params: DockerDeployDoctorParams = {},
753
- ): Promise<DockerDeployDoctorResult> {
754
- const checks: DockerDeployDoctorCheck[] = [];
755
- const deployment = await this.get(deploymentId);
756
- const metadata = deployment.metadata ?? {};
757
- const product = dockerDeployProduct(deployment);
758
- const hostId = dockerDeployHostId(deployment);
759
-
760
- addDoctorCheck(
761
- checks,
762
- "deployment_product",
763
- product === "docker_deploy",
764
- product === "docker_deploy"
765
- ? "Deployment is marked for Docker Deploy."
766
- : `Expected deployment_product=docker_deploy, got ${String(product ?? "missing")}.`,
767
- { deployment_product: product ?? null },
768
- );
769
-
770
- addDoctorCheck(
771
- checks,
772
- "docker_deploy_host_id",
773
- Boolean(hostId),
774
- hostId
775
- ? "Deployment has a Docker Deploy host id."
776
- : "Deployment has no docker_deploy_host_id.",
777
- { docker_deploy_host_id: hostId },
778
- );
779
-
780
- let host: DockerDeployHostData | undefined;
781
- if (hostId) {
782
- try {
783
- const rawHost = await this.http.get<unknown>(
784
- `/docker-deploy/hosts/${hostId}`,
785
- );
786
- host = unwrap(rawHost) as DockerDeployHostData;
787
- addDoctorCheck(
788
- checks,
789
- "docker_deploy_host_health",
790
- hostHealthy(host),
791
- hostHealthy(host)
792
- ? "Docker Deploy host is active and healthy."
793
- : `Docker Deploy host status=${host.status} appliance=${host.appliance_status}.`,
794
- {
795
- status: host.status,
796
- appliance_status: host.appliance_status,
797
- },
798
- );
799
- } catch (error) {
800
- addDoctorCheck(
801
- checks,
802
- "docker_deploy_host_health",
803
- false,
804
- error instanceof Error ? error.message : String(error),
805
- );
806
- }
807
- }
808
-
809
- const app = dockerDeployApp(deployment);
810
- const appPort = dockerDeployAppPort(app);
811
- const appRunning = app?.["status"] === "running" && appPort !== null;
812
- addDoctorCheck(
813
- checks,
814
- "docker_deploy_app",
815
- appRunning,
816
- appRunning
817
- ? "Docker Deploy app metadata points at a running container."
818
- : "Deployment is missing running Docker Deploy app metadata.",
819
- app
820
- ? {
821
- app_id: app["app_id"],
822
- container_id: app["container_id"],
823
- status: app["status"],
824
- url: app["url"],
825
- expected_port: appPort,
826
- }
827
- : undefined,
828
- );
829
-
830
- const runtime = metadata["runtime"];
831
- const hasRuntimeRoute =
832
- typeof runtime === "object" &&
833
- runtime !== null &&
834
- typeof (runtime as Record<string, unknown>)["ip"] === "string" &&
835
- typeof (runtime as Record<string, unknown>)["port"] === "number";
836
- const runtimeRecord =
837
- hasRuntimeRoute && typeof runtime === "object"
838
- ? (runtime as Record<string, unknown>)
839
- : undefined;
840
- const routeMatchesContainerPort =
841
- hasRuntimeRoute &&
842
- (appPort === null || runtimeRecord?.["port"] === appPort);
843
- addDoctorCheck(
844
- checks,
845
- "runtime_route",
846
- hasRuntimeRoute && routeMatchesContainerPort,
847
- hasRuntimeRoute && routeMatchesContainerPort
848
- ? "Deployment route points at the Docker container host port."
849
- : hasRuntimeRoute && appPort !== null
850
- ? `Deployment route port ${String(runtimeRecord?.["port"])} does not match Docker container host port ${appPort}.`
851
- : "Deployment is missing appliance runtime route metadata.",
852
- runtimeRecord
853
- ? {
854
- ...runtimeRecord,
855
- expected_port: appPort,
856
- docker_deploy_url: app?.["url"],
857
- }
858
- : undefined,
859
- );
860
-
861
- let probe: DockerDeployDoctorProbe | undefined;
862
- const publicUrl = deployment.public_url;
863
- const path = params.probePath ?? params.probe_path ?? "/";
864
- if (publicUrl && typeof fetch === "function") {
865
- const url = probeUrl(publicUrl, path);
866
- const controller = new AbortController();
867
- const timeout = setTimeout(
868
- () => controller.abort(),
869
- params.timeoutMs ?? params.timeout_ms ?? 10_000,
870
- );
871
- try {
872
- const response = await fetch(url, {
873
- method: "GET",
874
- signal: controller.signal,
875
- });
876
- probe = { url, ok: response.ok, status: response.status };
877
- addDoctorCheck(
878
- checks,
879
- "public_url_probe",
880
- response.ok,
881
- response.ok
882
- ? `Public URL returned HTTP ${response.status}.`
883
- : `Public URL returned HTTP ${response.status}.`,
884
- { url, status: response.status },
885
- );
886
- } catch (error) {
887
- probe = {
888
- url,
889
- ok: false,
890
- error: error instanceof Error ? error.message : String(error),
891
- };
892
- addDoctorCheck(
893
- checks,
894
- "public_url_probe",
895
- false,
896
- probe.error ?? "Public URL probe failed.",
897
- { url },
898
- );
899
- } finally {
900
- clearTimeout(timeout);
901
- }
902
- }
903
-
904
- return {
905
- ok: checks.every((check) => check.ok),
906
- deployment,
907
- ...(host ? { host } : {}),
908
- checks,
909
- ...(probe ? { probe } : {}),
910
- };
911
- }
912
-
913
- async update(
914
- deploymentId: string,
915
- params: DeploymentUpdateParams,
916
- ): Promise<DeploymentData> {
917
- const body = stripUndefined({
918
- name: params.name,
919
- branch: params.branch,
920
- build_command: params.buildCommand ?? params.build_command,
921
- run_command: params.runCommand ?? params.run_command,
922
- auto_deploy: params.autoDeploy ?? params.auto_deploy,
923
- });
924
- const data = await this.http.patch<unknown>(
925
- `/deployments/${deploymentId}`,
926
- body,
927
- );
928
- return unwrap(data) as DeploymentData;
929
- }
930
-
931
- async delete(deploymentId: string): Promise<void> {
932
- await this.http.delete<unknown>(`/deployments/${deploymentId}`);
933
- }
934
-
935
- async publish(
936
- deploymentId: string,
937
- params: PublishParams,
938
- ): Promise<PublishResult> {
939
- const body = stripUndefined({
940
- source_sandbox_id: params.sourceSandboxId ?? params.source_sandbox_id,
941
- output_path: params.outputPath ?? params.output_path,
942
- entrypoint: params.entrypoint,
943
- promote: params.promote,
944
- });
945
- const data = await this.http.request<unknown>(
946
- `/deployments/${deploymentId}/publish`,
947
- {
948
- method: "POST",
949
- body,
950
- headers: { "Idempotency-Key": idempotencyKey(params.idempotencyKey) },
951
- },
952
- );
953
- return unwrap(data) as PublishResult;
954
- }
955
-
956
- /**
957
- * Backward-compatible bridge: POST /sandboxes/:id/deploy. Works today;
958
- * returns either release-backed or sandbox-backed depending on backend
959
- * phase. Prefer `publish()` once Phase 2B/3 lands.
960
- */
961
- async publishFromSandbox(
962
- sandboxId: string,
963
- params: PublishFromSandboxParams = {},
964
- ): Promise<Record<string, unknown>> {
965
- const body = stripUndefined({
966
- name: params.name,
967
- deployment_id: params.deploymentId ?? params.deployment_id,
968
- output_path: params.outputPath ?? params.output_path,
969
- source_snapshot_path:
970
- params.sourceSnapshotPath ?? params.source_snapshot_path,
971
- entrypoint: params.entrypoint,
972
- domain: params.domain,
973
- custom_domain: params.customDomain ?? params.custom_domain,
974
- });
975
- const data = await this.http.request<unknown>(
976
- `/sandboxes/${sandboxId}/deploy`,
977
- {
978
- method: "POST",
979
- body,
980
- headers: { "Idempotency-Key": idempotencyKey(params.idempotencyKey) },
981
- },
982
- );
983
- return unwrap(data) as Record<string, unknown>;
984
- }
985
-
986
- async rollback(
987
- deploymentId: string,
988
- params: RollbackParams = {},
989
- ): Promise<DeploymentData> {
990
- const body = stripUndefined({
991
- version_id: params.versionId ?? params.version_id,
992
- });
993
- const data = await this.http.request<unknown>(
994
- `/deployments/${deploymentId}/rollback`,
995
- {
996
- method: "POST",
997
- body,
998
- headers: { "Idempotency-Key": idempotencyKey(params.idempotencyKey) },
999
- },
1000
- );
1001
- return unwrap(data) as DeploymentData;
1002
- }
1003
-
1004
- async listBuilds(deploymentId: string): Promise<DeploymentBuildData[]> {
1005
- const data = await this.http.get<unknown>(
1006
- `/deployments/${deploymentId}/builds`,
1007
- );
1008
- return listItems<DeploymentBuildData>(data);
1009
- }
1010
-
1011
- async getBuild(
1012
- deploymentId: string,
1013
- buildId: string,
1014
- ): Promise<DeploymentBuildData> {
1015
- const data = await this.http.get<unknown>(
1016
- `/deployments/${deploymentId}/builds/${buildId}`,
1017
- );
1018
- return unwrap(data) as DeploymentBuildData;
1019
- }
1020
-
1021
- async listEnv(deploymentId: string): Promise<Record<string, unknown>[]> {
1022
- const data = await this.http.get<unknown>(
1023
- `/deployments/${deploymentId}/env`,
1024
- );
1025
- return listItems<Record<string, unknown>>(data);
1026
- }
1027
-
1028
- async setEnv(
1029
- deploymentId: string,
1030
- vars: Record<string, string>,
1031
- opts: { environment?: string } = {},
1032
- ): Promise<Record<string, unknown>[]> {
1033
- const body = stripUndefined({ env: vars, environment: opts.environment });
1034
- const data = await this.http.post<unknown>(
1035
- `/deployments/${deploymentId}/env`,
1036
- body,
1037
- );
1038
- return listItems<Record<string, unknown>>(data);
1039
- }
1040
-
1041
- versions(deploymentId: string): DeploymentVersions {
1042
- return new DeploymentVersions(this.http, deploymentId);
1043
- }
1044
-
1045
- releases(deploymentId: string): DeploymentReleases {
1046
- return new DeploymentReleases(this.http, deploymentId);
1047
- }
1048
-
1049
- runtimeInstances(deploymentId: string): DeploymentRuntimeInstances {
1050
- return new DeploymentRuntimeInstances(this.http, deploymentId);
1051
- }
1052
-
1053
- runtime_instances(deploymentId: string): DeploymentRuntimeInstances {
1054
- return this.runtimeInstances(deploymentId);
1055
- }
1056
-
1057
- domains(deploymentId: string): DeploymentDomains {
1058
- return new DeploymentDomains(this.http, deploymentId);
1059
- }
1060
- }