sandlot 0.1.4 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/bundler.d.ts +68 -0
- package/dist/browser/bundler.d.ts.map +1 -0
- package/dist/browser/executor.d.ts +46 -0
- package/dist/browser/executor.d.ts.map +1 -0
- package/dist/browser/index.d.ts +9 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +2690 -0
- package/dist/browser/preset.d.ts +63 -0
- package/dist/browser/preset.d.ts.map +1 -0
- package/dist/commands/index.d.ts +20 -11
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/types.d.ts +37 -130
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/core/bundler-utils.d.ts +142 -0
- package/dist/core/bundler-utils.d.ts.map +1 -0
- package/dist/core/esm-types-resolver.d.ts +125 -0
- package/dist/core/esm-types-resolver.d.ts.map +1 -0
- package/dist/core/executor.d.ts +35 -0
- package/dist/core/executor.d.ts.map +1 -0
- package/dist/{fs.d.ts → core/fs.d.ts} +27 -29
- package/dist/core/fs.d.ts.map +1 -0
- package/dist/core/sandbox.d.ts +30 -0
- package/dist/core/sandbox.d.ts.map +1 -0
- package/dist/core/sandlot.d.ts +30 -0
- package/dist/core/sandlot.d.ts.map +1 -0
- package/dist/core/shared-module-registry.d.ts +46 -0
- package/dist/core/shared-module-registry.d.ts.map +1 -0
- package/dist/core/typechecker.d.ts +60 -0
- package/dist/core/typechecker.d.ts.map +1 -0
- package/dist/index.d.ts +11 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1398 -2010
- package/dist/node/bundler.d.ts +48 -0
- package/dist/node/bundler.d.ts.map +1 -0
- package/dist/node/executor.d.ts +48 -0
- package/dist/node/executor.d.ts.map +1 -0
- package/dist/node/index.d.ts +9 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +2644 -0
- package/dist/node/preset.d.ts +62 -0
- package/dist/node/preset.d.ts.map +1 -0
- package/dist/types.d.ts +528 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +16 -6
- package/src/browser/bundler.ts +294 -0
- package/src/browser/executor.ts +71 -0
- package/src/browser/index.ts +57 -0
- package/src/browser/preset.ts +179 -0
- package/src/commands/index.ts +498 -37
- package/src/commands/types.ts +117 -145
- package/src/core/bundler-utils.ts +630 -0
- package/src/core/esm-types-resolver.ts +432 -0
- package/src/core/executor.ts +161 -0
- package/src/{fs.ts → core/fs.ts} +59 -37
- package/src/core/sandbox.ts +624 -0
- package/src/core/sandlot.ts +77 -0
- package/src/core/shared-module-registry.ts +138 -0
- package/src/core/typechecker.ts +609 -0
- package/src/index.ts +106 -139
- package/src/node/bundler.ts +194 -0
- package/src/node/executor.ts +87 -0
- package/src/node/index.ts +39 -0
- package/src/node/preset.ts +178 -0
- package/src/types.ts +672 -0
- package/README.md +0 -243
- package/dist/build-emitter.d.ts +0 -47
- package/dist/build-emitter.d.ts.map +0 -1
- package/dist/builder.d.ts +0 -370
- package/dist/builder.d.ts.map +0 -1
- package/dist/bundler.d.ts +0 -152
- package/dist/bundler.d.ts.map +0 -1
- package/dist/commands/compile.d.ts +0 -13
- package/dist/commands/compile.d.ts.map +0 -1
- package/dist/commands/packages.d.ts +0 -17
- package/dist/commands/packages.d.ts.map +0 -1
- package/dist/commands/run.d.ts +0 -40
- package/dist/commands/run.d.ts.map +0 -1
- package/dist/commands.d.ts +0 -179
- package/dist/commands.d.ts.map +0 -1
- package/dist/fs.d.ts.map +0 -1
- package/dist/internal.d.ts +0 -79
- package/dist/internal.d.ts.map +0 -1
- package/dist/internal.js +0 -1942
- package/dist/loader.d.ts +0 -164
- package/dist/loader.d.ts.map +0 -1
- package/dist/packages.d.ts +0 -199
- package/dist/packages.d.ts.map +0 -1
- package/dist/runner.d.ts +0 -314
- package/dist/runner.d.ts.map +0 -1
- package/dist/sandbox-manager.d.ts +0 -261
- package/dist/sandbox-manager.d.ts.map +0 -1
- package/dist/sandbox.d.ts +0 -267
- package/dist/sandbox.d.ts.map +0 -1
- package/dist/shared-modules.d.ts +0 -148
- package/dist/shared-modules.d.ts.map +0 -1
- package/dist/shared-resources.d.ts +0 -102
- package/dist/shared-resources.d.ts.map +0 -1
- package/dist/ts-libs.d.ts +0 -85
- package/dist/ts-libs.d.ts.map +0 -1
- package/dist/typechecker.d.ts +0 -127
- package/dist/typechecker.d.ts.map +0 -1
- package/src/build-emitter.ts +0 -64
- package/src/builder.ts +0 -498
- package/src/bundler.ts +0 -575
- package/src/commands/compile.ts +0 -236
- package/src/commands/packages.ts +0 -154
- package/src/commands/run.ts +0 -245
- package/src/internal.ts +0 -119
- package/src/loader.ts +0 -229
- package/src/packages.ts +0 -936
- package/src/sandbox.ts +0 -398
- package/src/shared-modules.ts +0 -280
- package/src/shared-resources.ts +0 -166
- package/src/ts-libs.ts +0 -218
- package/src/typechecker.ts +0 -635
package/src/commands/index.ts
CHANGED
|
@@ -1,51 +1,512 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Command factories for sandbox bash environments.
|
|
2
|
+
* Command factories for v2 sandbox bash environments.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Provides a `sandlot` command with subcommands:
|
|
5
|
+
* - sandlot build Build the project
|
|
6
|
+
* - sandlot typecheck Type check without building
|
|
7
|
+
* - sandlot install Install packages
|
|
8
|
+
* - sandlot uninstall Remove packages
|
|
9
|
+
* - sandlot help Show help
|
|
7
10
|
*/
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
import { defineCommand, type CommandContext } from "just-bash/browser";
|
|
13
|
+
import type { SandboxRef } from "./types";
|
|
14
|
+
export type { SandboxRef } from "./types";
|
|
10
15
|
export {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
type RunOptions,
|
|
16
|
-
type RunResult,
|
|
17
|
-
formatEsbuildMessages,
|
|
16
|
+
formatSize,
|
|
17
|
+
formatDiagnostics,
|
|
18
|
+
formatBundleErrors,
|
|
19
|
+
formatBuildFailure,
|
|
18
20
|
} from "./types";
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Create the main `sandlot` command with all subcommands.
|
|
24
|
+
*
|
|
25
|
+
* The sandlot command is a dispatcher that routes to subcommand handlers.
|
|
26
|
+
*/
|
|
27
|
+
export function createSandlotCommand(sandboxRef: SandboxRef) {
|
|
28
|
+
return defineCommand("sandlot", async (args, ctx: CommandContext) => {
|
|
29
|
+
const subcommand = args[0];
|
|
22
30
|
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
// No subcommand or help
|
|
32
|
+
if (!subcommand || subcommand === "help" || subcommand === "--help" || subcommand === "-h") {
|
|
33
|
+
return showHelp();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Dispatch to subcommand handlers
|
|
37
|
+
switch (subcommand) {
|
|
38
|
+
case "build":
|
|
39
|
+
return handleBuild(sandboxRef, args.slice(1));
|
|
40
|
+
|
|
41
|
+
case "typecheck":
|
|
42
|
+
case "tsc":
|
|
43
|
+
return handleTypecheck(sandboxRef, args.slice(1));
|
|
44
|
+
|
|
45
|
+
case "install":
|
|
46
|
+
case "add":
|
|
47
|
+
case "i":
|
|
48
|
+
return handleInstall(sandboxRef, args.slice(1));
|
|
49
|
+
|
|
50
|
+
case "uninstall":
|
|
51
|
+
case "remove":
|
|
52
|
+
case "rm":
|
|
53
|
+
return handleUninstall(sandboxRef, args.slice(1));
|
|
54
|
+
|
|
55
|
+
case "run":
|
|
56
|
+
return handleRun(sandboxRef, args.slice(1));
|
|
57
|
+
|
|
58
|
+
default:
|
|
59
|
+
return {
|
|
60
|
+
stdout: "",
|
|
61
|
+
stderr: `Unknown command: sandlot ${subcommand}\n\nRun 'sandlot help' for available commands.\n`,
|
|
62
|
+
exitCode: 1,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// =============================================================================
|
|
69
|
+
// Help
|
|
70
|
+
// =============================================================================
|
|
71
|
+
|
|
72
|
+
function showHelp() {
|
|
73
|
+
return {
|
|
74
|
+
stdout: `sandlot - In-browser TypeScript sandbox
|
|
75
|
+
|
|
76
|
+
Usage: sandlot <command> [options]
|
|
77
|
+
|
|
78
|
+
Commands:
|
|
79
|
+
build Build the project (typecheck, bundle)
|
|
80
|
+
run Build and execute code
|
|
81
|
+
typecheck Type check without building (alias: tsc)
|
|
82
|
+
install Install packages (aliases: add, i)
|
|
83
|
+
uninstall Remove packages (aliases: remove, rm)
|
|
84
|
+
help Show this help message
|
|
85
|
+
|
|
86
|
+
Run 'sandlot <command> --help' for command-specific options.
|
|
87
|
+
|
|
88
|
+
Examples:
|
|
89
|
+
sandlot build
|
|
90
|
+
sandlot run
|
|
91
|
+
sandlot run --skip-typecheck --timeout 5000
|
|
92
|
+
sandlot install react react-dom
|
|
93
|
+
sandlot typecheck
|
|
94
|
+
`,
|
|
95
|
+
stderr: "",
|
|
96
|
+
exitCode: 0,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// =============================================================================
|
|
101
|
+
// Build
|
|
102
|
+
// =============================================================================
|
|
103
|
+
|
|
104
|
+
import {
|
|
105
|
+
formatSize,
|
|
106
|
+
formatDiagnostics,
|
|
107
|
+
formatBundleErrors,
|
|
108
|
+
formatBuildFailure,
|
|
109
|
+
} from "./types";
|
|
110
|
+
|
|
111
|
+
async function handleBuild(sandboxRef: SandboxRef, args: (string | undefined)[]) {
|
|
112
|
+
let entryPoint: string | undefined;
|
|
113
|
+
let skipTypecheck = false;
|
|
114
|
+
let minify = false;
|
|
115
|
+
let format: "esm" | "iife" | "cjs" = "esm";
|
|
116
|
+
|
|
117
|
+
for (let i = 0; i < args.length; i++) {
|
|
118
|
+
const arg = args[i];
|
|
119
|
+
if (arg === "--skip-typecheck" || arg === "-s") {
|
|
120
|
+
skipTypecheck = true;
|
|
121
|
+
} else if (arg === "--minify" || arg === "-m") {
|
|
122
|
+
minify = true;
|
|
123
|
+
} else if ((arg === "--format" || arg === "-f") && args[i + 1]) {
|
|
124
|
+
const f = args[++i]!.toLowerCase();
|
|
125
|
+
if (f === "esm" || f === "iife" || f === "cjs") {
|
|
126
|
+
format = f;
|
|
127
|
+
}
|
|
128
|
+
} else if ((arg === "--entry" || arg === "-e") && args[i + 1]) {
|
|
129
|
+
entryPoint = args[++i];
|
|
130
|
+
} else if (arg === "--help" || arg === "-h") {
|
|
131
|
+
return {
|
|
132
|
+
stdout: `Usage: sandlot build [options]
|
|
133
|
+
|
|
134
|
+
Options:
|
|
135
|
+
--entry, -e <path> Entry point (default: from package.json main)
|
|
136
|
+
--skip-typecheck, -s Skip type checking
|
|
137
|
+
--minify, -m Minify output
|
|
138
|
+
--format, -f <fmt> Output format (esm|iife|cjs)
|
|
139
|
+
--help, -h Show this help message
|
|
140
|
+
|
|
141
|
+
Examples:
|
|
142
|
+
sandlot build
|
|
143
|
+
sandlot build --entry /src/main.ts
|
|
144
|
+
sandlot build --skip-typecheck --minify
|
|
145
|
+
`,
|
|
146
|
+
stderr: "",
|
|
147
|
+
exitCode: 0,
|
|
148
|
+
};
|
|
149
|
+
} else if (arg && !arg.startsWith("-") && !entryPoint) {
|
|
150
|
+
entryPoint = arg;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const result = await sandboxRef.build({
|
|
155
|
+
entryPoint,
|
|
156
|
+
skipTypecheck,
|
|
157
|
+
minify,
|
|
158
|
+
format,
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// Handle build failure
|
|
162
|
+
if (!result.success) {
|
|
163
|
+
return {
|
|
164
|
+
stdout: "",
|
|
165
|
+
stderr: formatBuildFailure(result),
|
|
166
|
+
exitCode: 1,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Build succeeded
|
|
171
|
+
let output = `Build successful!\n`;
|
|
172
|
+
output += `Size: ${formatSize(result.code.length)}\n`;
|
|
173
|
+
output += `Files: ${result.includedFiles.length}\n`;
|
|
174
|
+
|
|
175
|
+
if (result.warnings.length > 0) {
|
|
176
|
+
output += `\nWarnings:\n`;
|
|
177
|
+
for (const warning of result.warnings) {
|
|
178
|
+
if (warning.location) {
|
|
179
|
+
output += ` ${warning.location.file}:${warning.location.line}: ${warning.text}\n`;
|
|
180
|
+
} else {
|
|
181
|
+
output += ` ${warning.text}\n`;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return {
|
|
187
|
+
stdout: output,
|
|
188
|
+
stderr: "",
|
|
189
|
+
exitCode: 0,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// =============================================================================
|
|
194
|
+
// Typecheck
|
|
195
|
+
// =============================================================================
|
|
196
|
+
|
|
197
|
+
async function handleTypecheck(sandboxRef: SandboxRef, args: (string | undefined)[]) {
|
|
198
|
+
let entryPoint: string | undefined;
|
|
199
|
+
|
|
200
|
+
for (let i = 0; i < args.length; i++) {
|
|
201
|
+
const arg = args[i];
|
|
202
|
+
if ((arg === "--entry" || arg === "-e") && args[i + 1]) {
|
|
203
|
+
entryPoint = args[++i];
|
|
204
|
+
} else if (arg === "--help" || arg === "-h") {
|
|
205
|
+
return {
|
|
206
|
+
stdout: `Usage: sandlot typecheck [options]
|
|
207
|
+
|
|
208
|
+
Options:
|
|
209
|
+
--entry, -e <path> Entry point (default: from package.json main)
|
|
210
|
+
--help, -h Show this help message
|
|
211
|
+
|
|
212
|
+
Aliases: sandlot tsc
|
|
213
|
+
|
|
214
|
+
Examples:
|
|
215
|
+
sandlot typecheck
|
|
216
|
+
sandlot typecheck --entry /src/main.ts
|
|
217
|
+
`,
|
|
218
|
+
stderr: "",
|
|
219
|
+
exitCode: 0,
|
|
220
|
+
};
|
|
221
|
+
} else if (arg && !arg.startsWith("-") && !entryPoint) {
|
|
222
|
+
entryPoint = arg;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
try {
|
|
227
|
+
const result = await sandboxRef.typecheck({ entryPoint });
|
|
228
|
+
|
|
229
|
+
if (!result.success) {
|
|
230
|
+
const errors = result.diagnostics.filter((d) => d.severity === "error");
|
|
231
|
+
const formatted = formatDiagnostics(errors);
|
|
232
|
+
return {
|
|
233
|
+
stdout: "",
|
|
234
|
+
stderr: `Type check failed\n\n${formatted}\n`,
|
|
235
|
+
exitCode: 1,
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const warnings = result.diagnostics.filter((d) => d.severity === "warning");
|
|
240
|
+
let output = `Type check passed\n`;
|
|
241
|
+
|
|
242
|
+
if (warnings.length > 0) {
|
|
243
|
+
output += `\nWarnings:\n\n${formatDiagnostics(warnings)}\n`;
|
|
244
|
+
}
|
|
29
245
|
|
|
30
|
-
|
|
31
|
-
|
|
246
|
+
return {
|
|
247
|
+
stdout: output,
|
|
248
|
+
stderr: "",
|
|
249
|
+
exitCode: 0,
|
|
250
|
+
};
|
|
251
|
+
} catch (err) {
|
|
252
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
253
|
+
return {
|
|
254
|
+
stdout: "",
|
|
255
|
+
stderr: `Type check error: ${message}\n`,
|
|
256
|
+
exitCode: 1,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// =============================================================================
|
|
262
|
+
// Install
|
|
263
|
+
// =============================================================================
|
|
264
|
+
|
|
265
|
+
async function handleInstall(sandboxRef: SandboxRef, args: (string | undefined)[]) {
|
|
266
|
+
// Check for help
|
|
267
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
268
|
+
return {
|
|
269
|
+
stdout: `Usage: sandlot install <package>[@version] [...packages]
|
|
270
|
+
|
|
271
|
+
Examples:
|
|
272
|
+
sandlot install react
|
|
273
|
+
sandlot install lodash@4.17.21
|
|
274
|
+
sandlot install @tanstack/react-query@5
|
|
275
|
+
sandlot install react react-dom
|
|
276
|
+
|
|
277
|
+
Aliases: sandlot add, sandlot i
|
|
278
|
+
`,
|
|
279
|
+
stderr: "",
|
|
280
|
+
exitCode: 0,
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const packages = args.filter((a): a is string => !!a && !a.startsWith("-"));
|
|
285
|
+
|
|
286
|
+
if (packages.length === 0) {
|
|
287
|
+
return {
|
|
288
|
+
stdout: "",
|
|
289
|
+
stderr: `Usage: sandlot install <package>[@version] [...packages]\n\nRun 'sandlot install --help' for more information.\n`,
|
|
290
|
+
exitCode: 1,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const results: string[] = [];
|
|
295
|
+
let hasError = false;
|
|
296
|
+
|
|
297
|
+
for (const packageSpec of packages) {
|
|
298
|
+
try {
|
|
299
|
+
const result = await sandboxRef.install(packageSpec);
|
|
300
|
+
|
|
301
|
+
let status = `+ ${result.name}@${result.version}`;
|
|
302
|
+
if (result.typesInstalled) {
|
|
303
|
+
status += ` (${result.typeFilesCount} type file${result.typeFilesCount !== 1 ? "s" : ""})`;
|
|
304
|
+
if (result.fromCache) {
|
|
305
|
+
status += " [cached]";
|
|
306
|
+
}
|
|
307
|
+
} else if (result.typesError) {
|
|
308
|
+
status += ` (no types: ${result.typesError})`;
|
|
309
|
+
}
|
|
310
|
+
results.push(status);
|
|
311
|
+
} catch (err) {
|
|
312
|
+
hasError = true;
|
|
313
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
314
|
+
results.push(`x ${packageSpec}: ${message}`);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const output = results.join("\n") + "\n";
|
|
319
|
+
|
|
320
|
+
return hasError
|
|
321
|
+
? { stdout: "", stderr: output, exitCode: 1 }
|
|
322
|
+
: { stdout: output, stderr: "", exitCode: 0 };
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// =============================================================================
|
|
326
|
+
// Uninstall
|
|
327
|
+
// =============================================================================
|
|
328
|
+
|
|
329
|
+
async function handleUninstall(sandboxRef: SandboxRef, args: (string | undefined)[]) {
|
|
330
|
+
// Check for help
|
|
331
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
332
|
+
return {
|
|
333
|
+
stdout: `Usage: sandlot uninstall <package> [...packages]
|
|
334
|
+
|
|
335
|
+
Examples:
|
|
336
|
+
sandlot uninstall lodash
|
|
337
|
+
sandlot uninstall react react-dom
|
|
338
|
+
|
|
339
|
+
Aliases: sandlot remove, sandlot rm
|
|
340
|
+
`,
|
|
341
|
+
stderr: "",
|
|
342
|
+
exitCode: 0,
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
const packages = args.filter((a): a is string => !!a && !a.startsWith("-"));
|
|
347
|
+
|
|
348
|
+
if (packages.length === 0) {
|
|
349
|
+
return {
|
|
350
|
+
stdout: "",
|
|
351
|
+
stderr: `Usage: sandlot uninstall <package> [...packages]\n\nRun 'sandlot uninstall --help' for more information.\n`,
|
|
352
|
+
exitCode: 1,
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
const results: string[] = [];
|
|
357
|
+
let hasError = false;
|
|
358
|
+
|
|
359
|
+
for (const packageName of packages) {
|
|
360
|
+
try {
|
|
361
|
+
const result = await sandboxRef.uninstall(packageName);
|
|
362
|
+
if (result.removed) {
|
|
363
|
+
results.push(`- ${result.name}`);
|
|
364
|
+
} else {
|
|
365
|
+
results.push(`x ${packageName}: not installed`);
|
|
366
|
+
hasError = true;
|
|
367
|
+
}
|
|
368
|
+
} catch (err) {
|
|
369
|
+
hasError = true;
|
|
370
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
371
|
+
results.push(`x ${packageName}: ${message}`);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
32
374
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
375
|
+
const output = results.join("\n") + "\n";
|
|
376
|
+
|
|
377
|
+
return hasError
|
|
378
|
+
? { stdout: "", stderr: output, exitCode: 1 }
|
|
379
|
+
: { stdout: output, stderr: "", exitCode: 0 };
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// =============================================================================
|
|
383
|
+
// Run
|
|
384
|
+
// =============================================================================
|
|
385
|
+
|
|
386
|
+
async function handleRun(sandboxRef: SandboxRef, args: (string | undefined)[]) {
|
|
387
|
+
let entryPoint: string | undefined;
|
|
388
|
+
let skipTypecheck = false;
|
|
389
|
+
let timeout = 30000;
|
|
390
|
+
let entryExport: "main" | "default" = "main";
|
|
391
|
+
|
|
392
|
+
for (let i = 0; i < args.length; i++) {
|
|
393
|
+
const arg = args[i];
|
|
394
|
+
if (arg === "--skip-typecheck" || arg === "-s") {
|
|
395
|
+
skipTypecheck = true;
|
|
396
|
+
} else if ((arg === "--timeout" || arg === "-t") && args[i + 1]) {
|
|
397
|
+
const t = parseInt(args[++i]!, 10);
|
|
398
|
+
if (!isNaN(t)) timeout = t;
|
|
399
|
+
} else if ((arg === "--entry" || arg === "-e") && args[i + 1]) {
|
|
400
|
+
entryPoint = args[++i];
|
|
401
|
+
} else if ((arg === "--export" || arg === "-x") && args[i + 1]) {
|
|
402
|
+
const e = args[++i]!.toLowerCase();
|
|
403
|
+
if (e === "main" || e === "default") {
|
|
404
|
+
entryExport = e;
|
|
405
|
+
}
|
|
406
|
+
} else if (arg === "--help" || arg === "-h") {
|
|
407
|
+
return {
|
|
408
|
+
stdout: `Usage: sandlot run [options]
|
|
409
|
+
|
|
410
|
+
Options:
|
|
411
|
+
--entry, -e <path> Entry point (default: from package.json main)
|
|
412
|
+
--skip-typecheck, -s Skip type checking
|
|
413
|
+
--timeout, -t <ms> Execution timeout (default: 30000, 0 = none)
|
|
414
|
+
--export, -x <name> Export to call: main or default (default: main)
|
|
415
|
+
--help, -h Show this help message
|
|
416
|
+
|
|
417
|
+
Examples:
|
|
418
|
+
sandlot run
|
|
419
|
+
sandlot run --entry /src/main.ts
|
|
420
|
+
sandlot run --skip-typecheck --timeout 5000
|
|
421
|
+
sandlot run --export default
|
|
422
|
+
`,
|
|
423
|
+
stderr: "",
|
|
424
|
+
exitCode: 0,
|
|
425
|
+
};
|
|
426
|
+
} else if (arg && !arg.startsWith("-") && !entryPoint) {
|
|
427
|
+
entryPoint = arg;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
try {
|
|
432
|
+
const result = await sandboxRef.run({
|
|
433
|
+
entryPoint,
|
|
434
|
+
skipTypecheck,
|
|
435
|
+
timeout,
|
|
436
|
+
entryExport,
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
// Handle failure
|
|
440
|
+
if (!result.success) {
|
|
441
|
+
let stderr = "";
|
|
442
|
+
|
|
443
|
+
// Build failure - use the shared formatter
|
|
444
|
+
if (result.buildFailure) {
|
|
445
|
+
stderr = formatBuildFailure(result.buildFailure, "Run failed");
|
|
446
|
+
} else {
|
|
447
|
+
// Execution failure
|
|
448
|
+
stderr = `Run failed: ${result.error ?? "Unknown error"}\n`;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// Include any logs that were captured before failure
|
|
452
|
+
let stdout = "";
|
|
453
|
+
if (result.logs.length > 0) {
|
|
454
|
+
stdout = result.logs.join("\n") + "\n";
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
return {
|
|
458
|
+
stdout,
|
|
459
|
+
stderr,
|
|
460
|
+
exitCode: 1,
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// Success
|
|
465
|
+
let output = "";
|
|
466
|
+
|
|
467
|
+
// Output captured logs
|
|
468
|
+
if (result.logs.length > 0) {
|
|
469
|
+
output = result.logs.join("\n") + "\n";
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// Output return value if present
|
|
473
|
+
if (result.returnValue !== undefined) {
|
|
474
|
+
const returnStr =
|
|
475
|
+
typeof result.returnValue === "object"
|
|
476
|
+
? JSON.stringify(result.returnValue, null, 2)
|
|
477
|
+
: String(result.returnValue);
|
|
478
|
+
output += `[return] ${returnStr}\n`;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// Execution time
|
|
482
|
+
if (result.executionTimeMs !== undefined) {
|
|
483
|
+
output += `\nCompleted in ${result.executionTimeMs.toFixed(2)}ms\n`;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
return {
|
|
487
|
+
stdout: output,
|
|
488
|
+
stderr: "",
|
|
489
|
+
exitCode: 0,
|
|
490
|
+
};
|
|
491
|
+
} catch (err) {
|
|
492
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
493
|
+
return {
|
|
494
|
+
stdout: "",
|
|
495
|
+
stderr: `Run error: ${message}\n`,
|
|
496
|
+
exitCode: 1,
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// =============================================================================
|
|
502
|
+
// Default Commands Factory
|
|
503
|
+
// =============================================================================
|
|
38
504
|
|
|
39
505
|
/**
|
|
40
|
-
* Create all default sandbox commands
|
|
506
|
+
* Create all default sandbox commands.
|
|
507
|
+
*
|
|
508
|
+
* Currently just the `sandlot` command which dispatches to subcommands.
|
|
41
509
|
*/
|
|
42
|
-
export function createDefaultCommands(
|
|
43
|
-
return [
|
|
44
|
-
createTscCommand(deps),
|
|
45
|
-
createBuildCommand(deps),
|
|
46
|
-
createRunCommand(deps),
|
|
47
|
-
createInstallCommand(deps),
|
|
48
|
-
createUninstallCommand(deps),
|
|
49
|
-
createListCommand(deps),
|
|
50
|
-
];
|
|
510
|
+
export function createDefaultCommands(sandboxRef: SandboxRef) {
|
|
511
|
+
return [createSandlotCommand(sandboxRef)];
|
|
51
512
|
}
|