@molecule/api-code-sandbox-flyio 1.0.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/LICENSE +115 -0
- package/README.md +2189 -0
- package/dist/api.d.ts +140 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +226 -0
- package/dist/browser-guard.d.ts +2 -0
- package/dist/browser-guard.d.ts.map +1 -0
- package/dist/browser-guard.js +18 -0
- package/dist/egress.d.ts +180 -0
- package/dist/egress.d.ts.map +1 -0
- package/dist/egress.js +283 -0
- package/dist/exec.d.ts +85 -0
- package/dist/exec.d.ts.map +1 -0
- package/dist/exec.js +215 -0
- package/dist/flycast.d.ts +173 -0
- package/dist/flycast.d.ts.map +1 -0
- package/dist/flycast.js +287 -0
- package/dist/ids.d.ts +79 -0
- package/dist/ids.d.ts.map +1 -0
- package/dist/ids.js +121 -0
- package/dist/index.d.ts +346 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +359 -0
- package/dist/provider.d.ts +24 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +1425 -0
- package/dist/storage.d.ts +119 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +241 -0
- package/dist/templates.d.ts +310 -0
- package/dist/templates.d.ts.map +1 -0
- package/dist/templates.js +655 -0
- package/dist/types.d.ts +519 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/utilities.d.ts +29 -0
- package/dist/utilities.d.ts.map +1 -0
- package/dist/utilities.js +44 -0
- package/package.json +63 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,519 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fly.io Machines sandbox provider configuration and wire types.
|
|
3
|
+
*
|
|
4
|
+
* Wire types mirror the Fly Machines OpenAPI specification
|
|
5
|
+
* (https://docs.machines.dev/openapi.json, servers: `https://api.machines.dev/v1`).
|
|
6
|
+
* Only the fields this provider actually reads or writes are modelled — the real
|
|
7
|
+
* schemas are much larger, and modelling fields we never use would rot silently.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Configuration for the Fly.io Machines sandbox provider.
|
|
13
|
+
*
|
|
14
|
+
* Every option is also readable from an environment variable (see
|
|
15
|
+
* {@link ProcessEnv}); explicit config always wins.
|
|
16
|
+
*/
|
|
17
|
+
export interface FlyioConfig {
|
|
18
|
+
/**
|
|
19
|
+
* Fly API token (sent as `Authorization: Bearer <token>`). Falls back to
|
|
20
|
+
* `FLY_API_TOKEN`, then `FLY_ACCESS_TOKEN`. Required — the provider throws a
|
|
21
|
+
* named error on the first API call if none is resolvable.
|
|
22
|
+
*/
|
|
23
|
+
apiToken?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Machines API base URL, INCLUDING the `/v1` path segment. Defaults to
|
|
26
|
+
* `FLY_API_HOSTNAME` (with `/v1` appended when the value has no path) or
|
|
27
|
+
* `https://api.machines.dev/v1`. From inside a Fly private network the
|
|
28
|
+
* documented internal endpoint is `http://_api.internal:4280/v1`.
|
|
29
|
+
*/
|
|
30
|
+
apiUrl?: string;
|
|
31
|
+
/**
|
|
32
|
+
* Fly organization slug that owns the sandbox apps. Falls back to
|
|
33
|
+
* `FLY_ORG_SLUG`, then `personal`. Required for app creation and for
|
|
34
|
+
* {@link FlyioConfig.appPerProject} listing.
|
|
35
|
+
*/
|
|
36
|
+
orgSlug?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Shared Fly app that holds every sandbox Machine. Only used when
|
|
39
|
+
* `appPerProject` is `false`. Falls back to `FLY_SANDBOX_APP`.
|
|
40
|
+
*
|
|
41
|
+
* A shared app puts every tenant on ONE 6PN private network, where each
|
|
42
|
+
* sandbox can reach every other sandbox's dev-server ports by private IPv6.
|
|
43
|
+
* That is the same cross-tenant exposure the Docker bond's `bridge` network
|
|
44
|
+
* has, so this mode is REFUSED in production.
|
|
45
|
+
*/
|
|
46
|
+
appName?: string;
|
|
47
|
+
/**
|
|
48
|
+
* Name prefix for the per-project Fly app when `appPerProject` is `true`
|
|
49
|
+
* (default). The app is `<appPrefix>-<sanitized projectId>`. Falls back to
|
|
50
|
+
* `FLY_SANDBOX_APP_PREFIX`, then `mol-sandbox`.
|
|
51
|
+
*/
|
|
52
|
+
appPrefix?: string;
|
|
53
|
+
/**
|
|
54
|
+
* Create one Fly app — on its own custom 6PN private network — per project,
|
|
55
|
+
* so tenants are network-isolated from each other. Defaults to `true`.
|
|
56
|
+
* Set `false` (or `FLY_SANDBOX_APP_PER_PROJECT=false`) only for a
|
|
57
|
+
* single-tenant deployment; it is refused in production.
|
|
58
|
+
*/
|
|
59
|
+
appPerProject?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Custom 6PN network name for a per-project app. Defaults to the app name, so
|
|
62
|
+
* every project lands on its own private network. Ignored when
|
|
63
|
+
* `appPerProject` is `false`. A Fly app's network CANNOT be changed after
|
|
64
|
+
* creation.
|
|
65
|
+
*/
|
|
66
|
+
network?: string;
|
|
67
|
+
/** Fly region for Machines and volumes (e.g. `iad`). Falls back to `FLY_REGION`, then `iad`. */
|
|
68
|
+
region?: string;
|
|
69
|
+
/**
|
|
70
|
+
* OCI image every sandbox Machine runs. Must be pullable by Fly — a tag in
|
|
71
|
+
* the org's `registry.fly.io` repository or a public registry. A LOCAL
|
|
72
|
+
* `molecule-sandbox:latest` is not reachable by Fly; push it first. Falls
|
|
73
|
+
* back to `FLY_SANDBOX_IMAGE`, then `registry.fly.io/molecule-sandbox:latest`.
|
|
74
|
+
*/
|
|
75
|
+
baseImage?: string;
|
|
76
|
+
/** Default vCPU count (`guest.cpus`). Defaults to 1. */
|
|
77
|
+
defaultCpu?: number;
|
|
78
|
+
/** Default `guest.cpu_kind` — `shared` or `performance`. Defaults to `shared`. */
|
|
79
|
+
defaultCpuKind?: string;
|
|
80
|
+
/** Default memory in MB (`guest.memory_mb`). Defaults to 1024. */
|
|
81
|
+
defaultMemoryMB?: number;
|
|
82
|
+
/**
|
|
83
|
+
* Size in GB of the volume created for a sandbox's `/workspace` when
|
|
84
|
+
* `SandboxConfig.volumeName` is set. Fly volumes are sized in whole GB, so the
|
|
85
|
+
* core's `resources.diskMB` is rounded UP to the next GB. Defaults to 10.
|
|
86
|
+
*/
|
|
87
|
+
defaultVolumeGB?: number;
|
|
88
|
+
/** Internal port the preview service forwards to (the Vite dev server). Defaults to 5173. */
|
|
89
|
+
previewPort?: number;
|
|
90
|
+
/**
|
|
91
|
+
* Preview URL template. Placeholders `{app}`, `{machineId}` and `{port}` are
|
|
92
|
+
* all replaced globally. Defaults to `https://{app}.fly.dev`.
|
|
93
|
+
*
|
|
94
|
+
* For a control plane that runs on the SAME Fly 6PN, the private form
|
|
95
|
+
* `http://{machineId}.vm.{app}.internal:{port}` reaches the Machine with no
|
|
96
|
+
* public exposure at all — but it does NOT work across custom 6PNs, which is
|
|
97
|
+
* exactly what `appPerProject` creates. See the module `@remarks`.
|
|
98
|
+
*/
|
|
99
|
+
previewUrlTemplate?: string;
|
|
100
|
+
/**
|
|
101
|
+
* Attach a public Fly Proxy service (`80` → http, `443` → tls+http) forwarding
|
|
102
|
+
* to {@link FlyioConfig.previewPort}. Defaults to `true`. Set `false` for a
|
|
103
|
+
* fully private sandbox reached only over 6PN/Flycast.
|
|
104
|
+
*/
|
|
105
|
+
publicService?: boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Fly Proxy idle behaviour for the preview service. `suspend` (the default)
|
|
108
|
+
* is the scale-to-zero mapping this bond exists for: the proxy suspends an
|
|
109
|
+
* idle Machine and resumes it from its memory snapshot on the next request.
|
|
110
|
+
* `stop` is a full stop (cold boot on wake); `off` never idles the Machine.
|
|
111
|
+
*/
|
|
112
|
+
autostop?: 'off' | 'stop' | 'suspend';
|
|
113
|
+
/**
|
|
114
|
+
* Allocate a shared Anycast IPv4 for a newly-created app so `<app>.fly.dev`
|
|
115
|
+
* serves traffic. Defaults to `false` (opt-in). See the module `@remarks` —
|
|
116
|
+
* the accepted `type` values for the IP-assignment endpoint are NOT enumerated
|
|
117
|
+
* in Fly's OpenAPI specification.
|
|
118
|
+
*/
|
|
119
|
+
assignSharedIpv4?: boolean;
|
|
120
|
+
/** IP type requested when {@link FlyioConfig.assignSharedIpv4} is on. Defaults to `shared_v4`. */
|
|
121
|
+
ipAssignmentType?: string;
|
|
122
|
+
/** Prefix for the Machine metadata keys this provider owns. Defaults to `molecule-sandbox`. */
|
|
123
|
+
metadataPrefix?: string;
|
|
124
|
+
/** Timeout for a single Machines API request, in ms. Defaults to 30000. */
|
|
125
|
+
requestTimeoutMs?: number;
|
|
126
|
+
/**
|
|
127
|
+
* How long `start()`/`wake()` block waiting for the Machine to actually reach
|
|
128
|
+
* `started`, in seconds. Clamped to Fly's own ceiling — `GET .../wait` "will
|
|
129
|
+
* block for up to 60 seconds". Defaults to 60.
|
|
130
|
+
*
|
|
131
|
+
* Without this wait, `start()` resolves the moment Fly ACCEPTS the request,
|
|
132
|
+
* and the caller's very next `exec` hits a Machine that is not running yet.
|
|
133
|
+
*/
|
|
134
|
+
startTimeoutSeconds?: number;
|
|
135
|
+
/**
|
|
136
|
+
* Ports a sandbox Machine may open outbound connections on. Setting this makes
|
|
137
|
+
* the provider apply a Fly **network policy** to every app it provisions;
|
|
138
|
+
* leaving it unset applies no policy at all, and `verifyEgress()` will then
|
|
139
|
+
* observe (correctly) that egress is `open`. Falls back to
|
|
140
|
+
* `FLY_SANDBOX_EGRESS_ALLOWED_PORTS` (`tcp:3128,udp:53`).
|
|
141
|
+
*
|
|
142
|
+
* Read {@link https://fly.io/docs/machines/guides-examples/network-policies/}
|
|
143
|
+
* before choosing a value, because the mechanism is narrower than it looks:
|
|
144
|
+
* rules match protocol and port ONLY — no host, no CIDR, no ranges — so this
|
|
145
|
+
* can never be a host allowlist. `tcp:443` lets a sandbox reach EVERY host on
|
|
146
|
+
* the internet that listens on 443. To get a host allowlist, allow only the
|
|
147
|
+
* port of an egress proxy you control and route sandbox traffic through it.
|
|
148
|
+
*
|
|
149
|
+
* An empty array is rejected rather than treated as "deny all": Fly documents
|
|
150
|
+
* the deny default as a consequence of an `allow` rule existing, and says
|
|
151
|
+
* nothing about a rule with no ports.
|
|
152
|
+
*/
|
|
153
|
+
egressAllowedPorts?: FlyNetworkPolicyPort[];
|
|
154
|
+
/** Name of the egress policy this provider owns on each app. Defaults to `molecule-sandbox-egress`. */
|
|
155
|
+
egressPolicyName?: string;
|
|
156
|
+
/**
|
|
157
|
+
* Apps every sandbox must be able to reach ACROSS its per-project 6PN — the
|
|
158
|
+
* tenant Postgres cluster and the control plane's egress proxy. For each one,
|
|
159
|
+
* this provider allocates a **Flycast** private address into the project's own
|
|
160
|
+
* network when the project's app is created, and releases it on `destroy()`.
|
|
161
|
+
* Falls back to `FLY_SANDBOX_PRIVATE_SERVICES` (`<app>:<port>` pairs).
|
|
162
|
+
*
|
|
163
|
+
* Without this, a project with a database DOES NOT WORK on Fly: per-project
|
|
164
|
+
* 6PNs are what stop tenants reaching each other, and the same isolation stops
|
|
165
|
+
* a sandbox reaching the database it is supposed to use. Flycast is the only
|
|
166
|
+
* mechanism Fly documents that grants ONE directed edge without exposing
|
|
167
|
+
* anything publicly — see the `flycast.ts` module description.
|
|
168
|
+
*
|
|
169
|
+
* The declared PORT is load-bearing twice: it is unioned into
|
|
170
|
+
* {@link FlyioConfig.egressAllowedPorts} so the network policy cannot drop the
|
|
171
|
+
* connection, and every `.flycast` URL in a sandbox's environment is checked
|
|
172
|
+
* against it, so a `DATABASE_URL` naming an app nobody declared FAILS the boot
|
|
173
|
+
* instead of timing out inside the user's project.
|
|
174
|
+
*
|
|
175
|
+
* Two things this cannot do for you: the target app needs an `[http_service]`
|
|
176
|
+
* or `[services]` section (Flycast routes through Fly Proxy), and it must bind
|
|
177
|
+
* `0.0.0.0` rather than `fly-local-6pn`
|
|
178
|
+
* (https://fly.io/docs/networking/flycast/).
|
|
179
|
+
*
|
|
180
|
+
* Ignored when `appPerProject` is `false` — a shared app sits on the org's
|
|
181
|
+
* default 6PN, where `<app>.internal` already resolves.
|
|
182
|
+
*/
|
|
183
|
+
privateServices?: FlyPrivateService[];
|
|
184
|
+
/**
|
|
185
|
+
* `type` sent to `POST /apps/{app}/ip_assignments` when allocating a Flycast
|
|
186
|
+
* address. Defaults to `private_v6`, the value flyctl passes for
|
|
187
|
+
* `fly ips allocate-v6 --private`. The field has no enum in Fly's OpenAPI
|
|
188
|
+
* specification, so treat the literal as UNVERIFIED and use this to override
|
|
189
|
+
* it if Fly renames it.
|
|
190
|
+
*/
|
|
191
|
+
privateIpAssignmentType?: string;
|
|
192
|
+
/**
|
|
193
|
+
* Literal `ip:port` targets `verifyEgress()` attempts raw TCP connections to.
|
|
194
|
+
* IPv6 literals must be bracketed. Falls back to `SANDBOX_EGRESS_PROBE_TARGETS`
|
|
195
|
+
* (the same variable the Docker bond reads), then to one IPv4 and one IPv6
|
|
196
|
+
* anycast resolver on 443.
|
|
197
|
+
*/
|
|
198
|
+
egressProbeTargets?: string[];
|
|
199
|
+
/** Per-connection timeout for the egress probe, in ms. Falls back to `SANDBOX_EGRESS_PROBE_TIMEOUT_MS`, then 3000. */
|
|
200
|
+
egressProbeTimeoutMs?: number;
|
|
201
|
+
/**
|
|
202
|
+
* Image the throwaway `verifyEgress()` probe Machine runs. Must contain `node`
|
|
203
|
+
* and `sleep`. Defaults to the configured sandbox base image, so the probe
|
|
204
|
+
* observes egress from the same image real sandboxes run.
|
|
205
|
+
*/
|
|
206
|
+
egressProbeImage?: string;
|
|
207
|
+
/**
|
|
208
|
+
* Bucket holding sandbox templates. Falls back to `SANDBOX_TEMPLATE_BUCKET`,
|
|
209
|
+
* then `BUCKET_NAME` (which `fly storage create` sets).
|
|
210
|
+
*
|
|
211
|
+
* Templates are the warm-start capability: Fly cannot commit a running Machine
|
|
212
|
+
* to an image, so a template is a tar archive in S3-compatible object storage.
|
|
213
|
+
* Without a bucket (and both credentials) the template methods throw an
|
|
214
|
+
* actionable error naming these settings, and `SandboxConfig.templateId` fails
|
|
215
|
+
* rather than silently booting the base image.
|
|
216
|
+
*/
|
|
217
|
+
templateBucket?: string;
|
|
218
|
+
/**
|
|
219
|
+
* S3 endpoint for {@link FlyioConfig.templateBucket}, e.g. Tigris's
|
|
220
|
+
* `https://t3.storage.dev`. Falls back to `SANDBOX_TEMPLATE_ENDPOINT`, then
|
|
221
|
+
* `AWS_ENDPOINT_URL_S3`. Omit for AWS S3 itself.
|
|
222
|
+
*/
|
|
223
|
+
templateEndpoint?: string;
|
|
224
|
+
/**
|
|
225
|
+
* Region used to sign template-store requests. Falls back to
|
|
226
|
+
* `SANDBOX_TEMPLATE_REGION`, then `AWS_REGION`, then `auto` — which Tigris and
|
|
227
|
+
* most S3-compatible stores accept, and which the AWS SDK still requires in
|
|
228
|
+
* order to build a signature.
|
|
229
|
+
*/
|
|
230
|
+
templateRegion?: string;
|
|
231
|
+
/** Access key for the template store. Falls back to `SANDBOX_TEMPLATE_ACCESS_KEY_ID`, then `AWS_ACCESS_KEY_ID`. */
|
|
232
|
+
templateAccessKeyId?: string;
|
|
233
|
+
/** Secret key for the template store. Falls back to `SANDBOX_TEMPLATE_SECRET_ACCESS_KEY`, then `AWS_SECRET_ACCESS_KEY`. */
|
|
234
|
+
templateSecretAccessKey?: string;
|
|
235
|
+
/** Session token for temporary template-store credentials. Falls back to `SANDBOX_TEMPLATE_SESSION_TOKEN`, then `AWS_SESSION_TOKEN`. */
|
|
236
|
+
templateSessionToken?: string;
|
|
237
|
+
/**
|
|
238
|
+
* Key prefix every template object lives under. Falls back to
|
|
239
|
+
* `SANDBOX_TEMPLATE_PREFIX`, then `molecule-sandbox-templates`. Give the
|
|
240
|
+
* templates their own prefix (or their own bucket): `removeTemplate` deletes
|
|
241
|
+
* every key under a template's prefix.
|
|
242
|
+
*/
|
|
243
|
+
templatePrefix?: string;
|
|
244
|
+
/**
|
|
245
|
+
* Address the template bucket path-style (`https://endpoint/bucket/key`)
|
|
246
|
+
* instead of virtual-host style. Falls back to
|
|
247
|
+
* `SANDBOX_TEMPLATE_FORCE_PATH_STYLE=true`. Needed by stores that do not serve
|
|
248
|
+
* `<bucket>.<endpoint>`; Tigris and AWS S3 do not need it.
|
|
249
|
+
*/
|
|
250
|
+
templateForcePathStyle?: boolean;
|
|
251
|
+
/**
|
|
252
|
+
* Lifetime of the presigned capture/restore URL handed to a sandbox, in
|
|
253
|
+
* seconds. Defaults to 3600 and is clamped to AWS's documented 7-day ceiling
|
|
254
|
+
* for a SigV4 presigned URL. It only has to outlast the START of the transfer:
|
|
255
|
+
* S3 "checks the expiration date and time of a signed URL at the time of the
|
|
256
|
+
* HTTP request", so a download already in progress is not cut off.
|
|
257
|
+
*/
|
|
258
|
+
templateUrlExpirySeconds?: number;
|
|
259
|
+
/**
|
|
260
|
+
* Wall-clock budget for one capture or restore transfer, in ms. Defaults to
|
|
261
|
+
* 900000 (15 min). Also bounds how long a stale restore lease keeps a template
|
|
262
|
+
* pinned against eviction.
|
|
263
|
+
*/
|
|
264
|
+
templateTransferTimeoutMs?: number;
|
|
265
|
+
/**
|
|
266
|
+
* Largest template archive this provider will store, in bytes. Defaults to
|
|
267
|
+
* and is clamped by S3's 5 GB single-`PUT` ceiling, because the sandbox
|
|
268
|
+
* uploads with exactly one presigned `PUT`. The capture refuses before
|
|
269
|
+
* spending the bandwidth.
|
|
270
|
+
*/
|
|
271
|
+
templateMaxArchiveBytes?: number;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Environment variables the Fly.io sandbox provider reads. Every one is
|
|
275
|
+
* overridden by the matching {@link FlyioConfig} field.
|
|
276
|
+
*/
|
|
277
|
+
export interface ProcessEnv {
|
|
278
|
+
/** Fly API token. Also accepted as `FLY_ACCESS_TOKEN`. */
|
|
279
|
+
FLY_API_TOKEN?: string;
|
|
280
|
+
/** Fly API token (flyctl's variable name). Used when `FLY_API_TOKEN` is unset. */
|
|
281
|
+
FLY_ACCESS_TOKEN?: string;
|
|
282
|
+
/** Machines API base URL. `/v1` is appended when the value carries no path. */
|
|
283
|
+
FLY_API_HOSTNAME?: string;
|
|
284
|
+
/** Fly organization slug owning the sandbox apps (default `personal`). */
|
|
285
|
+
FLY_ORG_SLUG?: string;
|
|
286
|
+
/** Shared Fly app name, used only when `FLY_SANDBOX_APP_PER_PROJECT=false`. */
|
|
287
|
+
FLY_SANDBOX_APP?: string;
|
|
288
|
+
/** Per-project Fly app name prefix (default `mol-sandbox`). */
|
|
289
|
+
FLY_SANDBOX_APP_PREFIX?: string;
|
|
290
|
+
/** `false` disables per-project apps (refused in production). */
|
|
291
|
+
FLY_SANDBOX_APP_PER_PROJECT?: string;
|
|
292
|
+
/** Fly region for Machines and volumes (default `iad`). */
|
|
293
|
+
FLY_REGION?: string;
|
|
294
|
+
/** OCI image for sandbox Machines. */
|
|
295
|
+
FLY_SANDBOX_IMAGE?: string;
|
|
296
|
+
/**
|
|
297
|
+
* Comma-separated `protocol:port` pairs a sandbox may open outbound
|
|
298
|
+
* connections on (e.g. `tcp:3128,udp:53`). Set it to make this provider apply
|
|
299
|
+
* a Fly network policy to every sandbox app; unset means no policy.
|
|
300
|
+
*/
|
|
301
|
+
FLY_SANDBOX_EGRESS_ALLOWED_PORTS?: string;
|
|
302
|
+
/**
|
|
303
|
+
* Comma-separated `<fly-app>:<port>` pairs every sandbox must reach across its
|
|
304
|
+
* per-project 6PN, e.g. `molecule-pg-tenant:5432,molecule-api:3129`. Each one
|
|
305
|
+
* gets a Flycast private address allocated into the project's network at app
|
|
306
|
+
* creation and released on destroy. Overridden by `config.privateServices`.
|
|
307
|
+
*/
|
|
308
|
+
FLY_SANDBOX_PRIVATE_SERVICES?: string;
|
|
309
|
+
/**
|
|
310
|
+
* Comma-separated literal `ip:port` targets the egress probe attempts. Shared
|
|
311
|
+
* with the Docker bond so a provider swap keeps the same configuration.
|
|
312
|
+
*/
|
|
313
|
+
SANDBOX_EGRESS_PROBE_TARGETS?: string;
|
|
314
|
+
/** Per-connection timeout for the egress probe, in ms (default 3000). */
|
|
315
|
+
SANDBOX_EGRESS_PROBE_TIMEOUT_MS?: string;
|
|
316
|
+
/** Bucket holding sandbox templates. Overridden by `config.templateBucket`. */
|
|
317
|
+
SANDBOX_TEMPLATE_BUCKET?: string;
|
|
318
|
+
/** Bucket name as exported by `fly storage create`. Used when `SANDBOX_TEMPLATE_BUCKET` is unset. */
|
|
319
|
+
BUCKET_NAME?: string;
|
|
320
|
+
/** S3 endpoint for the template bucket. Overridden by `config.templateEndpoint`. */
|
|
321
|
+
SANDBOX_TEMPLATE_ENDPOINT?: string;
|
|
322
|
+
/** S3 endpoint as exported by `fly storage create`. Used when `SANDBOX_TEMPLATE_ENDPOINT` is unset. */
|
|
323
|
+
AWS_ENDPOINT_URL_S3?: string;
|
|
324
|
+
/** Signing region for the template store (default `auto`). Overridden by `config.templateRegion`. */
|
|
325
|
+
SANDBOX_TEMPLATE_REGION?: string;
|
|
326
|
+
/** Signing region, standard AWS variable. Used when `SANDBOX_TEMPLATE_REGION` is unset. */
|
|
327
|
+
AWS_REGION?: string;
|
|
328
|
+
/** Access key for the template store. Overridden by `config.templateAccessKeyId`. */
|
|
329
|
+
SANDBOX_TEMPLATE_ACCESS_KEY_ID?: string;
|
|
330
|
+
/** Access key, standard AWS variable (also what `fly storage create` sets). */
|
|
331
|
+
AWS_ACCESS_KEY_ID?: string;
|
|
332
|
+
/** Secret key for the template store. Overridden by `config.templateSecretAccessKey`. */
|
|
333
|
+
SANDBOX_TEMPLATE_SECRET_ACCESS_KEY?: string;
|
|
334
|
+
/** Secret key, standard AWS variable (also what `fly storage create` sets). */
|
|
335
|
+
AWS_SECRET_ACCESS_KEY?: string;
|
|
336
|
+
/** Session token for the template store. Overridden by `config.templateSessionToken`. */
|
|
337
|
+
SANDBOX_TEMPLATE_SESSION_TOKEN?: string;
|
|
338
|
+
/** Session token, standard AWS variable. */
|
|
339
|
+
AWS_SESSION_TOKEN?: string;
|
|
340
|
+
/** Key prefix for template objects (default `molecule-sandbox-templates`). */
|
|
341
|
+
SANDBOX_TEMPLATE_PREFIX?: string;
|
|
342
|
+
/** `true` addresses the template bucket path-style rather than virtual-host style. */
|
|
343
|
+
SANDBOX_TEMPLATE_FORCE_PATH_STYLE?: string;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* One app made reachable from every sandbox's per-project 6PN through a Flycast
|
|
347
|
+
* private address.
|
|
348
|
+
*
|
|
349
|
+
* See the `flycast.ts` module description for why this exists at all: apps on
|
|
350
|
+
* separate 6PNs "can never communicate unless explicitly configured to do so",
|
|
351
|
+
* and this declaration IS that explicit configuration.
|
|
352
|
+
*/
|
|
353
|
+
export interface FlyPrivateService {
|
|
354
|
+
/**
|
|
355
|
+
* The Fly app to allocate a Flycast address ON. The sandbox reaches it at
|
|
356
|
+
* `<app>.flycast`. It must already exist, must carry a services block, and
|
|
357
|
+
* must be in the same organization.
|
|
358
|
+
*/
|
|
359
|
+
app: string;
|
|
360
|
+
/**
|
|
361
|
+
* The TCP port a sandbox dials it at. Unioned into the egress network policy,
|
|
362
|
+
* and checked against every `.flycast` URL in a sandbox's environment.
|
|
363
|
+
*/
|
|
364
|
+
port: number;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* An IP assignment, as returned by `POST`/`GET /v1/apps/{app}/ip_assignments`
|
|
368
|
+
* (`IPAssignment` in https://docs.machines.dev/openapi.json).
|
|
369
|
+
*
|
|
370
|
+
* Note what is NOT here: the assignment's **network**. Fly's own schema is
|
|
371
|
+
* `{created_at, ip, region, service_name, shared}`, so a listing cannot tell you
|
|
372
|
+
* which 6PN a private address serves — which is why this provider records the
|
|
373
|
+
* addresses it allocated in the sandbox Machine's metadata instead of
|
|
374
|
+
* rediscovering them.
|
|
375
|
+
*/
|
|
376
|
+
export interface FlyIpAssignment {
|
|
377
|
+
/** The allocated address. Required for a later `DELETE .../ip_assignments/{ip}`. */
|
|
378
|
+
ip?: string;
|
|
379
|
+
/** Region the address was allocated in, when Fly reports one. */
|
|
380
|
+
region?: string;
|
|
381
|
+
/** Service the address is bound to, when the assignment names one. */
|
|
382
|
+
service_name?: string;
|
|
383
|
+
/** Whether the address is shared (Anycast v4) rather than dedicated. */
|
|
384
|
+
shared?: boolean;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* One protocol/port pair in a Fly network-policy rule.
|
|
388
|
+
*
|
|
389
|
+
* Fly matches on protocol and port only — there is no host, IP, CIDR or
|
|
390
|
+
* port-range matching. See
|
|
391
|
+
* https://fly.io/docs/machines/guides-examples/network-policies/.
|
|
392
|
+
*/
|
|
393
|
+
export interface FlyNetworkPolicyPort {
|
|
394
|
+
/** `tcp` or `udp` — the only documented values. */
|
|
395
|
+
protocol: 'tcp' | 'udp';
|
|
396
|
+
/** A single port. Ranges are not supported. */
|
|
397
|
+
port: number;
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* One rule in a Fly network policy. `allow` is the only documented action:
|
|
401
|
+
* "Once you create a rule for a given direction, the default for that direction
|
|
402
|
+
* becomes drop."
|
|
403
|
+
*/
|
|
404
|
+
export interface FlyNetworkPolicyRule {
|
|
405
|
+
/** Only `allow` is supported by Fly. */
|
|
406
|
+
action: 'allow';
|
|
407
|
+
/** Traffic direction the rule (and its implied deny default) applies to. */
|
|
408
|
+
direction: 'ingress' | 'egress';
|
|
409
|
+
/** Ports this rule permits. */
|
|
410
|
+
ports: FlyNetworkPolicyPort[];
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Which Machines in the app a policy applies to. Documented criteria combine
|
|
414
|
+
* with AND, so this provider uses `{ all: true }` alone.
|
|
415
|
+
*/
|
|
416
|
+
export interface FlyNetworkPolicySelector {
|
|
417
|
+
/** Match every Machine in the app. */
|
|
418
|
+
all?: boolean;
|
|
419
|
+
/** Match specific Machine ids. */
|
|
420
|
+
machines?: Array<{
|
|
421
|
+
id: string;
|
|
422
|
+
}>;
|
|
423
|
+
/** Match Machines carrying these metadata keys. */
|
|
424
|
+
metadata?: Record<string, string>;
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* A Fly network policy, as accepted by
|
|
428
|
+
* `POST /v1/apps/{app}/network_policies`. The endpoint is documented in Fly's
|
|
429
|
+
* guide and announcement but is NOT in its OpenAPI specification, so only the
|
|
430
|
+
* fields those two documents show are modelled.
|
|
431
|
+
*/
|
|
432
|
+
export interface FlyNetworkPolicy {
|
|
433
|
+
/** Present to UPDATE an existing policy; omitted to create one. */
|
|
434
|
+
id?: string;
|
|
435
|
+
/** Policy name, unique per app in practice. */
|
|
436
|
+
name: string;
|
|
437
|
+
/** Machines the policy applies to. */
|
|
438
|
+
selector: FlyNetworkPolicySelector;
|
|
439
|
+
/** The allow rules. */
|
|
440
|
+
rules: FlyNetworkPolicyRule[];
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* A Fly Machine state, as documented at https://fly.io/docs/machines/machine-states/.
|
|
444
|
+
* Modelled as a union of the documented values plus `string` so an unrecognized
|
|
445
|
+
* future state is carried through rather than crashing the mapper.
|
|
446
|
+
*/
|
|
447
|
+
export type FlyMachineState = 'created' | 'creating' | 'starting' | 'started' | 'stopping' | 'stopped' | 'suspending' | 'suspended' | 'restarting' | 'updating' | 'replacing' | 'replaced' | 'migrated' | 'destroying' | 'destroyed' | 'failed' | 'launch_failed' | (string & {});
|
|
448
|
+
/** A Fly Machine, as returned by the Machines API (fields this provider reads). */
|
|
449
|
+
export interface FlyMachine {
|
|
450
|
+
id: string;
|
|
451
|
+
name?: string;
|
|
452
|
+
/** Optional so a response that omits it degrades to `created` rather than crashing the mapper. */
|
|
453
|
+
state?: FlyMachineState;
|
|
454
|
+
region?: string;
|
|
455
|
+
private_ip?: string;
|
|
456
|
+
config?: FlyMachineConfig;
|
|
457
|
+
}
|
|
458
|
+
/** A Machine as returned by the org-wide list endpoint (`GET /orgs/{org}/machines`). */
|
|
459
|
+
export interface FlyOrgMachine extends FlyMachine {
|
|
460
|
+
app_name: string;
|
|
461
|
+
}
|
|
462
|
+
/** Machine configuration (`fly.MachineConfig`) — the subset this provider writes. */
|
|
463
|
+
export interface FlyMachineConfig {
|
|
464
|
+
image: string;
|
|
465
|
+
env?: Record<string, string>;
|
|
466
|
+
metadata?: Record<string, string>;
|
|
467
|
+
guest?: {
|
|
468
|
+
cpus?: number;
|
|
469
|
+
cpu_kind?: string;
|
|
470
|
+
memory_mb?: number;
|
|
471
|
+
};
|
|
472
|
+
mounts?: Array<{
|
|
473
|
+
volume?: string;
|
|
474
|
+
name?: string;
|
|
475
|
+
path: string;
|
|
476
|
+
}>;
|
|
477
|
+
services?: FlyMachineService[];
|
|
478
|
+
restart?: {
|
|
479
|
+
policy?: 'no' | 'always' | 'on-failure' | 'spot-price';
|
|
480
|
+
max_retries?: number;
|
|
481
|
+
};
|
|
482
|
+
auto_destroy?: boolean;
|
|
483
|
+
init?: {
|
|
484
|
+
exec?: string[];
|
|
485
|
+
entrypoint?: string[];
|
|
486
|
+
cmd?: string[];
|
|
487
|
+
tty?: boolean;
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
/** A Fly Proxy service attached to a Machine (`fly.MachineService`). */
|
|
491
|
+
export interface FlyMachineService {
|
|
492
|
+
protocol: string;
|
|
493
|
+
internal_port: number;
|
|
494
|
+
ports: Array<{
|
|
495
|
+
port: number;
|
|
496
|
+
handlers?: string[];
|
|
497
|
+
force_https?: boolean;
|
|
498
|
+
}>;
|
|
499
|
+
autostart?: boolean;
|
|
500
|
+
autostop?: 'off' | 'stop' | 'suspend';
|
|
501
|
+
min_machines_running?: number;
|
|
502
|
+
}
|
|
503
|
+
/** A Fly volume (fields this provider reads). */
|
|
504
|
+
export interface FlyVolume {
|
|
505
|
+
id: string;
|
|
506
|
+
name: string;
|
|
507
|
+
state?: string;
|
|
508
|
+
size_gb?: number;
|
|
509
|
+
region?: string;
|
|
510
|
+
attached_machine_id?: string;
|
|
511
|
+
}
|
|
512
|
+
/** Response body of `POST /v1/apps/{app}/machines/{id}/exec` (`flydv1.ExecResponse`). */
|
|
513
|
+
export interface FlyExecResponse {
|
|
514
|
+
stdout?: string;
|
|
515
|
+
stderr?: string;
|
|
516
|
+
exit_code?: number;
|
|
517
|
+
exit_signal?: number;
|
|
518
|
+
}
|
|
519
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fly.io Machines sandbox provider configuration and wire types.
|
|
3
|
+
*
|
|
4
|
+
* Wire types mirror the Fly Machines OpenAPI specification
|
|
5
|
+
* (https://docs.machines.dev/openapi.json, servers: `https://api.machines.dev/v1`).
|
|
6
|
+
* Only the fields this provider actually reads or writes are modelled — the real
|
|
7
|
+
* schemas are much larger, and modelling fields we never use would rot silently.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shell-quoting and environment helpers shared by the exec and file paths.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Wraps a string in single quotes, escaping any single quotes it contains.
|
|
8
|
+
*
|
|
9
|
+
* Every command this provider runs goes through `sh -c`, so an unquoted path or
|
|
10
|
+
* value is a command-injection vector. Double quotes are NOT sufficient — `$()`,
|
|
11
|
+
* backticks and `!` still expand inside them.
|
|
12
|
+
* @param value - The raw string to embed in a shell command.
|
|
13
|
+
* @returns A single-quoted, shell-safe token.
|
|
14
|
+
*/
|
|
15
|
+
export declare function shellQuote(value: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Renders `ExecOptions.env` as `export` statements to prepend to a script.
|
|
18
|
+
*
|
|
19
|
+
* Fly's exec endpoint takes no environment map (only `command`, `stdin`,
|
|
20
|
+
* `container` and `timeout`), so per-command environment has to be set inside
|
|
21
|
+
* the shell script itself.
|
|
22
|
+
* @param env - Environment variables to set for the command.
|
|
23
|
+
* @returns One `export NAME='value'` line per variable, in insertion order.
|
|
24
|
+
* @throws {Error} When a name is not a valid shell identifier. Silently dropping it
|
|
25
|
+
* would make the command run with the variable unset, which surfaces far from
|
|
26
|
+
* the cause.
|
|
27
|
+
*/
|
|
28
|
+
export declare function renderEnvExports(env: Record<string, string> | undefined): string[];
|
|
29
|
+
//# sourceMappingURL=utilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../src/utilities.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GAAG,MAAM,EAAE,CAgBlF"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shell-quoting and environment helpers shared by the exec and file paths.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { t } from '@molecule/api-i18n';
|
|
7
|
+
/** Environment variable names must be valid shell identifiers to be `export`able. */
|
|
8
|
+
const ENV_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
9
|
+
/**
|
|
10
|
+
* Wraps a string in single quotes, escaping any single quotes it contains.
|
|
11
|
+
*
|
|
12
|
+
* Every command this provider runs goes through `sh -c`, so an unquoted path or
|
|
13
|
+
* value is a command-injection vector. Double quotes are NOT sufficient — `$()`,
|
|
14
|
+
* backticks and `!` still expand inside them.
|
|
15
|
+
* @param value - The raw string to embed in a shell command.
|
|
16
|
+
* @returns A single-quoted, shell-safe token.
|
|
17
|
+
*/
|
|
18
|
+
export function shellQuote(value) {
|
|
19
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Renders `ExecOptions.env` as `export` statements to prepend to a script.
|
|
23
|
+
*
|
|
24
|
+
* Fly's exec endpoint takes no environment map (only `command`, `stdin`,
|
|
25
|
+
* `container` and `timeout`), so per-command environment has to be set inside
|
|
26
|
+
* the shell script itself.
|
|
27
|
+
* @param env - Environment variables to set for the command.
|
|
28
|
+
* @returns One `export NAME='value'` line per variable, in insertion order.
|
|
29
|
+
* @throws {Error} When a name is not a valid shell identifier. Silently dropping it
|
|
30
|
+
* would make the command run with the variable unset, which surfaces far from
|
|
31
|
+
* the cause.
|
|
32
|
+
*/
|
|
33
|
+
export function renderEnvExports(env) {
|
|
34
|
+
if (!env)
|
|
35
|
+
return [];
|
|
36
|
+
return Object.entries(env).map(([name, value]) => {
|
|
37
|
+
if (!ENV_NAME_PATTERN.test(name)) {
|
|
38
|
+
throw new Error(t('codeSandbox.flyio.error.badEnvName', { name }, {
|
|
39
|
+
defaultValue: `Invalid environment variable name "${name}" — must match [A-Za-z_][A-Za-z0-9_]*.`,
|
|
40
|
+
}));
|
|
41
|
+
}
|
|
42
|
+
return `export ${name}=${shellQuote(value)}`;
|
|
43
|
+
});
|
|
44
|
+
}
|