unfazed 0.6.1 → 0.8.1
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/CHANGELOG.md +124 -0
- package/README.md +201 -52
- package/REFERENCE.md +298 -0
- package/dist/cli/login.d.ts +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/client.js.map +1 -1
- package/dist/errors.d.ts +64 -0
- package/dist/errors.js +95 -0
- package/dist/errors.js.map +1 -1
- package/dist/generated/gql.d.ts +90 -2
- package/dist/generated/gql.js +24 -2
- package/dist/generated/gql.js.map +1 -1
- package/dist/generated/graphql.d.ts +586 -6
- package/dist/generated/graphql.js +526 -3
- package/dist/generated/graphql.js.map +1 -1
- package/dist/index.d.ts +13 -4
- package/dist/index.js +12 -3
- package/dist/index.js.map +1 -1
- package/dist/operations.d.ts +144 -5
- package/dist/operations.js +448 -7
- package/dist/operations.js.map +1 -1
- package/dist/reference.d.ts +18 -0
- package/dist/reference.generated.d.ts +2 -0
- package/dist/reference.generated.js +5 -0
- package/dist/reference.generated.js.map +1 -0
- package/dist/reference.js +38 -0
- package/dist/reference.js.map +1 -0
- package/dist/unfazed.d.ts +599 -68
- package/dist/unfazed.js +842 -64
- package/dist/unfazed.js.map +1 -1
- package/dist/wait.d.ts +7 -0
- package/dist/wait.js.map +1 -1
- package/dist/workflow/nitro.js +5 -3
- package/dist/workflow/nitro.js.map +1 -1
- package/package.json +8 -4
- package/schema/SOURCE.json +4 -4
- package/schema/schema.graphqls +1704 -30
package/dist/unfazed.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { UnfazedClient, type ClientOptions, type RequestOptions } from "./client.js";
|
|
2
|
-
import type { CreateDeploymentInput, DeploymentFieldsFragment, ListDeploymentsInput, RunFieldsFragment, RunStatus, ServiceMode, ServiceRuntime, SdkCreateWorkspaceMutation, SdkRunHarnessesQuery } from "./generated/graphql.js";
|
|
2
|
+
import type { AppErrorGroupFieldsFragment, CreateDeploymentInput, DeploymentEventType, DeploymentFieldsFragment, FileCommitFieldsFragment, ListDeploymentsInput, RunFieldsFragment, RunStatus, ServiceMode, ServiceRuntime, SdkAppCommitQuery, SdkAppCommitsQuery, SdkAppErrorGroupQuery, SdkAppErrorsQuery, SdkCreateWorkspaceMutation, SdkDeleteAppMutation, SdkDeploymentEventsQuery, SdkEventTypesQuery, SdkPollEventsQuery, SdkRestoreVersionMutation, SdkRunHarnessesQuery, SdkWorkspaceLiveAppsQuery } from "./generated/graphql.js";
|
|
3
3
|
import { type WaitOptions } from "./wait.js";
|
|
4
4
|
/** A deployment as the workflow layer returns it. */
|
|
5
5
|
export type Deployment = DeploymentFieldsFragment;
|
|
@@ -17,16 +17,58 @@ export type RunHarness = SdkRunHarnessesQuery["runHarnesses"][number];
|
|
|
17
17
|
* a listed or a freshly created workspace under one type.
|
|
18
18
|
*/
|
|
19
19
|
export type Workspace = SdkCreateWorkspaceMutation["createWorkspace"]["workspace"];
|
|
20
|
+
/**
|
|
21
|
+
* An app a workspace serves right now, from {@link Unfazed.liveApps}: its
|
|
22
|
+
* alias, the deployment serving it, and the custom domains routing to it
|
|
23
|
+
* (listed for the app's owner only).
|
|
24
|
+
*/
|
|
25
|
+
export type LiveApp = NonNullable<SdkWorkspaceLiveAppsQuery["workspace"]>["liveApps"][number];
|
|
26
|
+
/** What {@link Unfazed.deleteApp} removed, as the server reports it. */
|
|
27
|
+
export type DeleteAppResult = SdkDeleteAppMutation["deleteApp"];
|
|
20
28
|
/** Options for {@link Unfazed.deleteWorkspace}. */
|
|
21
|
-
export type DeleteWorkspaceOptions = {
|
|
29
|
+
export type DeleteWorkspaceOptions = ({
|
|
30
|
+
/**
|
|
31
|
+
* Omitted or `false`: delete the workspace only when it has no
|
|
32
|
+
* deployment records left. The server refuses otherwise, and deletes
|
|
33
|
+
* nothing.
|
|
34
|
+
*/
|
|
35
|
+
withDeployments?: false;
|
|
36
|
+
/** Only with `withDeployments: true`. */
|
|
37
|
+
confirmAliases?: undefined;
|
|
38
|
+
} | {
|
|
22
39
|
/**
|
|
23
40
|
* Also delete every deployment snapshotted from the workspace, stopping
|
|
24
|
-
*
|
|
41
|
+
* its VMs. This takes EVERY app the workspace serves offline, so
|
|
42
|
+
* `confirmAliases` must name them.
|
|
25
43
|
*/
|
|
26
|
-
withDeployments
|
|
44
|
+
withDeployments: true;
|
|
45
|
+
/**
|
|
46
|
+
* Exactly the aliases of the apps the workspace serves
|
|
47
|
+
* ({@link Unfazed.liveApps}), in any order: every app this delete takes
|
|
48
|
+
* offline. `[]` when it serves none (only failed or retired records are
|
|
49
|
+
* left). A missing or extra alias makes the server refuse and delete
|
|
50
|
+
* nothing ({@link UnfazedUnconfirmedAppsError}). The SDK never fills
|
|
51
|
+
* this in for you.
|
|
52
|
+
*/
|
|
53
|
+
confirmAliases: readonly string[];
|
|
54
|
+
}) & {
|
|
27
55
|
/** Resolve `false` instead of throwing when the workspace is not visible. */
|
|
28
56
|
ignoreNotFound?: boolean;
|
|
29
57
|
} & RequestOptions;
|
|
58
|
+
/** The app {@link Unfazed.deleteApp} deletes. */
|
|
59
|
+
export interface AppRef {
|
|
60
|
+
workspaceId: string;
|
|
61
|
+
/** The app's alias in that workspace. */
|
|
62
|
+
alias: string;
|
|
63
|
+
}
|
|
64
|
+
/** Options for {@link Unfazed.deleteApp}. */
|
|
65
|
+
export type DeleteAppOptions = {
|
|
66
|
+
/**
|
|
67
|
+
* Resolve `null` instead of throwing when the app is not in the workspace
|
|
68
|
+
* (already deleted) or the workspace is not visible.
|
|
69
|
+
*/
|
|
70
|
+
ignoreNotFound?: boolean;
|
|
71
|
+
} & RequestOptions;
|
|
30
72
|
/** Options for {@link Unfazed.deleteDeployment}. */
|
|
31
73
|
export type DeleteDeploymentOptions = {
|
|
32
74
|
/** Resolve `false` instead of throwing when the deployment is not visible. */
|
|
@@ -50,6 +92,239 @@ export interface EnvVar {
|
|
|
50
92
|
masked: boolean;
|
|
51
93
|
updatedAt: string;
|
|
52
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* The commit a write made on an app with platform git, exactly as MCP
|
|
97
|
+
* `write_workspace_files` reports it.
|
|
98
|
+
*
|
|
99
|
+
* The three states of a write: SAVED (the call returned: the app's files
|
|
100
|
+
* have it, and the next deploy uses it); COMMITTED (`committed && !waiting`:
|
|
101
|
+
* it is in the app's history, `listCommits`); DEPLOYED (a deploy of those
|
|
102
|
+
* files went READY: `deployService({ wait: true })`, or — only when
|
|
103
|
+
* `deploys` is true — the import of the branch head the write triggers).
|
|
104
|
+
*
|
|
105
|
+
* - `waiting: true` — saved, and the commit waits for the git server; it
|
|
106
|
+
* lands in order. `sha` is null until then. Nothing to retry; await it with
|
|
107
|
+
* {@link Unfazed.waitForCommit} (or `writeFiles(…, { waitForCommit: true })`).
|
|
108
|
+
* - `committed: false` — git already held exactly these files.
|
|
109
|
+
* - `conflicts` — a push changed the same paths meanwhile: the head (`sha`,
|
|
110
|
+
* a merge) keeps the pushed version; yours is `writeSHA`.
|
|
111
|
+
* - `paused` — platform git is paused for recovery: saved, committed later.
|
|
112
|
+
*/
|
|
113
|
+
export type FileCommit = FileCommitFieldsFragment;
|
|
114
|
+
/** One file's outcome in {@link Unfazed.writeFiles}, in the order given. */
|
|
115
|
+
export interface FileWriteOutcome {
|
|
116
|
+
path: string;
|
|
117
|
+
ok: boolean;
|
|
118
|
+
/** Why this path was not written; null when it was. */
|
|
119
|
+
error: string | null;
|
|
120
|
+
/** The written file; null when it was not. */
|
|
121
|
+
file: WorkspaceFile | null;
|
|
122
|
+
}
|
|
123
|
+
/** What {@link Unfazed.writeFiles} wrote (MCP `write_workspace_files`' answer). */
|
|
124
|
+
export interface WriteFilesResult {
|
|
125
|
+
workspaceId: string;
|
|
126
|
+
/** Every file's outcome, in the order of the map. */
|
|
127
|
+
files: FileWriteOutcome[];
|
|
128
|
+
written: number;
|
|
129
|
+
failed: number;
|
|
130
|
+
/** Bytes written (decoded). */
|
|
131
|
+
totalBytes: number;
|
|
132
|
+
/**
|
|
133
|
+
* The commit the call made on an app with platform git; null on any other
|
|
134
|
+
* app, and on a platform too old to report it. A map over one request's
|
|
135
|
+
* limits (100 files, 32 MiB) is several requests and several commits: this
|
|
136
|
+
* is the last, `commits` has them all.
|
|
137
|
+
*/
|
|
138
|
+
commit: FileCommit | null;
|
|
139
|
+
/** One commit per request, in order. Usually exactly one. */
|
|
140
|
+
commits: FileCommit[];
|
|
141
|
+
/**
|
|
142
|
+
* With `waitForCommit`, when a commit was waiting: the branch head once
|
|
143
|
+
* every waiting write had landed (this write is in its history).
|
|
144
|
+
*/
|
|
145
|
+
landed?: CommitsLanded;
|
|
146
|
+
}
|
|
147
|
+
/** A single-file write's answer: the file, and the commit it made. */
|
|
148
|
+
export type WrittenFile = WorkspaceFile & {
|
|
149
|
+
commit: FileCommit | null;
|
|
150
|
+
};
|
|
151
|
+
/** What {@link Unfazed.waitForCommit} saw once no write was waiting. */
|
|
152
|
+
export interface CommitsLanded {
|
|
153
|
+
branch: string;
|
|
154
|
+
/** The branch head: every write made before the wait is in its history. */
|
|
155
|
+
head: string | null;
|
|
156
|
+
/** How long the wait took, in ms. */
|
|
157
|
+
waitedMs: number;
|
|
158
|
+
}
|
|
159
|
+
/** One page of an app's platform git history ({@link Unfazed.listCommits}). */
|
|
160
|
+
export type CommitPage = SdkAppCommitsQuery["appCommits"];
|
|
161
|
+
/** One commit with its diff ({@link Unfazed.getCommit}). */
|
|
162
|
+
export type CommitDetail = SdkAppCommitQuery["appCommit"];
|
|
163
|
+
/** Options for {@link Unfazed.restoreVersion} (MCP `restore_version`). */
|
|
164
|
+
export interface RestoreVersionOptions {
|
|
165
|
+
workspaceId: string;
|
|
166
|
+
/** Full 40-character sha of the commit whose files the app gets back. */
|
|
167
|
+
sha: string;
|
|
168
|
+
/** Refuse, changing nothing, unless the branch head is still this commit. */
|
|
169
|
+
expectedHead?: string;
|
|
170
|
+
/** Message of the new commit; default `Restore <short sha> (<its message>)`. */
|
|
171
|
+
commitMessage?: string;
|
|
172
|
+
/**
|
|
173
|
+
* When the restore deploys (`deploys: true`, an app that deploys every
|
|
174
|
+
* push), wait for that deploy: the platform's wait by commit
|
|
175
|
+
* ({@link Unfazed.waitForDeployment} with `gitCommit`, `alias` and `after`
|
|
176
|
+
* from the answer) resolves once it is READY; {@link UnfazedDeployError}
|
|
177
|
+
* when it or the import of the new commit failed. A link with unfazed.json
|
|
178
|
+
* `apps[]` (no `deployAlias`) deploys once per app: then the wait follows
|
|
179
|
+
* the import until every deployment it made is done.
|
|
180
|
+
*/
|
|
181
|
+
wait?: boolean;
|
|
182
|
+
/** Timeout/backoff for `wait`; default 10 minutes. */
|
|
183
|
+
waitOptions?: WaitOptions;
|
|
184
|
+
signal?: AbortSignal;
|
|
185
|
+
}
|
|
186
|
+
/** What {@link Unfazed.restoreVersion} did. */
|
|
187
|
+
export type RestoreVersionResult = SdkRestoreVersionMutation["restoreAppVersion"] & {
|
|
188
|
+
/**
|
|
189
|
+
* With `wait` and `deploys`: the deployments the restore's import made (one
|
|
190
|
+
* per alias it deploys), READY. Absent without `wait` or when nothing
|
|
191
|
+
* deploys. Without `wait`, wait later with `waitForDeployment({ workspaceId:
|
|
192
|
+
* workspaceID, gitCommit: sha, alias: deployAlias, after: waitAfter })`.
|
|
193
|
+
*/
|
|
194
|
+
deployments?: Deployment[];
|
|
195
|
+
};
|
|
196
|
+
/**
|
|
197
|
+
* The deploy a git import makes of a commit, for
|
|
198
|
+
* {@link Unfazed.waitForDeployment}: a restore, a push or a sync deploys
|
|
199
|
+
* before any deployment id exists, so the commit names it.
|
|
200
|
+
*/
|
|
201
|
+
export interface CommitDeploymentTarget {
|
|
202
|
+
workspaceId: string;
|
|
203
|
+
/** Full 40-character sha. */
|
|
204
|
+
gitCommit: string;
|
|
205
|
+
/** The app that deploys it; required when several apps (unfazed.json `apps[]`) deployed the commit. */
|
|
206
|
+
alias?: string | null;
|
|
207
|
+
/**
|
|
208
|
+
* Count only deployments begun after this point of the platform's
|
|
209
|
+
* deployment order (a restore's `waitAfter`), so an earlier deploy of the
|
|
210
|
+
* same commit never answers.
|
|
211
|
+
*/
|
|
212
|
+
after?: number | null;
|
|
213
|
+
}
|
|
214
|
+
/** A service app's error group (MCP `list_errors`). Title, type, culprit and level are untrusted app text. */
|
|
215
|
+
export type ErrorGroup = AppErrorGroupFieldsFragment;
|
|
216
|
+
/** One page of error groups ({@link Unfazed.listErrors}). */
|
|
217
|
+
export type ErrorGroupPage = SdkAppErrorsQuery["appErrors"];
|
|
218
|
+
/** One error group with its latest occurrence ({@link Unfazed.getErrorGroup}). */
|
|
219
|
+
export type ErrorGroupDetail = SdkAppErrorGroupQuery["appErrorGroup"];
|
|
220
|
+
/** Names one error group of one app. */
|
|
221
|
+
export interface ErrorGroupRef extends AppRef {
|
|
222
|
+
/** The group's id (from listErrors, or `group_id` of an error.new / error.regressed event). */
|
|
223
|
+
groupId: string;
|
|
224
|
+
}
|
|
225
|
+
/** Filter/paging for {@link Unfazed.listErrors}. */
|
|
226
|
+
export interface ListErrorsOptions extends AppRef {
|
|
227
|
+
status?: "open" | "resolved" | "muted";
|
|
228
|
+
/** 1 to 100; default 20. */
|
|
229
|
+
limit?: number;
|
|
230
|
+
/** The previous page's `nextCursor`. */
|
|
231
|
+
cursor?: string;
|
|
232
|
+
}
|
|
233
|
+
/** An event type {@link Unfazed.pollEvents} reads (MCP `list_event_types`). */
|
|
234
|
+
export type EventType = SdkEventTypesQuery["platformEventTypes"][number];
|
|
235
|
+
/** A page of events (MCP `poll_events` / `wait_for_events`). */
|
|
236
|
+
export type EventPage = SdkPollEventsQuery["pollEvents"];
|
|
237
|
+
/** One event: `name` (deployment.finished, service.crashed, error.new, git.conflict, …), and minimal `data`. */
|
|
238
|
+
export type PlatformEvent = EventPage["events"][number];
|
|
239
|
+
/** Which events to read (MCP `poll_events`' input). */
|
|
240
|
+
export interface EventsInput {
|
|
241
|
+
/** Event types; omit for every type you may receive. */
|
|
242
|
+
names?: string[];
|
|
243
|
+
/** Filters per type, keyed by its name: `{ "deployment.finished": { alias: "shop", status: "FAILED" } }`. */
|
|
244
|
+
arguments?: Record<string, Record<string, unknown>>;
|
|
245
|
+
/** Where to continue; omit to start from now (nothing is replayed). */
|
|
246
|
+
cursor?: string;
|
|
247
|
+
/** At most this many events. */
|
|
248
|
+
max?: number;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* A deployment event. `type` is the event's own name — `"service.vm_started"`,
|
|
252
|
+
* `"deployment.build_finished"` — exactly as MCP `list_deployment_events` and
|
|
253
|
+
* `wait_for_deployment` report it.
|
|
254
|
+
*/
|
|
255
|
+
export interface DeploymentEvent {
|
|
256
|
+
id: string;
|
|
257
|
+
deploymentID: string;
|
|
258
|
+
/** The event's name as the platform writes it, e.g. `"deployment.phases"`. */
|
|
259
|
+
type: string;
|
|
260
|
+
/**
|
|
261
|
+
* The GraphQL enum (`SERVICE_VM_STARTED`, …), `UNKNOWN` for every name the
|
|
262
|
+
* enum does not list (`deployment.build_finished`, `deployment.phases`, …).
|
|
263
|
+
* Match on `type` instead.
|
|
264
|
+
*/
|
|
265
|
+
typeEnum: DeploymentEventType;
|
|
266
|
+
/** @deprecated Same as `type` (before 0.8.0 `type` was the enum). */
|
|
267
|
+
rawType: string;
|
|
268
|
+
severity: SdkDeploymentEventsQuery["deploymentEvents"][number]["severity"];
|
|
269
|
+
message: string;
|
|
270
|
+
vmID: string | null;
|
|
271
|
+
/** The event's fields; timing events carry their phases as `*_ms` strings. */
|
|
272
|
+
metadata: Record<string, string> | null;
|
|
273
|
+
/**
|
|
274
|
+
* What a timing event (`deployment.build_finished`, `deployment.phases`)
|
|
275
|
+
* measured, as the platform parsed it; null for any other event.
|
|
276
|
+
* {@link parseDeploymentTimings} prefers it to `metadata`.
|
|
277
|
+
*/
|
|
278
|
+
timings: PlatformTimings | null;
|
|
279
|
+
createdAt: string;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* A deploy's phases as the platform measured them: from `deployment.phases`
|
|
283
|
+
* (recorded when the deploy goes READY) and `deployment.build_finished`.
|
|
284
|
+
* Milliseconds.
|
|
285
|
+
*/
|
|
286
|
+
export interface PlatformTimings {
|
|
287
|
+
/** Deployment created → READY, on the platform's clock. Null until `deployment.phases` is recorded. */
|
|
288
|
+
totalMs: number | null;
|
|
289
|
+
/** The build, as the build VM's host measured it. */
|
|
290
|
+
buildMs: number | null;
|
|
291
|
+
/** Promotion: health probe and alias switch (and a worker's pickup and boot). */
|
|
292
|
+
promoteMs: number | null;
|
|
293
|
+
/**
|
|
294
|
+
* Every other measured phase by name: the build VM's (`vm_install`,
|
|
295
|
+
* `vm_build`, `vm_bundle`, `vm_collect`, `image`, `vm`, `return`,
|
|
296
|
+
* `extract`) and the promotion's (`admission`, `worker_pickup`, `boot`, …).
|
|
297
|
+
*/
|
|
298
|
+
phases: Record<string, number>;
|
|
299
|
+
/** `local` or `worker`. */
|
|
300
|
+
buildMode: string | null;
|
|
301
|
+
artifactTransport: string | null;
|
|
302
|
+
buildMemoryMiB: number | null;
|
|
303
|
+
}
|
|
304
|
+
/** Wall time this client spent on a deploy with `wait: true`. Milliseconds. */
|
|
305
|
+
export interface ClientTimings {
|
|
306
|
+
/** Sending createDeployment until its answer. */
|
|
307
|
+
createMs: number;
|
|
308
|
+
/** Its answer until the client saw the final status. */
|
|
309
|
+
waitMs: number;
|
|
310
|
+
/** `createMs + waitMs`: what the caller waited. Compare with `platform.totalMs`. */
|
|
311
|
+
totalMs: number;
|
|
312
|
+
/** Requests the wait made: one per server-side wait (up to 45 s each), or one per poll. */
|
|
313
|
+
waitRequests: number;
|
|
314
|
+
/** `"server"`: the platform's server-side wait; `"poll"`: polling (platforms without it). */
|
|
315
|
+
waitMode: "server" | "poll";
|
|
316
|
+
}
|
|
317
|
+
/** Both sides of a deploy's time ({@link DeployResult.timings}). */
|
|
318
|
+
export interface DeployTimings {
|
|
319
|
+
client: ClientTimings;
|
|
320
|
+
/** Null when the platform recorded none (yet), or with `timings: false`. */
|
|
321
|
+
platform: PlatformTimings | null;
|
|
322
|
+
}
|
|
323
|
+
/** A deploy's answer: the deployment, and with `wait: true` its timings. */
|
|
324
|
+
export type DeployResult = Deployment & {
|
|
325
|
+
/** With `wait: true`: the platform's phases and this client's wall time. */
|
|
326
|
+
timings?: DeployTimings;
|
|
327
|
+
};
|
|
53
328
|
/**
|
|
54
329
|
* A file's contents for {@link Unfazed.writeFiles}.
|
|
55
330
|
*
|
|
@@ -68,16 +343,31 @@ export type FileContent = string | {
|
|
|
68
343
|
export type FilesMap = Record<string, FileContent>;
|
|
69
344
|
export interface WriteFilesOptions {
|
|
70
345
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
346
|
+
* On an app with platform git: the message of the call's commit. Default
|
|
347
|
+
* names the files. Ignored on other apps.
|
|
348
|
+
*/
|
|
349
|
+
commitMessage?: string;
|
|
350
|
+
/**
|
|
351
|
+
* When the commit waits for the git server (`commit.waiting`), resolve only
|
|
352
|
+
* once it landed ({@link Unfazed.waitForCommit}); `true` or the wait's
|
|
353
|
+
* options. The result's `landed` names the branch head then.
|
|
354
|
+
*/
|
|
355
|
+
waitForCommit?: boolean | WaitOptions;
|
|
356
|
+
/**
|
|
357
|
+
* Resolve with the result even when some files failed, instead of throwing
|
|
358
|
+
* {@link UnfazedWriteError}. Read `failed` and `files[].error` then.
|
|
359
|
+
*/
|
|
360
|
+
allowPartial?: boolean;
|
|
361
|
+
/**
|
|
362
|
+
* Max files per request. Default 100, the platform's per-call limit. A
|
|
363
|
+
* request is ONE commit on an app with platform git, so a map that needs
|
|
364
|
+
* several requests is several commits.
|
|
76
365
|
*/
|
|
77
366
|
batchSize?: number;
|
|
78
367
|
/**
|
|
79
|
-
* Max
|
|
80
|
-
*
|
|
368
|
+
* Max payload bytes per request (text, or base64 as sent). Default 32 MiB,
|
|
369
|
+
* the platform's per-call total. Whichever limit trips first closes a
|
|
370
|
+
* request; a single file over it is still sent, and refused on its own.
|
|
81
371
|
*/
|
|
82
372
|
maxBatchBytes?: number;
|
|
83
373
|
signal?: AbortSignal;
|
|
@@ -97,6 +387,12 @@ export interface DeployOptions {
|
|
|
97
387
|
wait?: boolean;
|
|
98
388
|
/** Backoff/timeout knobs used when `wait` is true. */
|
|
99
389
|
waitOptions?: WaitOptions;
|
|
390
|
+
/**
|
|
391
|
+
* With `wait: true`, read the platform's phase timings once the deploy is
|
|
392
|
+
* READY (one more request) into `result.timings.platform`. Default true;
|
|
393
|
+
* `false` skips the read (`timings.platform` is null).
|
|
394
|
+
*/
|
|
395
|
+
timings?: boolean;
|
|
100
396
|
signal?: AbortSignal;
|
|
101
397
|
}
|
|
102
398
|
export interface DeployServiceOptions extends DeployOptions {
|
|
@@ -115,7 +411,14 @@ export interface DeployStaticOptions extends DeployOptions {
|
|
|
115
411
|
spaMode?: boolean;
|
|
116
412
|
}
|
|
117
413
|
export interface DeployBoxOptions extends DeployOptions {
|
|
118
|
-
/**
|
|
414
|
+
/**
|
|
415
|
+
* VM size. Omit a field for the platform default; the server's
|
|
416
|
+
* `BoxResourcesInput` is authoritative. Today: 4096 MiB RAM (min 512, max
|
|
417
|
+
* 16384), 4 vCPU (max 16) and a 32 GiB disk (max 128), unless the platform
|
|
418
|
+
* operator raised the box's limit; a node may clamp lower. `diskGiB` sizes
|
|
419
|
+
* the disk when it is first created; a later redeploy asking for more grows
|
|
420
|
+
* it before the box boots, and it never shrinks.
|
|
421
|
+
*/
|
|
119
422
|
resources?: {
|
|
120
423
|
memMiB?: number;
|
|
121
424
|
vcpus?: number;
|
|
@@ -319,33 +622,98 @@ export declare class Unfazed {
|
|
|
319
622
|
updatedAt: string;
|
|
320
623
|
}[]>;
|
|
321
624
|
/**
|
|
322
|
-
* Deletes a workspace
|
|
323
|
-
*
|
|
625
|
+
* Deletes a workspace — its files, env and secrets, and a BOX's persistent
|
|
626
|
+
* data disk — and, with `withDeployments`, every app it serves.
|
|
324
627
|
*
|
|
325
|
-
*
|
|
326
|
-
*
|
|
327
|
-
*
|
|
328
|
-
*
|
|
329
|
-
*
|
|
330
|
-
*
|
|
331
|
-
*
|
|
332
|
-
*
|
|
333
|
-
*
|
|
334
|
-
* than cascading and is the safer choice when you are deleting a workspace
|
|
335
|
-
* you did not create:
|
|
628
|
+
* A workspace can serve several apps (each `unfazed.json` `apps[]` entry, or
|
|
629
|
+
* several aliases deployed into it), so deleting one with its deployments is
|
|
630
|
+
* never implicit: **name exactly the apps it takes offline** in
|
|
631
|
+
* `confirmAliases`. The server compares them with the workspace's live apps
|
|
632
|
+
* and refuses, deleting nothing, on a missing or extra alias; the refusal
|
|
633
|
+
* ({@link UnfazedUnconfirmedAppsError}) lists every live app with its
|
|
634
|
+
* domains. The SDK never fills the list in: look it up deliberately with
|
|
635
|
+
* {@link liveApps} and decide. To delete one app and keep the rest, use
|
|
636
|
+
* {@link deleteApp}.
|
|
336
637
|
*
|
|
337
638
|
* ```ts
|
|
338
|
-
* await unfazed.deleteWorkspace(ws.id);
|
|
339
|
-
* await unfazed.deleteWorkspace(ws.id, { withDeployments:
|
|
340
|
-
* await unfazed.deleteWorkspace(id, {
|
|
639
|
+
* await unfazed.deleteWorkspace(ws.id); // only when no deployment is left
|
|
640
|
+
* await unfazed.deleteWorkspace(ws.id, { withDeployments: true, confirmAliases: ["web", "api"] });
|
|
641
|
+
* await unfazed.deleteWorkspace(ws.id, { withDeployments: true, confirmAliases: [] }); // serves no app
|
|
642
|
+
* await unfazed.deleteWorkspace(id, { ignoreNotFound: true }); // false, not a throw
|
|
341
643
|
* ```
|
|
342
644
|
*
|
|
645
|
+
* Without `withDeployments` the server refuses while ANY deployment record
|
|
646
|
+
* is left — FAILED ones included — with `still has deployments; delete them
|
|
647
|
+
* first`. A workspace whose deploys all failed serves no app: delete it with
|
|
648
|
+
* `withDeployments: true, confirmAliases: []`.
|
|
649
|
+
*
|
|
650
|
+
* What is deleted disappears at once — gone from your views, its names and
|
|
651
|
+
* aliases free, its VMs stopped — but the platform keeps it for 30 days:
|
|
652
|
+
* within that time support (the platform operator) can restore it exactly
|
|
653
|
+
* as it was. You cannot restore it yourself; ask support. After 30 days it
|
|
654
|
+
* is erased for good.
|
|
655
|
+
*
|
|
343
656
|
* With `ignoreNotFound` a workspace that is absent (or belongs to someone
|
|
344
657
|
* else — the server returns one indistinguishable sentinel for both, on
|
|
345
658
|
* purpose) resolves to `false` instead of throwing, which makes teardown in
|
|
346
659
|
* a `finally` block idempotent.
|
|
347
660
|
*/
|
|
348
661
|
deleteWorkspace(workspaceId: string, options?: DeleteWorkspaceOptions): Promise<boolean>;
|
|
662
|
+
/**
|
|
663
|
+
* The apps a workspace serves right now, by alias, with the deployment
|
|
664
|
+
* serving each and its custom domains: everything
|
|
665
|
+
* `deleteWorkspace(id, { withDeployments: true, … })` takes offline, and the
|
|
666
|
+
* exact list its `confirmAliases` must name.
|
|
667
|
+
*
|
|
668
|
+
* It is a lookup for you to read, not something to pipe into a delete
|
|
669
|
+
* unseen: check that the apps are the ones you mean to take down.
|
|
670
|
+
*
|
|
671
|
+
* ```ts
|
|
672
|
+
* const live = await unfazed.liveApps(ws.id); // [{ alias: "web", deploymentID, domains: [] }, …]
|
|
673
|
+
* ```
|
|
674
|
+
*
|
|
675
|
+
* Throws {@link UnfazedNotFoundError} when the workspace is absent or not
|
|
676
|
+
* visible to this token.
|
|
677
|
+
*/
|
|
678
|
+
liveApps(workspaceId: string, options?: RequestOptions): Promise<LiveApp[]>;
|
|
679
|
+
/**
|
|
680
|
+
* Deletes ONE app of a workspace and nothing else: every deployment of the
|
|
681
|
+
* alias there (live release, retained releases, failed and building
|
|
682
|
+
* attempts — its VM stops, its URL and custom domains stop serving), its App
|
|
683
|
+
* State, its app-scoped env and secrets, and its integration bindings. The
|
|
684
|
+
* workspace, its files and defaults, its other apps (`otherApps` in the
|
|
685
|
+
* result) and a box's data disk stay.
|
|
686
|
+
*
|
|
687
|
+
* ```ts
|
|
688
|
+
* const gone = await unfazed.deleteApp({ workspaceId: ws.id, alias: "docs" });
|
|
689
|
+
* gone.deployments; // records deleted
|
|
690
|
+
* gone.otherApps; // the workspace's apps still serving, untouched
|
|
691
|
+
* ```
|
|
692
|
+
*
|
|
693
|
+
* In a git-linked workspace pushes and syncs skip the alias while
|
|
694
|
+
* `unfazed.json` `apps[]` still declares it (`skippedOnSync: true`): remove
|
|
695
|
+
* it from `apps[]`, or bring it back with the GraphQL `syncRepo` mutation's
|
|
696
|
+
* `restoreApps` (through {@link client}). The server refuses while a git
|
|
697
|
+
* import of the workspace runs. Owner only.
|
|
698
|
+
*
|
|
699
|
+
* What is deleted disappears at once, but the platform keeps the app for 30
|
|
700
|
+
* days: within that time support (the platform operator) can restore it
|
|
701
|
+
* exactly as it was. You cannot restore it yourself; ask support. After 30
|
|
702
|
+
* days it is erased for good. A custom domain's record stays with the alias,
|
|
703
|
+
* so a restored app serves it again.
|
|
704
|
+
*
|
|
705
|
+
* A delete that stops part-way throws with the server's message, which says
|
|
706
|
+
* so; deleting again finishes it. With `ignoreNotFound`, an app that is not
|
|
707
|
+
* in the workspace (already deleted) or a workspace that is not visible
|
|
708
|
+
* resolves to `null` instead of throwing.
|
|
709
|
+
*/
|
|
710
|
+
deleteApp(app: AppRef, options: DeleteAppOptions & {
|
|
711
|
+
ignoreNotFound: true;
|
|
712
|
+
}): Promise<DeleteAppResult | null>;
|
|
713
|
+
deleteApp(app: AppRef, options?: DeleteAppOptions & {
|
|
714
|
+
ignoreNotFound?: false;
|
|
715
|
+
}): Promise<DeleteAppResult>;
|
|
716
|
+
deleteApp(app: AppRef, options?: DeleteAppOptions): Promise<DeleteAppResult | null>;
|
|
349
717
|
/**
|
|
350
718
|
* Returns the workspace named `name`, creating it only if it does not exist.
|
|
351
719
|
*
|
|
@@ -371,33 +739,58 @@ export declare class Unfazed {
|
|
|
371
739
|
updatedAt: string;
|
|
372
740
|
}>;
|
|
373
741
|
/**
|
|
374
|
-
* Writes many files in
|
|
375
|
-
*
|
|
376
|
-
* The API is one-file-per-mutation, so writing a 12-file app naively costs 12
|
|
377
|
-
* round trips. This batches them into a single GraphQL document with one
|
|
378
|
-
* ALIASED root field per file (`f0: writeWorkspaceTextFile(...)`,
|
|
379
|
-
* `f1: ...`), which the server resolves in one request.
|
|
742
|
+
* Writes many files in ONE request — and, on an app with platform git, ONE
|
|
743
|
+
* commit — exactly as MCP `write_workspace_files` does.
|
|
380
744
|
*
|
|
381
745
|
* ```ts
|
|
382
|
-
* await unfazed.writeFiles(ws.id, {
|
|
746
|
+
* const out = await unfazed.writeFiles(ws.id, {
|
|
383
747
|
* "server.ts": serverCode,
|
|
384
|
-
* "
|
|
748
|
+
* "package.json": JSON.stringify(pkg),
|
|
385
749
|
* "public/logo.png": { bytes: pngBytes },
|
|
386
|
-
* });
|
|
750
|
+
* }, { commitMessage: "Add the server" });
|
|
751
|
+
* out.commit; // { sha, committed, waiting, conflicts, writeSHA, … } or null
|
|
387
752
|
* ```
|
|
388
753
|
*
|
|
389
|
-
*
|
|
390
|
-
*
|
|
391
|
-
* {@link
|
|
392
|
-
*
|
|
754
|
+
* A call is not transactional: files are written in order, each atomically,
|
|
755
|
+
* and a file's failure does not undo the others. When any file fails this
|
|
756
|
+
* throws {@link UnfazedWriteError} (its `result` lists what was written and
|
|
757
|
+
* `failed` what was not; retry only those), unless `allowPartial`. A
|
|
758
|
+
* repeated path keeps its last content.
|
|
759
|
+
*
|
|
760
|
+
* On an app with platform git the commit is made before any file is
|
|
761
|
+
* written: if it fails, the request fails and nothing is written. `commit`
|
|
762
|
+
* may come back `waiting` — the files are saved and the commit lands in
|
|
763
|
+
* order; pass `waitForCommit: true` (or call {@link waitForCommit}) to
|
|
764
|
+
* resolve only once it has. See {@link FileCommit} for saved, committed and
|
|
765
|
+
* deployed.
|
|
766
|
+
*
|
|
767
|
+
* One request carries up to 100 files and 32 MiB; a bigger map is split
|
|
768
|
+
* into several requests, each its own commit (`commits`). On a platform
|
|
769
|
+
* older than the batch write the SDK falls back to one mutation per file
|
|
770
|
+
* (one commit each) and reports `commit: null`.
|
|
771
|
+
*/
|
|
772
|
+
writeFiles(workspaceId: string, files: FilesMap, options?: WriteFilesOptions): Promise<WriteFilesResult>;
|
|
773
|
+
/**
|
|
774
|
+
* Writes one text file: {@link writeFiles} with one entry, so it is one
|
|
775
|
+
* commit with `commitMessage` on an app with platform git, and the answer
|
|
776
|
+
* carries that commit. Throws {@link UnfazedWriteError} when it is refused.
|
|
393
777
|
*/
|
|
394
|
-
|
|
395
|
-
/** Writes one
|
|
396
|
-
writeFile(workspaceId: string, path: string, text: string, options?: RequestOptions): Promise<WorkspaceFile>;
|
|
397
|
-
/** Writes one binary file. Accepts raw bytes or a base64 string. */
|
|
778
|
+
writeFile(workspaceId: string, path: string, text: string, options?: Omit<WriteFilesOptions, "allowPartial" | "batchSize" | "maxBatchBytes">): Promise<WrittenFile>;
|
|
779
|
+
/** Writes one binary file (raw bytes or base64), like {@link writeFile}. */
|
|
398
780
|
writeBinaryFile(workspaceId: string, path: string, content: Uint8Array | ArrayBuffer | {
|
|
399
781
|
base64: string;
|
|
400
|
-
}, options?:
|
|
782
|
+
}, options?: Omit<WriteFilesOptions, "allowPartial" | "batchSize" | "maxBatchBytes">): Promise<WrittenFile>;
|
|
783
|
+
/**
|
|
784
|
+
* Waits until no file write of the app waits for its commit: platform git
|
|
785
|
+
* commits a write at once, but when the git server is slow the write is
|
|
786
|
+
* saved and its commit `waiting`, landing in order. Resolves with the
|
|
787
|
+
* branch head then — every write made before the call is in its history.
|
|
788
|
+
* An app without platform git resolves at once (`head: null`).
|
|
789
|
+
*
|
|
790
|
+
* Default timeout 2 minutes; throws {@link UnfazedTimeoutError} past it
|
|
791
|
+
* (the writes stay saved, and still land).
|
|
792
|
+
*/
|
|
793
|
+
waitForCommit(workspaceId: string, waitOptions?: WaitOptions): Promise<CommitsLanded>;
|
|
401
794
|
/** Lists workspace files (paginated). */
|
|
402
795
|
listFiles(workspaceId: string, input?: {
|
|
403
796
|
limit?: number;
|
|
@@ -453,9 +846,9 @@ export declare class Unfazed {
|
|
|
453
846
|
* takes over the alias when it goes READY. Omitting `alias` lets the server
|
|
454
847
|
* generate one, which means a different app on every call.
|
|
455
848
|
*/
|
|
456
|
-
deployService(options: DeployServiceOptions): Promise<
|
|
849
|
+
deployService(options: DeployServiceOptions): Promise<DeployResult>;
|
|
457
850
|
/** Deploys the workspace as a STATIC site. */
|
|
458
|
-
deployStatic(options: DeployStaticOptions): Promise<
|
|
851
|
+
deployStatic(options: DeployStaticOptions): Promise<DeployResult>;
|
|
459
852
|
/**
|
|
460
853
|
* Deploys a BOX: a persistent always-on Linux VM with a data disk that
|
|
461
854
|
* survives stops and redeploys. A dev machine, not an HTTP service. The
|
|
@@ -480,19 +873,46 @@ export declare class Unfazed {
|
|
|
480
873
|
* await unfazed.deployBox({ workspaceId: ws.id, alias: "dev" }); // re-runnable
|
|
481
874
|
* ```
|
|
482
875
|
*/
|
|
483
|
-
deployBox(options: DeployBoxOptions): Promise<
|
|
876
|
+
deployBox(options: DeployBoxOptions): Promise<DeployResult>;
|
|
484
877
|
/** Escape hatch: deploy with a raw CreateDeploymentInput. */
|
|
485
|
-
deploy(input: CreateDeploymentInput, options?: Omit<DeployOptions, "workspaceId">): Promise<
|
|
878
|
+
deploy(input: CreateDeploymentInput, options?: Omit<DeployOptions, "workspaceId">): Promise<DeployResult>;
|
|
486
879
|
/**
|
|
487
|
-
*
|
|
880
|
+
* Waits until a deployment is READY, throwing {@link UnfazedDeployError} on
|
|
881
|
+
* FAILED or timeout (default 10 minutes).
|
|
882
|
+
*
|
|
883
|
+
* It waits SERVER-SIDE (MCP `wait_for_deployment`): each request blocks on
|
|
884
|
+
* the control plane until the deployment leaves BUILDING — woken by the
|
|
885
|
+
* deploy pipeline itself — or 45 s pass, and comes back with the full
|
|
886
|
+
* deployment; so READY reaches you one round trip after it happens, not at
|
|
887
|
+
* the next poll. A NEW app that starts directly on its server is READY
|
|
888
|
+
* before it serves there; the wait covers that landing too. On a platform
|
|
889
|
+
* without the server-side wait, or when the platform refuses one because
|
|
890
|
+
* the account already holds its cap of waits in progress (16), it polls
|
|
891
|
+
* instead (`waitOptions.mode: "poll"` forces that), every 0.5 s backing
|
|
892
|
+
* off to 3 s by default.
|
|
488
893
|
*
|
|
489
|
-
*
|
|
490
|
-
*
|
|
491
|
-
*
|
|
492
|
-
*
|
|
493
|
-
*
|
|
894
|
+
* Pass a {@link CommitDeploymentTarget} instead of an id to wait for the
|
|
895
|
+
* deploy a git import makes of a commit — a restore, a push or a sync
|
|
896
|
+
* deploys before any id exists. The wait covers the import too, and
|
|
897
|
+
* {@link UnfazedDeployError} carries the import's error when it failed on
|
|
898
|
+
* the commit.
|
|
899
|
+
*
|
|
900
|
+
* ```ts
|
|
901
|
+
* const back = await unfazed.restoreVersion({ workspaceId: ws.id, sha });
|
|
902
|
+
* await unfazed.waitForDeployment({
|
|
903
|
+
* workspaceId: back.workspaceID, gitCommit: back.sha, alias: back.deployAlias, after: back.waitAfter,
|
|
904
|
+
* });
|
|
905
|
+
* ```
|
|
494
906
|
*/
|
|
495
|
-
waitForDeployment(
|
|
907
|
+
waitForDeployment(target: string | CommitDeploymentTarget, waitOptions?: WaitOptions): Promise<Deployment>;
|
|
908
|
+
/**
|
|
909
|
+
* The platform's measured phases of a deploy ({@link PlatformTimings}), as
|
|
910
|
+
* it parses them from all of the deployment's timing events
|
|
911
|
+
* (`Deployment.timings`). Null when it recorded none (a deploy that is
|
|
912
|
+
* still building, or one from before timings existed), or for a deployment
|
|
913
|
+
* you cannot see.
|
|
914
|
+
*/
|
|
915
|
+
getDeploymentTimings(deploymentId: string, options?: RequestOptions): Promise<PlatformTimings | null>;
|
|
496
916
|
/** Reads one deployment by id. Null when absent. */
|
|
497
917
|
getDeployment(deploymentId: string, options?: RequestOptions): Promise<Deployment | null>;
|
|
498
918
|
/** Reads the deployment currently serving an alias. Null when absent. */
|
|
@@ -566,17 +986,23 @@ export declare class Unfazed {
|
|
|
566
986
|
stderrBytes: number;
|
|
567
987
|
tailBytes: number;
|
|
568
988
|
}>;
|
|
569
|
-
/**
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
989
|
+
/**
|
|
990
|
+
* Deployment lifecycle events — build, boot, probe, cron, restarts — the
|
|
991
|
+
* most recent `limit` (default 20), oldest first.
|
|
992
|
+
*
|
|
993
|
+
* `type` is the event's own name, as MCP reports it:
|
|
994
|
+
* `"deployment.build_finished"`, `"deployment.phases"`,
|
|
995
|
+
* `"service.vm_started"`, `"service.crashed"`. (`typeEnum` keeps the GraphQL
|
|
996
|
+
* enum, which reads `UNKNOWN` for names it does not list.) Timing events
|
|
997
|
+
* carry their phases in `metadata`; {@link getDeploymentTimings} turns them
|
|
998
|
+
* into numbers.
|
|
999
|
+
*
|
|
1000
|
+
* ```ts
|
|
1001
|
+
* const events = await unfazed.getEvents(app.id, 50);
|
|
1002
|
+
* events.filter((e) => e.type === "deployment.build_finished");
|
|
1003
|
+
* ```
|
|
1004
|
+
*/
|
|
1005
|
+
getEvents(deploymentId: string, limit?: number, options?: RequestOptions): Promise<DeploymentEvent[]>;
|
|
580
1006
|
/** Restarts a service's VM. */
|
|
581
1007
|
restartService(deploymentId: string, options?: RequestOptions): Promise<{
|
|
582
1008
|
deploymentID: string;
|
|
@@ -597,6 +1023,12 @@ export declare class Unfazed {
|
|
|
597
1023
|
}>;
|
|
598
1024
|
/**
|
|
599
1025
|
* Deletes a deployment: stops its VM, releases its alias, drops its release.
|
|
1026
|
+
* To delete a whole app — every release of the alias, its env, App State and
|
|
1027
|
+
* bindings — use {@link deleteApp}.
|
|
1028
|
+
*
|
|
1029
|
+
* The platform keeps a deleted release for 30 days: within that time
|
|
1030
|
+
* support (the platform operator) can restore it; then it is erased for
|
|
1031
|
+
* good.
|
|
600
1032
|
*
|
|
601
1033
|
* With `ignoreNotFound` a deployment that is absent — or belongs to another
|
|
602
1034
|
* tenant, which the server reports identically so ids cannot be probed —
|
|
@@ -749,6 +1181,90 @@ export declare class Unfazed {
|
|
|
749
1181
|
* run fails loudly instead of silently undoing the first.
|
|
750
1182
|
*/
|
|
751
1183
|
rollback(options: RollbackOptions): Promise<Deployment>;
|
|
1184
|
+
/**
|
|
1185
|
+
* The app's commits, newest first (MCP `list_commits`): `limit` per page
|
|
1186
|
+
* (default 20, max 100), `before: page.nextBefore` for the next. `deployed`
|
|
1187
|
+
* says what every live alias runs; `waitingCommits` counts writes whose
|
|
1188
|
+
* commit has not landed yet.
|
|
1189
|
+
*/
|
|
1190
|
+
listCommits(workspaceId: string, input?: {
|
|
1191
|
+
limit?: number;
|
|
1192
|
+
before?: string;
|
|
1193
|
+
}, options?: RequestOptions): Promise<CommitPage>;
|
|
1194
|
+
/**
|
|
1195
|
+
* One commit (full 40-character sha) with the paths it changed and a
|
|
1196
|
+
* unified diff against its first parent, capped at 64 KiB (MCP
|
|
1197
|
+
* `get_commit`). Commit messages and diffs are untrusted text.
|
|
1198
|
+
*/
|
|
1199
|
+
getCommit(workspaceId: string, sha: string, options?: RequestOptions): Promise<CommitDetail>;
|
|
1200
|
+
/**
|
|
1201
|
+
* Gives the app back the files of an earlier commit as ONE new commit on
|
|
1202
|
+
* its branch (MCP `restore_version`); nothing is rewritten, and a restore is
|
|
1203
|
+
* undone by restoring the commit before it.
|
|
1204
|
+
*
|
|
1205
|
+
* When the app deploys every push (`deploys: true`), the new commit is
|
|
1206
|
+
* imported and deployed like a push. That deploy is queued behind the
|
|
1207
|
+
* restore, so the platform answers before it exists; with `wait: true` the
|
|
1208
|
+
* SDK waits for it by commit on the platform ({@link Unfazed.waitForDeployment}
|
|
1209
|
+
* with `gitCommit: sha`, `alias: deployAlias`, `after: waitAfter`) and
|
|
1210
|
+
* resolves with it READY, or throws {@link UnfazedDeployError} with its
|
|
1211
|
+
* build error or the import's. A link with unfazed.json `apps[]` names no
|
|
1212
|
+
* `deployAlias` and deploys once per app: then it follows the import until
|
|
1213
|
+
* every deployment it made is done.
|
|
1214
|
+
*
|
|
1215
|
+
* ```ts
|
|
1216
|
+
* const page = await unfazed.listCommits(ws.id);
|
|
1217
|
+
* const back = await unfazed.restoreVersion({ workspaceId: ws.id, sha: page.commits[1]!.sha, wait: true });
|
|
1218
|
+
* back.deployments?.[0]?.url;
|
|
1219
|
+
* ```
|
|
1220
|
+
*/
|
|
1221
|
+
restoreVersion(options: RestoreVersionOptions): Promise<RestoreVersionResult>;
|
|
1222
|
+
/** A service app's error groups, most recently seen first (MCP `list_errors`). */
|
|
1223
|
+
listErrors(input: ListErrorsOptions, options?: RequestOptions): Promise<ErrorGroupPage>;
|
|
1224
|
+
/**
|
|
1225
|
+
* One error group with its latest occurrence whole (a Sentry event: stack,
|
|
1226
|
+
* request), its recent occurrences and the deployments it was seen in (MCP
|
|
1227
|
+
* `get_error_group`).
|
|
1228
|
+
*/
|
|
1229
|
+
getErrorGroup(ref: ErrorGroupRef, options?: RequestOptions): Promise<ErrorGroupDetail>;
|
|
1230
|
+
/**
|
|
1231
|
+
* Marks a group resolved in the app's current deployment, once its fix is
|
|
1232
|
+
* deployed (MCP `resolve_error_group`); another deployment reporting it
|
|
1233
|
+
* opens it again. Only on your human's say-so or a fix you verified.
|
|
1234
|
+
*/
|
|
1235
|
+
resolveErrorGroup(ref: ErrorGroupRef, options?: RequestOptions): Promise<ErrorGroup>;
|
|
1236
|
+
/** Mutes an expected group: still counted, never regresses or notifies (MCP `mute_error_group`). */
|
|
1237
|
+
muteErrorGroup(ref: ErrorGroupRef, options?: RequestOptions): Promise<ErrorGroup>;
|
|
1238
|
+
/** Opens a resolved or muted group again (MCP `reopen_error_group`). */
|
|
1239
|
+
reopenErrorGroup(ref: ErrorGroupRef, options?: RequestOptions): Promise<ErrorGroup>;
|
|
1240
|
+
/** The event types, with each one's filters and payload schema (MCP `list_event_types`). */
|
|
1241
|
+
listEventTypes(options?: RequestOptions): Promise<EventType[]>;
|
|
1242
|
+
/**
|
|
1243
|
+
* Events since `cursor` (MCP `poll_events`). Omit `cursor` to start from now
|
|
1244
|
+
* — nothing is replayed — and pass the returned `cursor` back: at once while
|
|
1245
|
+
* `hasMore`, otherwise after `nextPollMs`, or to {@link waitForEvents}.
|
|
1246
|
+
* `truncated` means events may be missing: re-read state.
|
|
1247
|
+
*/
|
|
1248
|
+
pollEvents(input?: EventsInput, options?: RequestOptions): Promise<EventPage>;
|
|
1249
|
+
/**
|
|
1250
|
+
* {@link pollEvents} that waits server-side until an event arrives (MCP
|
|
1251
|
+
* `wait_for_events`), for up to `timeoutMs` (default 45 s; longer waits are
|
|
1252
|
+
* several server waits of up to 45 s, continuing from each cursor). A
|
|
1253
|
+
* timeout is not an error: the page has `timedOut: true`, no events and a
|
|
1254
|
+
* cursor to wait again with. The platform caps an account's waits in
|
|
1255
|
+
* progress (16, deploy waits included); past it this throws an error that
|
|
1256
|
+
* `isTooManyWaits` recognizes: poll then.
|
|
1257
|
+
*
|
|
1258
|
+
* ```ts
|
|
1259
|
+
* let page = await unfazed.pollEvents({ names: ["deployment.finished"] }); // from now
|
|
1260
|
+
* page = await unfazed.waitForEvents({ names: ["deployment.finished"], cursor: page.cursor, timeoutMs: 120_000 });
|
|
1261
|
+
* ```
|
|
1262
|
+
*/
|
|
1263
|
+
waitForEvents(input?: EventsInput & {
|
|
1264
|
+
timeoutMs?: number;
|
|
1265
|
+
}, options?: RequestOptions & {
|
|
1266
|
+
now?: () => number;
|
|
1267
|
+
}): Promise<EventPage>;
|
|
752
1268
|
/**
|
|
753
1269
|
* Starts an agent run.
|
|
754
1270
|
*
|
|
@@ -936,3 +1452,18 @@ export declare class Unfazed {
|
|
|
936
1452
|
truncated: boolean;
|
|
937
1453
|
}>;
|
|
938
1454
|
}
|
|
1455
|
+
/** An event {@link parseDeploymentTimings} reads: `timings` when the platform parsed it, else `metadata`. */
|
|
1456
|
+
export type TimingEvent = Pick<DeploymentEvent, "type" | "metadata"> & {
|
|
1457
|
+
timings?: PlatformTimings | null;
|
|
1458
|
+
};
|
|
1459
|
+
/**
|
|
1460
|
+
* A deploy's phases from its events, as the platform reads them: the latest
|
|
1461
|
+
* `deployment.phases` (written when it went READY: build, promotion and its
|
|
1462
|
+
* split, total) over the latest `deployment.build_finished` (the build VM's
|
|
1463
|
+
* own phases). It prefers the `timings` the platform parsed into each event
|
|
1464
|
+
* ({@link Unfazed.getEvents} reads them); events without them (an older
|
|
1465
|
+
* platform, events built by hand) are parsed from their `*_ms` metadata the
|
|
1466
|
+
* same way. Durations are whole, non-negative milliseconds: anything else is
|
|
1467
|
+
* dropped, as the platform drops it. Null when neither event is there.
|
|
1468
|
+
*/
|
|
1469
|
+
export declare function parseDeploymentTimings(events: readonly TimingEvent[]): PlatformTimings | null;
|