@ninedeploy/sdk 0.3.0 → 0.5.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.
- package/dist/index.d.ts +734 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +105 -10
- package/dist/index.js.map +1 -1
- package/dist/manifest.d.ts +44 -2
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +83 -20
- package/dist/manifest.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { ActiveSession, ActivityEntry, AlertRule, AnalyzeRepoInput, CreateAlertRuleInput, ApiToken, PasskeyCredential, Attachment, CreateServiceVolumeAttachmentInput, CreateVolumeBackupInput, ServiceVolumeAttachment, UpdateServiceVolumeAttachmentInput, Backup, BackupWithDb,
|
|
1
|
+
import type { ActiveSession, ActivityEntry, AlertRule, AnalyzeRepoInput, CreateAlertRuleInput, ApiToken, PasskeyCredential, Attachment, CreateServiceVolumeAttachmentInput, CreateVolumeBackupInput, ServiceVolumeAttachment, UpdateServiceVolumeAttachmentInput, Backup, BackupWithDb, 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, 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
2
|
import { NineDeployError } from './errors.js';
|
|
3
3
|
export { NineDeployError };
|
|
4
4
|
export type * from '@ninedeploy/schemas';
|
|
5
|
-
export { detectProjectKind, formatManifestYaml, ManifestParseError, ManifestValidationError, parseManifestYaml, starterManifest, } from './manifest.js';
|
|
6
|
-
export type { ProjectKind } from './manifest.js';
|
|
5
|
+
export { detectProjectKind, formatManifestYaml, ManifestParseError, ManifestValidationError, parseManifestYaml, starterManifest, buildManifestFromTemplate, } from './manifest.js';
|
|
6
|
+
export type { ProjectKind, TemplateRegistryEntry } from './manifest.js';
|
|
7
7
|
/**
|
|
8
8
|
* Minimal structural fetch type so the SDK is isomorphic (browser + Node)
|
|
9
9
|
* without pulling in DOM lib types. Both `globalThis.fetch` implementations
|
|
@@ -24,6 +24,25 @@ export interface HealthStatus {
|
|
|
24
24
|
version?: string;
|
|
25
25
|
time?: string;
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Result of `GET /v1/auth/token`. Tells the caller what
|
|
29
|
+
* the current bearer credential is and what it can do.
|
|
30
|
+
* `kind` is `'session'` for JWTs and `'api'` for opaque
|
|
31
|
+
* API tokens. `scopes` lists the resource-scoped
|
|
32
|
+
* authorities (or the legacy `read` / `write` / `operator`
|
|
33
|
+
* shorthand); an interactive session reports
|
|
34
|
+
* `['session']` which is implicit full authority.
|
|
35
|
+
*/
|
|
36
|
+
export interface TokenIntrospection {
|
|
37
|
+
kind: 'session' | 'api';
|
|
38
|
+
userId: number;
|
|
39
|
+
scopes: string[];
|
|
40
|
+
expiresAt: string | null;
|
|
41
|
+
isOperator: boolean;
|
|
42
|
+
/** API tokens only. */
|
|
43
|
+
tokenId?: number;
|
|
44
|
+
name?: string;
|
|
45
|
+
}
|
|
27
46
|
export interface TemplateDeployResult {
|
|
28
47
|
serviceId: number;
|
|
29
48
|
serviceName: string;
|
|
@@ -52,6 +71,222 @@ export interface TemplatePrepareResult {
|
|
|
52
71
|
}>;
|
|
53
72
|
stages: TemplateDeployResult['stages'];
|
|
54
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Response from `services.manifest.apply`. The server returns the
|
|
76
|
+
* subset of fields the manifest actually changed under each
|
|
77
|
+
* section; untouched fields stay in the panel-managed column
|
|
78
|
+
* and do not appear in `diff`.
|
|
79
|
+
*/
|
|
80
|
+
export interface ApplyManifestResult {
|
|
81
|
+
ok: boolean;
|
|
82
|
+
serviceId: number;
|
|
83
|
+
/** Sections the server actually wrote: `service`, `build_config`. */
|
|
84
|
+
touched: string[];
|
|
85
|
+
diff: {
|
|
86
|
+
service: {
|
|
87
|
+
port?: number;
|
|
88
|
+
healthPath?: string;
|
|
89
|
+
publishedPort?: number | null;
|
|
90
|
+
};
|
|
91
|
+
build: {
|
|
92
|
+
installCmd?: string;
|
|
93
|
+
buildCmd?: string;
|
|
94
|
+
startCmd?: string;
|
|
95
|
+
baseDir?: string;
|
|
96
|
+
dockerfilePath?: string | null;
|
|
97
|
+
restartPolicy?: string;
|
|
98
|
+
stopGraceSeconds?: number;
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/** Body for `services.manifest.apply`. The manifest shape itself
|
|
103
|
+
* comes from `@ninedeploy/schemas`'s `ninedeployManifest` parser. */
|
|
104
|
+
export interface ApplyManifestInput {
|
|
105
|
+
manifest: NinedeployManifest;
|
|
106
|
+
/** `merge` (default) preserves fields the manifest omits;
|
|
107
|
+
* `replace` is per-field (not per-row) and still leaves
|
|
108
|
+
* unmentioned sections alone. */
|
|
109
|
+
strategy?: 'merge' | 'replace';
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Single row from `GET /v1/databases/:id/drills`. The drill
|
|
113
|
+
* is an engine-specific smoke check (pg_restore --list,
|
|
114
|
+
* redis-check-rdb, mysqldump header parse, ...) that proves
|
|
115
|
+
* a backup is at least parseable without spinning up a real
|
|
116
|
+
* database container. `details` is the engine-specific
|
|
117
|
+
* output (object counts, banner, ...).
|
|
118
|
+
*/
|
|
119
|
+
export interface BackupDrillResult {
|
|
120
|
+
drillId: number;
|
|
121
|
+
ok: true;
|
|
122
|
+
status: 'passed' | 'failed';
|
|
123
|
+
durationMs: number;
|
|
124
|
+
details: Record<string, unknown> | null;
|
|
125
|
+
error: string | null;
|
|
126
|
+
}
|
|
127
|
+
/** History row from `GET /v1/databases/:id/drills`. */
|
|
128
|
+
export interface BackupDrillEntry {
|
|
129
|
+
id: number;
|
|
130
|
+
databaseId: number;
|
|
131
|
+
backupId: number;
|
|
132
|
+
status: 'pending' | 'running' | 'passed' | 'failed';
|
|
133
|
+
engine: string;
|
|
134
|
+
durationMs: number;
|
|
135
|
+
error: string | null;
|
|
136
|
+
details: Record<string, unknown> | null;
|
|
137
|
+
startedAt: number;
|
|
138
|
+
completedAt: number | null;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Body for `POST /v1/log-drains/search` (G-16). The
|
|
142
|
+
* search round-trips to the configured Loki drain.
|
|
143
|
+
*/
|
|
144
|
+
export interface LogSearchInput {
|
|
145
|
+
/** Free-text search (case-insensitive substring). */
|
|
146
|
+
query: string;
|
|
147
|
+
/** Restrict to one service. */
|
|
148
|
+
serviceId?: number;
|
|
149
|
+
/** Window length in minutes (default 15). */
|
|
150
|
+
sinceMinutes?: number;
|
|
151
|
+
/** Hard cap on returned lines (default 200, max 1000). */
|
|
152
|
+
limit?: number;
|
|
153
|
+
/** Query a specific drain. */
|
|
154
|
+
drainId?: number;
|
|
155
|
+
}
|
|
156
|
+
export interface LogSearchLine {
|
|
157
|
+
ts: number;
|
|
158
|
+
line: string;
|
|
159
|
+
service: string | null;
|
|
160
|
+
}
|
|
161
|
+
export interface LogSearchResult {
|
|
162
|
+
drain: {
|
|
163
|
+
id: number;
|
|
164
|
+
name: string;
|
|
165
|
+
type: string;
|
|
166
|
+
};
|
|
167
|
+
serviceId: number | null;
|
|
168
|
+
window: {
|
|
169
|
+
since: string;
|
|
170
|
+
until: string;
|
|
171
|
+
};
|
|
172
|
+
lines: LogSearchLine[];
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Built-in email template names (G-30). The full set
|
|
176
|
+
* lives in `apps/server/src/lib/emailTemplates.ts`; the
|
|
177
|
+
* union here is the closed set the SDK can name. The
|
|
178
|
+
* server validates on the wire (zod enum) — a string
|
|
179
|
+
* the SDK does not know about returns 400.
|
|
180
|
+
*/
|
|
181
|
+
export type EmailTemplateName = 'password-reset' | 'workspace-invitation' | 'domain-transfer' | 'backup-drill-failed';
|
|
182
|
+
/** One row from `GET /v1/workspaces/:wid/email-templates`. */
|
|
183
|
+
export interface EmailTemplateEntry {
|
|
184
|
+
name: EmailTemplateName;
|
|
185
|
+
/** True when the workspace has an override for this name. */
|
|
186
|
+
overridden: boolean;
|
|
187
|
+
/** Override subject; null when the built-in default applies. */
|
|
188
|
+
subject: string | null;
|
|
189
|
+
/** Override text body; null when the built-in default applies. */
|
|
190
|
+
text: string | null;
|
|
191
|
+
}
|
|
192
|
+
/** Result of `POST /v1/workspaces/:wid/email-templates/preview`. */
|
|
193
|
+
export interface EmailTemplateRender {
|
|
194
|
+
subject: string;
|
|
195
|
+
text: string;
|
|
196
|
+
/** True when the rendered text came from a tenant override. */
|
|
197
|
+
overridden: boolean;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Result of `GET /v1/databases/:id/pgbouncer` (and the
|
|
201
|
+
* post-mutation body of the enable / disable routes).
|
|
202
|
+
* `pooledConnectionString` is non-null only when `running`
|
|
203
|
+
* is true — a `docker inspect` failure on the sidecar
|
|
204
|
+
* reports `enabled: true, running: false` so the panel
|
|
205
|
+
* can surface the discrepancy.
|
|
206
|
+
*/
|
|
207
|
+
export interface PgbouncerStatus {
|
|
208
|
+
enabled: boolean;
|
|
209
|
+
containerName: string | null;
|
|
210
|
+
port: number;
|
|
211
|
+
running: boolean;
|
|
212
|
+
poolMode: string | null;
|
|
213
|
+
pooledConnectionString: string | null;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Single image row from `GET /v1/housekeeping/images`. Both
|
|
217
|
+
* the human-readable `size` ("1.2GB") and a parsed byte
|
|
218
|
+
* count are returned so the panel can sort without
|
|
219
|
+
* re-parsing. `inUse` is true when at least one container
|
|
220
|
+
* is currently using the image id.
|
|
221
|
+
*/
|
|
222
|
+
export interface ImageInfo {
|
|
223
|
+
repository: string;
|
|
224
|
+
tag: string;
|
|
225
|
+
id: string;
|
|
226
|
+
size: string;
|
|
227
|
+
sizeBytes: number;
|
|
228
|
+
createdAt: string;
|
|
229
|
+
ageHours: number;
|
|
230
|
+
dangling: boolean;
|
|
231
|
+
inUse: boolean;
|
|
232
|
+
}
|
|
233
|
+
/** Body for `POST /v1/housekeeping/images/prune`. The server
|
|
234
|
+
* refuses the empty-options combination (it would delete
|
|
235
|
+
* every image not currently in use). */
|
|
236
|
+
export interface PruneImagesInput {
|
|
237
|
+
keepLast?: number;
|
|
238
|
+
olderThanHours?: number;
|
|
239
|
+
danglingOnly?: boolean;
|
|
240
|
+
dryRun?: boolean;
|
|
241
|
+
}
|
|
242
|
+
export interface PruneImagesResult {
|
|
243
|
+
freedBytes: number;
|
|
244
|
+
removed: string[];
|
|
245
|
+
removedLabels: string[];
|
|
246
|
+
dryRun: boolean;
|
|
247
|
+
output: string;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Result of `POST /v1/domains/:id/transfer` (start a
|
|
251
|
+
* transfer). The caller forwards `acceptUrl` to the target
|
|
252
|
+
* user out-of-band; the token is the only secret embedded
|
|
253
|
+
* in the URL.
|
|
254
|
+
*/
|
|
255
|
+
export interface StartDomainTransferResult {
|
|
256
|
+
ok: boolean;
|
|
257
|
+
transferId: number;
|
|
258
|
+
acceptUrl: string;
|
|
259
|
+
expiresAt: number;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Result of `GET /v1/domain-transfers/:token` (preview).
|
|
263
|
+
* `effectivelyExpired` is true when the row is still
|
|
264
|
+
* `pending` server-side but `expiresAt` is in the past;
|
|
265
|
+
* the route reports it as `expired` and refuses accept.
|
|
266
|
+
*/
|
|
267
|
+
export interface DomainTransferPreview {
|
|
268
|
+
id: number;
|
|
269
|
+
status: 'pending' | 'accepted' | 'cancelled' | 'expired';
|
|
270
|
+
hostname: string;
|
|
271
|
+
sourceEmail: string;
|
|
272
|
+
targetEmail: string;
|
|
273
|
+
expiresAt: number;
|
|
274
|
+
createdAt: number;
|
|
275
|
+
acceptedAt: number | null;
|
|
276
|
+
cancelledAt: number | null;
|
|
277
|
+
effectivelyExpired: boolean;
|
|
278
|
+
}
|
|
279
|
+
/** Body for `POST /v1/domain-transfers/:token/accept`. */
|
|
280
|
+
export interface AcceptDomainTransferInput {
|
|
281
|
+
targetServiceId: number;
|
|
282
|
+
}
|
|
283
|
+
export interface AcceptDomainTransferResult {
|
|
284
|
+
ok: boolean;
|
|
285
|
+
transferId: number;
|
|
286
|
+
domainId: number;
|
|
287
|
+
serviceId: number;
|
|
288
|
+
hostname: string;
|
|
289
|
+
}
|
|
55
290
|
export interface NineDeployClientOptions {
|
|
56
291
|
/** Base URL of the NineDeploy API, e.g. http://localhost:3000. */
|
|
57
292
|
baseUrl: string;
|
|
@@ -65,6 +300,15 @@ export interface NineDeployClient {
|
|
|
65
300
|
status: () => Promise<{
|
|
66
301
|
initialized: boolean;
|
|
67
302
|
}>;
|
|
303
|
+
/**
|
|
304
|
+
* Introspect the current bearer token. Returns the
|
|
305
|
+
* token's id (when opaque), name, scopes, expiry and
|
|
306
|
+
* the operator flag. Interactive sessions (JWT) report
|
|
307
|
+
* `scopes: ['session']`. The MCP server uses this to
|
|
308
|
+
* discover the token's authority before registering
|
|
309
|
+
* tools.
|
|
310
|
+
*/
|
|
311
|
+
introspectToken: () => Promise<TokenIntrospection>;
|
|
68
312
|
setup: (input: Register) => Promise<Session>;
|
|
69
313
|
register: (input: Register) => Promise<Session>;
|
|
70
314
|
login: (input: Login) => Promise<Session>;
|
|
@@ -107,7 +351,7 @@ export interface NineDeployClient {
|
|
|
107
351
|
};
|
|
108
352
|
me: () => Promise<PublicUser>;
|
|
109
353
|
tokens: {
|
|
110
|
-
create: (input?:
|
|
354
|
+
create: (input?: CreateApiTokenInput) => Promise<CreatedApiToken>;
|
|
111
355
|
list: () => Promise<ApiToken[]>;
|
|
112
356
|
remove: (id: number) => Promise<void>;
|
|
113
357
|
};
|
|
@@ -223,6 +467,23 @@ export interface NineDeployClient {
|
|
|
223
467
|
slug: string;
|
|
224
468
|
message: string;
|
|
225
469
|
}>;
|
|
470
|
+
/**
|
|
471
|
+
* `.ninedeploy` manifest endpoints. The server applies
|
|
472
|
+
* build / run / network sections to the service + build
|
|
473
|
+
* config rows (operator > manifest > DB merge semantics);
|
|
474
|
+
* routes / alerts / database reconcile happens at deploy
|
|
475
|
+
* time via the deploy pipeline and is intentionally
|
|
476
|
+
* outside this endpoint's scope.
|
|
477
|
+
*/
|
|
478
|
+
manifest: {
|
|
479
|
+
/**
|
|
480
|
+
* Push a parsed manifest to the panel and reconcile it
|
|
481
|
+
* into the service. Requires the `admin` role on the
|
|
482
|
+
* service. The response echoes the diff so the CLI can
|
|
483
|
+
* render a one-shot summary without a follow-up GET.
|
|
484
|
+
*/
|
|
485
|
+
apply: (serviceId: number, input: ApplyManifestInput) => Promise<ApplyManifestResult>;
|
|
486
|
+
};
|
|
226
487
|
};
|
|
227
488
|
labels: {
|
|
228
489
|
/** `query` is appended verbatim, e.g. `?workspaceId=1`. */
|
|
@@ -244,6 +505,13 @@ export interface NineDeployClient {
|
|
|
244
505
|
deploymentId: number;
|
|
245
506
|
}>;
|
|
246
507
|
list: (serviceId: number) => Promise<Deployment[]>;
|
|
508
|
+
/**
|
|
509
|
+
* Global deploy queue view: every in-flight (queued / building /
|
|
510
|
+
* deploying) deployment the caller can see, with service + project
|
|
511
|
+
* metadata. The optional `status` filter is a comma-separated token
|
|
512
|
+
* list (e.g. `?status=queued,building`).
|
|
513
|
+
*/
|
|
514
|
+
queue: (query?: string) => Promise<QueueResponse>;
|
|
247
515
|
rollback: (serviceId: number, deploymentId: number) => Promise<{
|
|
248
516
|
deploymentId: number;
|
|
249
517
|
}>;
|
|
@@ -252,6 +520,15 @@ export interface NineDeployClient {
|
|
|
252
520
|
ok: boolean;
|
|
253
521
|
status: string;
|
|
254
522
|
}>;
|
|
523
|
+
/**
|
|
524
|
+
* Remove a finished deployment from history, with its build log.
|
|
525
|
+
* Refused for an in-flight deployment (cancel it first) and for the one
|
|
526
|
+
* currently serving traffic. Requires the `admin` role on the service.
|
|
527
|
+
*/
|
|
528
|
+
remove: (serviceId: number, deploymentId: number) => Promise<{
|
|
529
|
+
ok: boolean;
|
|
530
|
+
id: number;
|
|
531
|
+
}>;
|
|
255
532
|
/** Build-config + env-key diff against the previous deployment. */
|
|
256
533
|
configDiff: (serviceId: number, deploymentId: number) => Promise<{
|
|
257
534
|
deploymentId: number;
|
|
@@ -271,6 +548,257 @@ export interface NineDeployClient {
|
|
|
271
548
|
id: number;
|
|
272
549
|
ssl: boolean;
|
|
273
550
|
}>;
|
|
551
|
+
/** Toggle sticky-session routing for the service (G-28). */
|
|
552
|
+
setStickySession: (serviceId: number, enabled: boolean) => Promise<{
|
|
553
|
+
id: number;
|
|
554
|
+
enabled: boolean;
|
|
555
|
+
active: boolean;
|
|
556
|
+
}>;
|
|
557
|
+
/**
|
|
558
|
+
* Start a domain transfer (G-29). The source user (admin
|
|
559
|
+
* on the source service) names the target email; the
|
|
560
|
+
* server returns a one-time `acceptUrl` to forward. The
|
|
561
|
+
* target user accepts via `acceptDomainTransfer(token,
|
|
562
|
+
* { targetServiceId })`. The transfer expires after 7
|
|
563
|
+
* days; cancelling is one call.
|
|
564
|
+
*/
|
|
565
|
+
transfer: (domainId: number, input: {
|
|
566
|
+
targetEmail: string;
|
|
567
|
+
}) => Promise<StartDomainTransferResult>;
|
|
568
|
+
/**
|
|
569
|
+
* Preview a transfer by token. Does NOT require auth
|
|
570
|
+
* (the token is the secret) — the panel uses this to
|
|
571
|
+
* render the accept page to a logged-out visitor.
|
|
572
|
+
*/
|
|
573
|
+
previewTransfer: (token: string) => Promise<DomainTransferPreview>;
|
|
574
|
+
/**
|
|
575
|
+
* Accept a transfer. The caller must be authenticated
|
|
576
|
+
* and the caller's email must equal the transfer's
|
|
577
|
+
* target email; the panel / CLI surfaces the preview
|
|
578
|
+
* first so the user knows what they're signing in to.
|
|
579
|
+
*/
|
|
580
|
+
acceptTransfer: (token: string, input: AcceptDomainTransferInput) => Promise<AcceptDomainTransferResult>;
|
|
581
|
+
/**
|
|
582
|
+
* Cancel a pending transfer. Only the source user
|
|
583
|
+
* (or an instance operator) can cancel.
|
|
584
|
+
*/
|
|
585
|
+
cancelTransfer: (token: string) => Promise<{
|
|
586
|
+
transferId: number;
|
|
587
|
+
status: 'cancelled';
|
|
588
|
+
}>;
|
|
589
|
+
};
|
|
590
|
+
domainPresets: {
|
|
591
|
+
/** Every `IDomainProvider` the running kernel has registered. */
|
|
592
|
+
list: () => Promise<{
|
|
593
|
+
providers: string[];
|
|
594
|
+
}>;
|
|
595
|
+
/**
|
|
596
|
+
* Manually create the DNS record for `hostname` via the operator's
|
|
597
|
+
* active provider. `content` is optional: when omitted the route
|
|
598
|
+
* falls back to the panel's `dns_records_content` setting, then to
|
|
599
|
+
* `detectPublicIp()`. Returns the upstream recordId so the caller
|
|
600
|
+
* can correlate.
|
|
601
|
+
*/
|
|
602
|
+
apply: (input: {
|
|
603
|
+
hostname: string;
|
|
604
|
+
content?: string;
|
|
605
|
+
}) => Promise<{
|
|
606
|
+
hostname: string;
|
|
607
|
+
provider: string;
|
|
608
|
+
zone: string;
|
|
609
|
+
recordId: string;
|
|
610
|
+
type: 'A' | 'CNAME';
|
|
611
|
+
content: string;
|
|
612
|
+
}>;
|
|
613
|
+
};
|
|
614
|
+
configPresets: {
|
|
615
|
+
/** Every preset the kernel has registered. */
|
|
616
|
+
list: () => Promise<{
|
|
617
|
+
presets: string[];
|
|
618
|
+
}>;
|
|
619
|
+
/** Fetch a single preset's values + description. */
|
|
620
|
+
get: (id: string) => Promise<{
|
|
621
|
+
id: string;
|
|
622
|
+
description: string | null;
|
|
623
|
+
values: Record<string, unknown>;
|
|
624
|
+
createdAt: string;
|
|
625
|
+
}>;
|
|
626
|
+
/** Register a new preset. Throws if `id` already exists. */
|
|
627
|
+
register: (input: {
|
|
628
|
+
id: string;
|
|
629
|
+
description?: string;
|
|
630
|
+
values: Record<string, unknown>;
|
|
631
|
+
}) => Promise<{
|
|
632
|
+
ok: boolean;
|
|
633
|
+
id: string;
|
|
634
|
+
keyCount: number;
|
|
635
|
+
}>;
|
|
636
|
+
/** Write every value in the preset to the live configCenter. */
|
|
637
|
+
apply: (id: string, opts?: {
|
|
638
|
+
override?: Record<string, unknown>;
|
|
639
|
+
}) => Promise<{
|
|
640
|
+
ok: boolean;
|
|
641
|
+
id: string;
|
|
642
|
+
keyCount: number;
|
|
643
|
+
failureCount?: number;
|
|
644
|
+
failures?: Array<{
|
|
645
|
+
key: string;
|
|
646
|
+
status: 'failed';
|
|
647
|
+
reason?: string;
|
|
648
|
+
}>;
|
|
649
|
+
}>;
|
|
650
|
+
/** Unregister a preset. Does NOT undo the apply. */
|
|
651
|
+
remove: (id: string) => Promise<{
|
|
652
|
+
ok: boolean;
|
|
653
|
+
id: string;
|
|
654
|
+
}>;
|
|
655
|
+
};
|
|
656
|
+
metricHistory: {
|
|
657
|
+
/** Current configuration snapshot (backend choice, enabled flag, retention, last-flush). */
|
|
658
|
+
get: () => Promise<{
|
|
659
|
+
enabled: boolean;
|
|
660
|
+
backend: 'builtin' | 'prometheus' | 'influxdb';
|
|
661
|
+
events: string[];
|
|
662
|
+
retentionDays: number;
|
|
663
|
+
lastFlush: {
|
|
664
|
+
ts: number;
|
|
665
|
+
backend: string;
|
|
666
|
+
count: number;
|
|
667
|
+
};
|
|
668
|
+
}>;
|
|
669
|
+
/** Run the built-in backend's retention sweep. Returns the row count trimmed. */
|
|
670
|
+
flush: () => Promise<{
|
|
671
|
+
ok: boolean;
|
|
672
|
+
backend: 'builtin';
|
|
673
|
+
deleted: number;
|
|
674
|
+
}>;
|
|
675
|
+
};
|
|
676
|
+
buildCache: {
|
|
677
|
+
/** Per-backend counters + merged totals. G-01 PR-A. */
|
|
678
|
+
stats: () => Promise<{
|
|
679
|
+
backends: Array<{
|
|
680
|
+
name: string;
|
|
681
|
+
entries: number;
|
|
682
|
+
totalBytes: number;
|
|
683
|
+
hits: number;
|
|
684
|
+
misses: number;
|
|
685
|
+
stores: number;
|
|
686
|
+
evictions: number;
|
|
687
|
+
}>;
|
|
688
|
+
totals: {
|
|
689
|
+
entries: number;
|
|
690
|
+
totalBytes: number;
|
|
691
|
+
hits: number;
|
|
692
|
+
misses: number;
|
|
693
|
+
stores: number;
|
|
694
|
+
evictions: number;
|
|
695
|
+
};
|
|
696
|
+
}>;
|
|
697
|
+
};
|
|
698
|
+
orchestrators: {
|
|
699
|
+
/** Every `IOrchestrator` the running kernel has registered. G-10 PR-A. */
|
|
700
|
+
list: () => Promise<{
|
|
701
|
+
orchestrators: Array<{
|
|
702
|
+
name: string;
|
|
703
|
+
stacks: Array<{
|
|
704
|
+
name: string;
|
|
705
|
+
serviceCount: number;
|
|
706
|
+
}>;
|
|
707
|
+
}>;
|
|
708
|
+
}>;
|
|
709
|
+
/** Stable snapshot of one stack. Returns `null` when the orchestrator has no record. */
|
|
710
|
+
stackStatus: (name: string) => Promise<{
|
|
711
|
+
name: string;
|
|
712
|
+
services: Array<{
|
|
713
|
+
name: string;
|
|
714
|
+
state: 'running' | 'stopped' | 'partial' | 'unknown';
|
|
715
|
+
replicas: number;
|
|
716
|
+
}>;
|
|
717
|
+
appliedAt: string;
|
|
718
|
+
} | null>;
|
|
719
|
+
};
|
|
720
|
+
branding: {
|
|
721
|
+
/** Read the four operator-overridable branding fields. G-30. */
|
|
722
|
+
get: () => Promise<{
|
|
723
|
+
logoUrl: string | null;
|
|
724
|
+
primaryColor: string | null;
|
|
725
|
+
supportEmail: string | null;
|
|
726
|
+
footerHtml: string | null;
|
|
727
|
+
}>;
|
|
728
|
+
/** Set one or more branding fields. Empty strings are stored as `null`. */
|
|
729
|
+
set: (input: {
|
|
730
|
+
logoUrl?: string | null;
|
|
731
|
+
primaryColor?: string | null;
|
|
732
|
+
supportEmail?: string | null;
|
|
733
|
+
footerHtml?: string | null;
|
|
734
|
+
}) => Promise<{
|
|
735
|
+
ok: boolean;
|
|
736
|
+
}>;
|
|
737
|
+
};
|
|
738
|
+
egress: {
|
|
739
|
+
/** Every egress IP rule across every registered driver. G-15. */
|
|
740
|
+
list: () => Promise<{
|
|
741
|
+
drivers: Array<{
|
|
742
|
+
name: string;
|
|
743
|
+
rules: Array<{
|
|
744
|
+
selector: {
|
|
745
|
+
projectId: number;
|
|
746
|
+
sourceCidr?: string;
|
|
747
|
+
};
|
|
748
|
+
ip: string;
|
|
749
|
+
createdAt: string;
|
|
750
|
+
}>;
|
|
751
|
+
}>;
|
|
752
|
+
}>;
|
|
753
|
+
/** Attach an egress IP to a project on the named (or first) driver. */
|
|
754
|
+
set: (input: {
|
|
755
|
+
projectId: number;
|
|
756
|
+
ip: string;
|
|
757
|
+
driver?: string;
|
|
758
|
+
}) => Promise<{
|
|
759
|
+
ok: boolean;
|
|
760
|
+
driver: string;
|
|
761
|
+
rule: {
|
|
762
|
+
selector: {
|
|
763
|
+
projectId: number;
|
|
764
|
+
sourceCidr?: string;
|
|
765
|
+
};
|
|
766
|
+
ip: string;
|
|
767
|
+
createdAt: string;
|
|
768
|
+
};
|
|
769
|
+
}>;
|
|
770
|
+
/** Detach the rule for a project. */
|
|
771
|
+
clear: (projectId: number) => Promise<{
|
|
772
|
+
ok: boolean;
|
|
773
|
+
driver: string;
|
|
774
|
+
}>;
|
|
775
|
+
};
|
|
776
|
+
sso: {
|
|
777
|
+
/** Every configured OIDC / SAML provider. G-22. */
|
|
778
|
+
listProviders: () => Promise<{
|
|
779
|
+
providers: Array<{
|
|
780
|
+
id: number;
|
|
781
|
+
type: 'oidc' | 'saml';
|
|
782
|
+
name: string;
|
|
783
|
+
createdAt: string;
|
|
784
|
+
}>;
|
|
785
|
+
}>;
|
|
786
|
+
/** Add a provider (OIDC issuer URL or SAML metadata URL lives in `config`). */
|
|
787
|
+
addProvider: (input: {
|
|
788
|
+
type: 'oidc' | 'saml';
|
|
789
|
+
name: string;
|
|
790
|
+
config: Record<string, unknown>;
|
|
791
|
+
}) => Promise<{
|
|
792
|
+
ok: boolean;
|
|
793
|
+
id?: number;
|
|
794
|
+
name?: string;
|
|
795
|
+
type?: 'oidc' | 'saml';
|
|
796
|
+
error?: string;
|
|
797
|
+
}>;
|
|
798
|
+
/** Remove a provider by id. */
|
|
799
|
+
removeProvider: (id: number) => Promise<{
|
|
800
|
+
ok: boolean;
|
|
801
|
+
}>;
|
|
274
802
|
};
|
|
275
803
|
volumes: {
|
|
276
804
|
list: () => Promise<VolumeEntry[]>;
|
|
@@ -337,6 +865,12 @@ export interface NineDeployClient {
|
|
|
337
865
|
exportUrl: () => string;
|
|
338
866
|
/** Latest-release check (admin). updateAvailable is null when offline/disabled. */
|
|
339
867
|
updateCheck: (force?: boolean) => Promise<UpdateCheckResult>;
|
|
868
|
+
/** State of a panel-initiated upgrade (idle/running/success/failed/unsupported). */
|
|
869
|
+
updateStatus: () => Promise<SelfUpdateStatus>;
|
|
870
|
+
/** Start upgrading the panel itself to an exact release tag; the updater survives the restart it performs. */
|
|
871
|
+
updateStart: (version: string) => Promise<{
|
|
872
|
+
ok: boolean;
|
|
873
|
+
}>;
|
|
340
874
|
/** Recent docker daemon events (single-shot, for the Docker dashboard feed). */
|
|
341
875
|
dockerEvents: (minutes?: number) => Promise<{
|
|
342
876
|
events: Array<{
|
|
@@ -488,6 +1022,41 @@ export interface NineDeployClient {
|
|
|
488
1022
|
error?: string;
|
|
489
1023
|
}>;
|
|
490
1024
|
};
|
|
1025
|
+
/** Namecheap DNS-record auto-provisioning for added domains (G-07 PR-A). */
|
|
1026
|
+
namecheap: {
|
|
1027
|
+
get: () => Promise<{
|
|
1028
|
+
configured: boolean;
|
|
1029
|
+
apiUser: string | null;
|
|
1030
|
+
clientIp: string | null;
|
|
1031
|
+
hasKey: boolean;
|
|
1032
|
+
}>;
|
|
1033
|
+
set: (input: {
|
|
1034
|
+
apiUser: string;
|
|
1035
|
+
apiKey: string;
|
|
1036
|
+
clientIp: string;
|
|
1037
|
+
}) => Promise<{
|
|
1038
|
+
ok: boolean;
|
|
1039
|
+
apiUser: string;
|
|
1040
|
+
}>;
|
|
1041
|
+
};
|
|
1042
|
+
/**
|
|
1043
|
+
* Master-key rotation. `rotate` re-encrypts every stored secret onto the
|
|
1044
|
+
* highest key version in `NINEDEPLOY_MASTER_KEYS`; it does NOT rewrite
|
|
1045
|
+
* backup envelopes, which is what `warning` reports.
|
|
1046
|
+
*/
|
|
1047
|
+
masterKey: {
|
|
1048
|
+
get: () => Promise<{
|
|
1049
|
+
activeVersion: number;
|
|
1050
|
+
knownVersions: number[];
|
|
1051
|
+
rotatable: boolean;
|
|
1052
|
+
}>;
|
|
1053
|
+
rotate: () => Promise<{
|
|
1054
|
+
rotated: number;
|
|
1055
|
+
activeVersion: number;
|
|
1056
|
+
backupsNotRotated: number;
|
|
1057
|
+
warning: string | null;
|
|
1058
|
+
}>;
|
|
1059
|
+
};
|
|
491
1060
|
};
|
|
492
1061
|
firewall: {
|
|
493
1062
|
status: () => Promise<{
|
|
@@ -550,6 +1119,19 @@ export interface NineDeployClient {
|
|
|
550
1119
|
url: string;
|
|
551
1120
|
expiresAt: string;
|
|
552
1121
|
}>;
|
|
1122
|
+
/**
|
|
1123
|
+
* Operator-only: grant or revoke the INSTANCE-operator flag.
|
|
1124
|
+
*
|
|
1125
|
+
* Not a workspace role — this is the flag that gates operator-only routes
|
|
1126
|
+
* and the host-privilege boundary (PM2/compose deploys, lifecycle hooks,
|
|
1127
|
+
* docker-socket templates). Creating a workspace does NOT confer it. The
|
|
1128
|
+
* last remaining operator cannot be demoted.
|
|
1129
|
+
*/
|
|
1130
|
+
setOperator: (id: number, isOperator: boolean) => Promise<{
|
|
1131
|
+
ok: boolean;
|
|
1132
|
+
id: number;
|
|
1133
|
+
isOperator: boolean;
|
|
1134
|
+
}>;
|
|
553
1135
|
};
|
|
554
1136
|
projects: {
|
|
555
1137
|
/** `query` is appended verbatim, e.g. `?workspaceId=2` (workspace scoping). */
|
|
@@ -594,6 +1176,7 @@ export interface NineDeployClient {
|
|
|
594
1176
|
type: string;
|
|
595
1177
|
eventFilter: string;
|
|
596
1178
|
active: boolean;
|
|
1179
|
+
configJson: string | null;
|
|
597
1180
|
createdAt: string;
|
|
598
1181
|
}>>;
|
|
599
1182
|
createChannel: (input: {
|
|
@@ -601,6 +1184,7 @@ export interface NineDeployClient {
|
|
|
601
1184
|
type: string;
|
|
602
1185
|
target: string;
|
|
603
1186
|
eventFilter?: string;
|
|
1187
|
+
configJson?: string | null;
|
|
604
1188
|
}) => Promise<{
|
|
605
1189
|
id: number;
|
|
606
1190
|
name: string;
|
|
@@ -611,6 +1195,7 @@ export interface NineDeployClient {
|
|
|
611
1195
|
target?: string;
|
|
612
1196
|
eventFilter?: string;
|
|
613
1197
|
active?: boolean;
|
|
1198
|
+
configJson?: string | null;
|
|
614
1199
|
}) => Promise<{
|
|
615
1200
|
id: number;
|
|
616
1201
|
active: boolean;
|
|
@@ -702,6 +1287,38 @@ export interface NineDeployClient {
|
|
|
702
1287
|
stopStudio: (id: number) => Promise<{
|
|
703
1288
|
ok: boolean;
|
|
704
1289
|
}>;
|
|
1290
|
+
/**
|
|
1291
|
+
* PgBouncer sidecar (G-32). Returns the current sidecar
|
|
1292
|
+
* state — `enabled` + `running` + the URL the services
|
|
1293
|
+
* should connect to. Use the same call after
|
|
1294
|
+
* `enablePgbouncer` / `disablePgbouncer` for a fresh
|
|
1295
|
+
* read (the route returns the post-mutation status).
|
|
1296
|
+
*/
|
|
1297
|
+
pgbouncerStatus: (id: number) => Promise<PgbouncerStatus>;
|
|
1298
|
+
/**
|
|
1299
|
+
* Spin up the sidecar. `port` is optional — the row's
|
|
1300
|
+
* existing `pgbouncerPort` (default 6432) is used
|
|
1301
|
+
* when omitted. Only `engine='postgres'` is supported;
|
|
1302
|
+
* the server returns 422 for any other engine.
|
|
1303
|
+
*/
|
|
1304
|
+
enablePgbouncer: (id: number, input?: {
|
|
1305
|
+
port?: number;
|
|
1306
|
+
}) => Promise<PgbouncerStatus>;
|
|
1307
|
+
/** Stop + remove the sidecar and clear the row's flags. */
|
|
1308
|
+
disablePgbouncer: (id: number) => Promise<PgbouncerStatus>;
|
|
1309
|
+
/**
|
|
1310
|
+
* Run an engine-specific smoke check against a backup
|
|
1311
|
+
* file (pg_restore --list, redis-check-rdb, mysqldump
|
|
1312
|
+
* header parse, ...). Returns the drill row with `status`
|
|
1313
|
+
* of `passed` or `failed`; a failed drill is a real
|
|
1314
|
+
* signal that the backup cannot be restored cleanly, not
|
|
1315
|
+
* a warning. Requires the `member` role on the database.
|
|
1316
|
+
*/
|
|
1317
|
+
drillBackup: (id: number, input: {
|
|
1318
|
+
backupId: number;
|
|
1319
|
+
}) => Promise<BackupDrillResult>;
|
|
1320
|
+
/** List the most recent drills for a database, newest first. */
|
|
1321
|
+
drills: (id: number) => Promise<BackupDrillEntry[]>;
|
|
705
1322
|
};
|
|
706
1323
|
attachments: {
|
|
707
1324
|
list: (serviceId: number) => Promise<Attachment[]>;
|
|
@@ -744,6 +1361,18 @@ export interface NineDeployClient {
|
|
|
744
1361
|
}>;
|
|
745
1362
|
/** Detach. The underlying Docker volume is NOT deleted (data persists). */
|
|
746
1363
|
remove: (serviceId: number, attachmentId: number) => Promise<void>;
|
|
1364
|
+
/** Delete a first-boot-baked config file from the volume and queue a
|
|
1365
|
+
* redeploy so the app regenerates it from the current environment
|
|
1366
|
+
* (WordPress wp-config.php et al.). Exactly one of `attachmentId` /
|
|
1367
|
+
* `volumeName` must be set; `filePath` is a single path segment. */
|
|
1368
|
+
repairConfig: (serviceId: number, input: {
|
|
1369
|
+
filePath: string;
|
|
1370
|
+
attachmentId?: number;
|
|
1371
|
+
volumeName?: string;
|
|
1372
|
+
}) => Promise<{
|
|
1373
|
+
ok: boolean;
|
|
1374
|
+
deploymentId: number;
|
|
1375
|
+
}>;
|
|
747
1376
|
};
|
|
748
1377
|
env: {
|
|
749
1378
|
list: (serviceId: number) => Promise<EnvVar[]>;
|
|
@@ -961,6 +1590,29 @@ export interface NineDeployClient {
|
|
|
961
1590
|
get: (id: string) => Promise<Template>;
|
|
962
1591
|
prepare: (id: string, input?: DeployTemplateInput) => Promise<TemplatePrepareResult>;
|
|
963
1592
|
deploy: (id: string, input?: DeployTemplateInput) => Promise<TemplateDeployResult>;
|
|
1593
|
+
/**
|
|
1594
|
+
* Community contributions (G-13). The `list` call
|
|
1595
|
+
* already merges community entries with the curated
|
|
1596
|
+
* catalog; the dedicated `community` namespace lets
|
|
1597
|
+
* the panel surface errors and the operator import
|
|
1598
|
+
* a new template from a PR comment or a file.
|
|
1599
|
+
*/
|
|
1600
|
+
community: {
|
|
1601
|
+
list: () => Promise<CommunityTemplateListResult>;
|
|
1602
|
+
import: (content: string, opts?: {
|
|
1603
|
+
replace?: boolean;
|
|
1604
|
+
}) => Promise<{
|
|
1605
|
+
ok: boolean;
|
|
1606
|
+
id: string;
|
|
1607
|
+
file: string;
|
|
1608
|
+
bytes: number;
|
|
1609
|
+
}>;
|
|
1610
|
+
remove: (id: string) => Promise<{
|
|
1611
|
+
ok: boolean;
|
|
1612
|
+
id: string;
|
|
1613
|
+
removed: boolean;
|
|
1614
|
+
}>;
|
|
1615
|
+
};
|
|
964
1616
|
};
|
|
965
1617
|
limits: {
|
|
966
1618
|
setService: (serviceId: number, input: SetLimitsInput) => Promise<{
|
|
@@ -976,6 +1628,30 @@ export interface NineDeployClient {
|
|
|
976
1628
|
get: () => Promise<TraefikInfo>;
|
|
977
1629
|
status: () => Promise<TraefikStatus>;
|
|
978
1630
|
certificates: () => Promise<TraefikCertificate[]>;
|
|
1631
|
+
/**
|
|
1632
|
+
* Richer certificate inventory (G-15). Same
|
|
1633
|
+
* underlying data as `certificates()` but adds a
|
|
1634
|
+
* `status` classification (valid / expiring-soon /
|
|
1635
|
+
* expired), a `summary` block, and the full set of
|
|
1636
|
+
* fields the Certificates page renders.
|
|
1637
|
+
* `threshold` is the days-out cutoff for the
|
|
1638
|
+
* `expiring-soon` bucket; default 30.
|
|
1639
|
+
*/
|
|
1640
|
+
certificateInventory: (opts?: {
|
|
1641
|
+
threshold?: number;
|
|
1642
|
+
}) => Promise<CertificateInventoryReport>;
|
|
1643
|
+
/**
|
|
1644
|
+
* Focused "expiring within N days" filter. Default
|
|
1645
|
+
* 30. Used by the alert engine and by the panel's
|
|
1646
|
+
* "About to expire" widget.
|
|
1647
|
+
*/
|
|
1648
|
+
expiringCertificates: (opts?: {
|
|
1649
|
+
days?: number;
|
|
1650
|
+
}) => Promise<{
|
|
1651
|
+
threshold: number;
|
|
1652
|
+
count: number;
|
|
1653
|
+
certificates: CertificateInventoryEntry[];
|
|
1654
|
+
}>;
|
|
979
1655
|
logs: (lines?: number) => Promise<{
|
|
980
1656
|
logs: string[];
|
|
981
1657
|
}>;
|
|
@@ -1007,7 +1683,9 @@ export interface NineDeployClient {
|
|
|
1007
1683
|
};
|
|
1008
1684
|
plugins: {
|
|
1009
1685
|
list: () => Promise<PluginListResponse>;
|
|
1010
|
-
marketplace: (
|
|
1686
|
+
marketplace: (opts?: {
|
|
1687
|
+
refresh?: boolean;
|
|
1688
|
+
}) => Promise<MarketplaceCatalogResponse>;
|
|
1011
1689
|
install: (input: InstallPluginInput) => Promise<{
|
|
1012
1690
|
ok: boolean;
|
|
1013
1691
|
id: string;
|
|
@@ -1053,11 +1731,62 @@ export interface NineDeployClient {
|
|
|
1053
1731
|
ok: boolean;
|
|
1054
1732
|
}>;
|
|
1055
1733
|
test: (id: number) => Promise<LogDrainTestResult>;
|
|
1734
|
+
/**
|
|
1735
|
+
* Search the configured Loki drain for `query` over
|
|
1736
|
+
* the last `sinceMinutes` (default 15). The route
|
|
1737
|
+
* round-trips to the drain's `url` so the upstream
|
|
1738
|
+
* does the heavy lifting; this is the same shape
|
|
1739
|
+
* the operator sees in the Loki Grafana panel.
|
|
1740
|
+
*/
|
|
1741
|
+
search: (input: LogSearchInput) => Promise<LogSearchResult>;
|
|
1742
|
+
};
|
|
1743
|
+
/**
|
|
1744
|
+
* Per-workspace email template overrides (G-30).
|
|
1745
|
+
* Read-side is open to members; write-side requires the
|
|
1746
|
+
* workspace's admin role. The list / preview are safe
|
|
1747
|
+
* to call from a CI script; `set` / `reset` mutate the
|
|
1748
|
+
* panel's outbound email and should be operator-only.
|
|
1749
|
+
*/
|
|
1750
|
+
emailTemplates: {
|
|
1751
|
+
list: (workspaceId: number) => Promise<{
|
|
1752
|
+
workspaceId: number;
|
|
1753
|
+
templates: EmailTemplateEntry[];
|
|
1754
|
+
}>;
|
|
1755
|
+
preview: (workspaceId: number, name: EmailTemplateName, vars?: Record<string, string | number | null>) => Promise<EmailTemplateRender>;
|
|
1756
|
+
set: (workspaceId: number, name: EmailTemplateName, subject: string, text: string) => Promise<{
|
|
1757
|
+
ok: boolean;
|
|
1758
|
+
}>;
|
|
1759
|
+
reset: (workspaceId: number, name: EmailTemplateName) => Promise<{
|
|
1760
|
+
ok: boolean;
|
|
1761
|
+
}>;
|
|
1056
1762
|
};
|
|
1057
1763
|
housekeeping: {
|
|
1058
1764
|
getAutoPrune: () => Promise<AutoPruneStatus>;
|
|
1059
1765
|
updateAutoPrune: (input: AutoPruneConfigUpdateInput) => Promise<AutoPruneStatus>;
|
|
1060
1766
|
runPrune: () => Promise<AutoPruneRunResult>;
|
|
1767
|
+
/**
|
|
1768
|
+
* List every image on the host with repo / tag / size /
|
|
1769
|
+
* created / dangling / inUse metadata. The companion to
|
|
1770
|
+
* the auto-prune cron: this is what the operator
|
|
1771
|
+
* inspects before `pruneImages({ keepLast: 5 })`.
|
|
1772
|
+
*/
|
|
1773
|
+
listImages: () => Promise<{
|
|
1774
|
+
images: ImageInfo[];
|
|
1775
|
+
totalCount: number;
|
|
1776
|
+
totalBytes: number;
|
|
1777
|
+
}>;
|
|
1778
|
+
/**
|
|
1779
|
+
* Prune images with operator-supplied filters. `dryRun`
|
|
1780
|
+
* returns the candidate set without deleting. Refused
|
|
1781
|
+
* when no filter is supplied (a naked prune would
|
|
1782
|
+
* delete every unused image).
|
|
1783
|
+
*/
|
|
1784
|
+
pruneImages: (input: PruneImagesInput) => Promise<PruneImagesResult>;
|
|
1785
|
+
};
|
|
1786
|
+
/** Host-wide analysis + guarded cleanup. */
|
|
1787
|
+
doctor: {
|
|
1788
|
+
scan: () => Promise<DoctorReport>;
|
|
1789
|
+
fix: (input: DoctorFixRequestInput) => Promise<DoctorFixResponse>;
|
|
1061
1790
|
};
|
|
1062
1791
|
health: () => Promise<HealthStatus>;
|
|
1063
1792
|
}
|