@ninedeploy/sdk 0.10.5 → 0.16.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.
Files changed (129) hide show
  1. package/LICENSE +21 -21
  2. package/dist/apiPath.d.ts +5 -0
  3. package/dist/apiPath.d.ts.map +1 -0
  4. package/dist/apiPath.js +18 -0
  5. package/dist/apiPath.js.map +1 -0
  6. package/dist/client.d.ts +29 -0
  7. package/dist/client.d.ts.map +1 -0
  8. package/dist/client.js +51 -0
  9. package/dist/client.js.map +1 -0
  10. package/dist/databaseImport.d.ts +138 -0
  11. package/dist/databaseImport.d.ts.map +1 -0
  12. package/dist/databaseImport.js +126 -0
  13. package/dist/databaseImport.js.map +1 -0
  14. package/dist/errors.js +1 -1
  15. package/dist/errors.js.map +1 -1
  16. package/dist/index.d.ts +12 -1973
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +9 -641
  19. package/dist/index.js.map +1 -1
  20. package/dist/manifest.d.ts.map +1 -1
  21. package/dist/manifest.js +25 -21
  22. package/dist/manifest.js.map +1 -1
  23. package/dist/resources/auth.d.ts +282 -0
  24. package/dist/resources/auth.d.ts.map +1 -0
  25. package/dist/resources/auth.js +111 -0
  26. package/dist/resources/auth.js.map +1 -0
  27. package/dist/resources/databases.d.ts +178 -0
  28. package/dist/resources/databases.d.ts.map +1 -0
  29. package/dist/resources/databases.js +82 -0
  30. package/dist/resources/databases.js.map +1 -0
  31. package/dist/resources/deploys.d.ts +125 -0
  32. package/dist/resources/deploys.d.ts.map +1 -0
  33. package/dist/resources/deploys.js +46 -0
  34. package/dist/resources/deploys.js.map +1 -0
  35. package/dist/resources/domains.d.ts +101 -0
  36. package/dist/resources/domains.d.ts.map +1 -0
  37. package/dist/resources/domains.js +28 -0
  38. package/dist/resources/domains.js.map +1 -0
  39. package/dist/resources/env.d.ts +55 -0
  40. package/dist/resources/env.d.ts.map +1 -0
  41. package/dist/resources/env.js +33 -0
  42. package/dist/resources/env.js.map +1 -0
  43. package/dist/resources/logs.d.ts +27 -0
  44. package/dist/resources/logs.d.ts.map +1 -0
  45. package/dist/resources/logs.js +18 -0
  46. package/dist/resources/logs.js.map +1 -0
  47. package/dist/resources/network.d.ts +134 -0
  48. package/dist/resources/network.d.ts.map +1 -0
  49. package/dist/resources/network.js +33 -0
  50. package/dist/resources/network.js.map +1 -0
  51. package/dist/resources/plugins.d.ts +42 -0
  52. package/dist/resources/plugins.d.ts.map +1 -0
  53. package/dist/resources/plugins.js +22 -0
  54. package/dist/resources/plugins.js.map +1 -0
  55. package/dist/resources/servers.d.ts +130 -0
  56. package/dist/resources/servers.d.ts.map +1 -0
  57. package/dist/resources/servers.js +37 -0
  58. package/dist/resources/servers.js.map +1 -0
  59. package/dist/resources/services.d.ts +185 -0
  60. package/dist/resources/services.d.ts.map +1 -0
  61. package/dist/resources/services.js +83 -0
  62. package/dist/resources/services.js.map +1 -0
  63. package/dist/resources/settings.d.ts +312 -0
  64. package/dist/resources/settings.d.ts.map +1 -0
  65. package/dist/resources/settings.js +85 -0
  66. package/dist/resources/settings.js.map +1 -0
  67. package/dist/resources/sources.d.ts +87 -0
  68. package/dist/resources/sources.d.ts.map +1 -0
  69. package/dist/resources/sources.js +39 -0
  70. package/dist/resources/sources.js.map +1 -0
  71. package/dist/resources/system.d.ts +240 -0
  72. package/dist/resources/system.d.ts.map +1 -0
  73. package/dist/resources/system.js +86 -0
  74. package/dist/resources/system.js.map +1 -0
  75. package/dist/resources/templates.d.ts +36 -0
  76. package/dist/resources/templates.d.ts.map +1 -0
  77. package/dist/resources/templates.js +17 -0
  78. package/dist/resources/templates.js.map +1 -0
  79. package/dist/resources/terminals.d.ts +60 -0
  80. package/dist/resources/terminals.d.ts.map +1 -0
  81. package/dist/resources/terminals.js +35 -0
  82. package/dist/resources/terminals.js.map +1 -0
  83. package/dist/resources/traefik.d.ts +84 -0
  84. package/dist/resources/traefik.d.ts.map +1 -0
  85. package/dist/resources/traefik.js +35 -0
  86. package/dist/resources/traefik.js.map +1 -0
  87. package/dist/resources/volumes.d.ts +114 -0
  88. package/dist/resources/volumes.d.ts.map +1 -0
  89. package/dist/resources/volumes.js +47 -0
  90. package/dist/resources/volumes.js.map +1 -0
  91. package/dist/terminal.d.ts +98 -0
  92. package/dist/terminal.d.ts.map +1 -0
  93. package/dist/terminal.js +180 -0
  94. package/dist/terminal.js.map +1 -0
  95. package/dist/transport.d.ts +61 -0
  96. package/dist/transport.d.ts.map +1 -0
  97. package/dist/transport.js +90 -0
  98. package/dist/transport.js.map +1 -0
  99. package/dist/types.d.ts +539 -0
  100. package/dist/types.d.ts.map +1 -0
  101. package/dist/types.js +5 -0
  102. package/dist/types.js.map +1 -0
  103. package/package.json +5 -4
  104. package/src/apiPath.ts +23 -0
  105. package/src/client.ts +70 -0
  106. package/src/databaseImport.ts +174 -0
  107. package/src/errors.ts +27 -0
  108. package/src/index.ts +118 -0
  109. package/src/manifest.ts +414 -0
  110. package/src/resources/auth.ts +357 -0
  111. package/src/resources/databases.ts +227 -0
  112. package/src/resources/deploys.ts +161 -0
  113. package/src/resources/domains.ts +142 -0
  114. package/src/resources/env.ts +84 -0
  115. package/src/resources/logs.ts +48 -0
  116. package/src/resources/network.ts +126 -0
  117. package/src/resources/plugins.ts +52 -0
  118. package/src/resources/servers.ts +141 -0
  119. package/src/resources/services.ts +250 -0
  120. package/src/resources/settings.ts +275 -0
  121. package/src/resources/sources.ts +131 -0
  122. package/src/resources/system.ts +281 -0
  123. package/src/resources/templates.ts +55 -0
  124. package/src/resources/terminals.ts +112 -0
  125. package/src/resources/traefik.ts +116 -0
  126. package/src/resources/volumes.ts +138 -0
  127. package/src/terminal.ts +254 -0
  128. package/src/transport.ts +154 -0
  129. package/src/types.ts +588 -0
package/dist/index.d.ts CHANGED
@@ -1,1977 +1,16 @@
1
- import type { ActiveSession, ActivityEntry, AlertRule, AnalyzeRepoInput, CreateAlertRuleInput, ApiToken, PasskeyCredential, Attachment, CreateServiceVolumeAttachmentInput, CreateVolumeBackupInput, ServiceVolumeAttachment, UpdateServiceVolumeAttachmentInput, Backup, BackupWithDb, ComposePreviewRequestInput, ComposePreviewResponse, CreateApiTokenInput, CreateDatabaseInput, CreateDomainInput, CreateProjectInput, CreateServiceInput, CreateSourceInput, CreateTunnelInput, CreateWebhookInput, CreatedApiToken, CreatedWebhook, ConfigItem, ConfigListResponse, SetConfigInput, DoctorFixRequestInput, DoctorFixResponse, DoctorReport, PluginListResponse, PluginInspectResponse, InstallPluginInput, MarketplaceCatalogResponse, MenuListResponse, DemoSeedResult, Deployment, QueueResponse, DeployTemplateInput, DockerResources, Domain, DomainPatch, DomainEntry, EnvVar, Label, CreateLabelInput, LabelPatchInput, Environment, EnvironmentCreateInput, AiConfigStatus, AiConfigUpdate, Login, ManagedDatabase, DatabaseDetail, DatabaseCredentials, PasswordChange, PasswordReset, MetricSeries, ProjectEntry, ProjectPatchInput, PublicUser, Refresh, Register, RepoInsights, Service, ServiceTags, SetServiceTagsInput, Session, SetLimitsInput, Source, StatsSnapshot, Template, TemplateSummary, CommunityTemplateListResult, TopologyGraph, TraefikCertificate, CertificateInventoryEntry, CertificateInventoryReport, TraefikInfo, TraefikStatus, TunnelEntry, UserCreate, VolumeFileEntry, VolumeFileWriteInput, VolumePathCreateInput, TriggerDeploy, UpdateCheckResult, SelfUpdateStatus, UpdateServiceInput, UpsertEnvVarInput, VolumeEntry, Webhook, LogDrain, LogDrainCreateInput, LogDrainUpdateInput, LogDrainTestResult, AutoPruneConfigUpdateInput, AutoPruneStatus, AutoPruneRunResult, ServerSshTest, ServerSshTestResult, ServerSshBootstrap, ServerBootstrapResult, WorkspaceEntry, WorkspaceDetail, WorkspaceCreateInput, WorkspaceUpdateInput, WorkspaceMemberEntry, WorkspaceMemberInviteEntry, WorkspaceMemberAddInput, WorkspaceMemberRoleUpdateInput, OidcPublicProvider, NinedeployManifest, WorkspaceInvitationEntry, WorkspaceInvitationPublic, WorkspaceRole, OidcProviderEntry, OidcProviderCreateInput, OidcProviderUpdateInput } from '@ninedeploy/schemas';
2
- import { NineDeployError } from './errors.js';
3
- export { NineDeployError };
1
+ export { NineDeployError } from './errors.js';
4
2
  export type * from '@ninedeploy/schemas';
5
3
  export { detectProjectKind, formatManifestYaml, ManifestParseError, ManifestValidationError, parseManifestYaml, starterManifest, buildManifestFromTemplate, } from './manifest.js';
6
4
  export type { ProjectKind, TemplateRegistryEntry } from './manifest.js';
7
- /**
8
- * Minimal structural fetch type so the SDK is isomorphic (browser + Node)
9
- * without pulling in DOM lib types. Both `globalThis.fetch` implementations
10
- * satisfy this shape.
11
- */
12
- export type FetchLike = (input: string, init: {
13
- method?: string;
14
- headers?: Record<string, string>;
15
- body?: string;
16
- credentials?: 'omit' | 'same-origin' | 'include';
17
- }) => Promise<{
18
- ok: boolean;
19
- status: number;
20
- text(): Promise<string>;
21
- }>;
22
- export interface HealthStatus {
23
- status: string;
24
- db?: string;
25
- version?: string;
26
- time?: string;
27
- }
28
- /**
29
- * Result of `GET /v1/auth/token`. Tells the caller what
30
- * the current bearer credential is and what it can do.
31
- * `kind` is `'session'` for JWTs and `'api'` for opaque
32
- * API tokens. `scopes` lists the resource-scoped
33
- * authorities (or the legacy `read` / `write` / `operator`
34
- * shorthand); an interactive session reports
35
- * `['session']` which is implicit full authority.
36
- */
37
- export interface TokenIntrospection {
38
- kind: 'session' | 'api';
39
- userId: number;
40
- scopes: string[];
41
- expiresAt: string | null;
42
- isOperator: boolean;
43
- /** API tokens only. */
44
- tokenId?: number;
45
- name?: string;
46
- }
47
- export interface TemplateDeployResult {
48
- serviceId: number;
49
- serviceName: string;
50
- serviceSlug: string;
51
- deploymentId: number;
52
- databaseId: number | null;
53
- generatedSecrets: Array<{
54
- key: string;
55
- value: string;
56
- }>;
57
- stages: Array<{
58
- id: 'service' | 'environment' | 'database' | 'attachment' | 'deployment';
59
- status: 'success' | 'skipped';
60
- message: string;
61
- }>;
62
- alreadyInProgress: boolean;
63
- }
64
- export interface TemplatePrepareResult {
65
- serviceId: number;
66
- serviceName: string;
67
- serviceSlug: string;
68
- deploymentId: number;
69
- generatedSecrets: Array<{
70
- key: string;
71
- value: string;
72
- }>;
73
- stages: TemplateDeployResult['stages'];
74
- }
75
- /**
76
- * Response from `services.manifest.apply`. The server returns the
77
- * subset of fields the manifest actually changed under each
78
- * section; untouched fields stay in the panel-managed column
79
- * and do not appear in `diff`.
80
- */
81
- export interface ApplyManifestResult {
82
- ok: boolean;
83
- serviceId: number;
84
- /** Sections the server actually wrote: `service`, `build_config`. */
85
- touched: string[];
86
- diff: {
87
- service: {
88
- port?: number;
89
- healthPath?: string;
90
- publishedPort?: number | null;
91
- };
92
- build: {
93
- installCmd?: string;
94
- buildCmd?: string;
95
- startCmd?: string;
96
- baseDir?: string;
97
- dockerfilePath?: string | null;
98
- restartPolicy?: string;
99
- stopGraceSeconds?: number;
100
- };
101
- };
102
- }
103
- /** Body for `services.manifest.apply`. The manifest shape itself
104
- * comes from `@ninedeploy/schemas`'s `ninedeployManifest` parser. */
105
- export interface ApplyManifestInput {
106
- manifest: NinedeployManifest;
107
- /** `merge` (default) preserves fields the manifest omits;
108
- * `replace` is per-field (not per-row) and still leaves
109
- * unmentioned sections alone. */
110
- strategy?: 'merge' | 'replace';
111
- }
112
- /**
113
- * Single row from `GET /v1/databases/:id/drills`. The drill
114
- * is an engine-specific smoke check (pg_restore --list,
115
- * redis-check-rdb, mysqldump header parse, ...) that proves
116
- * a backup is at least parseable without spinning up a real
117
- * database container. `details` is the engine-specific
118
- * output (object counts, banner, ...).
119
- */
120
- export interface BackupDrillResult {
121
- drillId: number;
122
- ok: true;
123
- status: 'passed' | 'failed';
124
- durationMs: number;
125
- details: Record<string, unknown> | null;
126
- error: string | null;
127
- }
128
- /** History row from `GET /v1/databases/:id/drills`. */
129
- export interface BackupDrillEntry {
130
- id: number;
131
- databaseId: number;
132
- backupId: number;
133
- status: 'pending' | 'running' | 'passed' | 'failed';
134
- engine: string;
135
- durationMs: number;
136
- error: string | null;
137
- details: Record<string, unknown> | null;
138
- startedAt: number;
139
- completedAt: number | null;
140
- }
141
- /**
142
- * Body for `POST /v1/log-drains/search` (G-16). The
143
- * search round-trips to the configured Loki drain.
144
- */
145
- export interface LogSearchInput {
146
- /** Free-text search (case-insensitive substring). */
147
- query: string;
148
- /** Restrict to one service. */
149
- serviceId?: number;
150
- /** Window length in minutes (default 15). */
151
- sinceMinutes?: number;
152
- /** Hard cap on returned lines (default 200, max 1000). */
153
- limit?: number;
154
- /** Query a specific drain. */
155
- drainId?: number;
156
- }
157
- export interface LogSearchLine {
158
- ts: number;
159
- line: string;
160
- service: string | null;
161
- }
162
- export interface LogSearchResult {
163
- drain: {
164
- id: number;
165
- name: string;
166
- type: string;
167
- };
168
- serviceId: number | null;
169
- window: {
170
- since: string;
171
- until: string;
172
- };
173
- lines: LogSearchLine[];
174
- }
175
- /**
176
- * Built-in email template names (G-30). The full set
177
- * lives in `apps/server/src/lib/emailTemplates.ts`; the
178
- * union here is the closed set the SDK can name. The
179
- * server validates on the wire (zod enum) — a string
180
- * the SDK does not know about returns 400.
181
- */
182
- export type EmailTemplateName = 'password-reset' | 'workspace-invitation' | 'domain-transfer' | 'backup-drill-failed';
183
- /** One row from `GET /v1/workspaces/:wid/email-templates`. */
184
- export interface EmailTemplateEntry {
185
- name: EmailTemplateName;
186
- /** True when the workspace has an override for this name. */
187
- overridden: boolean;
188
- /** Override subject; null when the built-in default applies. */
189
- subject: string | null;
190
- /** Override text body; null when the built-in default applies. */
191
- text: string | null;
192
- }
193
- /** Result of `POST /v1/workspaces/:wid/email-templates/preview`. */
194
- export interface EmailTemplateRender {
195
- subject: string;
196
- text: string;
197
- /** True when the rendered text came from a tenant override. */
198
- overridden: boolean;
199
- }
200
- /**
201
- * Result of `GET /v1/databases/:id/pgbouncer` (and the
202
- * post-mutation body of the enable / disable routes).
203
- * `pooledConnectionString` is non-null only when `running`
204
- * is true — a `docker inspect` failure on the sidecar
205
- * reports `enabled: true, running: false` so the panel
206
- * can surface the discrepancy.
207
- */
208
- export interface PgbouncerStatus {
209
- enabled: boolean;
210
- containerName: string | null;
211
- port: number;
212
- running: boolean;
213
- poolMode: string | null;
214
- pooledConnectionString: string | null;
215
- }
216
- /**
217
- * Single image row from `GET /v1/housekeeping/images`. Both
218
- * the human-readable `size` ("1.2GB") and a parsed byte
219
- * count are returned so the panel can sort without
220
- * re-parsing. `inUse` is true when at least one container
221
- * is currently using the image id.
222
- */
223
- export interface ImageInfo {
224
- repository: string;
225
- tag: string;
226
- id: string;
227
- size: string;
228
- sizeBytes: number;
229
- createdAt: string;
230
- ageHours: number;
231
- dangling: boolean;
232
- inUse: boolean;
233
- }
234
- /** Body for `POST /v1/housekeeping/images/prune`. The server
235
- * refuses the empty-options combination (it would delete
236
- * every image not currently in use). */
237
- export interface PruneImagesInput {
238
- keepLast?: number;
239
- olderThanHours?: number;
240
- danglingOnly?: boolean;
241
- dryRun?: boolean;
242
- }
243
- export interface PruneImagesResult {
244
- freedBytes: number;
245
- removed: string[];
246
- removedLabels: string[];
247
- dryRun: boolean;
248
- output: string;
249
- }
250
- /**
251
- * Result of `POST /v1/domains/:id/transfer` (start a
252
- * transfer). The caller forwards `acceptUrl` to the target
253
- * user out-of-band; the token is the only secret embedded
254
- * in the URL.
255
- */
256
- export interface StartDomainTransferResult {
257
- ok: boolean;
258
- transferId: number;
259
- acceptUrl: string;
260
- expiresAt: number;
261
- }
262
- /**
263
- * Result of `GET /v1/domain-transfers/:token` (preview).
264
- * `effectivelyExpired` is true when the row is still
265
- * `pending` server-side but `expiresAt` is in the past;
266
- * the route reports it as `expired` and refuses accept.
267
- */
268
- export interface DomainTransferPreview {
269
- id: number;
270
- status: 'pending' | 'accepted' | 'cancelled' | 'expired';
271
- hostname: string;
272
- sourceEmail: string;
273
- targetEmail: string;
274
- expiresAt: number;
275
- createdAt: number;
276
- acceptedAt: number | null;
277
- cancelledAt: number | null;
278
- effectivelyExpired: boolean;
279
- }
280
- /** Body for `POST /v1/domain-transfers/:token/accept`. */
281
- export interface AcceptDomainTransferInput {
282
- targetServiceId: number;
283
- }
284
- export interface AcceptDomainTransferResult {
285
- ok: boolean;
286
- transferId: number;
287
- domainId: number;
288
- serviceId: number;
289
- hostname: string;
290
- }
291
- export interface NineDeployClientOptions {
292
- /** Base URL of the NineDeploy API, e.g. http://localhost:3000. */
293
- baseUrl: string;
294
- /** Returns the current access token (or bearer credential). */
295
- getToken?: () => string | undefined | null;
296
- /**
297
- * Per-request timeout in milliseconds. A stalled backend must not hang
298
- * callers forever (worst in CI, where nothing is interactive to Ctrl-C).
299
- * Defaults to 30_000; pass `0` to disable entirely.
300
- */
301
- timeoutMs?: number;
302
- /** Custom fetch implementation (defaults to globalThis.fetch). */
303
- fetch?: FetchLike;
304
- }
305
- export interface NineDeployClient {
306
- auth: {
307
- status: () => Promise<{
308
- initialized: boolean;
309
- }>;
310
- /**
311
- * Introspect the current bearer token. Returns the
312
- * token's id (when opaque), name, scopes, expiry and
313
- * the operator flag. Interactive sessions (JWT) report
314
- * `scopes: ['session']`. The MCP server uses this to
315
- * discover the token's authority before registering
316
- * tools.
317
- */
318
- introspectToken: () => Promise<TokenIntrospection>;
319
- setup: (input: Register) => Promise<Session>;
320
- register: (input: Register) => Promise<Session>;
321
- login: (input: Login) => Promise<Session>;
322
- refresh: (input: Refresh) => Promise<Session>;
323
- logout: () => Promise<{
324
- ok: boolean;
325
- }>;
326
- /** Self-service password change; revokes other sessions, returns a fresh token pair. */
327
- changePassword: (input: PasswordChange) => Promise<Session>;
328
- /** Request a reset link (always 200 — no user enumeration). */
329
- forgotPassword: (email: string) => Promise<{
330
- ok: boolean;
331
- }>;
332
- /** Complete a reset with a single-use token; revokes all sessions. */
333
- resetPasswordWithToken: (input: {
334
- token: string;
335
- newPassword: string;
336
- }) => Promise<{
337
- ok: boolean;
338
- }>;
339
- twoFactor: {
340
- /** Generate a pending secret + otpauth URI (auth required). */
341
- setup: (input?: {
342
- password: string;
343
- }) => Promise<{
344
- secret: string;
345
- otpauthUri: string;
346
- }>;
347
- enable: (code: string) => Promise<{
348
- ok: boolean;
349
- totpEnabled: boolean;
350
- }>;
351
- disable: (input: {
352
- password: string;
353
- code: string;
354
- }) => Promise<{
355
- ok: boolean;
356
- totpEnabled: boolean;
357
- }>;
358
- };
359
- me: () => Promise<PublicUser>;
360
- tokens: {
361
- create: (input?: CreateApiTokenInput) => Promise<CreatedApiToken>;
362
- list: () => Promise<ApiToken[]>;
363
- remove: (id: number) => Promise<void>;
364
- };
365
- passkeys: {
366
- /** Start a registration ceremony (returns JSON options for the browser API). */
367
- registerOptions: () => Promise<{
368
- options: string;
369
- }>;
370
- /** Complete registration: verify the browser response, store the credential. */
371
- registerVerify: (input: {
372
- name: string;
373
- response: unknown;
374
- }) => Promise<PasskeyCredential>;
375
- list: () => Promise<PasskeyCredential[]>;
376
- remove: (id: number) => Promise<void>;
377
- /** Start a passwordless login ceremony (discoverable credentials). */
378
- loginOptions: () => Promise<{
379
- options: string;
380
- }>;
381
- /** Complete passkey login — returns a full session on success. */
382
- loginVerify: (response: unknown) => Promise<Session>;
383
- };
384
- sessions: {
385
- list: () => Promise<ActiveSession[]>;
386
- revoke: (id: number) => Promise<{
387
- ok: boolean;
388
- }>;
389
- };
390
- oidc: {
391
- publicProviders: () => Promise<OidcPublicProvider[]>;
392
- link: (slug: string) => Promise<{
393
- authUrl: string;
394
- }>;
395
- listProviders: () => Promise<OidcProviderEntry[]>;
396
- list: () => Promise<OidcProviderEntry[]>;
397
- createProvider: (input: OidcProviderCreateInput) => Promise<OidcProviderEntry>;
398
- create: (input: OidcProviderCreateInput) => Promise<OidcProviderEntry>;
399
- updateProvider: (id: number, input: OidcProviderUpdateInput) => Promise<OidcProviderEntry>;
400
- update: (id: number, input: OidcProviderUpdateInput) => Promise<OidcProviderEntry>;
401
- deleteProvider: (id: number) => Promise<{
402
- ok: boolean;
403
- }>;
404
- delete: (id: number) => Promise<{
405
- ok: boolean;
406
- }>;
407
- callback: (slug: string, payload: {
408
- code: string;
409
- state: string;
410
- }) => Promise<Session>;
411
- };
412
- };
413
- workspaces: {
414
- list: () => Promise<WorkspaceEntry[]>;
415
- get: (id: number) => Promise<WorkspaceDetail>;
416
- create: (input: WorkspaceCreateInput) => Promise<WorkspaceEntry>;
417
- update: (id: number, input: WorkspaceUpdateInput) => Promise<WorkspaceEntry>;
418
- delete: (id: number) => Promise<{
419
- ok: boolean;
420
- }>;
421
- addMember: (id: number, input: WorkspaceMemberAddInput) => Promise<WorkspaceMemberEntry | WorkspaceMemberInviteEntry>;
422
- /** Create a pending invitation for an email address that isn't a user yet. */
423
- inviteMember: (id: number, input: WorkspaceMemberAddInput) => Promise<WorkspaceInvitationEntry & {
424
- acceptUrl: string;
425
- }>;
426
- listInvitations: (id: number) => Promise<WorkspaceInvitationEntry[]>;
427
- revokeInvitation: (id: number, inviteId: number) => Promise<{
428
- ok: boolean;
429
- }>;
430
- /** Look up a pending invitation by its public token (no auth required). */
431
- previewInvitation: (token: string) => Promise<WorkspaceInvitationPublic>;
432
- /** Accept an invitation as the currently authenticated user. */
433
- acceptInvitation: (token: string) => Promise<{
434
- ok: boolean;
435
- workspaceId: number;
436
- role: WorkspaceRole;
437
- }>;
438
- updateMemberRole: (id: number, memberId: number, input: WorkspaceMemberRoleUpdateInput) => Promise<WorkspaceMemberEntry>;
439
- removeMember: (id: number, memberId: number) => Promise<{
440
- ok: boolean;
441
- }>;
442
- };
443
- services: {
444
- /**
445
- * `query` is appended verbatim. Use `?tagWorkspaceIds=1,2&tagProjectIds=3`
446
- * to scope the list by tag (each dimension ANDs, members within a
447
- * dimension OR). The legacy `?projectId=` query is no longer accepted.
448
- */
449
- list: (query?: string) => Promise<Service[]>;
450
- get: (id: number) => Promise<Service>;
451
- create: (input: CreateServiceInput) => Promise<Service>;
452
- update: (id: number, input: UpdateServiceInput) => Promise<Service>;
453
- /**
454
- * Dry-run a compose file before creating anything: blocking reasons,
455
- * host-privilege warnings, the declared services and the variables the
456
- * stack will ask for. Admin-only, and writes nothing.
457
- */
458
- composePreview: (input: ComposePreviewRequestInput) => Promise<ComposePreviewResponse>;
459
- remove: (id: number) => Promise<void>;
460
- stop: (id: number) => Promise<{
461
- ok: boolean;
462
- status: string;
463
- }>;
464
- start: (id: number) => Promise<{
465
- ok: boolean;
466
- status: string;
467
- }>;
468
- restart: (id: number) => Promise<{
469
- ok: boolean;
470
- status: string;
471
- }>;
472
- logs: (id: number) => Promise<{
473
- lines: string;
474
- }>;
475
- clone: (id: number, input?: {
476
- name?: string;
477
- slug?: string;
478
- }) => Promise<Service>;
479
- exportUrl: (id: number) => string;
480
- importBundle: (bundle: unknown) => Promise<{
481
- ok: boolean;
482
- serviceId: number;
483
- slug: string;
484
- message: string;
485
- }>;
486
- /**
487
- * `.ninedeploy` manifest endpoints. The server applies
488
- * build / run / network sections to the service + build
489
- * config rows (operator > manifest > DB merge semantics);
490
- * routes / alerts / database reconcile happens at deploy
491
- * time via the deploy pipeline and is intentionally
492
- * outside this endpoint's scope.
493
- */
494
- manifest: {
495
- /**
496
- * Push a parsed manifest to the panel and reconcile it
497
- * into the service. Requires the `admin` role on the
498
- * service. The response echoes the diff so the CLI can
499
- * render a one-shot summary without a follow-up GET.
500
- */
501
- apply: (serviceId: number, input: ApplyManifestInput) => Promise<ApplyManifestResult>;
502
- };
503
- };
504
- labels: {
505
- /** `query` is appended verbatim, e.g. `?workspaceId=1`. */
506
- list: (query?: string) => Promise<Label[]>;
507
- create: (input: CreateLabelInput) => Promise<Label>;
508
- update: (id: number, input: LabelPatchInput) => Promise<Label>;
509
- remove: (id: number) => Promise<{
510
- ok: boolean;
511
- }>;
512
- };
513
- /** Deployment lanes (production / staging / development) per workspace. */
514
- environments: {
515
- list: () => Promise<Environment[]>;
516
- create: (input: EnvironmentCreateInput) => Promise<Environment>;
517
- rename: (id: number, name: string) => Promise<Environment>;
518
- remove: (id: number) => Promise<{
519
- ok: boolean;
520
- }>;
521
- };
522
- /** AI failure diagnosis (BYO-key): operator-configured, OpenAI-compatible. */
523
- ai: {
524
- /** Never carries key material — only endpoint/model + hasApiKey. */
525
- getConfig: () => Promise<AiConfigStatus>;
526
- updateConfig: (input: AiConfigUpdate) => Promise<{
527
- ok: boolean;
528
- }>;
529
- /** Ask the configured provider to diagnose a failed build log. */
530
- diagnose: (serviceId: number, deploymentId: number) => Promise<{
531
- diagnosis: string;
532
- model: string;
533
- }>;
534
- /** Describe the app in plain language, get a schema-valid .ninedeploy manifest. */
535
- suggestManifest: (description: string) => Promise<{
536
- manifest: Record<string, unknown>;
537
- model: string;
538
- }>;
539
- };
540
- serviceTags: {
541
- /** Read the project's / workspace's / label memberships of a service. */
542
- get: (serviceId: number) => Promise<ServiceTags>;
543
- /** Replace the membership in a single round-trip. Empty arrays clear. */
544
- set: (serviceId: number, input: SetServiceTagsInput) => Promise<ServiceTags>;
545
- };
546
- deploys: {
547
- trigger: (serviceId: number, input?: TriggerDeploy) => Promise<{
548
- deploymentId: number;
549
- }>;
550
- list: (serviceId: number) => Promise<Deployment[]>;
551
- /**
552
- * Global deploy queue view: every in-flight (queued / building /
553
- * deploying) deployment the caller can see, with service + project
554
- * metadata. The optional `status` filter is a comma-separated token
555
- * list (e.g. `?status=queued,building`).
556
- */
557
- queue: (query?: string) => Promise<QueueResponse>;
558
- rollback: (serviceId: number, deploymentId: number) => Promise<{
559
- deploymentId: number;
560
- }>;
561
- /** Cancel a queued/in-flight deployment (checkpoints abort at step boundaries). */
562
- cancel: (serviceId: number, deploymentId: number) => Promise<{
563
- ok: boolean;
564
- status: string;
565
- }>;
566
- /**
567
- * Remove a finished deployment from history, with its build log.
568
- * Refused for an in-flight deployment (cancel it first) and for the one
569
- * currently serving traffic. Requires the `admin` role on the service.
570
- */
571
- remove: (serviceId: number, deploymentId: number) => Promise<{
572
- ok: boolean;
573
- id: number;
574
- }>;
575
- /** Build-config + env-key diff against the previous deployment. */
576
- configDiff: (serviceId: number, deploymentId: number) => Promise<{
577
- deploymentId: number;
578
- previousDeploymentId: number | null;
579
- changed: boolean;
580
- diff: string;
581
- }>;
582
- /** Build log download URL (serves the raw log file as an attachment). */
583
- logDownloadUrl: (serviceId: number, deploymentId: number) => string;
584
- /**
585
- * Promote: deploy ANOTHER service at this service's exact running
586
- * commit — the staging → production lane hop. Both services must
587
- * track the same repository and the caller needs `member` on both.
588
- */
589
- promote: (serviceId: number, targetServiceId: number) => Promise<{
590
- ok: boolean;
591
- deploymentId: number;
592
- commitSha: string;
593
- promotedFrom: string;
594
- }>;
595
- };
596
- domains: {
597
- list: (serviceId: number) => Promise<Domain[]>;
598
- create: (serviceId: number, input: CreateDomainInput) => Promise<Domain>;
599
- remove: (serviceId: number, domainId: number) => Promise<void>;
600
- /**
601
- * DNS status for a domain: does the hostname resolve to the addresses
602
- * this panel expects? Advisory — routing is governed by ownership.
603
- */
604
- dnsCheck: (serviceId: number, domainId: number) => Promise<{
605
- hostname: string;
606
- status: 'ok' | 'mismatch' | 'unresolved';
607
- addresses: {
608
- a: string[];
609
- aaaa: string[];
610
- };
611
- expected: string[];
612
- }>;
613
- /** Update routing extras: ssl toggle, www→apex redirect, custom headers, basicAuth, ipAllowlist, rateLimit. */
614
- update: (serviceId: number, domainId: number, input: DomainPatch) => Promise<Domain>;
615
- all: () => Promise<DomainEntry[]>;
616
- setSsl: (domainId: number, ssl: boolean) => Promise<{
617
- id: number;
618
- ssl: boolean;
619
- }>;
620
- /** Toggle sticky-session routing for the service (G-28). */
621
- setStickySession: (serviceId: number, enabled: boolean) => Promise<{
622
- id: number;
623
- enabled: boolean;
624
- active: boolean;
625
- }>;
626
- /**
627
- * Start a domain transfer (G-29). The source user (admin
628
- * on the source service) names the target email; the
629
- * server returns a one-time `acceptUrl` to forward. The
630
- * target user accepts via `acceptDomainTransfer(token,
631
- * { targetServiceId })`. The transfer expires after 7
632
- * days; cancelling is one call.
633
- */
634
- transfer: (domainId: number, input: {
635
- targetEmail: string;
636
- }) => Promise<StartDomainTransferResult>;
637
- /**
638
- * Preview a transfer by token. Does NOT require auth
639
- * (the token is the secret) — the panel uses this to
640
- * render the accept page to a logged-out visitor.
641
- */
642
- previewTransfer: (token: string) => Promise<DomainTransferPreview>;
643
- /**
644
- * Accept a transfer. The caller must be authenticated
645
- * and the caller's email must equal the transfer's
646
- * target email; the panel / CLI surfaces the preview
647
- * first so the user knows what they're signing in to.
648
- */
649
- acceptTransfer: (token: string, input: AcceptDomainTransferInput) => Promise<AcceptDomainTransferResult>;
650
- /**
651
- * Cancel a pending transfer. Only the source user
652
- * (or an instance operator) can cancel.
653
- */
654
- cancelTransfer: (token: string) => Promise<{
655
- transferId: number;
656
- status: 'cancelled';
657
- }>;
658
- };
659
- domainPresets: {
660
- /** Every `IDomainProvider` the running kernel has registered. */
661
- list: () => Promise<{
662
- providers: string[];
663
- }>;
664
- /**
665
- * Manually create the DNS record for `hostname` via the operator's
666
- * active provider. `content` is optional: when omitted the route
667
- * falls back to the panel's `dns_records_content` setting, then to
668
- * `detectPublicIp()`. Returns the upstream recordId so the caller
669
- * can correlate.
670
- */
671
- apply: (input: {
672
- hostname: string;
673
- content?: string;
674
- }) => Promise<{
675
- hostname: string;
676
- provider: string;
677
- zone: string;
678
- recordId: string;
679
- type: 'A' | 'CNAME';
680
- content: string;
681
- }>;
682
- };
683
- configPresets: {
684
- /** Every preset the kernel has registered. */
685
- list: () => Promise<{
686
- presets: string[];
687
- }>;
688
- /** Fetch a single preset's values + description. */
689
- get: (id: string) => Promise<{
690
- id: string;
691
- description: string | null;
692
- values: Record<string, unknown>;
693
- createdAt: string;
694
- }>;
695
- /** Register a new preset. Throws if `id` already exists. */
696
- register: (input: {
697
- id: string;
698
- description?: string;
699
- values: Record<string, unknown>;
700
- }) => Promise<{
701
- ok: boolean;
702
- id: string;
703
- keyCount: number;
704
- }>;
705
- /** Write every value in the preset to the live configCenter. */
706
- apply: (id: string, opts?: {
707
- override?: Record<string, unknown>;
708
- }) => Promise<{
709
- ok: boolean;
710
- id: string;
711
- keyCount: number;
712
- failureCount?: number;
713
- failures?: Array<{
714
- key: string;
715
- status: 'failed';
716
- reason?: string;
717
- }>;
718
- }>;
719
- /** Unregister a preset. Does NOT undo the apply. */
720
- remove: (id: string) => Promise<{
721
- ok: boolean;
722
- id: string;
723
- }>;
724
- };
725
- metricHistory: {
726
- /** Current configuration snapshot (backend choice, enabled flag, retention, last-flush). */
727
- get: () => Promise<{
728
- enabled: boolean;
729
- backend: 'builtin' | 'prometheus' | 'influxdb';
730
- events: string[];
731
- retentionDays: number;
732
- lastFlush: {
733
- ts: number;
734
- backend: string;
735
- count: number;
736
- };
737
- }>;
738
- /** Run the built-in backend's retention sweep. Returns the row count trimmed. */
739
- flush: () => Promise<{
740
- ok: boolean;
741
- backend: 'builtin';
742
- deleted: number;
743
- }>;
744
- };
745
- buildCache: {
746
- /** Per-backend counters + merged totals. G-01 PR-A. */
747
- stats: () => Promise<{
748
- backends: Array<{
749
- name: string;
750
- entries: number;
751
- totalBytes: number;
752
- hits: number;
753
- misses: number;
754
- stores: number;
755
- evictions: number;
756
- }>;
757
- totals: {
758
- entries: number;
759
- totalBytes: number;
760
- hits: number;
761
- misses: number;
762
- stores: number;
763
- evictions: number;
764
- };
765
- }>;
766
- };
767
- orchestrators: {
768
- /** Every `IOrchestrator` the running kernel has registered. G-10 PR-A. */
769
- list: () => Promise<{
770
- orchestrators: Array<{
771
- name: string;
772
- stacks: Array<{
773
- name: string;
774
- serviceCount: number;
775
- }>;
776
- }>;
777
- }>;
778
- /** The stacks one orchestrator knows about. */
779
- stacks: (orchestrator: string) => Promise<{
780
- stacks: Array<{
781
- name: string;
782
- serviceCount: number;
783
- }>;
784
- }>;
785
- /**
786
- * Stable snapshot of ONE stack. Returns `null` when the orchestrator has
787
- * no record of it.
788
- *
789
- * r036: this used to take only the orchestrator name and hit
790
- * `/:name/stacks`, which passed that name through as the STACK name — so
791
- * it answered `null` for every stack not coincidentally named after its
792
- * orchestrator. The stack now has its own argument and path segment.
793
- */
794
- stackStatus: (orchestrator: string, stack: string) => Promise<{
795
- name: string;
796
- services: Array<{
797
- name: string;
798
- state: 'running' | 'stopped' | 'partial' | 'unknown';
799
- replicas: number;
800
- }>;
801
- appliedAt: string;
802
- } | null>;
803
- };
804
- branding: {
805
- /** Read the four operator-overridable branding fields. G-30. */
806
- get: () => Promise<{
807
- logoUrl: string | null;
808
- primaryColor: string | null;
809
- supportEmail: string | null;
810
- footerHtml: string | null;
811
- }>;
812
- /** Set one or more branding fields. Empty strings are stored as `null`. */
813
- set: (input: {
814
- logoUrl?: string | null;
815
- primaryColor?: string | null;
816
- supportEmail?: string | null;
817
- footerHtml?: string | null;
818
- }) => Promise<{
819
- ok: boolean;
820
- }>;
821
- };
822
- egress: {
823
- /** Every egress IP rule across every registered driver. G-15. */
824
- list: () => Promise<{
825
- drivers: Array<{
826
- name: string;
827
- rules: Array<{
828
- selector: {
829
- projectId: number;
830
- sourceCidr?: string;
831
- };
832
- ip: string;
833
- createdAt: string;
834
- }>;
835
- }>;
836
- }>;
837
- /** Attach an egress IP to a project on the named (or first) driver. */
838
- set: (input: {
839
- projectId: number;
840
- ip: string;
841
- driver?: string;
842
- }) => Promise<{
843
- ok: boolean;
844
- driver: string;
845
- rule: {
846
- selector: {
847
- projectId: number;
848
- sourceCidr?: string;
849
- };
850
- ip: string;
851
- createdAt: string;
852
- };
853
- /** Present (with `ok: false`) when the route refused the request. */
854
- error?: string;
855
- }>;
856
- /** Detach the rule for a project (on the named or first driver). */
857
- clear: (projectId: number, driver?: string) => Promise<{
858
- ok: boolean;
859
- driver: string;
860
- error?: string;
861
- }>;
862
- };
863
- fanout: {
864
- /** The extra nodes an image/Dockerfile release is pushed to. */
865
- get: (serviceId: number) => Promise<Array<{
866
- serverId: number;
867
- runtimeId: string | null;
868
- status: string;
869
- }>>;
870
- /** Replace the target-node set (operator-only). */
871
- set: (serviceId: number, serverIds: number[]) => Promise<{
872
- targets: Array<{
873
- serverId: number;
874
- runtimeId: string | null;
875
- status: string;
876
- }>;
877
- }>;
878
- };
879
- scim: {
880
- /** SCIM 2.0 provisioning tokens (operator-managed). */
881
- listTokens: () => Promise<Array<{
882
- id: number;
883
- name: string;
884
- workspaceId: number;
885
- createdAt: string | null;
886
- lastUsedAt: string | null;
887
- revoked: boolean;
888
- }>>;
889
- /** The plaintext token is returned exactly once — only its sha256 persists. */
890
- createToken: (input: {
891
- name: string;
892
- workspaceId: number;
893
- }) => Promise<{
894
- id: number;
895
- token: string;
896
- }>;
897
- revokeToken: (id: number) => Promise<{
898
- ok: boolean;
899
- }>;
900
- };
901
- sso: {
902
- /** Every configured OIDC / SAML provider. G-22. */
903
- listProviders: () => Promise<{
904
- providers: Array<{
905
- id: number;
906
- type: 'oidc' | 'saml';
907
- name: string;
908
- createdAt: string;
909
- }>;
910
- }>;
911
- /** Add a provider (OIDC issuer URL or SAML metadata URL lives in `config`). */
912
- addProvider: (input: {
913
- type: 'oidc' | 'saml';
914
- name: string;
915
- config: Record<string, unknown>;
916
- }) => Promise<{
917
- ok: boolean;
918
- id?: number;
919
- name?: string;
920
- type?: 'oidc' | 'saml';
921
- error?: string;
922
- }>;
923
- /** Remove a provider by id. */
924
- removeProvider: (id: number) => Promise<{
925
- ok: boolean;
926
- }>;
927
- };
928
- volumes: {
929
- list: () => Promise<VolumeEntry[]>;
930
- remove: (name: string) => Promise<void>;
931
- prune: () => Promise<{
932
- ok: boolean;
933
- deleted: number;
934
- freedBytes: number;
935
- }>;
936
- /** File manager: list a directory inside the volume. */
937
- listFiles: (name: string, path?: string) => Promise<{
938
- path: string;
939
- entries: VolumeFileEntry[];
940
- }>;
941
- /** File manager: read a file (base64 content). */
942
- readFile: (name: string, path: string) => Promise<{
943
- content: string;
944
- encoding: 'utf8' | 'base64';
945
- }>;
946
- /** File manager: write/overwrite a file (base64 content). */
947
- writeFile: (name: string, input: VolumeFileWriteInput) => Promise<{
948
- ok: boolean;
949
- }>;
950
- /** File manager: create a directory. */
951
- mkdir: (name: string, input: VolumePathCreateInput) => Promise<{
952
- ok: boolean;
953
- }>;
954
- /** File manager: delete a file or directory (recursive). */
955
- deleteFile: (name: string, path: string) => Promise<void>;
956
- };
957
- containers: {
958
- inspect: (container: string) => Promise<ContainerInspectData>;
959
- compose: (container: string) => Promise<ContainerComposeData>;
960
- /** File manager: list a directory inside the container. */
961
- listFiles: (container: string, path?: string) => Promise<{
962
- path: string;
963
- entries: VolumeFileEntry[];
964
- }>;
965
- /** File manager: read a file (base64 content). */
966
- readFile: (container: string, path: string) => Promise<{
967
- content: string;
968
- encoding: 'utf8' | 'base64';
969
- }>;
970
- /** File manager: write/overwrite a file (base64 content). */
971
- writeFile: (container: string, input: VolumeFileWriteInput) => Promise<{
972
- ok: boolean;
973
- }>;
974
- /** File manager: create a directory. */
975
- mkdir: (container: string, input: VolumePathCreateInput) => Promise<{
976
- ok: boolean;
977
- }>;
978
- makeDir: (container: string, input: VolumePathCreateInput) => Promise<{
979
- ok: boolean;
980
- }>;
981
- /** File manager: delete a file or directory (recursive). */
982
- deleteFile: (container: string, path: string) => Promise<void>;
983
- deletePath: (container: string, path: string) => Promise<void>;
984
- };
985
- system: {
986
- resources: () => Promise<DockerResources>;
987
- pruneImages: () => Promise<{
988
- ok: boolean;
989
- }>;
990
- exportUrl: () => string;
991
- /** Latest-release check (admin). updateAvailable is null when offline/disabled. */
992
- updateCheck: (force?: boolean) => Promise<UpdateCheckResult>;
993
- /** State of a panel-initiated upgrade (idle/running/success/failed/unsupported). */
994
- updateStatus: () => Promise<SelfUpdateStatus>;
995
- /** Start upgrading the panel itself to an exact release tag; the updater survives the restart it performs. */
996
- updateStart: (version: string) => Promise<{
997
- ok: boolean;
998
- }>;
999
- /** Recent docker daemon events (single-shot, for the Docker dashboard feed). */
1000
- dockerEvents: (minutes?: number) => Promise<{
1001
- events: Array<{
1002
- time: string;
1003
- type: string;
1004
- action: string;
1005
- name: string;
1006
- }>;
1007
- }>;
1008
- };
1009
- networks: {
1010
- list: () => Promise<{
1011
- networks: Array<{
1012
- name: string;
1013
- driver: string;
1014
- members: string[];
1015
- /** True when the network is reserved by NineDeploy (cannot be removed). */
1016
- isManaged?: boolean;
1017
- }>;
1018
- remote: number | null;
1019
- }>;
1020
- create: (input: {
1021
- name: string;
1022
- driver?: 'bridge' | 'overlay';
1023
- serverId?: number | null;
1024
- }) => Promise<{
1025
- ok: boolean;
1026
- name: string;
1027
- }>;
1028
- remove: (name: string, serverId?: number) => Promise<{
1029
- ok: boolean;
1030
- }>;
1031
- attach: (input: {
1032
- network: string;
1033
- container: string;
1034
- serverId?: number | null;
1035
- }) => Promise<{
1036
- ok: boolean;
1037
- }>;
1038
- detach: (input: {
1039
- network: string;
1040
- container: string;
1041
- serverId?: number | null;
1042
- }) => Promise<{
1043
- ok: boolean;
1044
- }>;
1045
- };
1046
- tunnels: {
1047
- list: () => Promise<TunnelEntry[]>;
1048
- create: (input: CreateTunnelInput) => Promise<TunnelEntry>;
1049
- remove: (id: number) => Promise<void>;
1050
- };
1051
- activity: {
1052
- /** Filter + paginate the audit trail. Omitted filters return the newest page. */
1053
- list: (query?: {
1054
- entity?: string;
1055
- action?: string;
1056
- userId?: number;
1057
- before?: number;
1058
- }) => Promise<{
1059
- entries: ActivityEntry[];
1060
- nextCursor: number | null;
1061
- }>;
1062
- };
1063
- alerts: {
1064
- list: () => Promise<AlertRule[]>;
1065
- create: (input: CreateAlertRuleInput) => Promise<AlertRule>;
1066
- update: (id: number, input: Partial<CreateAlertRuleInput>) => Promise<AlertRule>;
1067
- remove: (id: number) => Promise<void>;
1068
- };
1069
- settings: {
1070
- get: () => Promise<{
1071
- allowRegistration: boolean;
1072
- acmeEmail: string | null;
1073
- templatesSource: string | null;
1074
- dnsProvider: string | null;
1075
- hasDnsToken: boolean;
1076
- wildcardApex: string | null;
1077
- panelDomain: string | null;
1078
- }>;
1079
- setPanelDomain: (domain: string) => Promise<{
1080
- ok: boolean;
1081
- panelDomain: string | null;
1082
- }>;
1083
- setAllowRegistration: (enabled: boolean) => Promise<{
1084
- ok: boolean;
1085
- allowRegistration: boolean;
1086
- }>;
1087
- setAcmeEmail: (email: string) => Promise<{
1088
- ok: boolean;
1089
- acmeEmail: string | null;
1090
- applied: string;
1091
- }>;
1092
- setTemplatesSource: (source: string) => Promise<{
1093
- ok: boolean;
1094
- templatesSource: string | null;
1095
- }>;
1096
- /** Configure the ACME DNS-01 challenge (wildcard certificates). */
1097
- setDns: (input: {
1098
- provider: string;
1099
- token?: string;
1100
- wildcardApex: string;
1101
- }) => Promise<{
1102
- ok: boolean;
1103
- dnsProvider: string | null;
1104
- wildcardApex: string | null;
1105
- applied: string;
1106
- }>;
1107
- /** Vault provider (deploy-time secret resolution). */
1108
- vault: {
1109
- get: () => Promise<{
1110
- provider: string | null;
1111
- hasToken: boolean;
1112
- projectId: string | null;
1113
- environment: string | null;
1114
- }>;
1115
- set: (input: {
1116
- provider: '' | 'infisical' | 'doppler';
1117
- token?: string;
1118
- projectId?: string;
1119
- environment?: string;
1120
- }) => Promise<{
1121
- ok: boolean;
1122
- provider: string | null;
1123
- }>;
1124
- test: () => Promise<{
1125
- ok: boolean;
1126
- secrets: number;
1127
- }>;
1128
- };
1129
- /** Cloudflare DNS-record auto-provisioning for added domains. */
1130
- dnsRecords: {
1131
- get: () => Promise<{
1132
- enabled: boolean;
1133
- hasToken: boolean;
1134
- content: string | null;
1135
- }>;
1136
- set: (input: {
1137
- enabled: boolean;
1138
- token?: string;
1139
- content?: string;
1140
- }) => Promise<{
1141
- ok: boolean;
1142
- enabled: boolean;
1143
- }>;
1144
- test: () => Promise<{
1145
- ok: boolean;
1146
- status?: string;
1147
- error?: string;
1148
- }>;
1149
- };
1150
- /** Namecheap DNS-record auto-provisioning for added domains (G-07 PR-A). */
1151
- namecheap: {
1152
- get: () => Promise<{
1153
- configured: boolean;
1154
- apiUser: string | null;
1155
- clientIp: string | null;
1156
- hasKey: boolean;
1157
- }>;
1158
- set: (input: {
1159
- apiUser: string;
1160
- apiKey: string;
1161
- clientIp: string;
1162
- }) => Promise<{
1163
- ok: boolean;
1164
- apiUser: string;
1165
- }>;
1166
- };
1167
- /**
1168
- * Master-key rotation. `rotate` re-encrypts every stored secret onto the
1169
- * highest key version in `NINEDEPLOY_MASTER_KEYS`; it does NOT rewrite
1170
- * backup envelopes, which is what `warning` reports.
1171
- */
1172
- masterKey: {
1173
- get: () => Promise<{
1174
- activeVersion: number;
1175
- knownVersions: number[];
1176
- rotatable: boolean;
1177
- }>;
1178
- rotate: () => Promise<{
1179
- rotated: number;
1180
- activeVersion: number;
1181
- backupsNotRotated: number;
1182
- warning: string | null;
1183
- }>;
1184
- };
1185
- };
1186
- firewall: {
1187
- status: () => Promise<{
1188
- installed: boolean;
1189
- active: boolean;
1190
- supported: boolean;
1191
- rules: Array<{
1192
- id: number;
1193
- to: string;
1194
- action: string;
1195
- from: string;
1196
- comment?: string;
1197
- }>;
1198
- defaultIncoming: string;
1199
- defaultOutgoing: string;
1200
- }>;
1201
- toggle: (enabled: boolean) => Promise<{
1202
- ok: boolean;
1203
- status: any;
1204
- }>;
1205
- addRule: (input: {
1206
- port: number | string;
1207
- proto?: 'tcp' | 'udp' | 'any';
1208
- action?: 'allow' | 'deny' | 'limit';
1209
- from?: string;
1210
- comment?: string;
1211
- }) => Promise<{
1212
- ok: boolean;
1213
- status: any;
1214
- }>;
1215
- deleteRule: (id: number | string) => Promise<{
1216
- ok: boolean;
1217
- status: any;
1218
- }>;
1219
- applyRecommended: () => Promise<{
1220
- ok: boolean;
1221
- status: any;
1222
- }>;
1223
- };
1224
- users: {
1225
- list: () => Promise<PublicUser[]>;
1226
- /**
1227
- * Operator-only: create a user directly (no registration flow needed).
1228
- * The new account has no workspace memberships — an existing owner/admin
1229
- * must invite it into at least one workspace before it can act.
1230
- */
1231
- create: (input: UserCreate) => Promise<PublicUser>;
1232
- /**
1233
- * Operator-only: delete a user. The `users.role` column was removed when
1234
- * authorization became workspace-only; the legacy `setRole` is gone with
1235
- * it. Role changes go through `workspaces.updateMemberRole`.
1236
- */
1237
- remove: (id: number) => Promise<void>;
1238
- /** Operator reset of another user's password (revokes their sessions). */
1239
- resetPassword: (id: number, input: PasswordReset) => Promise<{
1240
- ok: boolean;
1241
- }>;
1242
- /** Mint a one-time reset link for a user (returned exactly once). */
1243
- resetLink: (id: number) => Promise<{
1244
- url: string;
1245
- expiresAt: string;
1246
- }>;
1247
- /**
1248
- * Operator-only: grant or revoke the INSTANCE-operator flag.
1249
- *
1250
- * Not a workspace role — this is the flag that gates operator-only routes
1251
- * and the host-privilege boundary (PM2/compose deploys, lifecycle hooks,
1252
- * docker-socket templates). Creating a workspace does NOT confer it. The
1253
- * last remaining operator cannot be demoted.
1254
- */
1255
- setOperator: (id: number, isOperator: boolean) => Promise<{
1256
- ok: boolean;
1257
- id: number;
1258
- isOperator: boolean;
1259
- }>;
1260
- };
1261
- projects: {
1262
- /** `query` is appended verbatim, e.g. `?workspaceId=2` (workspace scoping). */
1263
- list: (query?: string) => Promise<ProjectEntry[]>;
1264
- create: (input: CreateProjectInput) => Promise<ProjectEntry>;
1265
- update: (id: number, input: ProjectPatchInput) => Promise<ProjectEntry>;
1266
- remove: (id: number) => Promise<{
1267
- ok: boolean;
1268
- }>;
1269
- };
1270
- about: {
1271
- get: () => Promise<{
1272
- name: string;
1273
- version: string;
1274
- description: string;
1275
- license: string;
1276
- repo: string;
1277
- docs: string;
1278
- techStack: Array<{
1279
- category: string;
1280
- items: string[];
1281
- }>;
1282
- changelog: Array<{
1283
- version: string;
1284
- date: string;
1285
- title: string;
1286
- changes: string[];
1287
- }>;
1288
- /** Instance counts are only returned for authenticated requests. */
1289
- stats?: {
1290
- services: number;
1291
- databases: number;
1292
- deployments: number;
1293
- users: number;
1294
- };
1295
- }>;
1296
- };
1297
- notifications: {
1298
- listChannels: () => Promise<Array<{
1299
- id: number;
1300
- name: string;
1301
- type: string;
1302
- eventFilter: string;
1303
- active: boolean;
1304
- configJson: string | null;
1305
- createdAt: string;
1306
- }>>;
1307
- createChannel: (input: {
1308
- name: string;
1309
- type: string;
1310
- target: string;
1311
- eventFilter?: string;
1312
- configJson?: string | null;
1313
- }) => Promise<{
1314
- id: number;
1315
- name: string;
1316
- type: string;
1317
- }>;
1318
- updateChannel: (id: number, input: {
1319
- name?: string;
1320
- target?: string;
1321
- eventFilter?: string;
1322
- active?: boolean;
1323
- configJson?: string | null;
1324
- }) => Promise<{
1325
- id: number;
1326
- active: boolean;
1327
- }>;
1328
- removeChannel: (id: number) => Promise<void>;
1329
- testChannel: (id: number) => Promise<{
1330
- ok: boolean;
1331
- }>;
1332
- log: () => Promise<Array<{
1333
- id: number;
1334
- channelId: number | null;
1335
- event: string;
1336
- entity: string | null;
1337
- status: string;
1338
- error: string | null;
1339
- ts: string;
1340
- }>>;
1341
- };
1342
- sources: {
1343
- list: () => Promise<Source[]>;
1344
- create: (input: CreateSourceInput) => Promise<Source>;
1345
- update: (id: number, input: Partial<CreateSourceInput>) => Promise<Source>;
1346
- remove: (id: number) => Promise<void>;
1347
- repos: (id: number) => Promise<Array<{
1348
- name: string;
1349
- fullName: string;
1350
- url: string;
1351
- defaultBranch: string;
1352
- isPrivate: boolean;
1353
- }>>;
1354
- branches: (id: number, repo: string) => Promise<string[]>;
1355
- /** Live credential check — proves a stored token still authenticates. */
1356
- test: (id: number) => Promise<{
1357
- ok: boolean;
1358
- provider?: string;
1359
- login?: string;
1360
- name?: string | null;
1361
- status?: number;
1362
- error?: string;
1363
- }>;
1364
- /**
1365
- * Server-side generation of an ed25519 deploy key pair. The private key
1366
- * is encrypted into the source row and never leaves the server; only the
1367
- * public key and fingerprint are returned (the operator pastes the public
1368
- * key into the Git provider's "Deploy keys" UI).
1369
- */
1370
- generateDeployKey: (id: number) => Promise<{
1371
- publicKey: string;
1372
- fingerprint: string;
1373
- }>;
1374
- };
1375
- insights: {
1376
- /** Pre-deploy repository inspection (DeployWizard): clone + framework detection. */
1377
- analyze: (input: AnalyzeRepoInput) => Promise<RepoInsights>;
1378
- /** Latest stored analysis for a service (null before the first deploy/refresh). */
1379
- get: (serviceId: number) => Promise<RepoInsights | null>;
1380
- /** Re-analyze the service's repository now and store the result. */
1381
- refresh: (serviceId: number) => Promise<RepoInsights>;
1382
- };
1383
- webhooks: {
1384
- list: (serviceId: number) => Promise<Webhook[]>;
1385
- create: (serviceId: number, input?: CreateWebhookInput) => Promise<CreatedWebhook>;
1386
- remove: (serviceId: number, hookId: number) => Promise<void>;
1387
- };
1388
- databases: {
1389
- /** `query` is appended verbatim, e.g. `?projectId=3` (project scoping). */
1390
- list: (query?: string) => Promise<ManagedDatabase[]>;
1391
- create: (input: CreateDatabaseInput) => Promise<ManagedDatabase>;
1392
- get: (id: number) => Promise<DatabaseDetail>;
1393
- remove: (id: number, options?: {
1394
- force?: boolean;
1395
- }) => Promise<void>;
1396
- restart: (id: number) => Promise<void>;
1397
- stop: (id: number) => Promise<void>;
1398
- start: (id: number) => Promise<void>;
1399
- logs: (id: number, lines?: number) => Promise<{
1400
- logs: string[];
1401
- }>;
1402
- credentials: (id: number) => Promise<DatabaseCredentials>;
1403
- setLimits: (id: number, input: SetLimitsInput) => Promise<{
1404
- cpuShares: number | null;
1405
- memLimitMb: number | null;
1406
- }>;
1407
- startStudio: (id: number, port?: number) => Promise<{
1408
- ok: boolean;
1409
- port: number;
1410
- url: string;
1411
- }>;
1412
- stopStudio: (id: number) => Promise<{
1413
- ok: boolean;
1414
- }>;
1415
- /**
1416
- * PgBouncer sidecar (G-32). Returns the current sidecar
1417
- * state — `enabled` + `running` + the URL the services
1418
- * should connect to. Use the same call after
1419
- * `enablePgbouncer` / `disablePgbouncer` for a fresh
1420
- * read (the route returns the post-mutation status).
1421
- */
1422
- pgbouncerStatus: (id: number) => Promise<PgbouncerStatus>;
1423
- /**
1424
- * Spin up the sidecar. `port` is optional — the row's
1425
- * existing `pgbouncerPort` (default 6432) is used
1426
- * when omitted. Only `engine='postgres'` is supported;
1427
- * the server returns 422 for any other engine.
1428
- */
1429
- enablePgbouncer: (id: number, input?: {
1430
- port?: number;
1431
- }) => Promise<PgbouncerStatus>;
1432
- /** Stop + remove the sidecar and clear the row's flags. */
1433
- disablePgbouncer: (id: number) => Promise<PgbouncerStatus>;
1434
- /**
1435
- * Run an engine-specific smoke check against a backup
1436
- * file (pg_restore --list, redis-check-rdb, mysqldump
1437
- * header parse, ...). Returns the drill row with `status`
1438
- * of `passed` or `failed`; a failed drill is a real
1439
- * signal that the backup cannot be restored cleanly, not
1440
- * a warning. Requires the `member` role on the database.
1441
- */
1442
- drillBackup: (id: number, input: {
1443
- backupId: number;
1444
- }) => Promise<BackupDrillResult>;
1445
- /** List the most recent drills for a database, newest first. */
1446
- drills: (id: number) => Promise<BackupDrillEntry[]>;
1447
- };
1448
- attachments: {
1449
- list: (serviceId: number) => Promise<Attachment[]>;
1450
- create: (serviceId: number, input: {
1451
- databaseId: number;
1452
- envAlias?: string;
1453
- reuseExisting?: boolean;
1454
- }) => Promise<Attachment>;
1455
- remove: (serviceId: number, attachmentId: number) => Promise<void>;
1456
- };
1457
- /** Per-volume backup history. The base URL is `/v1/volumes/:name/backups`;
1458
- * restore + download go through the same path. The global `/v1/backups`
1459
- * list/delete are exposed as `backups` below. */
1460
- volumeBackups: {
1461
- list: (volumeName: string) => Promise<Backup[]>;
1462
- create: (volumeName: string, input: CreateVolumeBackupInput) => Promise<Backup>;
1463
- restore: (volumeName: string, backupId: number) => Promise<{
1464
- ok: boolean;
1465
- }>;
1466
- downloadUrl: (volumeName: string, backupId: number) => string;
1467
- };
1468
- /** Per-service additional volume attachments. Distinct from the instance-wide
1469
- * `volumes` namespace (which lists every Docker volume on the host). The
1470
- * list endpoint returns runtime-computed metadata (size, in-use, sharing);
1471
- * the create/update endpoints return the database row only. */
1472
- serviceVolumes: {
1473
- list: (serviceId: number) => Promise<Array<ServiceVolumeAttachment & {
1474
- sizeBytes: number;
1475
- inUse: boolean;
1476
- sharedWith: number;
1477
- }>>;
1478
- /** Attach an existing managed volume or create a new one and attach it. */
1479
- create: (serviceId: number, input: CreateServiceVolumeAttachmentInput) => Promise<{
1480
- attachment: ServiceVolumeAttachment;
1481
- deploymentId: number;
1482
- }>;
1483
- update: (serviceId: number, attachmentId: number, input: UpdateServiceVolumeAttachmentInput) => Promise<{
1484
- attachment: ServiceVolumeAttachment;
1485
- deploymentId: number;
1486
- }>;
1487
- /** Detach. The underlying Docker volume is NOT deleted (data persists). */
1488
- remove: (serviceId: number, attachmentId: number) => Promise<void>;
1489
- /** Delete a first-boot-baked config file from the volume and queue a
1490
- * redeploy so the app regenerates it from the current environment
1491
- * (WordPress wp-config.php et al.). Exactly one of `attachmentId` /
1492
- * `volumeName` must be set; `filePath` is a single path segment. */
1493
- repairConfig: (serviceId: number, input: {
1494
- filePath: string;
1495
- attachmentId?: number;
1496
- volumeName?: string;
1497
- }) => Promise<{
1498
- ok: boolean;
1499
- deploymentId: number;
1500
- }>;
1501
- };
1502
- env: {
1503
- list: (serviceId: number) => Promise<EnvVar[]>;
1504
- create: (serviceId: number, input: UpsertEnvVarInput) => Promise<EnvVar>;
1505
- update: (serviceId: number, varId: number, input: UpsertEnvVarInput) => Promise<EnvVar>;
1506
- remove: (serviceId: number, varId: number) => Promise<void>;
1507
- /** Bulk import from a .env-formatted string. Returns imported/skipped counts. */
1508
- import: (serviceId: number, content: string) => Promise<{
1509
- imported: number;
1510
- skipped: number;
1511
- errors: Array<{
1512
- line: number;
1513
- message: string;
1514
- }>;
1515
- }>;
1516
- /** Export non-secret env vars as a .env-formatted string (admin floor). */
1517
- export: (serviceId: number) => Promise<{
1518
- content: string;
1519
- count: number;
1520
- }>;
1521
- /** Cross-scope key search: where a given env key is defined. */
1522
- search: (q: string) => Promise<{
1523
- results: Array<{
1524
- key: string;
1525
- isSecret: boolean;
1526
- scope: string;
1527
- serviceId: number | null;
1528
- serviceName: string | null;
1529
- }>;
1530
- }>;
1531
- };
1532
- projectEnv: {
1533
- /** Shared env vars applied to every service in a project (service env wins). */
1534
- list: (projectId: number) => Promise<EnvVar[]>;
1535
- create: (projectId: number, input: UpsertEnvVarInput) => Promise<EnvVar>;
1536
- update: (projectId: number, varId: number, input: UpsertEnvVarInput) => Promise<EnvVar>;
1537
- remove: (projectId: number, varId: number) => Promise<void>;
1538
- };
1539
- stats: {
1540
- snapshot: () => Promise<StatsSnapshot>;
1541
- metrics: (serviceId: number, opts?: {
1542
- kind?: 'cpu' | 'memory';
1543
- minutes?: number;
1544
- }) => Promise<MetricSeries>;
1545
- };
1546
- dashboard: {
1547
- get: () => Promise<{
1548
- stats: {
1549
- services: number;
1550
- databases: number;
1551
- deployments: number;
1552
- domains: number;
1553
- webhooks: number;
1554
- running: number;
1555
- stopped: number;
1556
- errored: number;
1557
- dbRunning: number;
1558
- containers: number;
1559
- };
1560
- health: Array<{
1561
- serviceId: number;
1562
- name: string;
1563
- slug: string;
1564
- type: string;
1565
- status: string;
1566
- healthy: boolean;
1567
- responseMs: number | null;
1568
- port: number | null;
1569
- runtimeId: string | null;
1570
- commitSha: string | null;
1571
- lastDeploy: string | null;
1572
- }>;
1573
- recentDeploys: Array<{
1574
- id: number;
1575
- serviceId: number;
1576
- serviceName: string;
1577
- status: string;
1578
- commitSha: string | null;
1579
- message: string | null;
1580
- trigger: string;
1581
- finishedAt: string | null;
1582
- createdAt: string;
1583
- }>;
1584
- }>;
1585
- };
1586
- topology: {
1587
- get: () => Promise<TopologyGraph>;
1588
- };
1589
- backups: {
1590
- storage: (databaseId: number) => Promise<{
1591
- sizeBytes: number;
1592
- }>;
1593
- backupNow: (databaseId: number) => Promise<Backup>;
1594
- listForDb: (databaseId: number) => Promise<Backup[]>;
1595
- restore: (databaseId: number, backupId: number) => Promise<{
1596
- ok: boolean;
1597
- }>;
1598
- list: () => Promise<BackupWithDb[]>;
1599
- remove: (backupId: number) => Promise<void>;
1600
- downloadUrl: (backupId: number) => string;
1601
- };
1602
- backupDestinations: {
1603
- list: () => Promise<Array<{
1604
- id: number;
1605
- name: string;
1606
- endpoint: string;
1607
- region: string;
1608
- bucket: string;
1609
- prefix: string;
1610
- active: boolean;
1611
- createdAt: string;
1612
- }>>;
1613
- create: (input: {
1614
- name: string;
1615
- endpoint: string;
1616
- region?: string;
1617
- bucket: string;
1618
- prefix?: string;
1619
- accessKeyId: string;
1620
- secretAccessKey: string;
1621
- }) => Promise<{
1622
- id: number;
1623
- }>;
1624
- update: (id: number, input: Partial<{
1625
- name: string;
1626
- endpoint: string;
1627
- region: string;
1628
- bucket: string;
1629
- prefix: string;
1630
- active: boolean;
1631
- accessKeyId: string;
1632
- secretAccessKey: string;
1633
- }>) => Promise<{
1634
- ok: boolean;
1635
- }>;
1636
- remove: (id: number) => Promise<{
1637
- ok: boolean;
1638
- }>;
1639
- test: (id: number) => Promise<{
1640
- ok: boolean;
1641
- }>;
1642
- };
1643
- jobs: {
1644
- list: (serviceId: number) => Promise<Array<{
1645
- id: number;
1646
- name: string;
1647
- cron: string;
1648
- kind: 'deploy' | 'exec';
1649
- command: string;
1650
- enabled: boolean;
1651
- lastRunAt: string | null;
1652
- }>>;
1653
- create: (serviceId: number, input: {
1654
- name: string;
1655
- cron: string;
1656
- kind: 'deploy' | 'exec';
1657
- command?: string;
1658
- enabled?: boolean;
1659
- }) => Promise<{
1660
- id: number;
1661
- }>;
1662
- update: (serviceId: number, jobId: number, input: Partial<{
1663
- name: string;
1664
- cron: string;
1665
- kind: 'deploy' | 'exec';
1666
- command: string;
1667
- enabled: boolean;
1668
- }>) => Promise<{
1669
- ok: boolean;
1670
- }>;
1671
- remove: (serviceId: number, jobId: number) => Promise<{
1672
- ok: boolean;
1673
- }>;
1674
- run: (serviceId: number, jobId: number) => Promise<{
1675
- ok: boolean;
1676
- }>;
1677
- runs: (serviceId: number, jobId: number) => Promise<Array<{
1678
- id: number;
1679
- status: string;
1680
- output: string;
1681
- exitCode: number | null;
1682
- createdAt: string;
1683
- }>>;
1684
- };
1685
- servers: {
1686
- list: () => Promise<Array<{
1687
- id: number;
1688
- name: string;
1689
- host: string;
1690
- port: number;
1691
- status: string;
1692
- lastSeenAt: string | null;
1693
- }>>;
1694
- /** Register a server — the agent token + its sha256 are returned exactly once. */
1695
- create: (input: {
1696
- name: string;
1697
- host: string;
1698
- port?: number;
1699
- }) => Promise<{
1700
- id: number;
1701
- token: string;
1702
- tokenSha256: string;
1703
- agentCommand: string;
1704
- }>;
1705
- remove: (id: number, options?: {
1706
- force?: boolean;
1707
- }) => Promise<{
1708
- ok: boolean;
1709
- }>;
1710
- test: (id: number) => Promise<{
1711
- ok: boolean;
1712
- status: string;
1713
- }>;
1714
- approve: (id: number) => Promise<{
1715
- ok: boolean;
1716
- status: string;
1717
- }>;
1718
- reject: (id: number) => Promise<{
1719
- ok: boolean;
1720
- }>;
1721
- sshTest: (input: ServerSshTest) => Promise<ServerSshTestResult>;
1722
- sshBootstrap: (input: ServerSshBootstrap) => Promise<ServerBootstrapResult>;
1723
- bootstrapLogs: (id: number) => Promise<{
1724
- logs: string[];
1725
- }>;
1726
- };
1727
- templates: {
1728
- list: () => Promise<TemplateSummary[]>;
1729
- get: (id: string) => Promise<Template>;
1730
- prepare: (id: string, input?: DeployTemplateInput) => Promise<TemplatePrepareResult>;
1731
- deploy: (id: string, input?: DeployTemplateInput) => Promise<TemplateDeployResult>;
1732
- /**
1733
- * Community contributions (G-13). The `list` call
1734
- * already merges community entries with the curated
1735
- * catalog; the dedicated `community` namespace lets
1736
- * the panel surface errors and the operator import
1737
- * a new template from a PR comment or a file.
1738
- */
1739
- community: {
1740
- list: () => Promise<CommunityTemplateListResult>;
1741
- import: (content: string, opts?: {
1742
- replace?: boolean;
1743
- }) => Promise<{
1744
- ok: boolean;
1745
- id: string;
1746
- file: string;
1747
- bytes: number;
1748
- }>;
1749
- remove: (id: string) => Promise<{
1750
- ok: boolean;
1751
- id: string;
1752
- removed: boolean;
1753
- }>;
1754
- };
1755
- };
1756
- limits: {
1757
- setService: (serviceId: number, input: SetLimitsInput) => Promise<{
1758
- cpuShares: number;
1759
- cpuLimitMilli: number;
1760
- memLimitMb: number;
1761
- liveApplied: boolean;
1762
- }>;
1763
- setDatabase: (databaseId: number, input: SetLimitsInput) => Promise<{
1764
- cpuShares: number;
1765
- cpuLimitMilli: number;
1766
- memLimitMb: number;
1767
- }>;
1768
- };
1769
- traefik: {
1770
- get: () => Promise<TraefikInfo>;
1771
- status: () => Promise<TraefikStatus>;
1772
- certificates: () => Promise<TraefikCertificate[]>;
1773
- /**
1774
- * Richer certificate inventory (G-15). Same
1775
- * underlying data as `certificates()` but adds a
1776
- * `status` classification (valid / expiring-soon /
1777
- * expired), a `summary` block, and the full set of
1778
- * fields the Certificates page renders.
1779
- * `threshold` is the days-out cutoff for the
1780
- * `expiring-soon` bucket; default 30.
1781
- */
1782
- certificateInventory: (opts?: {
1783
- threshold?: number;
1784
- }) => Promise<CertificateInventoryReport>;
1785
- /**
1786
- * Focused "expiring within N days" filter. Default
1787
- * 30. Used by the alert engine and by the panel's
1788
- * "About to expire" widget.
1789
- */
1790
- expiringCertificates: (opts?: {
1791
- days?: number;
1792
- }) => Promise<{
1793
- threshold: number;
1794
- count: number;
1795
- certificates: CertificateInventoryEntry[];
1796
- }>;
1797
- logs: (lines?: number) => Promise<{
1798
- logs: string[];
1799
- }>;
1800
- restart: () => Promise<{
1801
- ok: boolean;
1802
- message?: string;
1803
- }>;
1804
- backupCerts: () => Promise<{
1805
- ok: boolean;
1806
- message?: string;
1807
- filename?: string;
1808
- }>;
1809
- };
1810
- config: {
1811
- list: (query?: {
1812
- category?: string;
1813
- pluginId?: string;
1814
- reveal?: boolean;
1815
- }) => Promise<ConfigListResponse>;
1816
- get: (key: string) => Promise<ConfigItem>;
1817
- set: (key: string, input: SetConfigInput) => Promise<{
1818
- ok: boolean;
1819
- key: string;
1820
- }>;
1821
- delete: (key: string) => Promise<{
1822
- ok: boolean;
1823
- key: string;
1824
- }>;
1825
- };
1826
- plugins: {
1827
- list: () => Promise<PluginListResponse>;
1828
- marketplace: (opts?: {
1829
- refresh?: boolean;
1830
- }) => Promise<MarketplaceCatalogResponse>;
1831
- install: (input: InstallPluginInput) => Promise<{
1832
- ok: boolean;
1833
- id: string;
1834
- status: string;
1835
- }>;
1836
- enable: (id: string) => Promise<{
1837
- ok: boolean;
1838
- id: string;
1839
- status: string;
1840
- }>;
1841
- disable: (id: string) => Promise<{
1842
- ok: boolean;
1843
- id: string;
1844
- status: string;
1845
- }>;
1846
- reload: (id: string) => Promise<{
1847
- ok: boolean;
1848
- id: string;
1849
- status: string;
1850
- }>;
1851
- inspect: (id: string) => Promise<PluginInspectResponse>;
1852
- uninstall: (id: string) => Promise<{
1853
- ok: boolean;
1854
- id: string;
1855
- }>;
1856
- };
1857
- menus: {
1858
- list: (query?: {
1859
- slot?: string;
1860
- }) => Promise<MenuListResponse>;
1861
- };
1862
- demo: {
1863
- seed: () => Promise<DemoSeedResult>;
1864
- };
1865
- logDrains: {
1866
- list: (query?: {
1867
- serviceId?: number;
1868
- }) => Promise<LogDrain[]>;
1869
- get: (id: number) => Promise<LogDrain>;
1870
- create: (input: LogDrainCreateInput) => Promise<LogDrain>;
1871
- update: (id: number, input: LogDrainUpdateInput) => Promise<LogDrain>;
1872
- remove: (id: number) => Promise<{
1873
- ok: boolean;
1874
- }>;
1875
- test: (id: number) => Promise<LogDrainTestResult>;
1876
- /**
1877
- * Search the configured Loki drain for `query` over
1878
- * the last `sinceMinutes` (default 15). The route
1879
- * round-trips to the drain's `url` so the upstream
1880
- * does the heavy lifting; this is the same shape
1881
- * the operator sees in the Loki Grafana panel.
1882
- */
1883
- search: (input: LogSearchInput) => Promise<LogSearchResult>;
1884
- };
1885
- /**
1886
- * Per-workspace email template overrides (G-30).
1887
- * Read-side is open to members; write-side requires the
1888
- * workspace's admin role. The list / preview are safe
1889
- * to call from a CI script; `set` / `reset` mutate the
1890
- * panel's outbound email and should be operator-only.
1891
- */
1892
- emailTemplates: {
1893
- list: (workspaceId: number) => Promise<{
1894
- workspaceId: number;
1895
- templates: EmailTemplateEntry[];
1896
- }>;
1897
- preview: (workspaceId: number, name: EmailTemplateName, vars?: Record<string, string | number | null>) => Promise<EmailTemplateRender>;
1898
- set: (workspaceId: number, name: EmailTemplateName, subject: string, text: string) => Promise<{
1899
- ok: boolean;
1900
- }>;
1901
- reset: (workspaceId: number, name: EmailTemplateName) => Promise<{
1902
- ok: boolean;
1903
- }>;
1904
- };
1905
- housekeeping: {
1906
- getAutoPrune: () => Promise<AutoPruneStatus>;
1907
- updateAutoPrune: (input: AutoPruneConfigUpdateInput) => Promise<AutoPruneStatus>;
1908
- runPrune: () => Promise<AutoPruneRunResult>;
1909
- /**
1910
- * List every image on the host with repo / tag / size /
1911
- * created / dangling / inUse metadata. The companion to
1912
- * the auto-prune cron: this is what the operator
1913
- * inspects before `pruneImages({ keepLast: 5 })`.
1914
- */
1915
- listImages: () => Promise<{
1916
- images: ImageInfo[];
1917
- totalCount: number;
1918
- totalBytes: number;
1919
- }>;
1920
- /**
1921
- * Prune images with operator-supplied filters. `dryRun`
1922
- * returns the candidate set without deleting. Refused
1923
- * when no filter is supplied (a naked prune would
1924
- * delete every unused image).
1925
- */
1926
- pruneImages: (input: PruneImagesInput) => Promise<PruneImagesResult>;
1927
- };
1928
- /** Host-wide analysis + guarded cleanup. */
1929
- doctor: {
1930
- scan: () => Promise<DoctorReport>;
1931
- fix: (input: DoctorFixRequestInput) => Promise<DoctorFixResponse>;
1932
- };
1933
- health: () => Promise<HealthStatus>;
1934
- }
1935
- export interface ContainerInspectData {
1936
- id: string;
1937
- name: string;
1938
- image: string;
1939
- state: {
1940
- status: string;
1941
- running: boolean;
1942
- startedAt: string;
1943
- finishedAt: string;
1944
- exitCode: number;
1945
- error: string;
1946
- };
1947
- labels: Record<string, string>;
1948
- traefikTags: Record<string, string>;
1949
- env: string[];
1950
- ports: Record<string, unknown>;
1951
- mounts: Array<{
1952
- source: string;
1953
- destination: string;
1954
- mode: string;
1955
- rw: boolean;
1956
- }>;
1957
- networks: string[];
1958
- resources: {
1959
- memoryLimitBytes: number;
1960
- cpuShares: number;
1961
- restartPolicy: string;
1962
- };
1963
- raw: unknown;
1964
- }
1965
- export interface ContainerComposeData {
1966
- yaml: string;
1967
- inspect: ContainerInspectData;
1968
- }
1969
- /**
1970
- * Create a typed NineDeploy API client. Used by both the web dashboard and the CLI.
1971
- *
1972
- * @example
1973
- * const client = createClient({ baseUrl: 'http://localhost:3000', getToken: () => token });
1974
- * const services = await client.services.list();
1975
- */
1976
- export declare function createClient(opts: NineDeployClientOptions): NineDeployClient;
5
+ export type { FetchLike, NineDeployClientOptions, } from './transport.js';
6
+ export type { JobKind, ScheduledJob, JobRun, TraefikVersionInfo, TraefikRoutingConfig, HealthStatus, VaultAllowlistView, VaultSettings, TokenIntrospection, TemplateDeployResult, TemplatePrepareResult, ApplyManifestResult, ApplyManifestInput, BackupDrillResult, BackupDrillEntry, LogSearchInput, LogSearchLine, LogSearchResult, EmailTemplateName, EmailTemplateEntry, EmailTemplateRender, PgbouncerStatus, ImageInfo, PruneImagesInput, PruneImagesResult, DomainVerificationChallenge, CreatedDomain, DomainVerifyResult, StartDomainTransferResult, DomainTransferPreview, AcceptDomainTransferInput, AcceptDomainTransferResult, DatabaseCredentialsWithPublic, GithubAppInstallationSync, SourceRepo, SourceUpdateInput, ServerListEntry, ServerRolesResult, SwarmJoinResult, SwarmLeaveResult, VolumeListEntry, VolumeCreateResult, ServiceDetail, NodeTerminalCapability, TerminalListQuery, TrafficQuery, ContainerInspectData, ContainerComposeData, } from './types.js';
7
+ export { DATABASE_IMPORT_FINISHED_STATUSES, } from './databaseImport.js';
8
+ export type { ImportWaitOptions, ImportFileData, ImportFileOptions, } from './databaseImport.js';
9
+ export type { ApiQuery, } from './apiPath.js';
10
+ export { apiGetUrl, } from './apiPath.js';
11
+ export { AGENT_SWARM_MANAGER_VAR, } from './types.js';
12
+ export { TERMINAL_SUBPROTOCOL, TERMINAL_TICKET_PREFIX, TERMINAL_INPUT_CHUNK_BYTES, TERMINAL_PENDING_INPUT_MAX, terminalAttachInfo, terminalCloseMessage, connectTerminal, } from './terminal.js';
13
+ export type { TerminalAttachSource, WebSocketLocation, TerminalAttachInfo, TerminalSocketLike, TerminalSocketFactory, TerminalReady, TerminalHandlers, TerminalConnectOptions, TerminalConnection, } from './terminal.js';
14
+ export { createClient } from './client.js';
15
+ export type { NineDeployClient } from './client.js';
1977
16
  //# sourceMappingURL=index.d.ts.map