@usestatemachines/sdk 0.11.0 → 0.12.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/README.md +126 -21
- package/agents/SKILL.md +33 -11
- package/agents/index.js +7 -7
- package/agents/llms.txt +14 -11
- package/agents/prompt.md +4 -4
- package/esm/extensions/client.d.ts +72 -8
- package/esm/extensions/client.js +89 -5
- package/esm/extensions/credentials.js +4 -0
- package/esm/extensions/environment.d.ts +18 -2
- package/esm/extensions/errors.d.ts +33 -0
- package/esm/extensions/errors.js +53 -0
- package/esm/extensions/import-data.d.ts +43 -0
- package/esm/extensions/import-data.js +88 -0
- package/esm/extensions/index.d.ts +4 -3
- package/esm/extensions/index.js +1 -1
- package/esm/extensions/packaging.d.ts +1 -0
- package/esm/extensions/packaging.js +1 -0
- package/esm/extensions/zip.d.ts +8 -0
- package/esm/extensions/zip.js +121 -0
- package/esm/funcs/environments-actors.d.ts +11 -0
- package/esm/funcs/environments-actors.js +102 -0
- package/esm/funcs/get-import-file.d.ts +12 -0
- package/esm/funcs/get-import-file.js +97 -0
- package/esm/funcs/list-import-files.d.ts +12 -0
- package/esm/funcs/list-import-files.js +98 -0
- package/esm/funcs/upload-import.d.ts +12 -0
- package/esm/funcs/upload-import.js +96 -0
- package/esm/lib/config.d.ts +2 -2
- package/esm/lib/config.js +2 -2
- package/esm/models/absent-record.d.ts +7 -3
- package/esm/models/absent-record.js +3 -2
- package/esm/models/actor.d.ts +3 -0
- package/esm/models/app-user.d.ts +17 -0
- package/esm/models/app-user.js +18 -0
- package/esm/models/credentials.d.ts +6 -1
- package/esm/models/credentials.js +2 -0
- package/esm/models/environment.d.ts +4 -4
- package/esm/models/environment.js +3 -4
- package/esm/models/error.d.ts +7 -0
- package/esm/models/error.js +4 -0
- package/esm/models/filled-field.d.ts +14 -0
- package/esm/models/filled-field.js +16 -0
- package/esm/models/import-actor.d.ts +16 -0
- package/esm/models/import-actor.js +15 -0
- package/esm/models/import-file.d.ts +56 -0
- package/esm/models/import-file.js +67 -0
- package/esm/models/import-folder.d.ts +56 -0
- package/esm/models/import-folder.js +75 -0
- package/esm/models/import-problem.d.ts +4 -4
- package/esm/models/import-problem.js +1 -1
- package/esm/models/index.d.ts +18 -1
- package/esm/models/index.js +18 -1
- package/esm/models/known-difference.d.ts +21 -0
- package/esm/models/known-difference.js +16 -0
- package/esm/models/launch-ui-session.d.ts +12 -2
- package/esm/models/launch-ui-session.js +2 -1
- package/esm/models/made-id.d.ts +22 -0
- package/esm/models/made-id.js +17 -0
- package/esm/models/matched-record.d.ts +22 -0
- package/esm/models/matched-record.js +17 -0
- package/esm/models/object-load.d.ts +21 -0
- package/esm/models/object-load.js +17 -0
- package/esm/models/operations/create-credentials.d.ts +10 -0
- package/esm/models/operations/create-credentials.js +1 -0
- package/esm/models/operations/get-import-file.d.ts +13 -0
- package/esm/models/operations/get-import-file.js +12 -0
- package/esm/models/operations/index.d.ts +4 -0
- package/esm/models/operations/index.js +4 -0
- package/esm/models/operations/list-actors.d.ts +32 -0
- package/esm/models/operations/list-actors.js +26 -0
- package/esm/models/operations/list-import-files.d.ts +15 -0
- package/esm/models/operations/list-import-files.js +13 -0
- package/esm/models/operations/list-snapshots.d.ts +2 -2
- package/esm/models/operations/list-snapshots.js +1 -1
- package/esm/models/operations/upload-import.d.ts +13 -0
- package/esm/models/operations/upload-import.js +17 -0
- package/esm/models/problem-counts.d.ts +17 -0
- package/esm/models/problem-counts.js +14 -0
- package/esm/models/received-import.d.ts +9 -0
- package/esm/models/received-import.js +13 -0
- package/esm/models/record-source.d.ts +13 -0
- package/esm/models/{absent-record-source.js → record-source.js} +3 -3
- package/esm/models/snapshot-app-full-load-counts.d.ts +57 -0
- package/esm/models/snapshot-app-full-load-counts.js +25 -0
- package/esm/models/snapshot-app-full-load.d.ts +101 -0
- package/esm/models/snapshot-app-full-load.js +42 -0
- package/esm/models/snapshot-app-limited-load-counts.d.ts +16 -0
- package/esm/models/snapshot-app-limited-load-counts.js +14 -0
- package/esm/models/snapshot-app-limited-load.d.ts +18 -0
- package/esm/models/snapshot-app-limited-load.js +16 -0
- package/esm/models/snapshot-app-load-counts.d.ts +13 -0
- package/esm/models/snapshot-app-load-counts.js +15 -0
- package/esm/models/snapshot-app-load.d.ts +5 -12
- package/esm/models/snapshot-app-load.js +6 -6
- package/esm/models/snapshot-list-item.d.ts +53 -0
- package/esm/models/snapshot-list-item.js +42 -0
- package/esm/models/snapshot.d.ts +1 -1
- package/esm/models/version.d.ts +3 -0
- package/esm/sdk/environments.d.ts +1 -0
- package/esm/sdk/environments.js +4 -0
- package/esm/sdk/sdk.d.ts +3 -0
- package/esm/sdk/sdk.js +12 -0
- package/openapi.json +1868 -510
- package/package.json +8 -4
- package/esm/models/absent-record-source.d.ts +0 -13
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import type { App } from '../models/app.js';
|
|
2
|
+
import type { AppUser } from '../models/app-user.js';
|
|
2
3
|
import type { AuditEvent } from '../models/audit-event.js';
|
|
3
4
|
import type { CreateEnvironment } from '../models/create-environment.js';
|
|
4
5
|
import type { Import } from '../models/import.js';
|
|
6
|
+
import type { LaunchUiSession } from '../models/launch-ui-session.js';
|
|
5
7
|
import type { Me } from '../models/me.js';
|
|
6
8
|
import type { CreateCredentialsRequestBody } from '../models/operations/create-credentials.js';
|
|
7
9
|
import type { GetRequestStatsRequest } from '../models/operations/get-request-stats.js';
|
|
10
|
+
import type { ListActorsRequest } from '../models/operations/list-actors.js';
|
|
8
11
|
import type { ListAuditEventsRequest } from '../models/operations/list-audit-events.js';
|
|
9
12
|
import type { ListEnvironmentsRequest } from '../models/operations/list-environments.js';
|
|
10
13
|
import type { ListImportsRequest } from '../models/operations/list-imports.js';
|
|
@@ -16,10 +19,15 @@ import type { RequestT as Request } from '../models/request.js';
|
|
|
16
19
|
import type { RequestDetail } from '../models/request-detail.js';
|
|
17
20
|
import type { RequestStats } from '../models/request-stats.js';
|
|
18
21
|
import type { Snapshot } from '../models/snapshot.js';
|
|
22
|
+
import type { SnapshotListItem } from '../models/snapshot-list-item.js';
|
|
23
|
+
import type { UiSessionLaunch } from '../models/ui-session-launch.js';
|
|
24
|
+
import type { UiSessionRevocation } from '../models/ui-session-revocation.js';
|
|
19
25
|
import type { Version } from '../models/version.js';
|
|
20
26
|
import type { Workspace } from '../models/workspace.js';
|
|
21
27
|
import { type Credentials } from './credentials.js';
|
|
22
28
|
import type { Environment } from './environment.js';
|
|
29
|
+
import { ActorCannotSignInError, ActorNotFoundError } from './errors.js';
|
|
30
|
+
import { type ImportData } from './import-data.js';
|
|
23
31
|
import { type KnownEnvironmentStatus, type KnownSnapshotStatus, type WaitOptions } from './wait.js';
|
|
24
32
|
export interface StateMachinesOptions {
|
|
25
33
|
/** An API key or a member's access token. Defaults to `STATEMACHINES_API_KEY` where a `process` exists. */
|
|
@@ -50,13 +58,34 @@ export interface UploadImportOptions extends SignalOptions {
|
|
|
50
58
|
/** A repeat with the same key and the same bytes finds the same import. Defaults to a new UUID. */
|
|
51
59
|
idempotencyKey?: string;
|
|
52
60
|
}
|
|
61
|
+
/** The input of `snapshots.create` that builds the snapshot from the data of an import. */
|
|
62
|
+
interface CreateSnapshotFromData {
|
|
63
|
+
/** The manifest of the import, with each app's records in it. */
|
|
64
|
+
import: ImportData;
|
|
65
|
+
name?: string | null;
|
|
66
|
+
/** The workspace of the import and the snapshot. Defaults to the client's `workspaceId`; an API key has its own. */
|
|
67
|
+
workspaceId?: string;
|
|
68
|
+
}
|
|
53
69
|
/**
|
|
54
|
-
* The body of the credentials call. `
|
|
55
|
-
*
|
|
56
|
-
*
|
|
70
|
+
* The body of the credentials call. `as` names the user to act as, by email,
|
|
71
|
+
* username or ID. Without it, the credentials act as the app's default user:
|
|
72
|
+
* the first user that the snapshot's import names in `actors`, or else the
|
|
73
|
+
* app's administrator. `services` names more services to
|
|
74
|
+
* list, by ID. The credentials always list every `public` service, and a
|
|
57
75
|
* `preview` service only when `services` names it.
|
|
58
76
|
*/
|
|
59
|
-
export type ConnectOptions = Pick<CreateCredentialsRequestBody, 'actorId' | 'services'>;
|
|
77
|
+
export type ConnectOptions = Pick<CreateCredentialsRequestBody, 'as' | 'actorId' | 'services'>;
|
|
78
|
+
export interface ConnectAllOptions {
|
|
79
|
+
/** An email, a username or an ID, which each app looks up among its own users. */
|
|
80
|
+
as: string;
|
|
81
|
+
}
|
|
82
|
+
/** Credentials for each app that lets the user act, and the refusal of each other app. */
|
|
83
|
+
export interface ConnectAllResult {
|
|
84
|
+
/** By app name. */
|
|
85
|
+
readonly credentials: Readonly<Record<string, Credentials>>;
|
|
86
|
+
/** In the order of the environment's apps. */
|
|
87
|
+
readonly errors: readonly (ActorNotFoundError | ActorCannotSignInError)[];
|
|
88
|
+
}
|
|
60
89
|
export interface Page<T> {
|
|
61
90
|
data: T[];
|
|
62
91
|
nextCursor: string | null;
|
|
@@ -66,6 +95,8 @@ export type PageQuery = {
|
|
|
66
95
|
cursor?: string;
|
|
67
96
|
};
|
|
68
97
|
export type ListEnvironmentsQuery = ListEnvironmentsRequest;
|
|
98
|
+
/** `search` matches part of a name, an email or a username in any case, or a whole ID. */
|
|
99
|
+
export type ListActorsQuery = Omit<ListActorsRequest, 'environmentId' | 'appName'>;
|
|
69
100
|
export type ListSnapshotsQuery = ListSnapshotsRequest;
|
|
70
101
|
export type ListImportsQuery = ListImportsRequest;
|
|
71
102
|
export type ListAuditEventsQuery = ListAuditEventsRequest;
|
|
@@ -101,8 +132,27 @@ export declare class StateMachines {
|
|
|
101
132
|
* another call: `EnvironmentFailedError` if it failed, else `UnexpectedStatusError`.
|
|
102
133
|
*/
|
|
103
134
|
wait: (environmentId: string, options: WaitOptions<KnownEnvironmentStatus>) => Promise<Environment>;
|
|
104
|
-
/**
|
|
135
|
+
/**
|
|
136
|
+
* Credentials for one app of the environment. A user that the app does not have
|
|
137
|
+
* throws `ActorNotFoundError`, and one it does not let sign in throws
|
|
138
|
+
* `ActorCannotSignInError`.
|
|
139
|
+
*/
|
|
105
140
|
connect: (environmentId: string, appName: string, options?: ConnectOptions) => Promise<Credentials>;
|
|
141
|
+
/** One page of the users who can act in one app of a running environment, the default user first. */
|
|
142
|
+
actors: (environmentId: string, appName: string, query?: ListActorsQuery) => Promise<Page<AppUser>>;
|
|
143
|
+
/**
|
|
144
|
+
* Launches a browser session of one user in a browser service of the app.
|
|
145
|
+
* `entryPath` must match one of the service's document routes, and `as` names
|
|
146
|
+
* the user as `connect` takes it. The
|
|
147
|
+
* launch holds a one-use `grant` that expires soon, and no reusable credential.
|
|
148
|
+
* Give it only to the browser it is for, which posts it to `exchangeUrl` from
|
|
149
|
+
* `launcherOrigin`, such as with `submitLaunch` from `@usestatemachines/sdk/ui`.
|
|
150
|
+
* A user that the app does not have throws `ActorNotFoundError`, and one it
|
|
151
|
+
* does not let sign in throws `ActorCannotSignInError`.
|
|
152
|
+
*/
|
|
153
|
+
launchUiSession: (environmentId: string, appName: string, input: LaunchUiSession, options?: SignalOptions) => Promise<UiSessionLaunch>;
|
|
154
|
+
/** Ends a browser session that this credential launched. Safe to repeat. */
|
|
155
|
+
revokeUiSession: (environmentId: string, appName: string, sessionId: string, options?: SignalOptions) => Promise<UiSessionRevocation>;
|
|
106
156
|
};
|
|
107
157
|
readonly snapshots: {
|
|
108
158
|
/**
|
|
@@ -110,16 +160,29 @@ export declare class StateMachines {
|
|
|
110
160
|
* and, unless `wait` is false, waits until it is `ready`. A snapshot from an import
|
|
111
161
|
* takes every app of the import, each on its default version, with empty setup and
|
|
112
162
|
* services. An import that an app refuses throws `SnapshotFailedError` with its problems.
|
|
163
|
+
*
|
|
164
|
+
* `{ import }` takes an import as one object, which is the manifest with each app's
|
|
165
|
+
* records in it. The SDK writes the object as a zip file, uploads it as `imports.upload`
|
|
166
|
+
* does, and builds the snapshot from the import. The zip file holds each object's records
|
|
167
|
+
* in `<app>/records/<Object>.jsonl`, one record per line, so a problem at line N of that
|
|
168
|
+
* file names `apps.<app>.records.<Object>[N - 1]`. Data that the SDK cannot write as a
|
|
169
|
+
* zip file throws `StateMachinesError` with `code: 'invalid_request'` before any request.
|
|
170
|
+
* An import that its check leaves `invalid` throws `ImportInvalidError`, and the SDK
|
|
171
|
+
* creates no snapshot. The import and the snapshot share one idempotency key, so a
|
|
172
|
+
* retry with the same key and the same data finds both.
|
|
113
173
|
*/
|
|
114
|
-
create: (input: {
|
|
174
|
+
create: (input: CreateSnapshotFromData | {
|
|
115
175
|
environmentId: string;
|
|
116
176
|
name?: string | null;
|
|
117
177
|
} | {
|
|
118
178
|
importId: string;
|
|
119
179
|
name?: string | null;
|
|
120
180
|
}, options?: CreateEnvironmentOptions) => Promise<Snapshot>;
|
|
121
|
-
/**
|
|
122
|
-
|
|
181
|
+
/**
|
|
182
|
+
* Newest first. Leaves deleted snapshots out unless `status` asks for them.
|
|
183
|
+
* Each app's load holds its counts only. `get` answers its lists too.
|
|
184
|
+
*/
|
|
185
|
+
list: (query?: ListSnapshotsRequest) => Promise<Page<SnapshotListItem>>;
|
|
123
186
|
get: (snapshotId: string) => Promise<Snapshot>;
|
|
124
187
|
/** `null` clears the name. */
|
|
125
188
|
update: (snapshotId: string, body: {
|
|
@@ -165,3 +228,4 @@ export declare class StateMachines {
|
|
|
165
228
|
* collection a clone's signal no longer follows the call's (Node 20 and 24).
|
|
166
229
|
*/
|
|
167
230
|
export declare const CALL_HEADER = "x-statemachines-call";
|
|
231
|
+
export {};
|
package/esm/extensions/client.js
CHANGED
|
@@ -2,7 +2,8 @@ import { SDK_METADATA } from '../lib/config.js';
|
|
|
2
2
|
import { HTTPClient } from '../lib/http.js';
|
|
3
3
|
import { StateMachines as Generated } from '../sdk/sdk.js';
|
|
4
4
|
import { bindCredentials } from './credentials.js';
|
|
5
|
-
import { CallerAbortedError, StateMachinesError, toStateMachinesError, uploadRefused, uploadUnanswered, } from './errors.js';
|
|
5
|
+
import { ActorCannotSignInError, ActorNotFoundError, actorError, CallerAbortedError, ImportInvalidError, StateMachinesError, toStateMachinesError, uploadRefused, uploadUnanswered, } from './errors.js';
|
|
6
|
+
import { zipImport } from './import-data.js';
|
|
6
7
|
import { linkSignal } from './signal.js';
|
|
7
8
|
import { environmentAt, poll, snapshotAt, } from './wait.js';
|
|
8
9
|
export class StateMachines {
|
|
@@ -79,8 +80,27 @@ export class StateMachines {
|
|
|
79
80
|
* another call: `EnvironmentFailedError` if it failed, else `UnexpectedStatusError`.
|
|
80
81
|
*/
|
|
81
82
|
wait: async (environmentId, options) => this.#bind(await poll(environmentId, (signal) => this.#read(signal, (call) => this.#sdk.environments.get({ environmentId }, call)), environmentAt(options.status), options)),
|
|
82
|
-
/**
|
|
83
|
+
/**
|
|
84
|
+
* Credentials for one app of the environment. A user that the app does not have
|
|
85
|
+
* throws `ActorNotFoundError`, and one it does not let sign in throws
|
|
86
|
+
* `ActorCannotSignInError`.
|
|
87
|
+
*/
|
|
83
88
|
connect: (environmentId, appName, options = {}) => this.#connect(environmentId, appName, options),
|
|
89
|
+
/** One page of the users who can act in one app of a running environment, the default user first. */
|
|
90
|
+
actors: (environmentId, appName, query = {}) => this.#call(undefined, (call) => this.#sdk.environments.actors({ ...query, environmentId, appName }, call)),
|
|
91
|
+
/**
|
|
92
|
+
* Launches a browser session of one user in a browser service of the app.
|
|
93
|
+
* `entryPath` must match one of the service's document routes, and `as` names
|
|
94
|
+
* the user as `connect` takes it. The
|
|
95
|
+
* launch holds a one-use `grant` that expires soon, and no reusable credential.
|
|
96
|
+
* Give it only to the browser it is for, which posts it to `exchangeUrl` from
|
|
97
|
+
* `launcherOrigin`, such as with `submitLaunch` from `@usestatemachines/sdk/ui`.
|
|
98
|
+
* A user that the app does not have throws `ActorNotFoundError`, and one it
|
|
99
|
+
* does not let sign in throws `ActorCannotSignInError`.
|
|
100
|
+
*/
|
|
101
|
+
launchUiSession: (environmentId, appName, input, options = {}) => this.#launchUiSession(environmentId, appName, input, options),
|
|
102
|
+
/** Ends a browser session that this credential launched. Safe to repeat. */
|
|
103
|
+
revokeUiSession: (environmentId, appName, sessionId, options = {}) => this.#call(options.signal, (call) => this.#sdk.revokeUiSession({ environmentId, appName, sessionId }, call)),
|
|
84
104
|
};
|
|
85
105
|
snapshots = {
|
|
86
106
|
/**
|
|
@@ -88,10 +108,24 @@ export class StateMachines {
|
|
|
88
108
|
* and, unless `wait` is false, waits until it is `ready`. A snapshot from an import
|
|
89
109
|
* takes every app of the import, each on its default version, with empty setup and
|
|
90
110
|
* services. An import that an app refuses throws `SnapshotFailedError` with its problems.
|
|
111
|
+
*
|
|
112
|
+
* `{ import }` takes an import as one object, which is the manifest with each app's
|
|
113
|
+
* records in it. The SDK writes the object as a zip file, uploads it as `imports.upload`
|
|
114
|
+
* does, and builds the snapshot from the import. The zip file holds each object's records
|
|
115
|
+
* in `<app>/records/<Object>.jsonl`, one record per line, so a problem at line N of that
|
|
116
|
+
* file names `apps.<app>.records.<Object>[N - 1]`. Data that the SDK cannot write as a
|
|
117
|
+
* zip file throws `StateMachinesError` with `code: 'invalid_request'` before any request.
|
|
118
|
+
* An import that its check leaves `invalid` throws `ImportInvalidError`, and the SDK
|
|
119
|
+
* creates no snapshot. The import and the snapshot share one idempotency key, so a
|
|
120
|
+
* retry with the same key and the same data finds both.
|
|
91
121
|
*/
|
|
92
122
|
create: async (input, options = {}) => {
|
|
123
|
+
const { signal } = options;
|
|
93
124
|
const idempotencyKey = options.idempotencyKey ?? crypto.randomUUID();
|
|
94
|
-
const
|
|
125
|
+
const body = 'import' in input
|
|
126
|
+
? await this.#fromData(input, idempotencyKey, signal)
|
|
127
|
+
: input;
|
|
128
|
+
const created = await this.#call(signal, (call) => this.#sdk.snapshots.create({ idempotencyKey, body }, call));
|
|
95
129
|
return options.wait === false
|
|
96
130
|
? created
|
|
97
131
|
: this.snapshots.wait(created.id, {
|
|
@@ -99,7 +133,10 @@ export class StateMachines {
|
|
|
99
133
|
...waitOptions(options),
|
|
100
134
|
});
|
|
101
135
|
},
|
|
102
|
-
/**
|
|
136
|
+
/**
|
|
137
|
+
* Newest first. Leaves deleted snapshots out unless `status` asks for them.
|
|
138
|
+
* Each app's load holds its counts only. `get` answers its lists too.
|
|
139
|
+
*/
|
|
103
140
|
list: (query = {}) => this.#call(undefined, (call) => this.#sdk.snapshots.list(this.#inWorkspace(query), call)),
|
|
104
141
|
get: (snapshotId) => this.#call(undefined, (call) => this.#sdk.snapshots.get({ snapshotId }, call)),
|
|
105
142
|
/** `null` clears the name. */
|
|
@@ -166,12 +203,55 @@ export class StateMachines {
|
|
|
166
203
|
}
|
|
167
204
|
async #connect(environmentId, appName, options) {
|
|
168
205
|
const body = {
|
|
206
|
+
...(options.as === undefined ? {} : { as: options.as }),
|
|
169
207
|
...(options.actorId === undefined ? {} : { actorId: options.actorId }),
|
|
170
208
|
...(options.services === undefined ? {} : { services: options.services }),
|
|
171
209
|
};
|
|
172
|
-
|
|
210
|
+
// Typed inside the call, because the error that `#call` throws no longer holds the response body.
|
|
211
|
+
const credentials = await this.#call(undefined, (call) => this.#sdk.environments
|
|
212
|
+
.connect({ environmentId, appName, body }, call)
|
|
213
|
+
.catch((error) => {
|
|
214
|
+
throw actorError(error, appName);
|
|
215
|
+
}));
|
|
173
216
|
return bindCredentials(credentials, this.#fetch);
|
|
174
217
|
}
|
|
218
|
+
#launchUiSession(environmentId, appName, body, options) {
|
|
219
|
+
return this.#call(options.signal, (call) => this.#sdk
|
|
220
|
+
.launchUiSession({ environmentId, appName, body }, call)
|
|
221
|
+
.catch((error) => {
|
|
222
|
+
throw actorError(error, appName);
|
|
223
|
+
}));
|
|
224
|
+
}
|
|
225
|
+
async #connectAll(environment, { as }) {
|
|
226
|
+
const outcomes = await Promise.allSettled(environment.apps.map((app) => this.#connect(environment.id, app.name, { as })));
|
|
227
|
+
const credentials = {};
|
|
228
|
+
const errors = [];
|
|
229
|
+
for (const outcome of outcomes) {
|
|
230
|
+
if (outcome.status === 'fulfilled') {
|
|
231
|
+
credentials[outcome.value.appName] = outcome.value;
|
|
232
|
+
}
|
|
233
|
+
else if (outcome.reason instanceof ActorNotFoundError ||
|
|
234
|
+
outcome.reason instanceof ActorCannotSignInError) {
|
|
235
|
+
errors.push(outcome.reason);
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
throw outcome.reason;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return { credentials, errors };
|
|
242
|
+
}
|
|
243
|
+
/** Uploads the data as an import under `idempotencyKey`, and answers the body that builds the snapshot from it. */
|
|
244
|
+
async #fromData({ import: data, workspaceId, ...snapshot }, idempotencyKey, signal) {
|
|
245
|
+
const imported = await this.imports.upload(zipImport(data), {
|
|
246
|
+
...(workspaceId === undefined ? {} : { workspaceId }),
|
|
247
|
+
...(signal ? { signal } : {}),
|
|
248
|
+
idempotencyKey,
|
|
249
|
+
});
|
|
250
|
+
if (imported.status === 'invalid') {
|
|
251
|
+
throw new ImportInvalidError(imported);
|
|
252
|
+
}
|
|
253
|
+
return { ...snapshot, importId: imported.id };
|
|
254
|
+
}
|
|
175
255
|
async #send(upload, zip, signal) {
|
|
176
256
|
const fetcher = this.#fetch ?? fetch;
|
|
177
257
|
const scope = linkSignal(signal);
|
|
@@ -203,9 +283,13 @@ export class StateMachines {
|
|
|
203
283
|
#bind(data) {
|
|
204
284
|
const { id } = data;
|
|
205
285
|
const helpers = {
|
|
286
|
+
actors: (appName, query) => this.environments.actors(id, appName, query),
|
|
206
287
|
connect: (appName, options = {}) => this.#connect(id, appName, options),
|
|
288
|
+
connectAll: (options) => this.#connectAll(data, options),
|
|
207
289
|
delete: (options) => this.environments.delete(id, options),
|
|
290
|
+
launchUiSession: (appName, input, options) => this.environments.launchUiSession(id, appName, input, options),
|
|
208
291
|
refresh: () => this.environments.get(id),
|
|
292
|
+
revokeUiSession: (appName, sessionId, options) => this.environments.revokeUiSession(id, appName, sessionId, options),
|
|
209
293
|
snapshots: {
|
|
210
294
|
create: (input = {}, options) => this.snapshots.create({ ...input, environmentId: id }, options),
|
|
211
295
|
},
|
|
@@ -27,6 +27,10 @@ class BoundCredentials {
|
|
|
27
27
|
this.services = data.services;
|
|
28
28
|
this.token = data.token;
|
|
29
29
|
this.#fetcher = fetcher;
|
|
30
|
+
// Set only when present, so JSON and a spread hold the API's fields.
|
|
31
|
+
if (data.actor) {
|
|
32
|
+
this.actor = data.actor;
|
|
33
|
+
}
|
|
30
34
|
const api = data.services.find((candidate) => candidate.id === 'api');
|
|
31
35
|
this.#api = api
|
|
32
36
|
? { base: baseUrl(api.url), headers: { ...api.headers } }
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import type { AppUser } from '../models/app-user.js';
|
|
1
2
|
import type { Environment as EnvironmentData } from '../models/environment.js';
|
|
3
|
+
import type { LaunchUiSession } from '../models/launch-ui-session.js';
|
|
2
4
|
import type { Snapshot } from '../models/snapshot.js';
|
|
3
|
-
import type {
|
|
5
|
+
import type { UiSessionLaunch } from '../models/ui-session-launch.js';
|
|
6
|
+
import type { UiSessionRevocation } from '../models/ui-session-revocation.js';
|
|
7
|
+
import type { ConnectAllOptions, ConnectAllResult, ConnectOptions, CreateSnapshotOptions, ListActorsQuery, Page, SignalOptions } from './client.js';
|
|
4
8
|
import type { Credentials } from './credentials.js';
|
|
5
9
|
/**
|
|
6
10
|
* An environment as the API returned it, with helpers bound to it. The helpers are not
|
|
@@ -8,11 +12,23 @@ import type { Credentials } from './credentials.js';
|
|
|
8
12
|
*/
|
|
9
13
|
export type Environment = EnvironmentData & EnvironmentHelpers;
|
|
10
14
|
export interface EnvironmentHelpers {
|
|
11
|
-
/** Credentials for one app
|
|
15
|
+
/** Credentials for one app, acting as the user that `as` names, else as the app's default user. */
|
|
12
16
|
connect(appName: string, options?: ConnectOptions): Promise<Credentials>;
|
|
17
|
+
/**
|
|
18
|
+
* Credentials for each app that lets the user that `as` names act. An app that
|
|
19
|
+
* does not have the user, or does not let the user sign in, adds its error to
|
|
20
|
+
* `errors`. Any other error throws.
|
|
21
|
+
*/
|
|
22
|
+
connectAll(options: ConnectAllOptions): Promise<ConnectAllResult>;
|
|
23
|
+
/** One page of the users who can act in one app, the default user first. */
|
|
24
|
+
actors(appName: string, query?: ListActorsQuery): Promise<Page<AppUser>>;
|
|
13
25
|
delete(options?: SignalOptions): Promise<Environment>;
|
|
26
|
+
/** Launches a browser session in a browser service of one app. The launch holds a one-use grant for one browser. */
|
|
27
|
+
launchUiSession(appName: string, input: LaunchUiSession, options?: SignalOptions): Promise<UiSessionLaunch>;
|
|
14
28
|
/** Reads the environment again. */
|
|
15
29
|
refresh(): Promise<Environment>;
|
|
30
|
+
/** Ends a browser session that this credential launched. Safe to repeat. */
|
|
31
|
+
revokeUiSession(appName: string, sessionId: string, options?: SignalOptions): Promise<UiSessionRevocation>;
|
|
16
32
|
readonly snapshots: {
|
|
17
33
|
/** Waits until `ready` unless `wait` is false. */
|
|
18
34
|
create(input?: {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import type { AppUser } from '../models/app-user.js';
|
|
1
2
|
import type { Environment as EnvironmentData } from '../models/environment.js';
|
|
2
3
|
import type { ErrorCode } from '../models/error.js';
|
|
4
|
+
import type { Import } from '../models/import.js';
|
|
3
5
|
import type { ImportProblem } from '../models/import-problem.js';
|
|
4
6
|
import type { Snapshot } from '../models/snapshot.js';
|
|
5
7
|
export interface ErrorDetails {
|
|
@@ -42,6 +44,37 @@ export declare class SnapshotFailedError extends StateMachinesError {
|
|
|
42
44
|
readonly problems: readonly ImportProblem[];
|
|
43
45
|
constructor(snapshot: Snapshot);
|
|
44
46
|
}
|
|
47
|
+
/** An import that `snapshots.create` uploaded and its check left `invalid`, so the SDK created no snapshot. */
|
|
48
|
+
export declare class ImportInvalidError extends StateMachinesError {
|
|
49
|
+
readonly name = "ImportInvalidError";
|
|
50
|
+
readonly import: Import;
|
|
51
|
+
/** The first problems that the check found, errors before warnings. `import.problemCount` counts them all. */
|
|
52
|
+
readonly problems: readonly ImportProblem[];
|
|
53
|
+
constructor(invalid: Import);
|
|
54
|
+
}
|
|
55
|
+
/** The app has no user with the email, username or ID that the call sent as `as`. */
|
|
56
|
+
export declare class ActorNotFoundError extends StateMachinesError {
|
|
57
|
+
readonly appName: string;
|
|
58
|
+
/** The users who can act in the app that are nearest to `as`, nearest first. */
|
|
59
|
+
readonly nearest: readonly AppUser[];
|
|
60
|
+
readonly name = "ActorNotFoundError";
|
|
61
|
+
readonly code: 'actor_not_found';
|
|
62
|
+
constructor(error: StateMachinesError, appName: string,
|
|
63
|
+
/** The users who can act in the app that are nearest to `as`, nearest first. */
|
|
64
|
+
nearest: readonly AppUser[]);
|
|
65
|
+
}
|
|
66
|
+
/** The app has the user, and does not let the user sign in now, for the reason in `fields.as`. */
|
|
67
|
+
export declare class ActorCannotSignInError extends StateMachinesError {
|
|
68
|
+
readonly appName: string;
|
|
69
|
+
readonly name = "ActorCannotSignInError";
|
|
70
|
+
readonly code: 'actor_cannot_sign_in';
|
|
71
|
+
constructor(error: StateMachinesError, appName: string);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* The typed error for an answer that refuses the user a credentials call
|
|
75
|
+
* names, else the error that any call fails with.
|
|
76
|
+
*/
|
|
77
|
+
export declare function actorError(error: unknown, appName: string): StateMachinesError;
|
|
45
78
|
/** The resource reached a status from which the awaited one needs a call of yours. */
|
|
46
79
|
export declare class UnexpectedStatusError extends Error {
|
|
47
80
|
readonly resource: EnvironmentData | Snapshot;
|
package/esm/extensions/errors.js
CHANGED
|
@@ -92,6 +92,59 @@ export class SnapshotFailedError extends StateMachinesError {
|
|
|
92
92
|
this.problems = problems;
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
|
+
/** An import that `snapshots.create` uploaded and its check left `invalid`, so the SDK created no snapshot. */
|
|
96
|
+
export class ImportInvalidError extends StateMachinesError {
|
|
97
|
+
name = 'ImportInvalidError';
|
|
98
|
+
import;
|
|
99
|
+
/** The first problems that the check found, errors before warnings. `import.problemCount` counts them all. */
|
|
100
|
+
problems;
|
|
101
|
+
constructor(invalid) {
|
|
102
|
+
super({
|
|
103
|
+
...noResponse,
|
|
104
|
+
message: `Import ${invalid.id} is invalid.${firstProblem(invalid.problems)}`,
|
|
105
|
+
});
|
|
106
|
+
this.import = invalid;
|
|
107
|
+
this.problems = invalid.problems;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/** The app has no user with the email, username or ID that the call sent as `as`. */
|
|
111
|
+
export class ActorNotFoundError extends StateMachinesError {
|
|
112
|
+
appName;
|
|
113
|
+
nearest;
|
|
114
|
+
name = 'ActorNotFoundError';
|
|
115
|
+
constructor(error, appName,
|
|
116
|
+
/** The users who can act in the app that are nearest to `as`, nearest first. */
|
|
117
|
+
nearest) {
|
|
118
|
+
super(error);
|
|
119
|
+
this.appName = appName;
|
|
120
|
+
this.nearest = nearest;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/** The app has the user, and does not let the user sign in now, for the reason in `fields.as`. */
|
|
124
|
+
export class ActorCannotSignInError extends StateMachinesError {
|
|
125
|
+
appName;
|
|
126
|
+
name = 'ActorCannotSignInError';
|
|
127
|
+
constructor(error, appName) {
|
|
128
|
+
super(error);
|
|
129
|
+
this.appName = appName;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* The typed error for an answer that refuses the user a credentials call
|
|
134
|
+
* names, else the error that any call fails with.
|
|
135
|
+
*/
|
|
136
|
+
export function actorError(error, appName) {
|
|
137
|
+
const failure = toStateMachinesError(error);
|
|
138
|
+
const body = error instanceof ErrorT ? error.error : null;
|
|
139
|
+
switch (body?.code) {
|
|
140
|
+
case 'actor_not_found':
|
|
141
|
+
return new ActorNotFoundError(failure, appName, body.nearest ?? []);
|
|
142
|
+
case 'actor_cannot_sign_in':
|
|
143
|
+
return new ActorCannotSignInError(failure, appName);
|
|
144
|
+
default:
|
|
145
|
+
return failure;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
95
148
|
/** The resource reached a status from which the awaited one needs a call of yours. */
|
|
96
149
|
export class UnexpectedStatusError extends Error {
|
|
97
150
|
resource;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** An import as one object, which is its manifest with each app's records and content in it. */
|
|
2
|
+
export interface ImportData {
|
|
3
|
+
readonly format: 'statemachines.import/v1';
|
|
4
|
+
/** The import's name. */
|
|
5
|
+
readonly name: string;
|
|
6
|
+
/** By the app's name in the import, such as `salesforce`. */
|
|
7
|
+
readonly apps: Readonly<Record<string, ImportAppData>>;
|
|
8
|
+
}
|
|
9
|
+
/** One app of an import: its settings, its records and the files that its records name. */
|
|
10
|
+
export interface ImportAppData {
|
|
11
|
+
/** Defaults to the app's name in the import. */
|
|
12
|
+
readonly appId?: string;
|
|
13
|
+
/**
|
|
14
|
+
* What the load does with a record that cannot load. `refuse`, the default,
|
|
15
|
+
* fails the snapshot. `skipRecord` leaves the record out, with each record
|
|
16
|
+
* that references it.
|
|
17
|
+
*/
|
|
18
|
+
readonly loadMode?: 'skipRecord' | 'refuse';
|
|
19
|
+
/** The users to act as, by email, username or ID. */
|
|
20
|
+
readonly actors?: readonly string[];
|
|
21
|
+
/** The objects that the load leaves out, and the fields that it leaves out by object. */
|
|
22
|
+
readonly skip?: {
|
|
23
|
+
readonly objects?: readonly string[];
|
|
24
|
+
readonly fields?: Readonly<Record<string, readonly string[]>>;
|
|
25
|
+
};
|
|
26
|
+
/** The records in the app's own JSON, by object, such as `Account`. */
|
|
27
|
+
readonly records?: Readonly<Record<string, readonly Readonly<Record<string, unknown>>[]>>;
|
|
28
|
+
/**
|
|
29
|
+
* The bytes of the files that the app's records name, by path inside the
|
|
30
|
+
* app's `content/` folder, such as Box's `file_version/41500000004`.
|
|
31
|
+
*/
|
|
32
|
+
readonly content?: Readonly<Record<string, Uint8Array>>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The zip file of `data` in the folder form. `statemachines.json` holds the
|
|
36
|
+
* manifest without each app's `records` and `content`. Each object's records
|
|
37
|
+
* go to `<app>/records/<Object>.jsonl`, one record per line, so line N of the
|
|
38
|
+
* file names the record at index N - 1. Each content file goes to
|
|
39
|
+
* `<app>/content/<path>`. Data in a shape that the folder form cannot hold
|
|
40
|
+
* throws `invalid_request`, with the path of each wrong field. The API checks
|
|
41
|
+
* the rest.
|
|
42
|
+
*/
|
|
43
|
+
export declare function zipImport(data: ImportData): Uint8Array<ArrayBuffer>;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { invalidInput } from './errors.js';
|
|
2
|
+
import { zipFiles } from './zip.js';
|
|
3
|
+
const PLAIN_OBJECT = 'Expected a plain object.';
|
|
4
|
+
const utf8 = new TextEncoder();
|
|
5
|
+
/**
|
|
6
|
+
* The zip file of `data` in the folder form. `statemachines.json` holds the
|
|
7
|
+
* manifest without each app's `records` and `content`. Each object's records
|
|
8
|
+
* go to `<app>/records/<Object>.jsonl`, one record per line, so line N of the
|
|
9
|
+
* file names the record at index N - 1. Each content file goes to
|
|
10
|
+
* `<app>/content/<path>`. Data in a shape that the folder form cannot hold
|
|
11
|
+
* throws `invalid_request`, with the path of each wrong field. The API checks
|
|
12
|
+
* the rest.
|
|
13
|
+
*/
|
|
14
|
+
export function zipImport(data) {
|
|
15
|
+
const fields = shapeProblems(data);
|
|
16
|
+
if (Object.keys(fields).length > 0) {
|
|
17
|
+
throw invalidInput('The import data is invalid.', fields);
|
|
18
|
+
}
|
|
19
|
+
return zipFiles(folderFiles(data));
|
|
20
|
+
}
|
|
21
|
+
/** The fields of `data` that the folder form cannot hold, by dotted path. */
|
|
22
|
+
function shapeProblems(data) {
|
|
23
|
+
const fields = {};
|
|
24
|
+
const add = (path, message) => {
|
|
25
|
+
fields[path] = [...(fields[path] ?? []), message];
|
|
26
|
+
};
|
|
27
|
+
const entriesAt = (value, path) => {
|
|
28
|
+
if (isPlainObject(value)) {
|
|
29
|
+
return Object.entries(value);
|
|
30
|
+
}
|
|
31
|
+
add(path, PLAIN_OBJECT);
|
|
32
|
+
return [];
|
|
33
|
+
};
|
|
34
|
+
if (!isPlainObject(data)) {
|
|
35
|
+
add('import', PLAIN_OBJECT);
|
|
36
|
+
return fields;
|
|
37
|
+
}
|
|
38
|
+
const { apps } = data;
|
|
39
|
+
for (const [name, app] of entriesAt(apps, 'import.apps')) {
|
|
40
|
+
const at = `import.apps.${name}`;
|
|
41
|
+
if (!isPlainObject(app)) {
|
|
42
|
+
add(at, PLAIN_OBJECT);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const { records = {}, content = {} } = app;
|
|
46
|
+
for (const [object, list] of entriesAt(records, `${at}.records`)) {
|
|
47
|
+
if (!Array.isArray(list)) {
|
|
48
|
+
add(`${at}.records.${object}`, 'Expected an array.');
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
for (const [index, record] of list.entries()) {
|
|
52
|
+
if (!isPlainObject(record)) {
|
|
53
|
+
add(`${at}.records.${object}.${index}`, PLAIN_OBJECT);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
for (const [path, bytes] of entriesAt(content, `${at}.content`)) {
|
|
58
|
+
if (!(bytes instanceof Uint8Array)) {
|
|
59
|
+
add(`${at}.content.${path}`, 'Expected a Uint8Array.');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return fields;
|
|
64
|
+
}
|
|
65
|
+
function folderFiles(data) {
|
|
66
|
+
const files = new Map();
|
|
67
|
+
const apps = {};
|
|
68
|
+
for (const [name, app] of Object.entries(data.apps)) {
|
|
69
|
+
const { records = {}, content = {}, ...settings } = app;
|
|
70
|
+
apps[name] = settings;
|
|
71
|
+
for (const [object, list] of Object.entries(records)) {
|
|
72
|
+
files.set(`${name}/records/${object}.jsonl`, utf8.encode(list.map((record) => `${JSON.stringify(record)}\n`).join('')));
|
|
73
|
+
}
|
|
74
|
+
for (const [path, bytes] of Object.entries(content)) {
|
|
75
|
+
files.set(`${name}/content/${path}`, bytes);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// The spread keeps any field that the manifest refuses, so the API names it.
|
|
79
|
+
files.set('statemachines.json', utf8.encode(`${JSON.stringify({ ...data, apps }, null, 2)}\n`));
|
|
80
|
+
return files;
|
|
81
|
+
}
|
|
82
|
+
function isPlainObject(value) {
|
|
83
|
+
if (typeof value !== 'object' || value === null) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
const prototype = Object.getPrototypeOf(value);
|
|
87
|
+
return prototype === Object.prototype || prototype === null;
|
|
88
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
export type { Actor, App, AppEntry, AuditEvent, BodyPreview, CreateEnvironment, CreateEnvironmentApp, EnvironmentApp, EnvironmentFailure, EnvironmentFailureCode, EnvironmentStatus, ErrorCode, Import, ImportApp, ImportProblem, ImportStatus, Me, Permission, Principal, RequestDetail, RequestStats, RequestT as Request, Snapshot, SnapshotStatus, Version, Workspace, } from '../models/index.js';
|
|
2
|
-
export type { ConnectOptions, CreateEnvironmentOptions, CreateSnapshotOptions, ListAuditEventsQuery, ListEnvironmentsQuery, ListImportsQuery, ListRequestsQuery, ListSnapshotsQuery, ListWorkspacesQuery, Page, PageQuery, RequestStatsQuery, SignalOptions, StateMachinesOptions, UploadImportOptions, } from './client.js';
|
|
1
|
+
export type { AbsentReason, AbsentRecord, Actor, App, AppEntry, AppUser, AuditEvent, BodyPreview, CreateEnvironment, CreateEnvironmentApp, EnvironmentApp, EnvironmentFailure, EnvironmentFailureCode, EnvironmentStatus, ErrorCode, FilledField, Import, ImportActor, ImportApp, ImportProblem, ImportStatus, KnownDifference, LaunchUiSession, MadeId, MatchedRecord, Me, ObjectLoad, Permission, Principal, ProblemCounts, RecordSource, RequestDetail, RequestStats, RequestT as Request, Snapshot, SnapshotAppLoad, SnapshotAppLoadCounts, SnapshotListItem, SnapshotStatus, UiSessionLaunch, UiSessionMode, UiSessionRevocation, Version, Workspace, } from '../models/index.js';
|
|
2
|
+
export type { ConnectAllOptions, ConnectAllResult, ConnectOptions, CreateEnvironmentOptions, CreateSnapshotOptions, ListActorsQuery, ListAuditEventsQuery, ListEnvironmentsQuery, ListImportsQuery, ListRequestsQuery, ListSnapshotsQuery, ListWorkspacesQuery, Page, PageQuery, RequestStatsQuery, SignalOptions, StateMachinesOptions, UploadImportOptions, } from './client.js';
|
|
3
3
|
export { StateMachines } from './client.js';
|
|
4
4
|
export type { Credentials, McpServerCredentials, ServiceCredentials, } from './credentials.js';
|
|
5
5
|
export type { Environment, EnvironmentHelpers } from './environment.js';
|
|
6
|
-
export { EnvironmentFailedError, SnapshotFailedError, StateMachinesError, UnexpectedStatusError, WaitTimeoutError, } from './errors.js';
|
|
6
|
+
export { ActorCannotSignInError, ActorNotFoundError, EnvironmentFailedError, ImportInvalidError, SnapshotFailedError, StateMachinesError, UnexpectedStatusError, WaitTimeoutError, } from './errors.js';
|
|
7
|
+
export type { ImportAppData, ImportData } from './import-data.js';
|
|
7
8
|
export type { WaitOptions } from './wait.js';
|
|
8
9
|
export { parseEnvironmentYaml } from './yaml.js';
|
package/esm/extensions/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { StateMachines } from './client.js';
|
|
2
|
-
export { EnvironmentFailedError, SnapshotFailedError, StateMachinesError, UnexpectedStatusError, WaitTimeoutError, } from './errors.js';
|
|
2
|
+
export { ActorCannotSignInError, ActorNotFoundError, EnvironmentFailedError, ImportInvalidError, SnapshotFailedError, StateMachinesError, UnexpectedStatusError, WaitTimeoutError, } from './errors.js';
|
|
3
3
|
export { parseEnvironmentYaml } from './yaml.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { zipFiles } from './zip.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { zipFiles } from './zip.js';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A zip file of `files`, keyed by their paths, in the order of their paths.
|
|
3
|
+
* Each file is stored, with a UTF-8 name, the earliest MS-DOS time, and no
|
|
4
|
+
* extra field, so the same files always give the same bytes. It refuses what
|
|
5
|
+
* needs ZIP64. It needs no `node:zlib`, because the SDK imports no Node
|
|
6
|
+
* module and runs in Cloudflare Workers.
|
|
7
|
+
*/
|
|
8
|
+
export declare function zipFiles(files: ReadonlyMap<string, Uint8Array>): Uint8Array<ArrayBuffer>;
|