@kubb/studio 5.1.0 → 5.2.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/dist/index.d.ts CHANGED
@@ -1,9 +1,19 @@
1
1
  import { t as __name } from "./rolldown-runtime-CRm0XQPb.js";
2
- import { s as ClientInfo } from "./index-BVn89Nw2.js";
2
+ import { a as AgentPermissions, c as ClientInfo } from "./index-Y-wkaxbL.js";
3
3
  import { Storage } from "unstorage";
4
4
  import { Config, Hookable, KubbHooks } from "@kubb/core";
5
- //#region src/connectStudio.d.ts
6
- type ConnectToStudioOptions = {
5
+ //#region src/api.d.ts
6
+ /**
7
+ * Thrown when Studio rejects the agent token itself (401). Retrying cannot help: the token was
8
+ * revoked, or the agent it belonged to was deleted in the Studio UI. Hosts catch this to forget
9
+ * the stored credential and pair again.
10
+ */
11
+ export declare class InvalidAgentTokenError extends Error {
12
+ constructor(studioUrl: string, options?: ErrorOptions);
13
+ }
14
+ //#endregion
15
+ //#region src/StudioSession.d.ts
16
+ type StudioSessionOptions = {
7
17
  token: string;
8
18
  studioUrl?: string;
9
19
  configPath: string;
@@ -21,25 +31,24 @@ type ConnectToStudioOptions = {
21
31
  * Identifies the host to Studio, so the UI can badge a CLI connection and show the real project.
22
32
  */
23
33
  client?: ClientInfo;
24
- allowWrite?: boolean;
25
- /**
26
- * Whether Studio may edit the project's `kubb.config.ts`. Granted separately from `allowWrite`,
27
- * which only covers generated output: this rewrites a file the user wrote by hand.
28
- */
29
- allowConfigEdit?: boolean;
30
- allowInput?: boolean;
31
34
  /**
32
- * Whether the formatter, the linter, and `output.postGenerate` may run as child processes.
33
- * Defaults to true, which is what the Docker agent has always done. The CLI runs in the user's
34
- * own project, so it defaults this off and asks before granting it.
35
+ * What Studio may do in this project, off unless the host grants it. A sandbox session narrows
36
+ * them further: it never writes to disk and never edits a config file, and it always generates
37
+ * from the spec Studio sends.
35
38
  */
36
- allowExec?: boolean;
39
+ permissions?: Partial<AgentPermissions>;
37
40
  root?: string;
38
41
  retryInterval?: number;
42
+ /**
43
+ * Milliseconds between keep-alive pings, clamped to `agentDefaults.maxHeartbeatIntervalMs`.
44
+ * Raise it to halve the traffic and database writes a long-lived agent costs, at the price of
45
+ * Studio taking that much longer to notice the agent has gone. Lower it in development to see
46
+ * connection state move immediately.
47
+ */
39
48
  heartbeatInterval?: number;
40
49
  /**
41
50
  * Number of pool sessions this agent serves. Read by `createClient`, which opens one
42
- * `connectToStudio` per slot, and reported to Studio at registration.
51
+ * session per slot, and reported to Studio at registration.
43
52
  */
44
53
  poolSize?: number;
45
54
  /**
@@ -48,19 +57,36 @@ type ConnectToStudioOptions = {
48
57
  */
49
58
  signal?: AbortSignal;
50
59
  /**
51
- * Installs listeners on an event emitter, once for the session and once per generation. Left out,
52
- * the runtime prints nothing, which is what a library should default to.
60
+ * Installs listeners on the session's event emitter, which carries both the session events and
61
+ * the generations it runs. Left out, the runtime prints nothing, which is what a library should
62
+ * default to.
53
63
  */
54
64
  installLogger?: (hooks: Hookable<KubbHooks>) => void | Promise<void>;
65
+ /**
66
+ * Called when this session's background reconnect is rejected with an invalid token. Unlike
67
+ * `ClientOptions.onAuthRequired`, this fires once per session rather than once per pool:
68
+ * `createClient` wraps it into that deduped, pool-stopping callback. Not meant to be set
69
+ * directly by a host.
70
+ */
71
+ onTokenRejected?: (error: InvalidAgentTokenError) => void;
55
72
  };
56
73
  //#endregion
57
74
  //#region src/client.d.ts
58
- type ClientOptions = Omit<ConnectToStudioOptions, 'signal'> & {
75
+ type ClientOptions = Omit<StudioSessionOptions, 'signal' | 'onTokenRejected'> & {
59
76
  /**
60
77
  * Where the machine secret and the last Studio config are persisted. Defaults to in-memory,
61
78
  * which gives up a stable machine identity across restarts.
62
79
  */
63
80
  storage?: Storage;
81
+ /**
82
+ * Called once when a live pool's token is rejected during background reconnect (401: revoked, or
83
+ * the agent was deleted). The whole pool is already stopped by the time this fires, so a host
84
+ * only needs to get a replacement token and start a new client.
85
+ *
86
+ * Never fires for a startup rejection, which `connect()` reports by throwing, nor for an ordinary
87
+ * session expiry or revocation, both of which reconnect on their own.
88
+ */
89
+ onAuthRequired?: (error: InvalidAgentTokenError) => void;
64
90
  };
65
91
  type Client = {
66
92
  /**
@@ -85,7 +111,7 @@ type Client = {
85
111
  * await studio.connect()
86
112
  * ```
87
113
  */
88
- declare function createClient({ storage, ...options }: ClientOptions): Client;
114
+ export declare function createClient({ storage, onAuthRequired, ...options }: ClientOptions): Client;
89
115
  //#endregion
90
116
  //#region src/hooks.d.ts
91
117
  /**
@@ -170,33 +196,91 @@ declare global {
170
196
  }
171
197
  }
172
198
  //#endregion
173
- //#region src/api.d.ts
174
- /**
175
- * Thrown when Studio rejects the agent token itself (401). Retrying cannot help: the token was
176
- * revoked, or the agent it belonged to was deleted in the Studio UI. Hosts catch this to forget
177
- * the stored credential and pair again.
178
- */
179
- declare class InvalidAgentTokenError extends Error {
180
- constructor(studioUrl: string, options?: ErrorOptions);
181
- }
182
- //#endregion
183
199
  //#region src/constants.d.ts
184
200
  /**
185
201
  * Hosted Kubb Studio URL. Exported so credential stores can bind tokens to the resolved instance,
186
202
  * not whatever default the client would pick on its own.
187
203
  */
188
- declare const defaultStudioUrl = "https://kubb.studio";
204
+ export declare const defaultStudioUrl = "https://kubb.studio";
189
205
  //#endregion
190
206
  //#region src/machine.d.ts
191
207
  /**
192
208
  * Installs the storage driver the runtime persists to. Call once, before connecting.
193
209
  */
194
- declare function setStorage(next: Storage): void;
210
+ export declare function setStorage(next: Storage): void;
195
211
  /**
196
212
  * A storage backed by files under `base`, so the machine secret and the last Studio config
197
213
  * survive a restart. Repeated pairings of one machine depend on that secret staying put.
198
214
  */
199
- declare function createFileStorage(base: string): Storage;
215
+ export declare function createFileStorage(base: string): Storage;
216
+ //#endregion
217
+ //#region src/runConnection.d.ts
218
+ /**
219
+ * Why a connection ended: the host asked it to stop through its `signal`, or the host declined to
220
+ * replace a rejected token.
221
+ */
222
+ type ConnectionOutcome = 'shutdown' | 'stopped';
223
+ /**
224
+ * A rejected token, and whether it was already serving a live session when Studio rejected it.
225
+ */
226
+ type TokenRejection<TCredentials> = {
227
+ error: InvalidAgentTokenError;
228
+ /**
229
+ * The credential Studio rejected, so a host can carry parts of it into the replacement.
230
+ */
231
+ credentials: TCredentials;
232
+ /**
233
+ * `false` when the token was dead before a session ever opened, which is what `connect()` itself
234
+ * reports. `true` when a live pool's background reconnect was rejected, well after the session
235
+ * was up. Hosts treat the two differently: only the first has nothing to tear down.
236
+ */
237
+ live: boolean;
238
+ };
239
+ type ConnectionOptions<TCredentials extends {
240
+ token: string;
241
+ }> = {
242
+ /**
243
+ * The credential to open with. Only its token is read here, so a host keeps whatever else it
244
+ * stores alongside.
245
+ */
246
+ credentials: TCredentials;
247
+ /**
248
+ * Builds the client options for one attempt. Called again for every reconnect, so a host whose
249
+ * options depend on which agent approved, such as the permissions it granted, re-derives them
250
+ * rather than reusing the ones the rejected token was opened with.
251
+ */
252
+ clientOptions: (credentials: TCredentials) => Omit<ClientOptions, 'token' | 'onAuthRequired'>;
253
+ /**
254
+ * Called when Studio rejects the token. Return the credential to reconnect with, or `null` to
255
+ * end the run. Throwing fails it, which is what a host does when it cannot pair again.
256
+ */
257
+ onTokenRejected: (rejection: TokenRejection<TCredentials>) => Promise<TCredentials | null>;
258
+ /**
259
+ * Aborting this disconnects and ends the run. Hosts wire it to their own shutdown: `SIGINT` in
260
+ * the CLI, Nitro's `close` hook in the Docker agent.
261
+ */
262
+ signal?: AbortSignal;
263
+ };
264
+ /**
265
+ * Keeps a host connected to Studio across token changes: it opens a client, waits until the run
266
+ * ends or Studio rejects the token, and reconnects with whatever credential the host hands back.
267
+ *
268
+ * The host owns everything around that. Where credentials live, whether a rejected token may be
269
+ * replaced, and how any of it is reported are all decisions `onTokenRejected` makes.
270
+ *
271
+ * @example
272
+ * ```ts
273
+ * const outcome = await runConnection({
274
+ * credentials,
275
+ * clientOptions: () => ({ studioUrl, configPath, version, loadConfig }),
276
+ * signal: shutdown.signal,
277
+ * onTokenRejected: ({ error, live }) => pairAgain(error, live),
278
+ * })
279
+ * ```
280
+ */
281
+ export declare function runConnection<TCredentials extends {
282
+ token: string;
283
+ }>({ credentials, clientOptions, onTokenRejected, signal }: ConnectionOptions<TCredentials>): Promise<ConnectionOutcome>;
200
284
  //#endregion
201
285
  //#region src/pair.d.ts
202
286
  /**
@@ -231,6 +315,14 @@ type PairingResult = {
231
315
  name: string;
232
316
  };
233
317
  };
318
+ /**
319
+ * Thrown when a caller aborts `startPairing` or `pollForPairingToken` through their `signal`, such
320
+ * as a `kubb studio` shutdown mid-pairing. Distinct from a denial or an expired code, so a host can
321
+ * exit quietly instead of reporting a pairing failure.
322
+ */
323
+ export declare class PairingCanceledError extends Error {
324
+ constructor();
325
+ }
234
326
  type StartPairingOptions = {
235
327
  studioUrl?: string;
236
328
  /**
@@ -248,16 +340,25 @@ type StartPairingOptions = {
248
340
  * and ignores it for the CLI.
249
341
  */
250
342
  agentKind?: 'user' | 'sandbox';
343
+ /**
344
+ * Aborting this cancels the request in flight and rejects with {@link PairingCanceledError}.
345
+ */
346
+ signal?: AbortSignal;
251
347
  };
252
348
  /**
253
349
  * Asks Studio for a pairing code. The machine token travels with the request and is stored against
254
350
  * the code, so approval knows which machine it is pairing: the same machine pairing twice rotates
255
351
  * one agent's token instead of creating a second agent.
256
352
  */
257
- declare function startPairing({ studioUrl, name, hostname, clientId, agentKind }: StartPairingOptions): Promise<PairingSession>;
353
+ export declare function startPairing({ studioUrl, name, hostname, clientId, agentKind, signal }: StartPairingOptions): Promise<PairingSession>;
258
354
  type PollOptions = {
259
355
  studioUrl?: string;
260
356
  session: PairingSession;
357
+ /**
358
+ * Aborting this stops polling and rejects with {@link PairingCanceledError}, whether the abort
359
+ * lands between polls or during the wait for the next one.
360
+ */
361
+ signal?: AbortSignal;
261
362
  };
262
363
  /**
263
364
  * Polls until the user approves or denies, honoring the server's `slow_down` back-off. A poll that
@@ -268,7 +369,7 @@ type PollOptions = {
268
369
  *
269
370
  * @throws when the code expires, the user denies it, or Studio returns an unexpected error.
270
371
  */
271
- declare function pollForPairingToken({ studioUrl, session }: PollOptions): Promise<PairingResult>;
372
+ export declare function pollForPairingToken({ studioUrl, session, signal }: PollOptions): Promise<PairingResult>;
272
373
  //#endregion
273
- export { type Client, type ClientOptions, InvalidAgentTokenError, type StudioCommandEndContext, type StudioCommandStartContext, type StudioConnectedContext, type StudioConnectingContext, type StudioDisconnectedContext, type StudioErrorContext, type StudioWarnContext, createClient, createFileStorage, defaultStudioUrl, pollForPairingToken, setStorage, startPairing };
374
+ export type { Client, ClientOptions, ConnectionOptions, StudioConnectedContext };
274
375
  //# sourceMappingURL=index.d.ts.map