@axiom-lattice/microsandbox-service 0.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/.turbo/turbo-build.log +29 -0
- package/CHANGELOG.md +7 -0
- package/LICENSE +201 -0
- package/dist/chunk-2W4CTYPX.mjs +464 -0
- package/dist/chunk-2W4CTYPX.mjs.map +1 -0
- package/dist/index.d.mts +208 -0
- package/dist/index.d.ts +208 -0
- package/dist/index.js +496 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +11 -0
- package/dist/index.mjs.map +1 -0
- package/dist/server.d.mts +9 -0
- package/dist/server.d.ts +9 -0
- package/dist/server.js +566 -0
- package/dist/server.js.map +1 -0
- package/dist/server.mjs +82 -0
- package/dist/server.mjs.map +1 -0
- package/jest.config.js +17 -0
- package/package.json +46 -0
- package/src/__tests__/MicrosandboxRuntimeService.test.ts +251 -0
- package/src/__tests__/SandboxRegistry.test.ts +101 -0
- package/src/__tests__/app.test.ts +224 -0
- package/src/__tests__/index.test.ts +33 -0
- package/src/__tests__/server-cli.test.ts +26 -0
- package/src/__tests__/server.test.ts +25 -0
- package/src/app.ts +31 -0
- package/src/controllers/sandbox.ts +138 -0
- package/src/index.ts +3 -0
- package/src/lib/errors.ts +44 -0
- package/src/lib/http.ts +11 -0
- package/src/lib/server-cli.ts +59 -0
- package/src/routes/health.ts +6 -0
- package/src/routes/sandbox.ts +28 -0
- package/src/schemas/sandbox.ts +79 -0
- package/src/server.ts +43 -0
- package/src/services/MicrosandboxRuntimeService.ts +247 -0
- package/src/services/SandboxRegistry.ts +69 -0
- package/src/types/runtime-service.ts +23 -0
- package/tsconfig.json +22 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
MicrosandboxRuntimeService: () => MicrosandboxRuntimeService,
|
|
34
|
+
SandboxRegistry: () => SandboxRegistry,
|
|
35
|
+
buildApp: () => buildApp
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(index_exports);
|
|
38
|
+
|
|
39
|
+
// src/app.ts
|
|
40
|
+
var import_cors = __toESM(require("@fastify/cors"));
|
|
41
|
+
var import_multipart = __toESM(require("@fastify/multipart"));
|
|
42
|
+
var import_sensible = __toESM(require("@fastify/sensible"));
|
|
43
|
+
var import_fastify = __toESM(require("fastify"));
|
|
44
|
+
|
|
45
|
+
// src/lib/errors.ts
|
|
46
|
+
var HttpError = class extends Error {
|
|
47
|
+
constructor(statusCode, code, message) {
|
|
48
|
+
super(message);
|
|
49
|
+
this.statusCode = statusCode;
|
|
50
|
+
this.code = code;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
function toErrorResponse(error) {
|
|
54
|
+
if (error instanceof HttpError) {
|
|
55
|
+
return {
|
|
56
|
+
statusCode: error.statusCode,
|
|
57
|
+
body: {
|
|
58
|
+
success: false,
|
|
59
|
+
error: {
|
|
60
|
+
code: error.code,
|
|
61
|
+
message: error.message
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
statusCode: 500,
|
|
68
|
+
body: {
|
|
69
|
+
success: false,
|
|
70
|
+
error: {
|
|
71
|
+
code: "INTERNAL_ERROR",
|
|
72
|
+
message: error instanceof Error ? error.message : String(error)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// src/lib/http.ts
|
|
79
|
+
function ok(data) {
|
|
80
|
+
return {
|
|
81
|
+
success: true,
|
|
82
|
+
data
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// src/routes/health.ts
|
|
87
|
+
function registerHealthRoutes(app) {
|
|
88
|
+
app.get("/health", async () => ok({ status: "ok" }));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/schemas/sandbox.ts
|
|
92
|
+
var import_zod = __toESM(require("zod"));
|
|
93
|
+
var bindMountSchema = import_zod.default.object({
|
|
94
|
+
type: import_zod.default.literal("bind"),
|
|
95
|
+
source: import_zod.default.string().min(1),
|
|
96
|
+
readonly: import_zod.default.boolean().optional()
|
|
97
|
+
});
|
|
98
|
+
var namedMountSchema = import_zod.default.object({
|
|
99
|
+
type: import_zod.default.literal("named"),
|
|
100
|
+
name: import_zod.default.string().min(1),
|
|
101
|
+
readonly: import_zod.default.boolean().optional()
|
|
102
|
+
});
|
|
103
|
+
var tmpfsMountSchema = import_zod.default.object({
|
|
104
|
+
type: import_zod.default.literal("tmpfs"),
|
|
105
|
+
sizeMib: import_zod.default.number().int().positive().optional()
|
|
106
|
+
});
|
|
107
|
+
var volumeSchema = import_zod.default.union([
|
|
108
|
+
bindMountSchema,
|
|
109
|
+
namedMountSchema,
|
|
110
|
+
tmpfsMountSchema
|
|
111
|
+
]);
|
|
112
|
+
var ensureSandboxSchema = import_zod.default.object({
|
|
113
|
+
image: import_zod.default.string().optional(),
|
|
114
|
+
cpus: import_zod.default.number().int().positive().optional(),
|
|
115
|
+
memoryMib: import_zod.default.number().int().positive().optional(),
|
|
116
|
+
env: import_zod.default.record(import_zod.default.string()).optional(),
|
|
117
|
+
volumes: import_zod.default.record(volumeSchema).optional()
|
|
118
|
+
});
|
|
119
|
+
var sandboxAndPathSchema = import_zod.default.object({
|
|
120
|
+
sandboxName: import_zod.default.string().min(1),
|
|
121
|
+
path: import_zod.default.string().min(1)
|
|
122
|
+
});
|
|
123
|
+
var readFileSchema = sandboxAndPathSchema;
|
|
124
|
+
var writeFileSchema = sandboxAndPathSchema.extend({
|
|
125
|
+
content: import_zod.default.string()
|
|
126
|
+
});
|
|
127
|
+
var listPathSchema = sandboxAndPathSchema.extend({
|
|
128
|
+
recursive: import_zod.default.boolean().optional()
|
|
129
|
+
});
|
|
130
|
+
var findFilesSchema = sandboxAndPathSchema.extend({
|
|
131
|
+
pattern: import_zod.default.string().min(1)
|
|
132
|
+
});
|
|
133
|
+
var searchInFileSchema = sandboxAndPathSchema.extend({
|
|
134
|
+
query: import_zod.default.string().min(1)
|
|
135
|
+
});
|
|
136
|
+
var replaceInFileSchema = sandboxAndPathSchema.extend({
|
|
137
|
+
search: import_zod.default.string(),
|
|
138
|
+
replace: import_zod.default.string()
|
|
139
|
+
});
|
|
140
|
+
var uploadFileSchema = sandboxAndPathSchema.and(
|
|
141
|
+
import_zod.default.union([
|
|
142
|
+
import_zod.default.object({ contentBase64: import_zod.default.string() }),
|
|
143
|
+
import_zod.default.object({ content: import_zod.default.string().transform((content) => Buffer.from(content).toString("base64")) })
|
|
144
|
+
])
|
|
145
|
+
);
|
|
146
|
+
var downloadFileSchema = sandboxAndPathSchema;
|
|
147
|
+
var shellExecSchema = import_zod.default.object({
|
|
148
|
+
sandboxName: import_zod.default.string().min(1),
|
|
149
|
+
command: import_zod.default.string().min(1),
|
|
150
|
+
exec_dir: import_zod.default.string().optional(),
|
|
151
|
+
timeout: import_zod.default.number().int().positive().optional()
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
// src/controllers/sandbox.ts
|
|
155
|
+
function createSandboxController(runtimeService) {
|
|
156
|
+
return {
|
|
157
|
+
ensureSandbox: async (request, reply) => {
|
|
158
|
+
const body = ensureSandboxSchema.parse(request.body ?? {});
|
|
159
|
+
const result = await runtimeService.ensureSandbox(request.params.name, body);
|
|
160
|
+
return reply.send(ok(result));
|
|
161
|
+
},
|
|
162
|
+
startSandbox: async (request, reply) => {
|
|
163
|
+
return reply.send(ok(await runtimeService.startSandbox(request.params.name)));
|
|
164
|
+
},
|
|
165
|
+
stopSandbox: async (request, reply) => {
|
|
166
|
+
return reply.send(ok(await runtimeService.stopSandbox(request.params.name)));
|
|
167
|
+
},
|
|
168
|
+
killSandbox: async (request, reply) => {
|
|
169
|
+
return reply.send(ok(await runtimeService.killSandbox(request.params.name)));
|
|
170
|
+
},
|
|
171
|
+
deleteSandbox: async (request, reply) => {
|
|
172
|
+
return reply.send(ok(await runtimeService.deleteSandbox(request.params.name)));
|
|
173
|
+
},
|
|
174
|
+
getStatus: async (request, reply) => {
|
|
175
|
+
return reply.send(ok(await runtimeService.getStatus(request.params.name)));
|
|
176
|
+
},
|
|
177
|
+
readFile: async (request, reply) => {
|
|
178
|
+
const body = readFileSchema.parse(request.body ?? {});
|
|
179
|
+
return reply.send(ok(await runtimeService.readFile(body.sandboxName, body.path)));
|
|
180
|
+
},
|
|
181
|
+
writeFile: async (request, reply) => {
|
|
182
|
+
const body = writeFileSchema.parse(request.body ?? {});
|
|
183
|
+
return reply.send(ok(await runtimeService.writeFile(body.sandboxName, body.path, body.content)));
|
|
184
|
+
},
|
|
185
|
+
listPath: async (request, reply) => {
|
|
186
|
+
const body = listPathSchema.parse(request.body ?? {});
|
|
187
|
+
return reply.send(ok(await runtimeService.listPath(body.sandboxName, body.path, body.recursive)));
|
|
188
|
+
},
|
|
189
|
+
findFiles: async (request, reply) => {
|
|
190
|
+
const body = findFilesSchema.parse(request.body ?? {});
|
|
191
|
+
return reply.send(ok(await runtimeService.findFiles(body.sandboxName, body.path, body.pattern)));
|
|
192
|
+
},
|
|
193
|
+
searchInFile: async (request, reply) => {
|
|
194
|
+
const body = searchInFileSchema.parse(request.body ?? {});
|
|
195
|
+
return reply.send(ok(await runtimeService.searchInFile(body.sandboxName, body.path, body.query)));
|
|
196
|
+
},
|
|
197
|
+
replaceInFile: async (request, reply) => {
|
|
198
|
+
const body = replaceInFileSchema.parse(request.body ?? {});
|
|
199
|
+
return reply.send(
|
|
200
|
+
ok(
|
|
201
|
+
await runtimeService.replaceInFile(body.sandboxName, {
|
|
202
|
+
path: body.path,
|
|
203
|
+
search: body.search,
|
|
204
|
+
replace: body.replace
|
|
205
|
+
})
|
|
206
|
+
)
|
|
207
|
+
);
|
|
208
|
+
},
|
|
209
|
+
uploadFile: async (request, reply) => {
|
|
210
|
+
const body = uploadFileSchema.parse(request.body ?? {});
|
|
211
|
+
return reply.send(ok(await runtimeService.uploadFile(body.sandboxName, body.path, body.contentBase64)));
|
|
212
|
+
},
|
|
213
|
+
downloadFile: async (request, reply) => {
|
|
214
|
+
const query = downloadFileSchema.parse(request.query ?? {});
|
|
215
|
+
return reply.send(ok(await runtimeService.downloadFile(query.sandboxName, query.path)));
|
|
216
|
+
},
|
|
217
|
+
execCommand: async (request, reply) => {
|
|
218
|
+
const body = shellExecSchema.parse(request.body ?? {});
|
|
219
|
+
return reply.send(ok(await runtimeService.execCommand(body)));
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// src/routes/sandbox.ts
|
|
225
|
+
function registerSandboxRoutes(app, runtimeService) {
|
|
226
|
+
const controller = createSandboxController(runtimeService);
|
|
227
|
+
app.put("/api/sandboxes/:name", controller.ensureSandbox);
|
|
228
|
+
app.post("/api/sandboxes/:name/start", controller.startSandbox);
|
|
229
|
+
app.post("/api/sandboxes/:name/stop", controller.stopSandbox);
|
|
230
|
+
app.post("/api/sandboxes/:name/kill", controller.killSandbox);
|
|
231
|
+
app.delete("/api/sandboxes/:name", controller.deleteSandbox);
|
|
232
|
+
app.get("/api/sandboxes/:name/status", controller.getStatus);
|
|
233
|
+
app.post("/api/files/read", controller.readFile);
|
|
234
|
+
app.post("/api/files/write", controller.writeFile);
|
|
235
|
+
app.post("/api/files/list", controller.listPath);
|
|
236
|
+
app.post("/api/files/find", controller.findFiles);
|
|
237
|
+
app.post("/api/files/search", controller.searchInFile);
|
|
238
|
+
app.post("/api/files/replace", controller.replaceInFile);
|
|
239
|
+
app.post("/api/files/upload", controller.uploadFile);
|
|
240
|
+
app.get("/api/files/download", controller.downloadFile);
|
|
241
|
+
app.post("/api/shell/exec", controller.execCommand);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// src/services/MicrosandboxRuntimeService.ts
|
|
245
|
+
var import_microsandbox2 = require("microsandbox");
|
|
246
|
+
|
|
247
|
+
// src/services/SandboxRegistry.ts
|
|
248
|
+
var import_microsandbox = require("microsandbox");
|
|
249
|
+
var DEFAULT_IMAGE = process.env.MICROSANDBOX_IMAGE ?? "daytonaio/sandbox:0.6.0";
|
|
250
|
+
var SandboxRegistry = class {
|
|
251
|
+
constructor() {
|
|
252
|
+
this.handles = /* @__PURE__ */ new Map();
|
|
253
|
+
this.creating = /* @__PURE__ */ new Map();
|
|
254
|
+
}
|
|
255
|
+
async ensure(name, createOptions) {
|
|
256
|
+
const cached = this.handles.get(name);
|
|
257
|
+
if (cached) {
|
|
258
|
+
return cached;
|
|
259
|
+
}
|
|
260
|
+
const inflight = this.creating.get(name);
|
|
261
|
+
if (inflight) {
|
|
262
|
+
return inflight;
|
|
263
|
+
}
|
|
264
|
+
const creation = (async () => {
|
|
265
|
+
let native;
|
|
266
|
+
const createConfig = {
|
|
267
|
+
name,
|
|
268
|
+
image: DEFAULT_IMAGE,
|
|
269
|
+
...createOptions ?? {}
|
|
270
|
+
};
|
|
271
|
+
try {
|
|
272
|
+
const handle = await import_microsandbox.Sandbox.get(name);
|
|
273
|
+
if (handle.status === "running") {
|
|
274
|
+
native = await handle.connect();
|
|
275
|
+
} else if (handle.status === "stopped") {
|
|
276
|
+
native = await import_microsandbox.Sandbox.start(name);
|
|
277
|
+
} else if (handle.status === "crashed" || handle.status === "draining") {
|
|
278
|
+
await import_microsandbox.Sandbox.remove(name);
|
|
279
|
+
}
|
|
280
|
+
} catch {
|
|
281
|
+
native = void 0;
|
|
282
|
+
}
|
|
283
|
+
if (!native) {
|
|
284
|
+
native = await import_microsandbox.Sandbox.createDetached(createConfig);
|
|
285
|
+
}
|
|
286
|
+
this.handles.set(name, native);
|
|
287
|
+
return native;
|
|
288
|
+
})();
|
|
289
|
+
this.creating.set(name, creation);
|
|
290
|
+
void creation.finally(() => this.creating.delete(name));
|
|
291
|
+
return creation;
|
|
292
|
+
}
|
|
293
|
+
get(name) {
|
|
294
|
+
const handle = this.handles.get(name);
|
|
295
|
+
if (!handle) {
|
|
296
|
+
throw new Error(`Sandbox ${name} not found`);
|
|
297
|
+
}
|
|
298
|
+
return handle;
|
|
299
|
+
}
|
|
300
|
+
delete(name) {
|
|
301
|
+
this.handles.delete(name);
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
// src/services/MicrosandboxRuntimeService.ts
|
|
306
|
+
var MicrosandboxRuntimeService = class {
|
|
307
|
+
constructor(deps = {}) {
|
|
308
|
+
this.deps = deps;
|
|
309
|
+
}
|
|
310
|
+
get registry() {
|
|
311
|
+
return this.deps.registry ?? (this.deps.registry = new SandboxRegistry());
|
|
312
|
+
}
|
|
313
|
+
buildVolumes(volumes) {
|
|
314
|
+
if (!volumes) {
|
|
315
|
+
return void 0;
|
|
316
|
+
}
|
|
317
|
+
return Object.fromEntries(
|
|
318
|
+
Object.entries(volumes).map(([mountPath, definition]) => [mountPath, this.buildVolume(definition)])
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
buildVolume(definition) {
|
|
322
|
+
if (definition.type === "bind") {
|
|
323
|
+
return import_microsandbox2.Mount.bind(definition.source, { readonly: definition.readonly ?? false });
|
|
324
|
+
}
|
|
325
|
+
if (definition.type === "named") {
|
|
326
|
+
return import_microsandbox2.Mount.named(definition.name, { readonly: definition.readonly ?? false });
|
|
327
|
+
}
|
|
328
|
+
return import_microsandbox2.Mount.tmpfs({ sizeMib: definition.sizeMib });
|
|
329
|
+
}
|
|
330
|
+
getNative(name) {
|
|
331
|
+
return this.registry.get(name);
|
|
332
|
+
}
|
|
333
|
+
async getOrEnsureNative(name) {
|
|
334
|
+
try {
|
|
335
|
+
return this.getNative(name);
|
|
336
|
+
} catch {
|
|
337
|
+
return await this.registry.ensure(name);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
async ensureSandbox(name, input) {
|
|
341
|
+
await this.registry.ensure(name, {
|
|
342
|
+
image: input.image ?? process.env.MICROSANDBOX_IMAGE ?? "python:3.11-slim",
|
|
343
|
+
cpus: input.cpus ?? Number(process.env.MICROSANDBOX_CPUS ?? "1"),
|
|
344
|
+
memoryMib: input.memoryMib ?? Number(process.env.MICROSANDBOX_MEMORY ?? "512"),
|
|
345
|
+
env: input.env,
|
|
346
|
+
volumes: this.buildVolumes(input.volumes)
|
|
347
|
+
});
|
|
348
|
+
return {
|
|
349
|
+
name,
|
|
350
|
+
status: "running"
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
async startSandbox(name) {
|
|
354
|
+
await import_microsandbox2.Sandbox.start(name);
|
|
355
|
+
this.registry.delete(name);
|
|
356
|
+
await this.registry.ensure(name);
|
|
357
|
+
return { name, status: "running" };
|
|
358
|
+
}
|
|
359
|
+
async stopSandbox(name) {
|
|
360
|
+
const native = await this.getOrEnsureNative(name);
|
|
361
|
+
await native.stop();
|
|
362
|
+
this.registry.delete(name);
|
|
363
|
+
return { name, status: "stopped" };
|
|
364
|
+
}
|
|
365
|
+
async killSandbox(name) {
|
|
366
|
+
const native = await this.getOrEnsureNative(name);
|
|
367
|
+
await native.kill();
|
|
368
|
+
this.registry.delete(name);
|
|
369
|
+
return { name, status: "unknown" };
|
|
370
|
+
}
|
|
371
|
+
async deleteSandbox(name) {
|
|
372
|
+
try {
|
|
373
|
+
await this.getNative(name).kill();
|
|
374
|
+
} catch {
|
|
375
|
+
}
|
|
376
|
+
await import_microsandbox2.Sandbox.remove(name);
|
|
377
|
+
this.registry.delete(name);
|
|
378
|
+
return { name, status: "unknown" };
|
|
379
|
+
}
|
|
380
|
+
async getStatus(name) {
|
|
381
|
+
try {
|
|
382
|
+
this.getNative(name);
|
|
383
|
+
return { name, status: "running" };
|
|
384
|
+
} catch {
|
|
385
|
+
return { name, status: "unknown" };
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
async readFile(sandboxName, path) {
|
|
389
|
+
const content = await this.getNative(sandboxName).fs().readString(path);
|
|
390
|
+
return { path, content };
|
|
391
|
+
}
|
|
392
|
+
async writeFile(sandboxName, path, content) {
|
|
393
|
+
await this.getNative(sandboxName).fs().write(path, Buffer.from(content));
|
|
394
|
+
return { path };
|
|
395
|
+
}
|
|
396
|
+
async listPath(sandboxName, path, recursive) {
|
|
397
|
+
const entries = await this.getNative(sandboxName).fs().list(path, { recursive });
|
|
398
|
+
return {
|
|
399
|
+
entries: entries.map((entry) => ({
|
|
400
|
+
path: entry.path,
|
|
401
|
+
type: entry.kind
|
|
402
|
+
}))
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
async findFiles(sandboxName, path, pattern) {
|
|
406
|
+
const output = await this.getNative(sandboxName).execWithConfig({
|
|
407
|
+
cmd: "sh",
|
|
408
|
+
args: ["-c", `find "${path}" -name "${pattern}" -type f`]
|
|
409
|
+
});
|
|
410
|
+
return { files: output.stdout().split("\n").filter(Boolean) };
|
|
411
|
+
}
|
|
412
|
+
async searchInFile(sandboxName, path, query) {
|
|
413
|
+
let stdout;
|
|
414
|
+
try {
|
|
415
|
+
const output = await this.getNative(sandboxName).execWithConfig({
|
|
416
|
+
cmd: "grep",
|
|
417
|
+
args: ["-n", "-E", query, path]
|
|
418
|
+
});
|
|
419
|
+
stdout = output.stdout();
|
|
420
|
+
} catch (error) {
|
|
421
|
+
if (typeof error === "object" && error !== null && "code" in error && error.code === 1) {
|
|
422
|
+
return { matches: [] };
|
|
423
|
+
}
|
|
424
|
+
throw error;
|
|
425
|
+
}
|
|
426
|
+
return {
|
|
427
|
+
matches: stdout.split("\n").filter(Boolean).map((line) => {
|
|
428
|
+
const separator = line.indexOf(":");
|
|
429
|
+
return {
|
|
430
|
+
line: Number(line.slice(0, separator)),
|
|
431
|
+
content: line.slice(separator + 1)
|
|
432
|
+
};
|
|
433
|
+
})
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
async replaceInFile(sandboxName, input) {
|
|
437
|
+
const fs = this.getNative(sandboxName).fs();
|
|
438
|
+
const original = await fs.readString(input.path);
|
|
439
|
+
if (!input.search) {
|
|
440
|
+
return { replaced: 0 };
|
|
441
|
+
}
|
|
442
|
+
const occurrences = original.split(input.search).length - 1;
|
|
443
|
+
if (occurrences === 0) {
|
|
444
|
+
return { replaced: 0 };
|
|
445
|
+
}
|
|
446
|
+
const updated = original.split(input.search).join(input.replace);
|
|
447
|
+
await fs.write(input.path, Buffer.from(updated));
|
|
448
|
+
return { replaced: occurrences };
|
|
449
|
+
}
|
|
450
|
+
async uploadFile(sandboxName, path, contentBase64) {
|
|
451
|
+
await this.getNative(sandboxName).fs().write(path, Buffer.from(contentBase64, "base64"));
|
|
452
|
+
return { path };
|
|
453
|
+
}
|
|
454
|
+
async downloadFile(sandboxName, path) {
|
|
455
|
+
const data = await this.getNative(sandboxName).fs().read(path);
|
|
456
|
+
const buffer = Buffer.isBuffer(data) ? data : Buffer.from(data);
|
|
457
|
+
return { path, contentBase64: buffer.toString("base64") };
|
|
458
|
+
}
|
|
459
|
+
async execCommand(input) {
|
|
460
|
+
const output = await this.getNative(input.sandboxName).execWithConfig({
|
|
461
|
+
cmd: "sh",
|
|
462
|
+
args: ["-c", input.command],
|
|
463
|
+
cwd: input.exec_dir,
|
|
464
|
+
timeoutMs: input.timeout ? input.timeout * 1e3 : void 0
|
|
465
|
+
});
|
|
466
|
+
return {
|
|
467
|
+
stdout: output.stdout(),
|
|
468
|
+
stderr: output.stderr ? output.stderr() : "",
|
|
469
|
+
exitCode: output.code ?? 0
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
};
|
|
473
|
+
|
|
474
|
+
// src/app.ts
|
|
475
|
+
function buildApp({
|
|
476
|
+
runtimeService = new MicrosandboxRuntimeService()
|
|
477
|
+
} = {}) {
|
|
478
|
+
const app = (0, import_fastify.default)({ logger: false });
|
|
479
|
+
app.register(import_cors.default, { origin: true });
|
|
480
|
+
app.register(import_sensible.default);
|
|
481
|
+
app.register(import_multipart.default);
|
|
482
|
+
registerHealthRoutes(app);
|
|
483
|
+
registerSandboxRoutes(app, runtimeService);
|
|
484
|
+
app.setErrorHandler((error, _request, reply) => {
|
|
485
|
+
const { statusCode, body } = toErrorResponse(error);
|
|
486
|
+
reply.status(statusCode).send(body);
|
|
487
|
+
});
|
|
488
|
+
return app;
|
|
489
|
+
}
|
|
490
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
491
|
+
0 && (module.exports = {
|
|
492
|
+
MicrosandboxRuntimeService,
|
|
493
|
+
SandboxRegistry,
|
|
494
|
+
buildApp
|
|
495
|
+
});
|
|
496
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/app.ts","../src/lib/errors.ts","../src/lib/http.ts","../src/routes/health.ts","../src/schemas/sandbox.ts","../src/controllers/sandbox.ts","../src/routes/sandbox.ts","../src/services/MicrosandboxRuntimeService.ts","../src/services/SandboxRegistry.ts"],"sourcesContent":["export { buildApp } from \"./app\";\nexport { MicrosandboxRuntimeService } from \"./services/MicrosandboxRuntimeService\";\nexport { SandboxRegistry } from \"./services/SandboxRegistry\";\n","import cors from \"@fastify/cors\";\nimport multipart from \"@fastify/multipart\";\nimport sensible from \"@fastify/sensible\";\nimport fastify, { type FastifyInstance } from \"fastify\";\nimport { toErrorResponse } from \"./lib/errors\";\nimport { registerHealthRoutes } from \"./routes/health\";\nimport { registerSandboxRoutes } from \"./routes/sandbox\";\nimport { MicrosandboxRuntimeService } from \"./services/MicrosandboxRuntimeService\";\nimport type { RuntimeService } from \"./types/runtime-service\";\n\nexport function buildApp({\n runtimeService = new MicrosandboxRuntimeService(),\n}: {\n runtimeService?: RuntimeService;\n} = {}): FastifyInstance {\n const app = fastify({ logger: false });\n\n app.register(cors, { origin: true });\n app.register(sensible);\n app.register(multipart);\n\n registerHealthRoutes(app);\n registerSandboxRoutes(app, runtimeService);\n\n app.setErrorHandler((error, _request, reply) => {\n const { statusCode, body } = toErrorResponse(error);\n reply.status(statusCode).send(body);\n });\n\n return app;\n}\n","export class HttpError extends Error {\n constructor(\n public statusCode: number,\n public code: string,\n message: string\n ) {\n super(message);\n }\n}\n\nexport function toErrorResponse(error: unknown): {\n statusCode: number;\n body: {\n success: false;\n error: {\n code: string;\n message: string;\n };\n };\n} {\n if (error instanceof HttpError) {\n return {\n statusCode: error.statusCode,\n body: {\n success: false,\n error: {\n code: error.code,\n message: error.message,\n },\n },\n };\n }\n\n return {\n statusCode: 500,\n body: {\n success: false,\n error: {\n code: \"INTERNAL_ERROR\",\n message: error instanceof Error ? error.message : String(error),\n },\n },\n };\n}\n","export type SuccessResponse<T> = {\n success: true;\n data: T;\n};\n\nexport function ok<T>(data: T): SuccessResponse<T> {\n return {\n success: true,\n data,\n };\n}\n","import type { FastifyInstance } from \"fastify\";\nimport { ok } from \"../lib/http\";\n\nexport function registerHealthRoutes(app: FastifyInstance): void {\n app.get(\"/health\", async () => ok({ status: \"ok\" }));\n}\n","import z from \"zod\";\n\nconst bindMountSchema = z.object({\n type: z.literal(\"bind\"),\n source: z.string().min(1),\n readonly: z.boolean().optional(),\n});\n\nconst namedMountSchema = z.object({\n type: z.literal(\"named\"),\n name: z.string().min(1),\n readonly: z.boolean().optional(),\n});\n\nconst tmpfsMountSchema = z.object({\n type: z.literal(\"tmpfs\"),\n sizeMib: z.number().int().positive().optional(),\n});\n\nexport const volumeSchema = z.union([\n bindMountSchema,\n namedMountSchema,\n tmpfsMountSchema,\n]);\n\nexport const ensureSandboxSchema = z.object({\n image: z.string().optional(),\n cpus: z.number().int().positive().optional(),\n memoryMib: z.number().int().positive().optional(),\n env: z.record(z.string()).optional(),\n volumes: z.record(volumeSchema).optional(),\n});\n\nconst sandboxAndPathSchema = z.object({\n sandboxName: z.string().min(1),\n path: z.string().min(1),\n});\n\nexport const readFileSchema = sandboxAndPathSchema;\n\nexport const writeFileSchema = sandboxAndPathSchema.extend({\n content: z.string(),\n});\n\nexport const listPathSchema = sandboxAndPathSchema.extend({\n recursive: z.boolean().optional(),\n});\n\nexport const findFilesSchema = sandboxAndPathSchema.extend({\n pattern: z.string().min(1),\n});\n\nexport const searchInFileSchema = sandboxAndPathSchema.extend({\n query: z.string().min(1),\n});\n\nexport const replaceInFileSchema = sandboxAndPathSchema.extend({\n search: z.string(),\n replace: z.string(),\n});\n\nexport const uploadFileSchema = sandboxAndPathSchema.and(\n z.union([\n z.object({ contentBase64: z.string() }),\n z.object({ content: z.string().transform((content) => Buffer.from(content).toString(\"base64\")) }),\n ])\n);\n\nexport const downloadFileSchema = sandboxAndPathSchema;\n\nexport const shellExecSchema = z.object({\n sandboxName: z.string().min(1),\n command: z.string().min(1),\n exec_dir: z.string().optional(),\n timeout: z.number().int().positive().optional(),\n});\n\nexport type EnsureSandboxInput = z.infer<typeof ensureSandboxSchema>;\nexport type ShellExecInput = z.infer<typeof shellExecSchema>;\n","import type { FastifyReply, FastifyRequest } from \"fastify\";\nimport {\n downloadFileSchema,\n ensureSandboxSchema,\n findFilesSchema,\n listPathSchema,\n readFileSchema,\n replaceInFileSchema,\n searchInFileSchema,\n shellExecSchema,\n uploadFileSchema,\n writeFileSchema,\n} from \"../schemas/sandbox\";\nimport { ok } from \"../lib/http\";\nimport type { RuntimeService } from \"../types/runtime-service\";\n\nexport function createSandboxController(runtimeService: RuntimeService): {\n ensureSandbox(\n request: FastifyRequest<{ Params: { name: string }; Body: unknown }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n startSandbox(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n stopSandbox(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n killSandbox(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n deleteSandbox(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n getStatus(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n readFile(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n writeFile(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n listPath(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n findFiles(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n searchInFile(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n replaceInFile(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n uploadFile(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n downloadFile(\n request: FastifyRequest<{ Querystring: unknown }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n execCommand(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n} {\n return {\n ensureSandbox: async (\n request: FastifyRequest<{ Params: { name: string }; Body: unknown }>,\n reply: FastifyReply\n ) => {\n const body = ensureSandboxSchema.parse(request.body ?? {});\n const result = await runtimeService.ensureSandbox(request.params.name, body);\n return reply.send(ok(result));\n },\n\n startSandbox: async (request, reply) => {\n return reply.send(ok(await runtimeService.startSandbox(request.params.name)));\n },\n\n stopSandbox: async (request, reply) => {\n return reply.send(ok(await runtimeService.stopSandbox(request.params.name)));\n },\n\n killSandbox: async (request, reply) => {\n return reply.send(ok(await runtimeService.killSandbox(request.params.name)));\n },\n\n deleteSandbox: async (request, reply) => {\n return reply.send(ok(await runtimeService.deleteSandbox(request.params.name)));\n },\n\n getStatus: async (request, reply) => {\n return reply.send(ok(await runtimeService.getStatus(request.params.name)));\n },\n\n readFile: async (request, reply) => {\n const body = readFileSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.readFile(body.sandboxName, body.path)));\n },\n\n writeFile: async (request, reply) => {\n const body = writeFileSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.writeFile(body.sandboxName, body.path, body.content)));\n },\n\n listPath: async (request, reply) => {\n const body = listPathSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.listPath(body.sandboxName, body.path, body.recursive)));\n },\n\n findFiles: async (request, reply) => {\n const body = findFilesSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.findFiles(body.sandboxName, body.path, body.pattern)));\n },\n\n searchInFile: async (request, reply) => {\n const body = searchInFileSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.searchInFile(body.sandboxName, body.path, body.query)));\n },\n\n replaceInFile: async (request, reply) => {\n const body = replaceInFileSchema.parse(request.body ?? {});\n return reply.send(\n ok(\n await runtimeService.replaceInFile(body.sandboxName, {\n path: body.path,\n search: body.search,\n replace: body.replace,\n })\n )\n );\n },\n\n uploadFile: async (request, reply) => {\n const body = uploadFileSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.uploadFile(body.sandboxName, body.path, body.contentBase64)));\n },\n\n downloadFile: async (request, reply) => {\n const query = downloadFileSchema.parse(request.query ?? {});\n return reply.send(ok(await runtimeService.downloadFile(query.sandboxName, query.path)));\n },\n\n execCommand: async (request, reply) => {\n const body = shellExecSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.execCommand(body)));\n },\n };\n}\n","import type { FastifyInstance } from \"fastify\";\nimport { createSandboxController } from \"../controllers/sandbox\";\nimport type { RuntimeService } from \"../types/runtime-service\";\n\nexport function registerSandboxRoutes(\n app: FastifyInstance,\n runtimeService: RuntimeService\n): void {\n const controller = createSandboxController(runtimeService);\n\n app.put(\"/api/sandboxes/:name\", controller.ensureSandbox);\n app.post(\"/api/sandboxes/:name/start\", controller.startSandbox);\n app.post(\"/api/sandboxes/:name/stop\", controller.stopSandbox);\n app.post(\"/api/sandboxes/:name/kill\", controller.killSandbox);\n app.delete(\"/api/sandboxes/:name\", controller.deleteSandbox);\n app.get(\"/api/sandboxes/:name/status\", controller.getStatus);\n\n app.post(\"/api/files/read\", controller.readFile);\n app.post(\"/api/files/write\", controller.writeFile);\n app.post(\"/api/files/list\", controller.listPath);\n app.post(\"/api/files/find\", controller.findFiles);\n app.post(\"/api/files/search\", controller.searchInFile);\n app.post(\"/api/files/replace\", controller.replaceInFile);\n app.post(\"/api/files/upload\", controller.uploadFile);\n app.get(\"/api/files/download\", controller.downloadFile);\n\n app.post(\"/api/shell/exec\", controller.execCommand);\n}\n","import { Mount, Sandbox } from \"microsandbox\";\nimport type { EnsureSandboxInput, ShellExecInput } from \"../schemas/sandbox\";\nimport { SandboxRegistry } from \"./SandboxRegistry\";\n\ntype VolumeConfig = NonNullable<EnsureSandboxInput[\"volumes\"]>[string];\n\ntype RuntimeNative = {\n fs(): {\n readString(path: string): Promise<string>;\n write(path: string, data: Buffer): Promise<void>;\n list(\n path: string,\n options?: { recursive?: boolean }\n ): Promise<Array<{ path: string; kind: string; size?: number; modified?: unknown }>>;\n read(path: string): Promise<Buffer | Uint8Array | string>;\n };\n execWithConfig(config: {\n cmd: string;\n args?: string[];\n cwd?: string;\n timeoutMs?: number;\n }): Promise<{\n stdout(): string;\n stderr?(): string;\n code?: number;\n }>;\n stop(): Promise<void>;\n kill(): Promise<void>;\n};\n\nexport class MicrosandboxRuntimeService {\n constructor(private deps: { registry?: SandboxRegistry } = {}) {}\n\n private get registry(): SandboxRegistry {\n return this.deps.registry ?? (this.deps.registry = new SandboxRegistry());\n }\n\n private buildVolumes(volumes?: EnsureSandboxInput[\"volumes\"]): Record<string, unknown> | undefined {\n if (!volumes) {\n return undefined;\n }\n\n return Object.fromEntries(\n Object.entries(volumes).map(([mountPath, definition]) => [mountPath, this.buildVolume(definition)])\n );\n }\n\n private buildVolume(definition: VolumeConfig): unknown {\n if (definition.type === \"bind\") {\n return Mount.bind(definition.source, { readonly: definition.readonly ?? false });\n }\n\n if (definition.type === \"named\") {\n return Mount.named(definition.name, { readonly: definition.readonly ?? false });\n }\n\n return Mount.tmpfs({ sizeMib: definition.sizeMib });\n }\n\n private getNative(name: string): RuntimeNative {\n return this.registry.get(name) as RuntimeNative;\n }\n\n private async getOrEnsureNative(name: string): Promise<RuntimeNative> {\n try {\n return this.getNative(name);\n } catch {\n return (await this.registry.ensure(name)) as RuntimeNative;\n }\n }\n\n async ensureSandbox(name: string, input: EnsureSandboxInput): Promise<{\n name: string;\n status: string;\n }> {\n await this.registry.ensure(name, {\n image: input.image ?? process.env.MICROSANDBOX_IMAGE ?? \"python:3.11-slim\",\n cpus: input.cpus ?? Number(process.env.MICROSANDBOX_CPUS ?? \"1\"),\n memoryMib: input.memoryMib ?? Number(process.env.MICROSANDBOX_MEMORY ?? \"512\"),\n env: input.env,\n volumes: this.buildVolumes(input.volumes),\n });\n\n return {\n name,\n status: \"running\",\n };\n }\n\n async startSandbox(name: string): Promise<{ name: string; status: string }> {\n await Sandbox.start(name);\n this.registry.delete(name);\n await this.registry.ensure(name);\n return { name, status: \"running\" };\n }\n\n async stopSandbox(name: string): Promise<{ name: string; status: string }> {\n const native = await this.getOrEnsureNative(name);\n await native.stop();\n this.registry.delete(name);\n return { name, status: \"stopped\" };\n }\n\n async killSandbox(name: string): Promise<{ name: string; status: string }> {\n const native = await this.getOrEnsureNative(name);\n await native.kill();\n this.registry.delete(name);\n return { name, status: \"unknown\" };\n }\n\n async deleteSandbox(name: string): Promise<{ name: string; status: string }> {\n try {\n await this.getNative(name).kill();\n } catch {\n // Ignore missing cached native handle before remove.\n }\n\n await Sandbox.remove(name);\n this.registry.delete(name);\n\n return { name, status: \"unknown\" };\n }\n\n async getStatus(name: string): Promise<{ name: string; status: string }> {\n try {\n this.getNative(name);\n return { name, status: \"running\" };\n } catch {\n return { name, status: \"unknown\" };\n }\n }\n\n async readFile(sandboxName: string, path: string): Promise<{ path: string; content: string }> {\n const content = await this.getNative(sandboxName).fs().readString(path);\n return { path, content };\n }\n\n async writeFile(sandboxName: string, path: string, content: string): Promise<{ path: string }> {\n await this.getNative(sandboxName).fs().write(path, Buffer.from(content));\n return { path };\n }\n\n async listPath(\n sandboxName: string,\n path: string,\n recursive?: boolean\n ): Promise<{ entries: Array<{ path: string; type: string }> }> {\n const entries = await this.getNative(sandboxName).fs().list(path, { recursive });\n return {\n entries: entries.map((entry) => ({\n path: entry.path,\n type: entry.kind,\n })),\n };\n }\n\n async findFiles(sandboxName: string, path: string, pattern: string): Promise<{ files: string[] }> {\n const output = await this.getNative(sandboxName).execWithConfig({\n cmd: \"sh\",\n args: [\"-c\", `find \"${path}\" -name \"${pattern}\" -type f`],\n });\n return { files: output.stdout().split(\"\\n\").filter(Boolean) };\n }\n\n async searchInFile(\n sandboxName: string,\n path: string,\n query: string\n ): Promise<{ matches: Array<{ line: number; content: string }> }> {\n let stdout: string;\n\n try {\n const output = await this.getNative(sandboxName).execWithConfig({\n cmd: \"grep\",\n args: [\"-n\", \"-E\", query, path],\n });\n stdout = output.stdout();\n } catch (error) {\n if (typeof error === \"object\" && error !== null && \"code\" in error && error.code === 1) {\n return { matches: [] };\n }\n\n throw error;\n }\n\n return {\n matches: stdout\n .split(\"\\n\")\n .filter(Boolean)\n .map((line) => {\n const separator = line.indexOf(\":\");\n return {\n line: Number(line.slice(0, separator)),\n content: line.slice(separator + 1),\n };\n }),\n };\n }\n\n async replaceInFile(\n sandboxName: string,\n input: { path: string; search: string; replace: string }\n ): Promise<{ replaced: number }> {\n const fs = this.getNative(sandboxName).fs();\n const original = await fs.readString(input.path);\n\n if (!input.search) {\n return { replaced: 0 };\n }\n\n const occurrences = original.split(input.search).length - 1;\n if (occurrences === 0) {\n return { replaced: 0 };\n }\n\n const updated = original.split(input.search).join(input.replace);\n await fs.write(input.path, Buffer.from(updated));\n\n return { replaced: occurrences };\n }\n\n async uploadFile(sandboxName: string, path: string, contentBase64: string): Promise<{ path: string }> {\n await this.getNative(sandboxName).fs().write(path, Buffer.from(contentBase64, \"base64\"));\n return { path };\n }\n\n async downloadFile(sandboxName: string, path: string): Promise<{ path: string; contentBase64: string }> {\n const data = await this.getNative(sandboxName).fs().read(path);\n const buffer = Buffer.isBuffer(data) ? data : Buffer.from(data);\n return { path, contentBase64: buffer.toString(\"base64\") };\n }\n\n async execCommand(input: ShellExecInput): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n const output = await this.getNative(input.sandboxName).execWithConfig({\n cmd: \"sh\",\n args: [\"-c\", input.command],\n cwd: input.exec_dir,\n timeoutMs: input.timeout ? input.timeout * 1000 : undefined,\n });\n\n return {\n stdout: output.stdout(),\n stderr: output.stderr ? output.stderr() : \"\",\n exitCode: output.code ?? 0,\n };\n }\n}\n","import { Sandbox } from \"microsandbox\";\n\nconst DEFAULT_IMAGE = process.env.MICROSANDBOX_IMAGE ?? \"daytonaio/sandbox:0.6.0\";\n\nexport class SandboxRegistry {\n private handles = new Map<string, unknown>();\n private creating = new Map<string, Promise<unknown>>();\n\n async ensure(name: string, createOptions?: Record<string, unknown>): Promise<unknown> {\n const cached = this.handles.get(name);\n if (cached) {\n return cached;\n }\n\n const inflight = this.creating.get(name);\n if (inflight) {\n return inflight;\n }\n\n const creation = (async () => {\n let native: unknown;\n const createConfig = {\n name,\n image: DEFAULT_IMAGE,\n ...(createOptions ?? {}),\n };\n\n try {\n const handle = await Sandbox.get(name);\n\n if (handle.status === \"running\") {\n native = await handle.connect();\n } else if (handle.status === \"stopped\") {\n native = await Sandbox.start(name);\n } else if (handle.status === \"crashed\" || handle.status === \"draining\") {\n await Sandbox.remove(name);\n }\n } catch {\n native = undefined;\n }\n\n if (!native) {\n native = await Sandbox.createDetached(createConfig);\n }\n\n this.handles.set(name, native);\n return native;\n })();\n\n this.creating.set(name, creation);\n void creation.finally(() => this.creating.delete(name));\n\n return creation;\n }\n\n get(name: string): unknown {\n const handle = this.handles.get(name);\n\n if (!handle) {\n throw new Error(`Sandbox ${name} not found`);\n }\n\n return handle;\n }\n\n delete(name: string): void {\n this.handles.delete(name);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,kBAAiB;AACjB,uBAAsB;AACtB,sBAAqB;AACrB,qBAA8C;;;ACHvC,IAAM,YAAN,cAAwB,MAAM;AAAA,EACnC,YACS,YACA,MACP,SACA;AACA,UAAM,OAAO;AAJN;AACA;AAAA,EAIT;AACF;AAEO,SAAS,gBAAgB,OAS9B;AACA,MAAI,iBAAiB,WAAW;AAC9B,WAAO;AAAA,MACL,YAAY,MAAM;AAAA,MAClB,MAAM;AAAA,QACJ,SAAS;AAAA,QACT,OAAO;AAAA,UACL,MAAM,MAAM;AAAA,UACZ,SAAS,MAAM;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,MAAM;AAAA,MACJ,SAAS;AAAA,MACT,OAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MAChE;AAAA,IACF;AAAA,EACF;AACF;;;ACtCO,SAAS,GAAM,MAA6B;AACjD,SAAO;AAAA,IACL,SAAS;AAAA,IACT;AAAA,EACF;AACF;;;ACPO,SAAS,qBAAqB,KAA4B;AAC/D,MAAI,IAAI,WAAW,YAAY,GAAG,EAAE,QAAQ,KAAK,CAAC,CAAC;AACrD;;;ACLA,iBAAc;AAEd,IAAM,kBAAkB,WAAAA,QAAE,OAAO;AAAA,EAC/B,MAAM,WAAAA,QAAE,QAAQ,MAAM;AAAA,EACtB,QAAQ,WAAAA,QAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACxB,UAAU,WAAAA,QAAE,QAAQ,EAAE,SAAS;AACjC,CAAC;AAED,IAAM,mBAAmB,WAAAA,QAAE,OAAO;AAAA,EAChC,MAAM,WAAAA,QAAE,QAAQ,OAAO;AAAA,EACvB,MAAM,WAAAA,QAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACtB,UAAU,WAAAA,QAAE,QAAQ,EAAE,SAAS;AACjC,CAAC;AAED,IAAM,mBAAmB,WAAAA,QAAE,OAAO;AAAA,EAChC,MAAM,WAAAA,QAAE,QAAQ,OAAO;AAAA,EACvB,SAAS,WAAAA,QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAChD,CAAC;AAEM,IAAM,eAAe,WAAAA,QAAE,MAAM;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,sBAAsB,WAAAA,QAAE,OAAO;AAAA,EAC1C,OAAO,WAAAA,QAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,MAAM,WAAAA,QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAAA,EAC3C,WAAW,WAAAA,QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAAA,EAChD,KAAK,WAAAA,QAAE,OAAO,WAAAA,QAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACnC,SAAS,WAAAA,QAAE,OAAO,YAAY,EAAE,SAAS;AAC3C,CAAC;AAED,IAAM,uBAAuB,WAAAA,QAAE,OAAO;AAAA,EACpC,aAAa,WAAAA,QAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC7B,MAAM,WAAAA,QAAE,OAAO,EAAE,IAAI,CAAC;AACxB,CAAC;AAEM,IAAM,iBAAiB;AAEvB,IAAM,kBAAkB,qBAAqB,OAAO;AAAA,EACzD,SAAS,WAAAA,QAAE,OAAO;AACpB,CAAC;AAEM,IAAM,iBAAiB,qBAAqB,OAAO;AAAA,EACxD,WAAW,WAAAA,QAAE,QAAQ,EAAE,SAAS;AAClC,CAAC;AAEM,IAAM,kBAAkB,qBAAqB,OAAO;AAAA,EACzD,SAAS,WAAAA,QAAE,OAAO,EAAE,IAAI,CAAC;AAC3B,CAAC;AAEM,IAAM,qBAAqB,qBAAqB,OAAO;AAAA,EAC5D,OAAO,WAAAA,QAAE,OAAO,EAAE,IAAI,CAAC;AACzB,CAAC;AAEM,IAAM,sBAAsB,qBAAqB,OAAO;AAAA,EAC7D,QAAQ,WAAAA,QAAE,OAAO;AAAA,EACjB,SAAS,WAAAA,QAAE,OAAO;AACpB,CAAC;AAEM,IAAM,mBAAmB,qBAAqB;AAAA,EACnD,WAAAA,QAAE,MAAM;AAAA,IACN,WAAAA,QAAE,OAAO,EAAE,eAAe,WAAAA,QAAE,OAAO,EAAE,CAAC;AAAA,IACtC,WAAAA,QAAE,OAAO,EAAE,SAAS,WAAAA,QAAE,OAAO,EAAE,UAAU,CAAC,YAAY,OAAO,KAAK,OAAO,EAAE,SAAS,QAAQ,CAAC,EAAE,CAAC;AAAA,EAClG,CAAC;AACH;AAEO,IAAM,qBAAqB;AAE3B,IAAM,kBAAkB,WAAAA,QAAE,OAAO;AAAA,EACtC,aAAa,WAAAA,QAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC7B,SAAS,WAAAA,QAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACzB,UAAU,WAAAA,QAAE,OAAO,EAAE,SAAS;AAAA,EAC9B,SAAS,WAAAA,QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAChD,CAAC;;;AC3DM,SAAS,wBAAwB,gBAqCtC;AACA,SAAO;AAAA,IACL,eAAe,OACb,SACA,UACG;AACH,YAAM,OAAO,oBAAoB,MAAM,QAAQ,QAAQ,CAAC,CAAC;AACzD,YAAM,SAAS,MAAM,eAAe,cAAc,QAAQ,OAAO,MAAM,IAAI;AAC3E,aAAO,MAAM,KAAK,GAAG,MAAM,CAAC;AAAA,IAC9B;AAAA,IAEA,cAAc,OAAO,SAAS,UAAU;AACtC,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,aAAa,QAAQ,OAAO,IAAI,CAAC,CAAC;AAAA,IAC9E;AAAA,IAEA,aAAa,OAAO,SAAS,UAAU;AACrC,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,YAAY,QAAQ,OAAO,IAAI,CAAC,CAAC;AAAA,IAC7E;AAAA,IAEA,aAAa,OAAO,SAAS,UAAU;AACrC,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,YAAY,QAAQ,OAAO,IAAI,CAAC,CAAC;AAAA,IAC7E;AAAA,IAEA,eAAe,OAAO,SAAS,UAAU;AACvC,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,cAAc,QAAQ,OAAO,IAAI,CAAC,CAAC;AAAA,IAC/E;AAAA,IAEA,WAAW,OAAO,SAAS,UAAU;AACnC,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,UAAU,QAAQ,OAAO,IAAI,CAAC,CAAC;AAAA,IAC3E;AAAA,IAEA,UAAU,OAAO,SAAS,UAAU;AAClC,YAAM,OAAO,eAAe,MAAM,QAAQ,QAAQ,CAAC,CAAC;AACpD,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,SAAS,KAAK,aAAa,KAAK,IAAI,CAAC,CAAC;AAAA,IAClF;AAAA,IAEA,WAAW,OAAO,SAAS,UAAU;AACnC,YAAM,OAAO,gBAAgB,MAAM,QAAQ,QAAQ,CAAC,CAAC;AACrD,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,UAAU,KAAK,aAAa,KAAK,MAAM,KAAK,OAAO,CAAC,CAAC;AAAA,IACjG;AAAA,IAEA,UAAU,OAAO,SAAS,UAAU;AAClC,YAAM,OAAO,eAAe,MAAM,QAAQ,QAAQ,CAAC,CAAC;AACpD,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,SAAS,KAAK,aAAa,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC;AAAA,IAClG;AAAA,IAEA,WAAW,OAAO,SAAS,UAAU;AACnC,YAAM,OAAO,gBAAgB,MAAM,QAAQ,QAAQ,CAAC,CAAC;AACrD,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,UAAU,KAAK,aAAa,KAAK,MAAM,KAAK,OAAO,CAAC,CAAC;AAAA,IACjG;AAAA,IAEA,cAAc,OAAO,SAAS,UAAU;AACtC,YAAM,OAAO,mBAAmB,MAAM,QAAQ,QAAQ,CAAC,CAAC;AACxD,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,aAAa,KAAK,aAAa,KAAK,MAAM,KAAK,KAAK,CAAC,CAAC;AAAA,IAClG;AAAA,IAEA,eAAe,OAAO,SAAS,UAAU;AACvC,YAAM,OAAO,oBAAoB,MAAM,QAAQ,QAAQ,CAAC,CAAC;AACzD,aAAO,MAAM;AAAA,QACX;AAAA,UACE,MAAM,eAAe,cAAc,KAAK,aAAa;AAAA,YACnD,MAAM,KAAK;AAAA,YACX,QAAQ,KAAK;AAAA,YACb,SAAS,KAAK;AAAA,UAChB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,IAEA,YAAY,OAAO,SAAS,UAAU;AACpC,YAAM,OAAO,iBAAiB,MAAM,QAAQ,QAAQ,CAAC,CAAC;AACtD,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,WAAW,KAAK,aAAa,KAAK,MAAM,KAAK,aAAa,CAAC,CAAC;AAAA,IACxG;AAAA,IAEA,cAAc,OAAO,SAAS,UAAU;AACtC,YAAM,QAAQ,mBAAmB,MAAM,QAAQ,SAAS,CAAC,CAAC;AAC1D,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,aAAa,MAAM,aAAa,MAAM,IAAI,CAAC,CAAC;AAAA,IACxF;AAAA,IAEA,aAAa,OAAO,SAAS,UAAU;AACrC,YAAM,OAAO,gBAAgB,MAAM,QAAQ,QAAQ,CAAC,CAAC;AACrD,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,YAAY,IAAI,CAAC,CAAC;AAAA,IAC9D;AAAA,EACF;AACF;;;ACrIO,SAAS,sBACd,KACA,gBACM;AACN,QAAM,aAAa,wBAAwB,cAAc;AAEzD,MAAI,IAAI,wBAAwB,WAAW,aAAa;AACxD,MAAI,KAAK,8BAA8B,WAAW,YAAY;AAC9D,MAAI,KAAK,6BAA6B,WAAW,WAAW;AAC5D,MAAI,KAAK,6BAA6B,WAAW,WAAW;AAC5D,MAAI,OAAO,wBAAwB,WAAW,aAAa;AAC3D,MAAI,IAAI,+BAA+B,WAAW,SAAS;AAE3D,MAAI,KAAK,mBAAmB,WAAW,QAAQ;AAC/C,MAAI,KAAK,oBAAoB,WAAW,SAAS;AACjD,MAAI,KAAK,mBAAmB,WAAW,QAAQ;AAC/C,MAAI,KAAK,mBAAmB,WAAW,SAAS;AAChD,MAAI,KAAK,qBAAqB,WAAW,YAAY;AACrD,MAAI,KAAK,sBAAsB,WAAW,aAAa;AACvD,MAAI,KAAK,qBAAqB,WAAW,UAAU;AACnD,MAAI,IAAI,uBAAuB,WAAW,YAAY;AAEtD,MAAI,KAAK,mBAAmB,WAAW,WAAW;AACpD;;;AC3BA,IAAAC,uBAA+B;;;ACA/B,0BAAwB;AAExB,IAAM,gBAAgB,QAAQ,IAAI,sBAAsB;AAEjD,IAAM,kBAAN,MAAsB;AAAA,EAAtB;AACL,SAAQ,UAAU,oBAAI,IAAqB;AAC3C,SAAQ,WAAW,oBAAI,IAA8B;AAAA;AAAA,EAErD,MAAM,OAAO,MAAc,eAA2D;AACpF,UAAM,SAAS,KAAK,QAAQ,IAAI,IAAI;AACpC,QAAI,QAAQ;AACV,aAAO;AAAA,IACT;AAEA,UAAM,WAAW,KAAK,SAAS,IAAI,IAAI;AACvC,QAAI,UAAU;AACZ,aAAO;AAAA,IACT;AAEA,UAAM,YAAY,YAAY;AAC5B,UAAI;AACJ,YAAM,eAAe;AAAA,QACnB;AAAA,QACA,OAAO;AAAA,QACP,GAAI,iBAAiB,CAAC;AAAA,MACxB;AAEA,UAAI;AACF,cAAM,SAAS,MAAM,4BAAQ,IAAI,IAAI;AAErC,YAAI,OAAO,WAAW,WAAW;AAC/B,mBAAS,MAAM,OAAO,QAAQ;AAAA,QAChC,WAAW,OAAO,WAAW,WAAW;AACtC,mBAAS,MAAM,4BAAQ,MAAM,IAAI;AAAA,QACnC,WAAW,OAAO,WAAW,aAAa,OAAO,WAAW,YAAY;AACtE,gBAAM,4BAAQ,OAAO,IAAI;AAAA,QAC3B;AAAA,MACF,QAAQ;AACN,iBAAS;AAAA,MACX;AAEA,UAAI,CAAC,QAAQ;AACX,iBAAS,MAAM,4BAAQ,eAAe,YAAY;AAAA,MACpD;AAEA,WAAK,QAAQ,IAAI,MAAM,MAAM;AAC7B,aAAO;AAAA,IACT,GAAG;AAEH,SAAK,SAAS,IAAI,MAAM,QAAQ;AAChC,SAAK,SAAS,QAAQ,MAAM,KAAK,SAAS,OAAO,IAAI,CAAC;AAEtD,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,MAAuB;AACzB,UAAM,SAAS,KAAK,QAAQ,IAAI,IAAI;AAEpC,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,WAAW,IAAI,YAAY;AAAA,IAC7C;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,MAAoB;AACzB,SAAK,QAAQ,OAAO,IAAI;AAAA,EAC1B;AACF;;;ADtCO,IAAM,6BAAN,MAAiC;AAAA,EACtC,YAAoB,OAAuC,CAAC,GAAG;AAA3C;AAAA,EAA4C;AAAA,EAEhE,IAAY,WAA4B;AACtC,WAAO,KAAK,KAAK,aAAa,KAAK,KAAK,WAAW,IAAI,gBAAgB;AAAA,EACzE;AAAA,EAEQ,aAAa,SAA8E;AACjG,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AAEA,WAAO,OAAO;AAAA,MACZ,OAAO,QAAQ,OAAO,EAAE,IAAI,CAAC,CAAC,WAAW,UAAU,MAAM,CAAC,WAAW,KAAK,YAAY,UAAU,CAAC,CAAC;AAAA,IACpG;AAAA,EACF;AAAA,EAEQ,YAAY,YAAmC;AACrD,QAAI,WAAW,SAAS,QAAQ;AAC9B,aAAO,2BAAM,KAAK,WAAW,QAAQ,EAAE,UAAU,WAAW,YAAY,MAAM,CAAC;AAAA,IACjF;AAEA,QAAI,WAAW,SAAS,SAAS;AAC/B,aAAO,2BAAM,MAAM,WAAW,MAAM,EAAE,UAAU,WAAW,YAAY,MAAM,CAAC;AAAA,IAChF;AAEA,WAAO,2BAAM,MAAM,EAAE,SAAS,WAAW,QAAQ,CAAC;AAAA,EACpD;AAAA,EAEQ,UAAU,MAA6B;AAC7C,WAAO,KAAK,SAAS,IAAI,IAAI;AAAA,EAC/B;AAAA,EAEA,MAAc,kBAAkB,MAAsC;AACpE,QAAI;AACF,aAAO,KAAK,UAAU,IAAI;AAAA,IAC5B,QAAQ;AACN,aAAQ,MAAM,KAAK,SAAS,OAAO,IAAI;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,MAAc,OAG/B;AACD,UAAM,KAAK,SAAS,OAAO,MAAM;AAAA,MAC/B,OAAO,MAAM,SAAS,QAAQ,IAAI,sBAAsB;AAAA,MACxD,MAAM,MAAM,QAAQ,OAAO,QAAQ,IAAI,qBAAqB,GAAG;AAAA,MAC/D,WAAW,MAAM,aAAa,OAAO,QAAQ,IAAI,uBAAuB,KAAK;AAAA,MAC7E,KAAK,MAAM;AAAA,MACX,SAAS,KAAK,aAAa,MAAM,OAAO;AAAA,IAC1C,CAAC;AAED,WAAO;AAAA,MACL;AAAA,MACA,QAAQ;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAM,aAAa,MAAyD;AAC1E,UAAM,6BAAQ,MAAM,IAAI;AACxB,SAAK,SAAS,OAAO,IAAI;AACzB,UAAM,KAAK,SAAS,OAAO,IAAI;AAC/B,WAAO,EAAE,MAAM,QAAQ,UAAU;AAAA,EACnC;AAAA,EAEA,MAAM,YAAY,MAAyD;AACzE,UAAM,SAAS,MAAM,KAAK,kBAAkB,IAAI;AAChD,UAAM,OAAO,KAAK;AAClB,SAAK,SAAS,OAAO,IAAI;AACzB,WAAO,EAAE,MAAM,QAAQ,UAAU;AAAA,EACnC;AAAA,EAEA,MAAM,YAAY,MAAyD;AACzE,UAAM,SAAS,MAAM,KAAK,kBAAkB,IAAI;AAChD,UAAM,OAAO,KAAK;AAClB,SAAK,SAAS,OAAO,IAAI;AACzB,WAAO,EAAE,MAAM,QAAQ,UAAU;AAAA,EACnC;AAAA,EAEA,MAAM,cAAc,MAAyD;AAC3E,QAAI;AACF,YAAM,KAAK,UAAU,IAAI,EAAE,KAAK;AAAA,IAClC,QAAQ;AAAA,IAER;AAEA,UAAM,6BAAQ,OAAO,IAAI;AACzB,SAAK,SAAS,OAAO,IAAI;AAEzB,WAAO,EAAE,MAAM,QAAQ,UAAU;AAAA,EACnC;AAAA,EAEA,MAAM,UAAU,MAAyD;AACvE,QAAI;AACF,WAAK,UAAU,IAAI;AACnB,aAAO,EAAE,MAAM,QAAQ,UAAU;AAAA,IACnC,QAAQ;AACN,aAAO,EAAE,MAAM,QAAQ,UAAU;AAAA,IACnC;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,aAAqB,MAA0D;AAC5F,UAAM,UAAU,MAAM,KAAK,UAAU,WAAW,EAAE,GAAG,EAAE,WAAW,IAAI;AACtE,WAAO,EAAE,MAAM,QAAQ;AAAA,EACzB;AAAA,EAEA,MAAM,UAAU,aAAqB,MAAc,SAA4C;AAC7F,UAAM,KAAK,UAAU,WAAW,EAAE,GAAG,EAAE,MAAM,MAAM,OAAO,KAAK,OAAO,CAAC;AACvE,WAAO,EAAE,KAAK;AAAA,EAChB;AAAA,EAEA,MAAM,SACJ,aACA,MACA,WAC6D;AAC7D,UAAM,UAAU,MAAM,KAAK,UAAU,WAAW,EAAE,GAAG,EAAE,KAAK,MAAM,EAAE,UAAU,CAAC;AAC/E,WAAO;AAAA,MACL,SAAS,QAAQ,IAAI,CAAC,WAAW;AAAA,QAC/B,MAAM,MAAM;AAAA,QACZ,MAAM,MAAM;AAAA,MACd,EAAE;AAAA,IACJ;AAAA,EACF;AAAA,EAEA,MAAM,UAAU,aAAqB,MAAc,SAA+C;AAChG,UAAM,SAAS,MAAM,KAAK,UAAU,WAAW,EAAE,eAAe;AAAA,MAC9D,KAAK;AAAA,MACL,MAAM,CAAC,MAAM,SAAS,IAAI,YAAY,OAAO,WAAW;AAAA,IAC1D,CAAC;AACD,WAAO,EAAE,OAAO,OAAO,OAAO,EAAE,MAAM,IAAI,EAAE,OAAO,OAAO,EAAE;AAAA,EAC9D;AAAA,EAEA,MAAM,aACJ,aACA,MACA,OACgE;AAChE,QAAI;AAEJ,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,UAAU,WAAW,EAAE,eAAe;AAAA,QAC9D,KAAK;AAAA,QACL,MAAM,CAAC,MAAM,MAAM,OAAO,IAAI;AAAA,MAChC,CAAC;AACD,eAAS,OAAO,OAAO;AAAA,IACzB,SAAS,OAAO;AACd,UAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU,SAAS,MAAM,SAAS,GAAG;AACtF,eAAO,EAAE,SAAS,CAAC,EAAE;AAAA,MACvB;AAEA,YAAM;AAAA,IACR;AAEA,WAAO;AAAA,MACL,SAAS,OACN,MAAM,IAAI,EACV,OAAO,OAAO,EACd,IAAI,CAAC,SAAS;AACb,cAAM,YAAY,KAAK,QAAQ,GAAG;AAClC,eAAO;AAAA,UACL,MAAM,OAAO,KAAK,MAAM,GAAG,SAAS,CAAC;AAAA,UACrC,SAAS,KAAK,MAAM,YAAY,CAAC;AAAA,QACnC;AAAA,MACF,CAAC;AAAA,IACL;AAAA,EACF;AAAA,EAEA,MAAM,cACJ,aACA,OAC+B;AAC/B,UAAM,KAAK,KAAK,UAAU,WAAW,EAAE,GAAG;AAC1C,UAAM,WAAW,MAAM,GAAG,WAAW,MAAM,IAAI;AAE/C,QAAI,CAAC,MAAM,QAAQ;AACjB,aAAO,EAAE,UAAU,EAAE;AAAA,IACvB;AAEA,UAAM,cAAc,SAAS,MAAM,MAAM,MAAM,EAAE,SAAS;AAC1D,QAAI,gBAAgB,GAAG;AACrB,aAAO,EAAE,UAAU,EAAE;AAAA,IACvB;AAEA,UAAM,UAAU,SAAS,MAAM,MAAM,MAAM,EAAE,KAAK,MAAM,OAAO;AAC/D,UAAM,GAAG,MAAM,MAAM,MAAM,OAAO,KAAK,OAAO,CAAC;AAE/C,WAAO,EAAE,UAAU,YAAY;AAAA,EACjC;AAAA,EAEA,MAAM,WAAW,aAAqB,MAAc,eAAkD;AACpG,UAAM,KAAK,UAAU,WAAW,EAAE,GAAG,EAAE,MAAM,MAAM,OAAO,KAAK,eAAe,QAAQ,CAAC;AACvF,WAAO,EAAE,KAAK;AAAA,EAChB;AAAA,EAEA,MAAM,aAAa,aAAqB,MAAgE;AACtG,UAAM,OAAO,MAAM,KAAK,UAAU,WAAW,EAAE,GAAG,EAAE,KAAK,IAAI;AAC7D,UAAM,SAAS,OAAO,SAAS,IAAI,IAAI,OAAO,OAAO,KAAK,IAAI;AAC9D,WAAO,EAAE,MAAM,eAAe,OAAO,SAAS,QAAQ,EAAE;AAAA,EAC1D;AAAA,EAEA,MAAM,YAAY,OAAsF;AACtG,UAAM,SAAS,MAAM,KAAK,UAAU,MAAM,WAAW,EAAE,eAAe;AAAA,MACpE,KAAK;AAAA,MACL,MAAM,CAAC,MAAM,MAAM,OAAO;AAAA,MAC1B,KAAK,MAAM;AAAA,MACX,WAAW,MAAM,UAAU,MAAM,UAAU,MAAO;AAAA,IACpD,CAAC;AAED,WAAO;AAAA,MACL,QAAQ,OAAO,OAAO;AAAA,MACtB,QAAQ,OAAO,SAAS,OAAO,OAAO,IAAI;AAAA,MAC1C,UAAU,OAAO,QAAQ;AAAA,IAC3B;AAAA,EACF;AACF;;;AP5OO,SAAS,SAAS;AAAA,EACvB,iBAAiB,IAAI,2BAA2B;AAClD,IAEI,CAAC,GAAoB;AACvB,QAAM,UAAM,eAAAC,SAAQ,EAAE,QAAQ,MAAM,CAAC;AAErC,MAAI,SAAS,YAAAC,SAAM,EAAE,QAAQ,KAAK,CAAC;AACnC,MAAI,SAAS,gBAAAC,OAAQ;AACrB,MAAI,SAAS,iBAAAC,OAAS;AAEtB,uBAAqB,GAAG;AACxB,wBAAsB,KAAK,cAAc;AAEzC,MAAI,gBAAgB,CAAC,OAAO,UAAU,UAAU;AAC9C,UAAM,EAAE,YAAY,KAAK,IAAI,gBAAgB,KAAK;AAClD,UAAM,OAAO,UAAU,EAAE,KAAK,IAAI;AAAA,EACpC,CAAC;AAED,SAAO;AACT;","names":["z","import_microsandbox","fastify","cors","sensible","multipart"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { FastifyInstance } from 'fastify';
|
|
2
|
+
|
|
3
|
+
declare function startServer({ argv, env, app, }?: {
|
|
4
|
+
argv?: string[];
|
|
5
|
+
env?: NodeJS.ProcessEnv;
|
|
6
|
+
app?: Pick<FastifyInstance, "listen" | "close">;
|
|
7
|
+
}): Promise<Pick<FastifyInstance, "listen" | "close">>;
|
|
8
|
+
|
|
9
|
+
export { startServer };
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { FastifyInstance } from 'fastify';
|
|
2
|
+
|
|
3
|
+
declare function startServer({ argv, env, app, }?: {
|
|
4
|
+
argv?: string[];
|
|
5
|
+
env?: NodeJS.ProcessEnv;
|
|
6
|
+
app?: Pick<FastifyInstance, "listen" | "close">;
|
|
7
|
+
}): Promise<Pick<FastifyInstance, "listen" | "close">>;
|
|
8
|
+
|
|
9
|
+
export { startServer };
|