@ninedeploy/sdk 0.2.0

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.
@@ -0,0 +1,928 @@
1
+ import type { ActiveSession, ActivityEntry, AlertRule, CreateAlertRuleInput, ApiToken, PasskeyCredential, Attachment, Backup, BackupWithDb, CreateApiToken, CreateDatabaseInput, CreateDomainInput, CreateProjectInput, CreateServiceInput, CreateSourceInput, CreateTunnelInput, CreateWebhookInput, CreatedApiToken, CreatedWebhook, ConfigItem, ConfigListResponse, SetConfigInput, PluginListResponse, PluginInspectResponse, InstallPluginInput, MarketplaceCatalogResponse, MenuListResponse, DemoSeedResult, Deployment, DockerResources, Domain, DomainPatch, DomainEntry, EnvVar, Login, ManagedDatabase, DatabaseDetail, DatabaseCredentials, PasswordChange, PasswordReset, MetricSeries, ProjectEntry, ProjectPatchInput, PublicUser, Refresh, Register, Service, Session, SetLimitsInput, Source, StatsSnapshot, Template, TemplateSummary, TopologyGraph, TraefikCertificate, TraefikInfo, TraefikStatus, TunnelEntry, UserCreate, VolumeFileEntry, VolumeFileWriteInput, VolumePathCreateInput, TriggerDeploy, UpdateCheckResult, UpdateServiceInput, UpsertEnvVarInput, VolumeEntry, Webhook, LogDrain, LogDrainCreateInput, LogDrainUpdateInput, LogDrainTestResult, AutoPruneConfigUpdateInput, AutoPruneStatus, AutoPruneRunResult, ServerSshTest, ServerSshTestResult, ServerSshBootstrap, ServerBootstrapResult, WorkspaceEntry, WorkspaceDetail, WorkspaceCreateInput, WorkspaceUpdateInput, WorkspaceMemberEntry, WorkspaceMemberAddInput, WorkspaceMemberRoleUpdateInput, OidcPublicProvider, OidcProviderEntry, OidcProviderCreateInput, OidcProviderUpdateInput } from '@ninedeploy/schemas';
2
+ import { NineDeployError } from './errors.js';
3
+ export { NineDeployError };
4
+ export type * from '@ninedeploy/schemas';
5
+ /**
6
+ * Minimal structural fetch type so the SDK is isomorphic (browser + Node)
7
+ * without pulling in DOM lib types. Both `globalThis.fetch` implementations
8
+ * satisfy this shape.
9
+ */
10
+ export type FetchLike = (input: string, init: {
11
+ method?: string;
12
+ headers?: Record<string, string>;
13
+ body?: string;
14
+ }) => Promise<{
15
+ ok: boolean;
16
+ status: number;
17
+ text(): Promise<string>;
18
+ }>;
19
+ export interface HealthStatus {
20
+ status: string;
21
+ db?: string;
22
+ version?: string;
23
+ time?: string;
24
+ }
25
+ export interface NineDeployClientOptions {
26
+ /** Base URL of the NineDeploy API, e.g. http://localhost:3000. */
27
+ baseUrl: string;
28
+ /** Returns the current access token (or bearer credential). */
29
+ getToken?: () => string | undefined | null;
30
+ /** Custom fetch implementation (defaults to globalThis.fetch). */
31
+ fetch?: FetchLike;
32
+ }
33
+ export interface NineDeployClient {
34
+ auth: {
35
+ status: () => Promise<{
36
+ initialized: boolean;
37
+ }>;
38
+ setup: (input: Register) => Promise<Session>;
39
+ register: (input: Register) => Promise<Session>;
40
+ login: (input: Login) => Promise<Session>;
41
+ refresh: (input: Refresh) => Promise<Session>;
42
+ logout: () => Promise<{
43
+ ok: boolean;
44
+ }>;
45
+ /** Self-service password change; revokes other sessions, returns a fresh token pair. */
46
+ changePassword: (input: PasswordChange) => Promise<Session>;
47
+ /** Request a reset link (always 200 — no user enumeration). */
48
+ forgotPassword: (email: string) => Promise<{
49
+ ok: boolean;
50
+ }>;
51
+ /** Complete a reset with a single-use token; revokes all sessions. */
52
+ resetPasswordWithToken: (input: {
53
+ token: string;
54
+ newPassword: string;
55
+ }) => Promise<{
56
+ ok: boolean;
57
+ }>;
58
+ twoFactor: {
59
+ /** Generate a pending secret + otpauth URI (auth required). */
60
+ setup: (input?: {
61
+ password: string;
62
+ }) => Promise<{
63
+ secret: string;
64
+ otpauthUri: string;
65
+ }>;
66
+ enable: (code: string) => Promise<{
67
+ ok: boolean;
68
+ totpEnabled: boolean;
69
+ }>;
70
+ disable: (input: {
71
+ password: string;
72
+ code: string;
73
+ }) => Promise<{
74
+ ok: boolean;
75
+ totpEnabled: boolean;
76
+ }>;
77
+ };
78
+ me: () => Promise<PublicUser>;
79
+ tokens: {
80
+ create: (input?: CreateApiToken) => Promise<CreatedApiToken>;
81
+ list: () => Promise<ApiToken[]>;
82
+ remove: (id: number) => Promise<void>;
83
+ };
84
+ passkeys: {
85
+ /** Start a registration ceremony (returns JSON options for the browser API). */
86
+ registerOptions: () => Promise<{
87
+ options: string;
88
+ }>;
89
+ /** Complete registration: verify the browser response, store the credential. */
90
+ registerVerify: (input: {
91
+ name: string;
92
+ response: unknown;
93
+ }) => Promise<PasskeyCredential>;
94
+ list: () => Promise<PasskeyCredential[]>;
95
+ remove: (id: number) => Promise<void>;
96
+ /** Start a passwordless login ceremony (discoverable credentials). */
97
+ loginOptions: () => Promise<{
98
+ options: string;
99
+ }>;
100
+ /** Complete passkey login — returns a full session on success. */
101
+ loginVerify: (response: unknown) => Promise<Session>;
102
+ };
103
+ sessions: {
104
+ list: () => Promise<ActiveSession[]>;
105
+ revoke: (id: number) => Promise<{
106
+ ok: boolean;
107
+ }>;
108
+ };
109
+ oidc: {
110
+ publicProviders: () => Promise<OidcPublicProvider[]>;
111
+ listProviders: () => Promise<OidcProviderEntry[]>;
112
+ list: () => Promise<OidcProviderEntry[]>;
113
+ createProvider: (input: OidcProviderCreateInput) => Promise<OidcProviderEntry>;
114
+ create: (input: OidcProviderCreateInput) => Promise<OidcProviderEntry>;
115
+ updateProvider: (id: number, input: OidcProviderUpdateInput) => Promise<OidcProviderEntry>;
116
+ update: (id: number, input: OidcProviderUpdateInput) => Promise<OidcProviderEntry>;
117
+ deleteProvider: (id: number) => Promise<{
118
+ ok: boolean;
119
+ }>;
120
+ delete: (id: number) => Promise<{
121
+ ok: boolean;
122
+ }>;
123
+ callback: (slug: string, payload: {
124
+ code: string;
125
+ state: string;
126
+ }) => Promise<Session>;
127
+ };
128
+ };
129
+ workspaces: {
130
+ list: () => Promise<WorkspaceEntry[]>;
131
+ get: (id: number) => Promise<WorkspaceDetail>;
132
+ create: (input: WorkspaceCreateInput) => Promise<WorkspaceEntry>;
133
+ update: (id: number, input: WorkspaceUpdateInput) => Promise<WorkspaceEntry>;
134
+ delete: (id: number) => Promise<{
135
+ ok: boolean;
136
+ }>;
137
+ addMember: (id: number, input: WorkspaceMemberAddInput) => Promise<WorkspaceMemberEntry>;
138
+ updateMemberRole: (id: number, memberId: number, input: WorkspaceMemberRoleUpdateInput) => Promise<WorkspaceMemberEntry>;
139
+ removeMember: (id: number, memberId: number) => Promise<{
140
+ ok: boolean;
141
+ }>;
142
+ };
143
+ services: {
144
+ /** `query` is appended verbatim, e.g. `?projectId=3` (project scoping). */
145
+ list: (query?: string) => Promise<Service[]>;
146
+ get: (id: number) => Promise<Service>;
147
+ create: (input: CreateServiceInput) => Promise<Service>;
148
+ update: (id: number, input: UpdateServiceInput) => Promise<Service>;
149
+ remove: (id: number) => Promise<void>;
150
+ stop: (id: number) => Promise<{
151
+ ok: boolean;
152
+ status: string;
153
+ }>;
154
+ start: (id: number) => Promise<{
155
+ ok: boolean;
156
+ status: string;
157
+ }>;
158
+ restart: (id: number) => Promise<{
159
+ ok: boolean;
160
+ status: string;
161
+ }>;
162
+ logs: (id: number) => Promise<{
163
+ lines: string;
164
+ }>;
165
+ clone: (id: number, input?: {
166
+ name?: string;
167
+ slug?: string;
168
+ }) => Promise<Service>;
169
+ exportUrl: (id: number) => string;
170
+ importBundle: (bundle: unknown) => Promise<{
171
+ ok: boolean;
172
+ serviceId: number;
173
+ slug: string;
174
+ message: string;
175
+ }>;
176
+ };
177
+ deploys: {
178
+ trigger: (serviceId: number, input?: TriggerDeploy) => Promise<{
179
+ deploymentId: number;
180
+ }>;
181
+ list: (serviceId: number) => Promise<Deployment[]>;
182
+ rollback: (serviceId: number, deploymentId: number) => Promise<{
183
+ deploymentId: number;
184
+ }>;
185
+ /** Cancel a queued/in-flight deployment (checkpoints abort at step boundaries). */
186
+ cancel: (serviceId: number, deploymentId: number) => Promise<{
187
+ ok: boolean;
188
+ status: string;
189
+ }>;
190
+ /** Build-config + env-key diff against the previous deployment. */
191
+ configDiff: (serviceId: number, deploymentId: number) => Promise<{
192
+ deploymentId: number;
193
+ previousDeploymentId: number | null;
194
+ changed: boolean;
195
+ diff: string;
196
+ }>;
197
+ };
198
+ domains: {
199
+ list: (serviceId: number) => Promise<Domain[]>;
200
+ create: (serviceId: number, input: CreateDomainInput) => Promise<Domain>;
201
+ remove: (serviceId: number, domainId: number) => Promise<void>;
202
+ /** Update routing extras: ssl toggle, www→apex redirect, custom headers, basicAuth, ipAllowlist, rateLimit. */
203
+ update: (serviceId: number, domainId: number, input: DomainPatch) => Promise<Domain>;
204
+ all: () => Promise<DomainEntry[]>;
205
+ setSsl: (domainId: number, ssl: boolean) => Promise<{
206
+ id: number;
207
+ ssl: boolean;
208
+ }>;
209
+ };
210
+ volumes: {
211
+ list: () => Promise<VolumeEntry[]>;
212
+ remove: (name: string) => Promise<void>;
213
+ prune: () => Promise<{
214
+ ok: boolean;
215
+ deleted: number;
216
+ freedBytes: number;
217
+ }>;
218
+ /** File manager: list a directory inside the volume. */
219
+ listFiles: (name: string, path?: string) => Promise<{
220
+ path: string;
221
+ entries: VolumeFileEntry[];
222
+ }>;
223
+ /** File manager: read a file (base64 content). */
224
+ readFile: (name: string, path: string) => Promise<{
225
+ content: string;
226
+ encoding: 'utf8' | 'base64';
227
+ }>;
228
+ /** File manager: write/overwrite a file (base64 content). */
229
+ writeFile: (name: string, input: VolumeFileWriteInput) => Promise<{
230
+ ok: boolean;
231
+ }>;
232
+ /** File manager: create a directory. */
233
+ mkdir: (name: string, input: VolumePathCreateInput) => Promise<{
234
+ ok: boolean;
235
+ }>;
236
+ /** File manager: delete a file or directory (recursive). */
237
+ deleteFile: (name: string, path: string) => Promise<void>;
238
+ };
239
+ containers: {
240
+ inspect: (container: string) => Promise<ContainerInspectData>;
241
+ compose: (container: string) => Promise<ContainerComposeData>;
242
+ /** File manager: list a directory inside the container. */
243
+ listFiles: (container: string, path?: string) => Promise<{
244
+ path: string;
245
+ entries: VolumeFileEntry[];
246
+ }>;
247
+ /** File manager: read a file (base64 content). */
248
+ readFile: (container: string, path: string) => Promise<{
249
+ content: string;
250
+ encoding: 'utf8' | 'base64';
251
+ }>;
252
+ /** File manager: write/overwrite a file (base64 content). */
253
+ writeFile: (container: string, input: VolumeFileWriteInput) => Promise<{
254
+ ok: boolean;
255
+ }>;
256
+ /** File manager: create a directory. */
257
+ mkdir: (container: string, input: VolumePathCreateInput) => Promise<{
258
+ ok: boolean;
259
+ }>;
260
+ makeDir: (container: string, input: VolumePathCreateInput) => Promise<{
261
+ ok: boolean;
262
+ }>;
263
+ /** File manager: delete a file or directory (recursive). */
264
+ deleteFile: (container: string, path: string) => Promise<void>;
265
+ deletePath: (container: string, path: string) => Promise<void>;
266
+ };
267
+ system: {
268
+ resources: () => Promise<DockerResources>;
269
+ pruneImages: () => Promise<{
270
+ ok: boolean;
271
+ }>;
272
+ exportUrl: () => string;
273
+ /** Latest-release check (admin). updateAvailable is null when offline/disabled. */
274
+ updateCheck: (force?: boolean) => Promise<UpdateCheckResult>;
275
+ /** Recent docker daemon events (single-shot, for the Docker dashboard feed). */
276
+ dockerEvents: (minutes?: number) => Promise<{
277
+ events: Array<{
278
+ time: string;
279
+ type: string;
280
+ action: string;
281
+ name: string;
282
+ }>;
283
+ }>;
284
+ };
285
+ networks: {
286
+ list: () => Promise<{
287
+ networks: Array<{
288
+ name: string;
289
+ driver: string;
290
+ members: string[];
291
+ }>;
292
+ remote: number | null;
293
+ }>;
294
+ create: (input: {
295
+ name: string;
296
+ driver?: 'bridge' | 'overlay';
297
+ serverId?: number | null;
298
+ }) => Promise<{
299
+ ok: boolean;
300
+ name: string;
301
+ }>;
302
+ remove: (name: string, serverId?: number) => Promise<{
303
+ ok: boolean;
304
+ }>;
305
+ attach: (input: {
306
+ network: string;
307
+ container: string;
308
+ serverId?: number | null;
309
+ }) => Promise<{
310
+ ok: boolean;
311
+ }>;
312
+ detach: (input: {
313
+ network: string;
314
+ container: string;
315
+ serverId?: number | null;
316
+ }) => Promise<{
317
+ ok: boolean;
318
+ }>;
319
+ };
320
+ tunnels: {
321
+ list: () => Promise<TunnelEntry[]>;
322
+ create: (input: CreateTunnelInput) => Promise<TunnelEntry>;
323
+ remove: (id: number) => Promise<void>;
324
+ };
325
+ activity: {
326
+ /** Filter + paginate the audit trail. Omitted filters return the newest page. */
327
+ list: (query?: {
328
+ entity?: string;
329
+ action?: string;
330
+ userId?: number;
331
+ before?: number;
332
+ }) => Promise<{
333
+ entries: ActivityEntry[];
334
+ nextCursor: number | null;
335
+ }>;
336
+ };
337
+ alerts: {
338
+ list: () => Promise<AlertRule[]>;
339
+ create: (input: CreateAlertRuleInput) => Promise<AlertRule>;
340
+ update: (id: number, input: Partial<CreateAlertRuleInput>) => Promise<AlertRule>;
341
+ remove: (id: number) => Promise<void>;
342
+ };
343
+ settings: {
344
+ get: () => Promise<{
345
+ allowRegistration: boolean;
346
+ acmeEmail: string | null;
347
+ templatesSource: string | null;
348
+ dnsProvider: string | null;
349
+ hasDnsToken: boolean;
350
+ wildcardApex: string | null;
351
+ }>;
352
+ setAllowRegistration: (enabled: boolean) => Promise<{
353
+ ok: boolean;
354
+ allowRegistration: boolean;
355
+ }>;
356
+ setAcmeEmail: (email: string) => Promise<{
357
+ ok: boolean;
358
+ acmeEmail: string | null;
359
+ applied: string;
360
+ }>;
361
+ setTemplatesSource: (source: string) => Promise<{
362
+ ok: boolean;
363
+ templatesSource: string | null;
364
+ }>;
365
+ /** Configure the ACME DNS-01 challenge (wildcard certificates). */
366
+ setDns: (input: {
367
+ provider: string;
368
+ token?: string;
369
+ wildcardApex: string;
370
+ }) => Promise<{
371
+ ok: boolean;
372
+ dnsProvider: string | null;
373
+ wildcardApex: string | null;
374
+ applied: string;
375
+ }>;
376
+ /** Vault provider (deploy-time secret resolution). */
377
+ vault: {
378
+ get: () => Promise<{
379
+ provider: string | null;
380
+ hasToken: boolean;
381
+ projectId: string | null;
382
+ environment: string | null;
383
+ }>;
384
+ set: (input: {
385
+ provider: '' | 'infisical' | 'doppler';
386
+ token?: string;
387
+ projectId?: string;
388
+ environment?: string;
389
+ }) => Promise<{
390
+ ok: boolean;
391
+ provider: string | null;
392
+ }>;
393
+ test: () => Promise<{
394
+ ok: boolean;
395
+ secrets: number;
396
+ }>;
397
+ };
398
+ /** Cloudflare DNS-record auto-provisioning for added domains. */
399
+ dnsRecords: {
400
+ get: () => Promise<{
401
+ enabled: boolean;
402
+ hasToken: boolean;
403
+ content: string | null;
404
+ }>;
405
+ set: (input: {
406
+ enabled: boolean;
407
+ token?: string;
408
+ content?: string;
409
+ }) => Promise<{
410
+ ok: boolean;
411
+ enabled: boolean;
412
+ }>;
413
+ test: () => Promise<{
414
+ ok: boolean;
415
+ status?: string;
416
+ error?: string;
417
+ }>;
418
+ };
419
+ };
420
+ users: {
421
+ list: () => Promise<PublicUser[]>;
422
+ /** Admin-only: create a user directly (no registration flow needed). */
423
+ create: (input: UserCreate) => Promise<PublicUser>;
424
+ setRole: (id: number, role: 'admin' | 'member') => Promise<PublicUser>;
425
+ remove: (id: number) => Promise<void>;
426
+ /** Admin reset of another user's password (revokes their sessions). */
427
+ resetPassword: (id: number, input: PasswordReset) => Promise<{
428
+ ok: boolean;
429
+ }>;
430
+ /** Mint a one-time reset link for a user (returned exactly once). */
431
+ resetLink: (id: number) => Promise<{
432
+ url: string;
433
+ expiresAt: string;
434
+ }>;
435
+ };
436
+ projects: {
437
+ list: () => Promise<ProjectEntry[]>;
438
+ create: (input: CreateProjectInput) => Promise<ProjectEntry>;
439
+ update: (id: number, input: ProjectPatchInput) => Promise<ProjectEntry>;
440
+ remove: (id: number) => Promise<{
441
+ ok: boolean;
442
+ }>;
443
+ };
444
+ about: {
445
+ get: () => Promise<{
446
+ name: string;
447
+ version: string;
448
+ description: string;
449
+ license: string;
450
+ repo: string;
451
+ docs: string;
452
+ techStack: Array<{
453
+ category: string;
454
+ items: string[];
455
+ }>;
456
+ changelog: Array<{
457
+ version: string;
458
+ date: string;
459
+ title: string;
460
+ changes: string[];
461
+ }>;
462
+ /** Instance counts are only returned for authenticated requests. */
463
+ stats?: {
464
+ services: number;
465
+ databases: number;
466
+ deployments: number;
467
+ users: number;
468
+ };
469
+ }>;
470
+ };
471
+ notifications: {
472
+ listChannels: () => Promise<Array<{
473
+ id: number;
474
+ name: string;
475
+ type: string;
476
+ eventFilter: string;
477
+ active: boolean;
478
+ createdAt: string;
479
+ }>>;
480
+ createChannel: (input: {
481
+ name: string;
482
+ type: string;
483
+ target: string;
484
+ eventFilter?: string;
485
+ }) => Promise<{
486
+ id: number;
487
+ name: string;
488
+ type: string;
489
+ }>;
490
+ updateChannel: (id: number, input: {
491
+ name?: string;
492
+ target?: string;
493
+ eventFilter?: string;
494
+ active?: boolean;
495
+ }) => Promise<{
496
+ id: number;
497
+ active: boolean;
498
+ }>;
499
+ removeChannel: (id: number) => Promise<void>;
500
+ testChannel: (id: number) => Promise<{
501
+ ok: boolean;
502
+ }>;
503
+ log: () => Promise<Array<{
504
+ id: number;
505
+ channelId: number | null;
506
+ event: string;
507
+ entity: string | null;
508
+ status: string;
509
+ error: string | null;
510
+ ts: string;
511
+ }>>;
512
+ };
513
+ sources: {
514
+ list: () => Promise<Source[]>;
515
+ create: (input: CreateSourceInput) => Promise<Source>;
516
+ update: (id: number, input: Partial<CreateSourceInput>) => Promise<Source>;
517
+ remove: (id: number) => Promise<void>;
518
+ repos: (id: number) => Promise<Array<{
519
+ name: string;
520
+ fullName: string;
521
+ url: string;
522
+ defaultBranch: string;
523
+ isPrivate: boolean;
524
+ }>>;
525
+ branches: (id: number, repo: string) => Promise<string[]>;
526
+ };
527
+ webhooks: {
528
+ list: (serviceId: number) => Promise<Webhook[]>;
529
+ create: (serviceId: number, input?: CreateWebhookInput) => Promise<CreatedWebhook>;
530
+ remove: (serviceId: number, hookId: number) => Promise<void>;
531
+ };
532
+ databases: {
533
+ /** `query` is appended verbatim, e.g. `?projectId=3` (project scoping). */
534
+ list: (query?: string) => Promise<ManagedDatabase[]>;
535
+ create: (input: CreateDatabaseInput) => Promise<ManagedDatabase>;
536
+ get: (id: number) => Promise<DatabaseDetail>;
537
+ remove: (id: number, options?: {
538
+ force?: boolean;
539
+ }) => Promise<void>;
540
+ restart: (id: number) => Promise<void>;
541
+ stop: (id: number) => Promise<void>;
542
+ start: (id: number) => Promise<void>;
543
+ logs: (id: number, lines?: number) => Promise<{
544
+ logs: string[];
545
+ }>;
546
+ credentials: (id: number) => Promise<DatabaseCredentials>;
547
+ setLimits: (id: number, input: SetLimitsInput) => Promise<{
548
+ cpuShares: number | null;
549
+ memLimitMb: number | null;
550
+ }>;
551
+ startStudio: (id: number, port?: number) => Promise<{
552
+ ok: boolean;
553
+ port: number;
554
+ url: string;
555
+ }>;
556
+ stopStudio: (id: number) => Promise<{
557
+ ok: boolean;
558
+ }>;
559
+ };
560
+ attachments: {
561
+ list: (serviceId: number) => Promise<Attachment[]>;
562
+ create: (serviceId: number, input: {
563
+ databaseId: number;
564
+ envAlias?: string;
565
+ }) => Promise<Attachment>;
566
+ remove: (serviceId: number, attachmentId: number) => Promise<void>;
567
+ };
568
+ env: {
569
+ list: (serviceId: number) => Promise<EnvVar[]>;
570
+ create: (serviceId: number, input: UpsertEnvVarInput) => Promise<EnvVar>;
571
+ update: (serviceId: number, varId: number, input: UpsertEnvVarInput) => Promise<EnvVar>;
572
+ remove: (serviceId: number, varId: number) => Promise<void>;
573
+ /** Cross-scope key search: where a given env key is defined. */
574
+ search: (q: string) => Promise<{
575
+ results: Array<{
576
+ key: string;
577
+ isSecret: boolean;
578
+ scope: string;
579
+ serviceId: number | null;
580
+ serviceName: string | null;
581
+ }>;
582
+ }>;
583
+ };
584
+ projectEnv: {
585
+ /** Shared env vars applied to every service in a project (service env wins). */
586
+ list: (projectId: number) => Promise<EnvVar[]>;
587
+ create: (projectId: number, input: UpsertEnvVarInput) => Promise<EnvVar>;
588
+ update: (projectId: number, varId: number, input: UpsertEnvVarInput) => Promise<EnvVar>;
589
+ remove: (projectId: number, varId: number) => Promise<void>;
590
+ };
591
+ stats: {
592
+ snapshot: () => Promise<StatsSnapshot>;
593
+ metrics: (serviceId: number, opts?: {
594
+ kind?: 'cpu' | 'memory';
595
+ minutes?: number;
596
+ }) => Promise<MetricSeries>;
597
+ };
598
+ dashboard: {
599
+ get: () => Promise<{
600
+ stats: {
601
+ services: number;
602
+ databases: number;
603
+ deployments: number;
604
+ domains: number;
605
+ webhooks: number;
606
+ running: number;
607
+ stopped: number;
608
+ errored: number;
609
+ dbRunning: number;
610
+ containers: number;
611
+ };
612
+ health: Array<{
613
+ serviceId: number;
614
+ name: string;
615
+ slug: string;
616
+ type: string;
617
+ status: string;
618
+ healthy: boolean;
619
+ responseMs: number | null;
620
+ port: number | null;
621
+ runtimeId: string | null;
622
+ commitSha: string | null;
623
+ lastDeploy: string | null;
624
+ }>;
625
+ recentDeploys: Array<{
626
+ id: number;
627
+ serviceId: number;
628
+ serviceName: string;
629
+ status: string;
630
+ commitSha: string | null;
631
+ message: string | null;
632
+ trigger: string;
633
+ finishedAt: string | null;
634
+ createdAt: string;
635
+ }>;
636
+ }>;
637
+ };
638
+ topology: {
639
+ get: () => Promise<TopologyGraph>;
640
+ };
641
+ backups: {
642
+ storage: (databaseId: number) => Promise<{
643
+ sizeBytes: number;
644
+ }>;
645
+ backupNow: (databaseId: number) => Promise<Backup>;
646
+ listForDb: (databaseId: number) => Promise<Backup[]>;
647
+ restore: (databaseId: number, backupId: number) => Promise<{
648
+ ok: boolean;
649
+ }>;
650
+ list: () => Promise<BackupWithDb[]>;
651
+ remove: (backupId: number) => Promise<void>;
652
+ downloadUrl: (backupId: number) => string;
653
+ };
654
+ backupDestinations: {
655
+ list: () => Promise<Array<{
656
+ id: number;
657
+ name: string;
658
+ endpoint: string;
659
+ region: string;
660
+ bucket: string;
661
+ prefix: string;
662
+ active: boolean;
663
+ createdAt: string;
664
+ }>>;
665
+ create: (input: {
666
+ name: string;
667
+ endpoint: string;
668
+ region?: string;
669
+ bucket: string;
670
+ prefix?: string;
671
+ accessKeyId: string;
672
+ secretAccessKey: string;
673
+ }) => Promise<{
674
+ id: number;
675
+ }>;
676
+ update: (id: number, input: Partial<{
677
+ name: string;
678
+ endpoint: string;
679
+ region: string;
680
+ bucket: string;
681
+ prefix: string;
682
+ active: boolean;
683
+ accessKeyId: string;
684
+ secretAccessKey: string;
685
+ }>) => Promise<{
686
+ ok: boolean;
687
+ }>;
688
+ remove: (id: number) => Promise<{
689
+ ok: boolean;
690
+ }>;
691
+ test: (id: number) => Promise<{
692
+ ok: boolean;
693
+ }>;
694
+ };
695
+ jobs: {
696
+ list: (serviceId: number) => Promise<Array<{
697
+ id: number;
698
+ name: string;
699
+ cron: string;
700
+ kind: 'deploy' | 'exec';
701
+ command: string;
702
+ enabled: boolean;
703
+ lastRunAt: string | null;
704
+ }>>;
705
+ create: (serviceId: number, input: {
706
+ name: string;
707
+ cron: string;
708
+ kind: 'deploy' | 'exec';
709
+ command?: string;
710
+ enabled?: boolean;
711
+ }) => Promise<{
712
+ id: number;
713
+ }>;
714
+ update: (serviceId: number, jobId: number, input: Partial<{
715
+ name: string;
716
+ cron: string;
717
+ kind: 'deploy' | 'exec';
718
+ command: string;
719
+ enabled: boolean;
720
+ }>) => Promise<{
721
+ ok: boolean;
722
+ }>;
723
+ remove: (serviceId: number, jobId: number) => Promise<{
724
+ ok: boolean;
725
+ }>;
726
+ run: (serviceId: number, jobId: number) => Promise<{
727
+ ok: boolean;
728
+ }>;
729
+ runs: (serviceId: number, jobId: number) => Promise<Array<{
730
+ id: number;
731
+ status: string;
732
+ output: string;
733
+ exitCode: number | null;
734
+ createdAt: string;
735
+ }>>;
736
+ };
737
+ servers: {
738
+ list: () => Promise<Array<{
739
+ id: number;
740
+ name: string;
741
+ host: string;
742
+ port: number;
743
+ status: string;
744
+ lastSeenAt: string | null;
745
+ }>>;
746
+ /** Register a server — the agent token + its sha256 are returned exactly once. */
747
+ create: (input: {
748
+ name: string;
749
+ host: string;
750
+ port?: number;
751
+ }) => Promise<{
752
+ id: number;
753
+ token: string;
754
+ tokenSha256: string;
755
+ agentCommand: string;
756
+ }>;
757
+ remove: (id: number, options?: {
758
+ force?: boolean;
759
+ }) => Promise<{
760
+ ok: boolean;
761
+ }>;
762
+ test: (id: number) => Promise<{
763
+ ok: boolean;
764
+ status: string;
765
+ }>;
766
+ approve: (id: number) => Promise<{
767
+ ok: boolean;
768
+ status: string;
769
+ }>;
770
+ reject: (id: number) => Promise<{
771
+ ok: boolean;
772
+ }>;
773
+ sshTest: (input: ServerSshTest) => Promise<ServerSshTestResult>;
774
+ sshBootstrap: (input: ServerSshBootstrap) => Promise<ServerBootstrapResult>;
775
+ bootstrapLogs: (id: number) => Promise<{
776
+ logs: string[];
777
+ }>;
778
+ };
779
+ templates: {
780
+ list: () => Promise<TemplateSummary[]>;
781
+ get: (id: string) => Promise<Template>;
782
+ deploy: (id: string) => Promise<{
783
+ serviceId: number;
784
+ deploymentId: number;
785
+ }>;
786
+ };
787
+ limits: {
788
+ setService: (serviceId: number, input: SetLimitsInput) => Promise<{
789
+ cpuShares: number;
790
+ memLimitMb: number;
791
+ }>;
792
+ setDatabase: (databaseId: number, input: SetLimitsInput) => Promise<{
793
+ cpuShares: number;
794
+ memLimitMb: number;
795
+ }>;
796
+ };
797
+ traefik: {
798
+ get: () => Promise<TraefikInfo>;
799
+ status: () => Promise<TraefikStatus>;
800
+ certificates: () => Promise<TraefikCertificate[]>;
801
+ logs: (lines?: number) => Promise<{
802
+ logs: string[];
803
+ }>;
804
+ restart: () => Promise<{
805
+ ok: boolean;
806
+ message?: string;
807
+ }>;
808
+ backupCerts: () => Promise<{
809
+ ok: boolean;
810
+ message?: string;
811
+ filename?: string;
812
+ }>;
813
+ };
814
+ config: {
815
+ list: (query?: {
816
+ category?: string;
817
+ pluginId?: string;
818
+ reveal?: boolean;
819
+ }) => Promise<ConfigListResponse>;
820
+ get: (key: string) => Promise<ConfigItem>;
821
+ set: (key: string, input: SetConfigInput) => Promise<{
822
+ ok: boolean;
823
+ key: string;
824
+ }>;
825
+ delete: (key: string) => Promise<{
826
+ ok: boolean;
827
+ key: string;
828
+ }>;
829
+ };
830
+ plugins: {
831
+ list: () => Promise<PluginListResponse>;
832
+ marketplace: () => Promise<MarketplaceCatalogResponse>;
833
+ install: (input: InstallPluginInput) => Promise<{
834
+ ok: boolean;
835
+ id: string;
836
+ status: string;
837
+ }>;
838
+ enable: (id: string) => Promise<{
839
+ ok: boolean;
840
+ id: string;
841
+ status: string;
842
+ }>;
843
+ disable: (id: string) => Promise<{
844
+ ok: boolean;
845
+ id: string;
846
+ status: string;
847
+ }>;
848
+ reload: (id: string) => Promise<{
849
+ ok: boolean;
850
+ id: string;
851
+ status: string;
852
+ }>;
853
+ inspect: (id: string) => Promise<PluginInspectResponse>;
854
+ uninstall: (id: string) => Promise<{
855
+ ok: boolean;
856
+ id: string;
857
+ }>;
858
+ };
859
+ menus: {
860
+ list: (query?: {
861
+ slot?: string;
862
+ }) => Promise<MenuListResponse>;
863
+ };
864
+ demo: {
865
+ seed: () => Promise<DemoSeedResult>;
866
+ };
867
+ logDrains: {
868
+ list: (query?: {
869
+ serviceId?: number;
870
+ }) => Promise<LogDrain[]>;
871
+ get: (id: number) => Promise<LogDrain>;
872
+ create: (input: LogDrainCreateInput) => Promise<LogDrain>;
873
+ update: (id: number, input: LogDrainUpdateInput) => Promise<LogDrain>;
874
+ remove: (id: number) => Promise<{
875
+ ok: boolean;
876
+ }>;
877
+ test: (id: number) => Promise<LogDrainTestResult>;
878
+ };
879
+ housekeeping: {
880
+ getAutoPrune: () => Promise<AutoPruneStatus>;
881
+ updateAutoPrune: (input: AutoPruneConfigUpdateInput) => Promise<AutoPruneStatus>;
882
+ runPrune: () => Promise<AutoPruneRunResult>;
883
+ };
884
+ health: () => Promise<HealthStatus>;
885
+ }
886
+ export interface ContainerInspectData {
887
+ id: string;
888
+ name: string;
889
+ image: string;
890
+ state: {
891
+ status: string;
892
+ running: boolean;
893
+ startedAt: string;
894
+ finishedAt: string;
895
+ exitCode: number;
896
+ error: string;
897
+ };
898
+ labels: Record<string, string>;
899
+ traefikTags: Record<string, string>;
900
+ env: string[];
901
+ ports: Record<string, unknown>;
902
+ mounts: Array<{
903
+ source: string;
904
+ destination: string;
905
+ mode: string;
906
+ rw: boolean;
907
+ }>;
908
+ networks: string[];
909
+ resources: {
910
+ memoryLimitBytes: number;
911
+ cpuShares: number;
912
+ restartPolicy: string;
913
+ };
914
+ raw: unknown;
915
+ }
916
+ export interface ContainerComposeData {
917
+ yaml: string;
918
+ inspect: ContainerInspectData;
919
+ }
920
+ /**
921
+ * Create a typed NineDeploy API client. Used by both the web dashboard and the CLI.
922
+ *
923
+ * @example
924
+ * const client = createClient({ baseUrl: 'http://localhost:3000', getToken: () => token });
925
+ * const services = await client.services.list();
926
+ */
927
+ export declare function createClient(opts: NineDeployClientOptions): NineDeployClient;
928
+ //# sourceMappingURL=index.d.ts.map