@toshicloud/sdk 0.5.1 → 0.7.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/README.md +39 -455
- package/dist/client.d.ts +76 -6
- package/dist/client.js +20 -4
- package/dist/gen/toshi/permission_pb.d.ts +12 -0
- package/dist/gen/toshi/permission_pb.js +14 -2
- package/dist/gen/toshi/workspace/v1/connections_pb.d.ts +358 -29
- package/dist/gen/toshi/workspace/v1/connections_pb.js +112 -24
- package/dist/gen/toshi/workspace/v1/domains_pb.d.ts +26 -26
- package/dist/gen/toshi/workspace/v1/domains_pb.js +4 -4
- package/dist/gen/toshi/workspace/v1/{channels_pb.d.ts → endpoints_pb.d.ts} +945 -822
- package/dist/gen/toshi/workspace/v1/endpoints_pb.js +488 -0
- package/dist/gen/toshi/workspace/v1/grants_pb.d.ts +10 -10
- package/dist/gen/toshi/workspace/v1/grants_pb.js +3 -3
- package/dist/gen/toshi/workspace/v1/hostjobs_pb.d.ts +62 -24
- package/dist/gen/toshi/workspace/v1/hostjobs_pb.js +1 -1
- package/dist/gen/toshi/workspace/v1/hosts_pb.d.ts +110 -36
- package/dist/gen/toshi/workspace/v1/hosts_pb.js +1 -1
- package/dist/gen/toshi/workspace/v1/model_credentials_pb.d.ts +654 -0
- package/dist/gen/toshi/workspace/v1/model_credentials_pb.js +110 -0
- package/dist/gen/toshi/workspace/v1/recordings_pb.d.ts +21 -2
- package/dist/gen/toshi/workspace/v1/recordings_pb.js +1 -1
- package/dist/gen/toshi/workspace/v1/roles_pb.d.ts +1 -1
- package/dist/gen/toshi/workspace/v1/roles_pb.js +1 -1
- package/dist/gen/toshi/workspace/v1/secrets_pb.d.ts +19 -2
- package/dist/gen/toshi/workspace/v1/secrets_pb.js +1 -1
- package/dist/gen/toshi/workspace/v1/triggers_pb.d.ts +28 -28
- package/dist/gen/toshi/workspace/v1/triggers_pb.js +6 -6
- package/dist/gen/toshi/workspace/v1/webhook_pb.d.ts +202 -202
- package/dist/gen/toshi/workspace/v1/webhook_pb.js +46 -46
- package/dist/gen/toshi/workspace/v1/workloads_pb.d.ts +579 -30
- package/dist/gen/toshi/workspace/v1/workloads_pb.js +85 -55
- package/dist/gen/toshi/workspace/v1/workspace_pb.d.ts +991 -123
- package/dist/gen/toshi/workspace/v1/workspace_pb.js +294 -102
- package/dist/gen/toshi/workspace/v1/workspace_service_pb.d.ts +390 -8
- package/dist/gen/toshi/workspace/v1/workspace_service_pb.js +75 -50
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/retry.js +38 -22
- package/dist/test/alarms.d.ts +29 -0
- package/dist/test/alarms.js +144 -0
- package/dist/test/fake.js +31 -0
- package/dist/test/index.d.ts +12 -2
- package/dist/test/index.js +12 -2
- package/dist/test/procedures.js +40 -34
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/dist/gen/toshi/workspace/v1/channels_pb.js +0 -483
package/README.md
CHANGED
|
@@ -1,22 +1,34 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="docs/assets/toshi-logo.svg" alt="Toshi" width="120">
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
published as ES modules with type declarations.
|
|
5
|
+
<h1 align="center">toshi-ts</h1>
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
npm install @toshicloud/sdk @bufbuild/protobuf @connectrpc/connect
|
|
8
|
-
```
|
|
7
|
+
<p align="center">The TypeScript SDK for the Toshi API.</p>
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
<p align="center">
|
|
10
|
+
<img alt="licence" src="https://img.shields.io/badge/licence-Apache--2.0-blue">
|
|
11
|
+
<img alt="node" src="https://img.shields.io/badge/node-22%2B-339933">
|
|
12
|
+
<img alt="status" src="https://img.shields.io/badge/status-early-orange">
|
|
13
|
+
</p>
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
<p align="center">
|
|
16
|
+
<a href="docs/usage.md">Get started</a> ·
|
|
17
|
+
<a href="docs/usage.md">Docs</a> ·
|
|
18
|
+
<a href="https://github.com/toshicloud/toshi-ts/issues">Issues</a>
|
|
19
|
+
</p>
|
|
15
20
|
|
|
16
|
-
|
|
21
|
+
A TypeScript client for the Toshi Workspace API, `toshi.workspace.v1`, published as ES modules with type declarations, for Node and browser programs that start jobs, sandboxes and services on Toshi and follow them. It retries safe calls, resumes watches and ships an in-memory fake Toshi for tests.
|
|
17
22
|
|
|
18
|
-
|
|
19
|
-
|
|
23
|
+
> **Early stage.** The package stays at 0.x until a Toshi release serves the API; the latest release is the one to use.
|
|
24
|
+
> Interfaces may change before 1.0.
|
|
25
|
+
> Read the [release notes](https://github.com/toshicloud/toshi-ts/releases) when upgrading.
|
|
26
|
+
|
|
27
|
+
## Quick start
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
npm install @toshicloud/sdk @bufbuild/protobuf @connectrpc/connect @connectrpc/connect-node
|
|
31
|
+
```
|
|
20
32
|
|
|
21
33
|
<!-- examples/quick-start.ts -->
|
|
22
34
|
|
|
@@ -29,450 +41,22 @@ const { projects } = await toshi.project.listProjects({});
|
|
|
29
41
|
console.log(projects.length);
|
|
30
42
|
```
|
|
31
43
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
<!-- examples/browser.ts -->
|
|
35
|
-
|
|
36
|
-
```ts
|
|
37
|
-
import { createConnectTransport } from "@connectrpc/connect-web";
|
|
38
|
-
import { createToshiClient } from "@toshicloud/sdk";
|
|
39
|
-
|
|
40
|
-
// The token the browser app already holds.
|
|
41
|
-
declare const token: string;
|
|
42
|
-
|
|
43
|
-
export const toshi = createToshiClient({
|
|
44
|
-
transport: (interceptors) =>
|
|
45
|
-
createConnectTransport({ baseUrl: "https://toshi.example.com", interceptors }),
|
|
46
|
-
token,
|
|
47
|
-
project: "default",
|
|
48
|
-
});
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
Interceptors of your own go before the client's. The Node entry takes
|
|
52
|
-
`interceptors`; with a transport of your own, put them first:
|
|
53
|
-
`interceptors: [...mine, ...interceptors]`. Each unary call enters them
|
|
54
|
-
once, with its retries inside, and they never see the Authorization
|
|
55
|
-
header: the client sets it on a copy of the request below them.
|
|
56
|
-
|
|
57
|
-
The browser entry reads no environment variable and no file. The Node
|
|
58
|
-
entry reads `TOSHI_SERVER`, `TOSHI_TOKEN`, `TOSHI_TOKEN_FILE` and
|
|
59
|
-
`TOSHI_CA_FILE`; see Node options.
|
|
60
|
-
|
|
61
|
-
### Options
|
|
62
|
-
|
|
63
|
-
- `tokenSource`: a function that gives each request attempt its token, so a
|
|
64
|
-
refreshed token is used without a new client; it wins over `token`. See
|
|
65
|
-
Tokens that change.
|
|
66
|
-
- `token`: sent as `Authorization: Bearer <token>` on every call.
|
|
67
|
-
- `project`, `environment`: fill the request's `project` and
|
|
68
|
-
`environment` fields when they are empty. A value in the request wins.
|
|
69
|
-
`environment` is left empty on a request with `shared: true`.
|
|
70
|
-
- `retry`: `{ maxAttempts, initialBackoffMs, maxBackoffMs }`, by default
|
|
71
|
-
5, 200 ms and 10 s, with full jitter. Reads, and the calls whose request
|
|
72
|
-
takes a `request_key`, are retried; a stream and every other call is not.
|
|
73
|
-
`retry: false` turns off retries and watch reconnects.
|
|
74
|
-
- `defaultTimeoutMs`: bounds each unary call except the Wait calls,
|
|
75
|
-
which their request's timeout bounds; streams ignore it.
|
|
76
|
-
|
|
77
|
-
A call may set `timeoutMs` instead: it bounds the whole call, retries
|
|
78
|
-
included, and on a watch it bounds the open. It composes with `signal`.
|
|
79
|
-
`ToshiOptions` is the object the client takes, and `CallOptions` the second
|
|
80
|
-
argument of each call, which carries `signal` and `timeoutMs`.
|
|
81
|
-
|
|
82
|
-
### Node options
|
|
83
|
-
|
|
84
|
-
`@toshicloud/sdk/node` builds a connect-node transport over HTTP/2 and
|
|
85
|
-
fills what is missing from the environment:
|
|
86
|
-
|
|
87
|
-
- `server`, else `TOSHI_SERVER`: the control plane's URL. Without either,
|
|
88
|
-
the client refuses to start.
|
|
89
|
-
- `tokenSource`, `token`, `tokenFile`, `TOSHI_TOKEN`, `TOSHI_TOKEN_FILE`, in
|
|
90
|
-
that order. A token file is trimmed, and an empty file is an error.
|
|
91
|
-
- `caFile`, else `TOSHI_CA_FILE`: a PEM bundle trusted besides Node's
|
|
92
|
-
built-in roots.
|
|
93
|
-
- `userAgent`: put in front of the User-Agent, for example "myapp/1.2".
|
|
94
|
-
- `interceptors`: run before the client's own, in the order given.
|
|
95
|
-
- `defaultTimeoutMs`: bounds each unary call except the Wait calls,
|
|
96
|
-
which their request's timeout bounds; streams ignore it.
|
|
97
|
-
- `transport`: a transport of your own; then `server` and `caFile` are not
|
|
98
|
-
required.
|
|
99
|
-
|
|
100
|
-
Every request carries `User-Agent: toshi-ts/<version> (node/<node
|
|
101
|
-
version>)`, with `userAgent` and one space in front when it is set. The
|
|
102
|
-
root entry sends no User-Agent: browsers own it.
|
|
103
|
-
|
|
104
|
-
### Tokens that change
|
|
105
|
-
|
|
106
|
-
`tokenSource` gives the client a function it calls for the token of every
|
|
107
|
-
request attempt, so a token that is refreshed, for example from a secret
|
|
108
|
-
manager, is used without a new client. It wins over every other token
|
|
109
|
-
option. The client asks it once per attempt, a retry included, and may
|
|
110
|
-
ask it concurrently, so it must be fast: keep the token somewhere and
|
|
111
|
-
refresh it outside the call. A source that throws, or that answers an
|
|
112
|
-
empty token, fails the call with `UNAUTHENTICATED`, with the error as the
|
|
113
|
-
cause, and the call is not retried.
|
|
114
|
-
|
|
115
|
-
<!-- examples/token-source.ts -->
|
|
116
|
-
|
|
117
|
-
```ts
|
|
118
|
-
// A token a refresh loop replaces; the client asks for it on every call.
|
|
119
|
-
let token = "first-token";
|
|
120
|
-
|
|
121
|
-
export const toshi = createToshiClient({
|
|
122
|
-
project: "default",
|
|
123
|
-
tokenSource: () => token,
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
export function rotate(next: string): void {
|
|
127
|
-
token = next;
|
|
128
|
-
}
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
A token file, from `tokenFile` or `TOSHI_TOKEN_FILE`, is read again
|
|
132
|
-
before a request when its modification time or size has changed, so a
|
|
133
|
-
rotated token, such as a Kubernetes projected service account token, is
|
|
134
|
-
picked up without a new client.
|
|
135
|
-
|
|
136
|
-
### The client's shape
|
|
137
|
-
|
|
138
|
-
The client has one field per Workspace API service: `project`, `secret`,
|
|
139
|
-
`webhook`, `display`, `channel`, `recording`, `volume`, `artifact`,
|
|
140
|
-
`artifactUpload`, `workspace`, `hostJob`, `host`, `token`, `auditEvent`,
|
|
141
|
-
`filler`, `grant`, `storageProvider`, `product`, `discovery`, `connection`,
|
|
142
|
-
`role`, `trigger`, `account`, `image` and `domain`, each holding that service's
|
|
143
|
-
generated client.
|
|
144
|
-
`workload` holds `WorkloadService`'s calls, grouped by the type they
|
|
145
|
-
name: `workload.jobs`, `workload.sandboxes` and `workload.services`, one
|
|
146
|
-
method for each call (`create`, `get`, `list`, `update`, `delete`, `wait`,
|
|
147
|
-
`watch`, and `cancel` on a job, `execute`, `start` and `stop` on a sandbox,
|
|
148
|
-
`start`, `stop`, `setMode`, `listRuns`, `wake`, `hold`, `release`,
|
|
149
|
-
`listRevisions`, `getRevision`, `rollback` and `listActivations` on a
|
|
150
|
-
service). The calls that
|
|
151
|
-
span the three types sit on `workload` itself: `listEvents`, `watchEvents`,
|
|
152
|
-
`getOperation` and `waitOperation`. `run` sits at the top of the client, as
|
|
153
|
-
`toshi run` sits at the top of the CLI.
|
|
154
|
-
|
|
155
|
-
<!-- examples/client-shape.ts -->
|
|
156
|
-
|
|
157
|
-
```ts
|
|
158
|
-
const { jobs } = await toshi.workload.jobs.list({ pageSize: 10 });
|
|
159
|
-
const { job } = await toshi.workload.jobs.get({ id: jobs[0].id });
|
|
160
|
-
console.log(job?.id);
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
### Lists
|
|
164
|
-
|
|
165
|
-
`workload.jobs.all`, `workload.sandboxes.all`,
|
|
166
|
-
`workload.sandboxes.allPreviewShareLinks`, `workload.services.all`,
|
|
167
|
-
`workload.services.allRuns` and `workload.allEvents` take the request their
|
|
168
|
-
`list` method takes and yield every item, one page after another. Each
|
|
169
|
-
response's `nextPageToken` becomes the next request's `pageToken`, and a
|
|
170
|
-
`pageToken` in the request resumes from that page. A service with no
|
|
171
|
-
`all` method is one `paginate` call away: it takes the list call and a
|
|
172
|
-
function that picks a response's items.
|
|
173
|
-
|
|
174
|
-
<!-- examples/lists.ts -->
|
|
175
|
-
|
|
176
|
-
```ts
|
|
177
|
-
import { paginate } from "@toshicloud/sdk";
|
|
44
|
+
The Node entry reads `TOSHI_SERVER` and `TOSHI_TOKEN` from the environment; the [usage guide](docs/usage.md) continues from there, including the browser entry.
|
|
178
45
|
|
|
179
|
-
|
|
46
|
+
## Documentation
|
|
180
47
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
(req, opts) => toshi.project.listProjects(req, opts),
|
|
190
|
-
(resp) => resp.projects,
|
|
191
|
-
)) {
|
|
192
|
-
console.log(project.name);
|
|
193
|
-
}
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
`paginate` sends a copy of the request, so the caller's request keeps its
|
|
197
|
-
fields. Every page is a call of its own, so `opts` goes to each one, and
|
|
198
|
-
`timeoutMs` bounds a page and not the whole iteration. An error throws once
|
|
199
|
-
and ends the iteration; leaving the loop sends no further request.
|
|
200
|
-
`PageRequest` is a list request, which may name the page to read first with
|
|
201
|
-
`pageToken`, and `PageResponse` a list response, which names the page after
|
|
202
|
-
it with `nextPageToken`.
|
|
203
|
-
|
|
204
|
-
### Retries
|
|
205
|
-
|
|
206
|
-
The client retries a read, and a write that carries a request key, when
|
|
207
|
-
the connection fails: a `ConnectError` with code `Unavailable`, a
|
|
208
|
-
connection reset or destroyed stream that `@connectrpc/connect-node`
|
|
209
|
-
reports, or a stream the server refused before reading it
|
|
210
|
-
(`REFUSED_STREAM`). A write that takes a request key gets a random one when the
|
|
211
|
-
request has none, so the server applies a retried write once. Other
|
|
212
|
-
writes are never retried.
|
|
213
|
-
|
|
214
|
-
A `ResourceExhausted` refusal that names how long to wait, as the API's
|
|
215
|
-
rate limit does, is retried the same way. The wait comes from its
|
|
216
|
-
`google.rpc.RetryInfo` detail, else from its `Retry-After` header. So is an
|
|
217
|
-
HTTP 429 with a `Retry-After`, which reaches the client as `Unavailable`.
|
|
218
|
-
The client waits the longer of that wait and the backoff, never more than
|
|
219
|
-
`maxBackoffMs`, and stops when the call's signal aborts. A
|
|
220
|
-
`ResourceExhausted` that names no wait, such as a plan's limit, reaches the
|
|
221
|
-
caller unchanged, as do every other error the server sends, including
|
|
222
|
-
`Aborted` and `InvalidArgument`, and any connection failure the client
|
|
223
|
-
cannot tell apart from a server error.
|
|
224
|
-
|
|
225
|
-
`RetryPolicy` says how often and how long a call is retried, `maxAttempts`
|
|
226
|
-
counting the first try; `defaultRetryPolicy` is the default — five
|
|
227
|
-
attempts, a 200 ms initial backoff and a 10 s cap.
|
|
228
|
-
|
|
229
|
-
### Waiting and watching
|
|
230
|
-
|
|
231
|
-
- `workload.jobs.wait(req)`, `workload.sandboxes.wait(req)` and
|
|
232
|
-
`workload.services.wait(req)` ask again until the workload reaches the
|
|
233
|
-
state; `workload.waitOperation(req)` asks until the operation is done. A
|
|
234
|
-
call starts at least a second, and at most 1.2 seconds, after the start of
|
|
235
|
-
the one before, and a signal ends a pause with its own error.
|
|
236
|
-
- `workload.getOperation(req)` returns one operation by id: a call that
|
|
237
|
-
takes long hands one back, and this asks for it again.
|
|
238
|
-
- An event's payload says what happened: a trigger's `TriggerResult` names
|
|
239
|
-
the key's `reason` and its workload, and with `process_exited` or
|
|
240
|
-
`setup_failed` it carries the sandbox's `exitCode` and `message`.
|
|
241
|
-
- `workload.listEvents(req)` returns the events after a cursor, oldest
|
|
242
|
-
first, a page at a time, for a client that polls or catches up after
|
|
243
|
-
downtime; `workload.watchEvents(req)` is the live form.
|
|
244
|
-
- `workload.jobs.watch(req)`, `workload.sandboxes.watch(req)`,
|
|
245
|
-
`workload.services.watch(req)`, `workload.watchEvents(req)` and
|
|
246
|
-
`workload.jobs.watchOutput(req)` resolve to a watch you read with
|
|
247
|
-
`for await`. A watch opens its stream when you start reading and
|
|
248
|
-
reconnects after a connection failure from where it stopped: `cursor`
|
|
249
|
-
for the typed watches and events, `offsets` (bytes, as `bigint`) for
|
|
250
|
-
output. With no cursor, a typed watch lists that type first, and
|
|
251
|
-
`snapshot` holds them once its promise resolves; `watchEvents`
|
|
252
|
-
yields the past events page by page before the live ones. `close()` or
|
|
253
|
-
leaving the loop ends the stream. The output watch ends at the output's
|
|
254
|
-
end.
|
|
255
|
-
- Every watch yields the stream's responses: a job watch yields
|
|
256
|
-
`WatchJobsResponse` (`job`, `cursor`, `type`), an event watch yields
|
|
257
|
-
`WatchEventsResponse` (`event`), and the output watch yields
|
|
258
|
-
`WatchOutputResponse` (`stdout`, `stderr` or `end`).
|
|
259
|
-
|
|
260
|
-
<!-- examples/watch-events.ts -->
|
|
261
|
-
|
|
262
|
-
```ts
|
|
263
|
-
const id = "workload-id";
|
|
264
|
-
const watch = await toshi.workload.watchEvents({ workloadId: id });
|
|
265
|
-
for await (const { event } of watch) {
|
|
266
|
-
console.log(event?.name);
|
|
267
|
-
}
|
|
268
|
-
// watch.cursor resumes a later watch after the last event read.
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
Every helper takes `{ signal }`, an `AbortSignal` that ends it.
|
|
272
|
-
|
|
273
|
-
### Running a command
|
|
274
|
-
|
|
275
|
-
`workload.sandboxes.execute(start)` runs a command in a running sandbox
|
|
276
|
-
and resolves once the server has started it. The process is one stream of output chunks, `{ stream: "stdout" |
|
|
277
|
-
"stderr", data: Uint8Array }`. `write` sends standard input in frames of
|
|
278
|
-
at most 64 KiB and resolves once the stream has taken the last one; await
|
|
279
|
-
it before the next `write`, which is refused while one is pending, so the
|
|
280
|
-
client holds at most one buffer of input. `closeStdin` ends standard input
|
|
281
|
-
after a pending write, and a later `write` is refused. `wait` settles when
|
|
282
|
-
the command ends.
|
|
283
|
-
|
|
284
|
-
<!-- examples/execute.ts -->
|
|
285
|
-
|
|
286
|
-
```ts
|
|
287
|
-
const id = "sandbox-id";
|
|
288
|
-
const proc = await toshi.workload.sandboxes.execute({
|
|
289
|
-
sandboxId: id,
|
|
290
|
-
command: { argv: ["cat"] },
|
|
291
|
-
});
|
|
292
|
-
await proc.write("hello\n");
|
|
293
|
-
await proc.closeStdin();
|
|
294
|
-
for await (const chunk of proc) {
|
|
295
|
-
process[chunk.stream].write(chunk.data);
|
|
296
|
-
}
|
|
297
|
-
await proc.wait(); // rejects with ExitError on a non-zero exit
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
Without a loop, `wait()` reads and drops the output itself. It rejects
|
|
301
|
-
with `ExitError` when the command fails, is cancelled or ends without an
|
|
302
|
-
exit status, and with `StreamLostError` when the stream ends first. The
|
|
303
|
-
client never runs a command again by itself. Standard input cannot be
|
|
304
|
-
replayed, so the caller decides whether to start again with the same
|
|
305
|
-
`requestKey`. Leaving the loop early cancels the stream, and `wait()`
|
|
306
|
-
then rejects with a `Canceled` error.
|
|
307
|
-
|
|
308
|
-
Execute needs a bidirectional stream: `@connectrpc/connect-node` with
|
|
309
|
-
`httpVersion: "2"`. In a browser, `execute` rejects at once and makes no
|
|
310
|
-
call. Over a transport without HTTP/2, the call fails with the
|
|
311
|
-
transport's or the server's error.
|
|
312
|
-
|
|
313
|
-
### Running a job
|
|
314
|
-
|
|
315
|
-
`run(req)` creates a job with a `CreateJobRequest` and resolves to the
|
|
316
|
-
job and its output, which is what `toshi run` does: `CreateJob`, then
|
|
317
|
-
`WatchOutput`. It yields output chunks like an execution, and `wait()`
|
|
318
|
-
resolves when the job exits 0 and rejects with `JobExitError` otherwise.
|
|
319
|
-
|
|
320
|
-
<!-- examples/run-job.ts -->
|
|
321
|
-
|
|
322
|
-
```ts
|
|
323
|
-
const run = await toshi.run({
|
|
324
|
-
spec: { command: { argv: ["./test.sh"] } },
|
|
325
|
-
});
|
|
326
|
-
for await (const chunk of run) {
|
|
327
|
-
process[chunk.stream].write(chunk.data);
|
|
328
|
-
}
|
|
329
|
-
await run.wait(); // rejects with JobExitError on a non-zero exit
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
Stopping the loop stops only the output stream: the job keeps running,
|
|
333
|
-
and `workload.jobs.cancel` ends it.
|
|
334
|
-
|
|
335
|
-
## Products that are off
|
|
336
|
-
|
|
337
|
-
A call for a product that is off for the workspace rejects with a
|
|
338
|
-
`ProductError`, `wait`, the watches and `execute` included.
|
|
339
|
-
`isProductError(err)` tells it apart. It is still a `ConnectError` with the
|
|
340
|
-
same `code`, and it has the product's ID (`product`), the `reason`
|
|
341
|
-
(`ProductReason.Unavailable`), the input that turned the product off
|
|
342
|
-
(`productCause`: `build`, `operator`, `plan` or `workspace`) and, for a
|
|
343
|
-
product the deployment turns off, how far it has wound down (`state`:
|
|
344
|
-
`no_new_work`, `draining` or `stopped`).
|
|
345
|
-
|
|
346
|
-
<!-- examples/product-error.ts -->
|
|
347
|
-
|
|
348
|
-
```ts
|
|
349
|
-
import { isProductError } from "@toshicloud/sdk";
|
|
350
|
-
|
|
351
|
-
import { toshi } from "./client.js";
|
|
352
|
-
|
|
353
|
-
// Turn a product on for the workspace.
|
|
354
|
-
const enable = { id: "acme_ci", enabled: true };
|
|
355
|
-
try {
|
|
356
|
-
await toshi.product.updateProduct(enable);
|
|
357
|
-
} catch (err) {
|
|
358
|
-
if (!isProductError(err)) {
|
|
359
|
-
throw err;
|
|
360
|
-
}
|
|
361
|
-
// Off for the workspace: which product, the input that turns it off, and,
|
|
362
|
-
// for the deployment's config, how far it has wound down.
|
|
363
|
-
console.log(err.product, err.productCause, err.state);
|
|
364
|
-
}
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
## Refusals with a reason
|
|
368
|
-
|
|
369
|
-
A refusal that is not a product's rejects with a `RefusalError`;
|
|
370
|
-
`isRefusalError(err)` tells it apart. It is still a `ConnectError` with the
|
|
371
|
-
same `code`, and its `reason` is one of `RefusalReason`:
|
|
372
|
-
`RefusalReason.ImageInUse` when an image a workload or a revision still uses
|
|
373
|
-
cannot be deleted, `RefusalReason.ImageNotReady` when a job, a sandbox or a
|
|
374
|
-
service revision names a workspace image with no ready version,
|
|
375
|
-
`RefusalReason.PlanExcludesImages` when the plan has no images, `RefusalReason.LastIdentity` when the caller's last identity cannot
|
|
376
|
-
be unlinked, and so on for images, volumes, roles and display sessions.
|
|
377
|
-
|
|
378
|
-
`workload.services.rollback` asks the revision's registry whether it still
|
|
379
|
-
serves the revision's image before it selects it, and refuses with
|
|
380
|
-
`RefusalReason.ImageNotServed` when the registry answered that it does not
|
|
381
|
-
serve the image, or `RefusalReason.ImageCheckFailed` when it could not say.
|
|
382
|
-
A revision's `imageCheck` carries the last answer: its `outcome`, the
|
|
383
|
-
registry's `status` and `message`, and when it was asked, `checkedAt`.
|
|
384
|
-
Reading a revision asks no registry.
|
|
385
|
-
|
|
386
|
-
## Testing with `@toshicloud/sdk/test`
|
|
387
|
-
|
|
388
|
-
`createFake()` serves the whole Workspace API in memory: no server, no port,
|
|
389
|
-
nothing to close, and no Node module, so it runs in the same runtimes as the
|
|
390
|
-
client. `fake.client()` returns a `ToshiClient` wired to it, with the token
|
|
391
|
-
`test-token` and the scope `default`/`production`, which is enough to drive
|
|
392
|
-
`run`, the watchers and the generated clients from a test.
|
|
393
|
-
|
|
394
|
-
<!-- examples/testing.ts -->
|
|
395
|
-
|
|
396
|
-
```ts
|
|
397
|
-
import { createFake } from "@toshicloud/sdk/test";
|
|
398
|
-
|
|
399
|
-
const fake = createFake();
|
|
400
|
-
fake.job("job-1").stdout("deployed\n").exitCode(0);
|
|
401
|
-
|
|
402
|
-
const toshi = fake.client();
|
|
403
|
-
const run = await toshi.run({ spec: { command: { argv: ["./deploy.sh"] } } });
|
|
404
|
-
for await (const chunk of run) {
|
|
405
|
-
process[chunk.stream].write(chunk.data);
|
|
406
|
-
}
|
|
407
|
-
await run.wait();
|
|
408
|
-
```
|
|
409
|
-
|
|
410
|
-
`fake.on(method, impl)` replaces the state machine for one method with a hook
|
|
411
|
-
typed by that method: one call for unary, server-stream and bidirectional
|
|
412
|
-
methods alike. `fake.calls()` returns every call the fake received, oldest
|
|
413
|
-
first, with the procedure, the request and the headers.
|
|
414
|
-
|
|
415
|
-
## Generated code
|
|
416
|
-
|
|
417
|
-
`src/gen/toshi/workspace/v1/` is generated by
|
|
418
|
-
[`protoc-gen-es`](https://github.com/bufbuild/protobuf-es) from the protos
|
|
419
|
-
in `proto/toshi/workspace/v1` of the
|
|
420
|
-
[toshi-api](https://github.com/toshicloud/toshi-api) repository, one
|
|
421
|
-
`*_pb.ts` file per proto, and `src/gen/toshi/permission_pb.ts` from
|
|
422
|
-
`proto/toshi/permission.proto`, which they import. The generated code is committed and imports
|
|
423
|
-
only `@bufbuild/protobuf`, so installing the package needs no generator.
|
|
424
|
-
|
|
425
|
-
`pin.env` names the toshi-api commit the code is generated from:
|
|
426
|
-
`2184ae8440834bb5b91991b3e4d62d14ce9dd15a` today, the commit of the
|
|
427
|
-
release tag `v0.4.1`. `mise.toml` pins the versions of Node, pnpm and `buf`;
|
|
428
|
-
`package.json` pins `protoc-gen-es` at the same version as the
|
|
429
|
-
`@bufbuild/protobuf` development dependency.
|
|
430
|
-
|
|
431
|
-
To regenerate:
|
|
432
|
-
|
|
433
|
-
```sh
|
|
434
|
-
mise install
|
|
435
|
-
pnpm install --frozen-lockfile
|
|
436
|
-
mise exec -- scripts/generate.sh
|
|
437
|
-
```
|
|
438
|
-
|
|
439
|
-
Moving to another commit or tag is one pull request that changes
|
|
440
|
-
`pin.env` and `src/gen/` together. CI regenerates the code from `pin.env`
|
|
441
|
-
and fails if the result differs from what is committed
|
|
442
|
-
(`scripts/check-generated.sh`).
|
|
443
|
-
|
|
444
|
-
## Versions
|
|
445
|
-
|
|
446
|
-
The package's major version follows the API's: `1.x` will serve
|
|
447
|
-
`toshi.workspace.v1`, and a `toshi.workspace.v2` gets a new major
|
|
448
|
-
version. Until a Toshi release serves the API, the package stays at
|
|
449
|
-
`0.x` and is generated from a pinned commit. `VERSION` is the package
|
|
450
|
-
version, the one `package.json` carries.
|
|
451
|
-
|
|
452
|
-
## Publishing
|
|
453
|
-
|
|
454
|
-
Releases are published to npm by the publish workflow
|
|
455
|
-
(`.github/workflows/publish.yml`) through npm trusted publishing: the
|
|
456
|
-
workflow authenticates with its GitHub OIDC token, and no npm token
|
|
457
|
-
exists. It runs on a `vX.Y.Z` tag that matches the version in
|
|
458
|
-
`package.json`. A new version is a commit on `main` that sets the version
|
|
459
|
-
in `package.json`, followed by its tag.
|
|
460
|
-
|
|
461
|
-
## Integration test
|
|
462
|
-
|
|
463
|
-
`test/integration/` runs the client against a real `toshi serve` over
|
|
464
|
-
HTTPS with a test CA it mints itself. `TOSHI_INTEGRATION_BIN` names the
|
|
465
|
-
`toshi` binary it runs; when `TOSHI_INTEGRATION_EXPECT_COMMIT` is set, the
|
|
466
|
-
binary must report that commit:
|
|
467
|
-
|
|
468
|
-
```sh
|
|
469
|
-
TOSHI_INTEGRATION_BIN=/path/to/toshi mise exec -- pnpm vitest run test/integration
|
|
470
|
-
```
|
|
48
|
+
- [Usage](docs/usage.md): the client, options, retries, lists, watches, commands and jobs
|
|
49
|
+
- [Errors](docs/errors.md): products that are off and refusals with a reason
|
|
50
|
+
- [Testing with `@toshicloud/sdk/test`](docs/testing.md): the in-memory fake
|
|
51
|
+
- [Development](docs/development.md): generated code, versions, publishing and the integration test
|
|
52
|
+
- [The package on npm](https://www.npmjs.com/package/@toshicloud/sdk)
|
|
53
|
+
- [The Toshi API](https://github.com/toshicloud/toshi-api) the client calls
|
|
54
|
+
- [Releases](https://github.com/toshicloud/toshi-ts/releases)
|
|
55
|
+
- [Security](SECURITY.md) · [Licence](LICENSE)
|
|
471
56
|
|
|
472
|
-
|
|
473
|
-
`TOSHI_INTEGRATION_BIN`, `pnpm test` skips the integration test and says
|
|
474
|
-
why.
|
|
57
|
+
## Status and support
|
|
475
58
|
|
|
476
|
-
|
|
59
|
+
Issues and questions go to [GitHub issues](https://github.com/toshicloud/toshi-ts/issues).
|
|
60
|
+
Security reports follow [SECURITY.md](SECURITY.md).
|
|
477
61
|
|
|
478
|
-
Apache
|
|
62
|
+
Apache-2.0
|
package/dist/client.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { Client, Interceptor, Transport } from "@connectrpc/connect";
|
|
|
3
3
|
import { AccountService } from "./gen/toshi/workspace/v1/account_pb.js";
|
|
4
4
|
import { ArtifactService, ArtifactUploadService } from "./gen/toshi/workspace/v1/artifacts_pb.js";
|
|
5
5
|
import { AuditEventService } from "./gen/toshi/workspace/v1/audit_events_pb.js";
|
|
6
|
-
import {
|
|
6
|
+
import { EndpointService } from "./gen/toshi/workspace/v1/endpoints_pb.js";
|
|
7
7
|
import { ConnectionService } from "./gen/toshi/workspace/v1/connections_pb.js";
|
|
8
8
|
import { DiscoveryService } from "./gen/toshi/workspace/v1/discovery_pb.js";
|
|
9
9
|
import { DisplayService } from "./gen/toshi/workspace/v1/display_pb.js";
|
|
@@ -13,6 +13,7 @@ import { GrantService } from "./gen/toshi/workspace/v1/grants_pb.js";
|
|
|
13
13
|
import { ImageService } from "./gen/toshi/workspace/v1/images_pb.js";
|
|
14
14
|
import { HostJobService } from "./gen/toshi/workspace/v1/hostjobs_pb.js";
|
|
15
15
|
import { HostService } from "./gen/toshi/workspace/v1/hosts_pb.js";
|
|
16
|
+
import { ModelCredentialService } from "./gen/toshi/workspace/v1/model_credentials_pb.js";
|
|
16
17
|
import { ProductService } from "./gen/toshi/workspace/v1/products_pb.js";
|
|
17
18
|
import { ProjectService } from "./gen/toshi/workspace/v1/projects_pb.js";
|
|
18
19
|
import { RecordingService } from "./gen/toshi/workspace/v1/recordings_pb.js";
|
|
@@ -26,10 +27,10 @@ import { WebhookService } from "./gen/toshi/workspace/v1/webhook_pb.js";
|
|
|
26
27
|
import { WorkspaceService } from "./gen/toshi/workspace/v1/workspace_service_pb.js";
|
|
27
28
|
import { CreatePreviewShareLinkRequestSchema, ListPreviewShareLinksRequestSchema, RevokePreviewShareLinkRequestSchema, StartSandboxRequestSchema, StopSandboxRequestSchema } from "./gen/toshi/workspace/v1/workspace_pb.js";
|
|
28
29
|
import type { CreatePreviewShareLinkResponse, ListPreviewShareLinksResponse, RevokePreviewShareLinkResponse, StartSandboxResponse, StopSandboxResponse } from "./gen/toshi/workspace/v1/workspace_pb.js";
|
|
29
|
-
import { CancelJobRequestSchema, CreateJobRequestSchema, CreateSandboxRequestSchema, CreateServiceRequestSchema, DeleteJobRequestSchema, DeleteSandboxRequestSchema, DeleteServiceRequestSchema, GetJobRequestSchema, GetSandboxRequestSchema, GetServiceRequestSchema, ListJobsRequestSchema, ListSandboxesRequestSchema, ListServicesRequestSchema, UpdateJobRequestSchema, UpdateSandboxRequestSchema, UpdateServiceRequestSchema, WaitJobRequestSchema, WaitSandboxRequestSchema, WaitServiceRequestSchema, WatchJobsRequestSchema, WatchSandboxesRequestSchema, WatchServicesRequestSchema } from "./gen/toshi/workspace/v1/workloads_pb.js";
|
|
30
|
-
import type { CancelJobResponse, CreateJobResponse, CreateSandboxResponse, CreateServiceResponse, DeleteJobResponse, DeleteSandboxResponse, DeleteServiceResponse, GetJobResponse, GetSandboxResponse, GetServiceResponse, ListJobsResponse, ListSandboxesResponse, ListServicesResponse, UpdateJobResponse, UpdateSandboxResponse, UpdateServiceResponse, WaitJobResponse, WaitSandboxResponse, WaitServiceResponse, WatchJobsResponse, WatchSandboxesResponse, WatchServicesResponse } from "./gen/toshi/workspace/v1/workloads_pb.js";
|
|
31
|
-
import { ExecuteStartSchema, GetOperationRequestSchema, GetServiceRevisionRequestSchema, HoldServiceRequestSchema, ListEventsRequestSchema, ListServiceActivationsRequestSchema, ListServiceRevisionsRequestSchema, ListServiceRunsRequestSchema, ReleaseServiceRequestSchema, RollbackServiceRequestSchema, SetServiceModeRequestSchema, StartServiceRequestSchema, StopServiceRequestSchema, WaitOperationRequestSchema, WakeServiceRequestSchema, WatchEventsRequestSchema, WatchOutputRequestSchema } from "./gen/toshi/workspace/v1/workspace_pb.js";
|
|
32
|
-
import type { Event, GetOperationResponse, GetServiceRevisionResponse, HoldServiceResponse, Job, ListEventsResponse, ListServiceActivationsResponse, ListServiceRevisionsResponse, ListServiceRunsResponse, Operation, PreviewShareLink, ReleaseServiceResponse, RollbackServiceResponse, Sandbox, Service, ServiceRun, SetServiceModeResponse, StartServiceResponse, StopServiceResponse, WakeServiceResponse, WatchEventsResponse, WatchOutputResponse } from "./gen/toshi/workspace/v1/workspace_pb.js";
|
|
30
|
+
import { CancelJobRequestSchema, CreateJobRequestSchema, CreateSandboxRequestSchema, CreateServiceRequestSchema, DeleteJobRequestSchema, DeleteSandboxRequestSchema, DeleteServiceAlarmRequestSchema, DeleteServiceRequestSchema, EmitWorkloadEventRequestSchema, GetJobRequestSchema, GetSandboxRequestSchema, GetServiceAlarmRequestSchema, GetServiceRequestSchema, ListJobsRequestSchema, ListSandboxesRequestSchema, ListServiceAlarmsRequestSchema, ListServicesRequestSchema, PauseServiceAlarmRequestSchema, ResumeServiceAlarmRequestSchema, RunServiceAlarmNowRequestSchema, SetServiceAlarmRequestSchema, UpdateJobRequestSchema, UpdateSandboxRequestSchema, UpdateServiceRequestSchema, WaitJobRequestSchema, WaitSandboxRequestSchema, WaitServiceRequestSchema, WatchJobsRequestSchema, WatchSandboxesRequestSchema, WatchServicesRequestSchema } from "./gen/toshi/workspace/v1/workloads_pb.js";
|
|
31
|
+
import type { CancelJobResponse, CreateJobResponse, CreateSandboxResponse, CreateServiceResponse, DeleteJobResponse, DeleteSandboxResponse, DeleteServiceAlarmResponse, DeleteServiceResponse, EmitWorkloadEventResponse, GetJobResponse, GetSandboxResponse, GetServiceAlarmResponse, GetServiceResponse, ListJobsResponse, ListSandboxesResponse, ListServiceAlarmsResponse, ListServicesResponse, PauseServiceAlarmResponse, ResumeServiceAlarmResponse, RunServiceAlarmNowResponse, SetServiceAlarmResponse, UpdateJobResponse, UpdateSandboxResponse, UpdateServiceResponse, WaitJobResponse, WaitSandboxResponse, WaitServiceResponse, WatchJobsResponse, WatchSandboxesResponse, WatchServicesResponse } from "./gen/toshi/workspace/v1/workloads_pb.js";
|
|
32
|
+
import { AnswerServiceSignInRequestSchema, CancelServiceSignInRequestSchema, ExecuteStartSchema, GetOperationRequestSchema, GetServiceRevisionRequestSchema, GetServiceSignInStatusRequestSchema, HoldServiceRequestSchema, HoldWorkloadRequestSchema, ListEventsRequestSchema, ListServiceActivationsRequestSchema, ListServiceRevisionsRequestSchema, ListServiceRunsRequestSchema, ReleaseServiceRequestSchema, ReleaseWorkloadRequestSchema, RollbackServiceRequestSchema, SetServiceModeRequestSchema, StartServiceRequestSchema, StartServiceSignInRequestSchema, StopServiceRequestSchema, WaitOperationRequestSchema, WakeServiceRequestSchema, WatchEventsRequestSchema, WatchOutputRequestSchema } from "./gen/toshi/workspace/v1/workspace_pb.js";
|
|
33
|
+
import type { AnswerServiceSignInResponse, CancelServiceSignInResponse, Event, GetOperationResponse, GetServiceRevisionResponse, GetServiceSignInStatusResponse, HoldServiceResponse, HoldWorkloadResponse, Job, ListEventsResponse, ListServiceActivationsResponse, ListServiceRevisionsResponse, ListServiceRunsResponse, Operation, PreviewShareLink, ReleaseServiceResponse, ReleaseWorkloadResponse, RollbackServiceResponse, Sandbox, Service, ServiceRun, SetServiceModeResponse, StartServiceResponse, StartServiceSignInResponse, StopServiceResponse, WakeServiceResponse, WatchEventsResponse, WatchOutputResponse } from "./gen/toshi/workspace/v1/workspace_pb.js";
|
|
33
34
|
import type { RetryPolicy } from "./retry.js";
|
|
34
35
|
/** How the client is configured; the caller builds the transport. */
|
|
35
36
|
export interface ToshiOptions {
|
|
@@ -62,7 +63,7 @@ export interface ToshiClient {
|
|
|
62
63
|
readonly secret: Client<typeof SecretService>;
|
|
63
64
|
readonly webhook: Client<typeof WebhookService>;
|
|
64
65
|
readonly display: Client<typeof DisplayService>;
|
|
65
|
-
readonly
|
|
66
|
+
readonly endpoint: Client<typeof EndpointService>;
|
|
66
67
|
readonly recording: Client<typeof RecordingService>;
|
|
67
68
|
readonly volume: Client<typeof VolumeService>;
|
|
68
69
|
readonly artifact: Client<typeof ArtifactService>;
|
|
@@ -84,6 +85,7 @@ export interface ToshiClient {
|
|
|
84
85
|
readonly account: Client<typeof AccountService>;
|
|
85
86
|
readonly image: Client<typeof ImageService>;
|
|
86
87
|
readonly domain: Client<typeof DomainService>;
|
|
88
|
+
readonly modelCredential: Client<typeof ModelCredentialService>;
|
|
87
89
|
run(req: MessageInitShape<typeof CreateJobRequestSchema>, opts?: CallOptions): Promise<JobRun>;
|
|
88
90
|
}
|
|
89
91
|
/** WorkloadService's calls, grouped by the type they name. */
|
|
@@ -97,6 +99,22 @@ export interface WorkloadClient {
|
|
|
97
99
|
/** Yields every event listEvents lists, following the page token from one page to the next. */
|
|
98
100
|
allEvents(req: MessageInitShape<typeof ListEventsRequestSchema>, opts?: CallOptions): AsyncIterable<Event>;
|
|
99
101
|
watchEvents(req: MessageInitShape<typeof WatchEventsRequestSchema>, opts?: CallOptions): Promise<EventWatch>;
|
|
102
|
+
/**
|
|
103
|
+
* Appends an event of type EMITTED, with the name and data given, to a job's, sandbox's or
|
|
104
|
+
* service's event log, as its guest emits one, and returns it; the workload need not be running.
|
|
105
|
+
*/
|
|
106
|
+
emitEvent(req: MessageInitShape<typeof EmitWorkloadEventRequestSchema>, opts?: CallOptions): Promise<EmitWorkloadEventResponse>;
|
|
107
|
+
/**
|
|
108
|
+
* Places an operator's hold on a sandbox or service, stopping it if it runs. Only an
|
|
109
|
+
* operator may call it; the caller sets the operator's reason in the Toshi-Operator-Reason
|
|
110
|
+
* header with an interceptor, since the client sends none itself.
|
|
111
|
+
*/
|
|
112
|
+
holdWorkload(req: MessageInitShape<typeof HoldWorkloadRequestSchema>, opts?: CallOptions): Promise<HoldWorkloadResponse>;
|
|
113
|
+
/**
|
|
114
|
+
* Lifts an operator's hold and starts nothing. Only an operator may call it; the caller
|
|
115
|
+
* sets the operator's reason in the Toshi-Operator-Reason header with an interceptor.
|
|
116
|
+
*/
|
|
117
|
+
releaseWorkload(req: MessageInitShape<typeof ReleaseWorkloadRequestSchema>, opts?: CallOptions): Promise<ReleaseWorkloadResponse>;
|
|
100
118
|
/** Returns one operation: the id a long call hands back, asked for again. */
|
|
101
119
|
getOperation(req: MessageInitShape<typeof GetOperationRequestSchema>, opts?: CallOptions): Promise<GetOperationResponse>;
|
|
102
120
|
}
|
|
@@ -162,6 +180,58 @@ export interface ServicesClient {
|
|
|
162
180
|
rollback(req: MessageInitShape<typeof RollbackServiceRequestSchema>, opts?: CallOptions): Promise<RollbackServiceResponse>;
|
|
163
181
|
/** Returns a service's activations, oldest first. */
|
|
164
182
|
listActivations(req: MessageInitShape<typeof ListServiceActivationsRequestSchema>, opts?: CallOptions): Promise<ListServiceActivationsResponse>;
|
|
183
|
+
/**
|
|
184
|
+
* Creates or replaces the service's alarm with this name and returns it: at each instant of its
|
|
185
|
+
* schedule the alarm publishes its event, with its data, on one of the service's event endpoints.
|
|
186
|
+
*/
|
|
187
|
+
setAlarm(req: MessageInitShape<typeof SetServiceAlarmRequestSchema>, opts?: CallOptions): Promise<SetServiceAlarmResponse>;
|
|
188
|
+
/** Returns one alarm and its most recent occurrences, newest first. */
|
|
189
|
+
getAlarm(req: MessageInitShape<typeof GetServiceAlarmRequestSchema>, opts?: CallOptions): Promise<GetServiceAlarmResponse>;
|
|
190
|
+
/**
|
|
191
|
+
* Returns all of a service's alarms, by name, in one answer: the call has no page token, so
|
|
192
|
+
* there is no `allAlarms`.
|
|
193
|
+
*/
|
|
194
|
+
listAlarms(req: MessageInitShape<typeof ListServiceAlarmsRequestSchema>, opts?: CallOptions): Promise<ListServiceAlarmsResponse>;
|
|
195
|
+
/** Removes an alarm and its occurrences; messages it already published stay on the endpoint. */
|
|
196
|
+
deleteAlarm(req: MessageInitShape<typeof DeleteServiceAlarmRequestSchema>, opts?: CallOptions): Promise<DeleteServiceAlarmResponse>;
|
|
197
|
+
/** Stops an alarm publishing until it is resumed; pausing a paused alarm changes nothing. */
|
|
198
|
+
pauseAlarm(req: MessageInitShape<typeof PauseServiceAlarmRequestSchema>, opts?: CallOptions): Promise<PauseServiceAlarmResponse>;
|
|
199
|
+
/**
|
|
200
|
+
* Starts a paused alarm again from the next instant of its schedule; instants that passed while
|
|
201
|
+
* it was paused are not published.
|
|
202
|
+
*/
|
|
203
|
+
resumeAlarm(req: MessageInitShape<typeof ResumeServiceAlarmRequestSchema>, opts?: CallOptions): Promise<ResumeServiceAlarmResponse>;
|
|
204
|
+
/**
|
|
205
|
+
* Publishes the alarm's event once, now, paused or not, and returns the occurrence; it does not
|
|
206
|
+
* move the alarm's next instant. It takes a request key, so a retried call is applied once.
|
|
207
|
+
*/
|
|
208
|
+
runAlarmNow(req: MessageInitShape<typeof RunServiceAlarmNowRequestSchema>, opts?: CallOptions): Promise<RunServiceAlarmNowResponse>;
|
|
209
|
+
/**
|
|
210
|
+
* Runs one of the service's recipe's sign_in programs and hands back its stream as the server
|
|
211
|
+
* sends it. The caller reads the started message first, which names the sign-in; then the
|
|
212
|
+
* output messages, the program's standard output and standard error; answers the program with
|
|
213
|
+
* `answerSignIn` or ends it early with `cancelSignIn`; and reads the ended message last, which
|
|
214
|
+
* says how it ended. A sign-in may run for 15 minutes.
|
|
215
|
+
*
|
|
216
|
+
* The stream is not retried or resumed: a sign-in has no cursor. Its stream ending for another
|
|
217
|
+
* reason, as a client that leaves, also ends it, cancelled; the caller starts a new one.
|
|
218
|
+
*/
|
|
219
|
+
startSignIn(req: MessageInitShape<typeof StartServiceSignInRequestSchema>, opts?: CallOptions): AsyncIterable<StartServiceSignInResponse>;
|
|
220
|
+
/**
|
|
221
|
+
* Writes one line, of at most 4 KiB and with no newline in it, to a running sign-in's standard
|
|
222
|
+
* input; the sign-in's program reads it.
|
|
223
|
+
*/
|
|
224
|
+
answerSignIn(req: MessageInitShape<typeof AnswerServiceSignInRequestSchema>, opts?: CallOptions): Promise<AnswerServiceSignInResponse>;
|
|
225
|
+
/**
|
|
226
|
+
* Ends a running sign-in: its program is cancelled and its stream ends CANCELLED. It returns
|
|
227
|
+
* once the cancel is asked for, not once the sign-in has ended.
|
|
228
|
+
*/
|
|
229
|
+
cancelSignIn(req: MessageInitShape<typeof CancelServiceSignInRequestSchema>, opts?: CallOptions): Promise<CancelServiceSignInResponse>;
|
|
230
|
+
/**
|
|
231
|
+
* Runs the status commands of the service's recipe and reports, for each sign_in program,
|
|
232
|
+
* whether it is signed in and what its status command wrote.
|
|
233
|
+
*/
|
|
234
|
+
getSignInStatus(req: MessageInitShape<typeof GetServiceSignInStatusRequestSchema>, opts?: CallOptions): Promise<GetServiceSignInStatusResponse>;
|
|
165
235
|
}
|
|
166
236
|
/** A live stream of a job's changes. */
|
|
167
237
|
export interface JobWatch extends AsyncIterable<WatchJobsResponse> {
|