Skip to content

Commit 72e3259

Browse files
authored
fix(core): spawn the sandbox dev server as one shell string (no DEP0190 on Node 24) (#981)
1 parent aa045c3 commit 72e3259

3 files changed

Lines changed: 42 additions & 4 deletions

File tree

‎.changeset/sandbox-dep0190.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@aws-blocks/core": patch
3+
"@aws-blocks/blocks": patch
4+
---
5+
6+
fix(core): stop `npm run sandbox` printing a DEP0190 deprecation warning on Node 24
7+
8+
The sandbox started the local dev server by splitting its command on spaces and passing the pieces as separate args together with `shell: true`. Node 24 warns about that combination (DEP0190, args are concatenated rather than escaped). The command now goes to the shell as a single string, so the warning is gone and the dev server starts exactly as before.

‎packages/core/src/scripts/sandbox-args.test.ts‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { join } from 'node:path';
99
import type { CloudFormationClient } from '@aws-sdk/client-cloudformation';
1010
import {
1111
buildSandboxCdkEnv,
12+
buildDevServerSpawn,
1213
buildSandboxDeployArgs,
1314
buildSandboxSynthArgs,
1415
findExpressUnsafeStacks,
@@ -207,3 +208,23 @@ describe('buildSandboxCdkEnv — framework sink reaches the synth child, and hon
207208
assert.ok(!(FRAMEWORK_SINK_ENV in env), `opted-out run must not set ${FRAMEWORK_SINK_ENV}`);
208209
});
209210
});
211+
212+
describe('buildDevServerSpawn', () => {
213+
// The dev server runs under `shell: true`. Node 24 emits DEP0190 whenever a
214+
// non-empty args array is passed alongside `shell: true` (the args are only
215+
// concatenated, not escaped), so the whole command must go to the shell as
216+
// one string with no separate args.
217+
it('passes the default command as one shell string with no args', () => {
218+
assert.deepStrictEqual(buildDevServerSpawn(undefined), {
219+
command: 'npx tsx watch aws-blocks/scripts/server.ts',
220+
args: [],
221+
});
222+
});
223+
224+
it('passes a custom devCommand through unsplit', () => {
225+
assert.deepStrictEqual(buildDevServerSpawn('npx next dev --port 3100'), {
226+
command: 'npx next dev --port 3100',
227+
args: [],
228+
});
229+
});
230+
});

‎packages/core/src/scripts/sandbox.ts‎

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@ export interface SandboxOptions {
4444
devCommand?: string;
4545
}
4646

47+
/**
48+
* How the sandbox spawns the local dev server. It runs under `shell: true`, so
49+
* the whole command goes to the shell as one string with no separate args:
50+
* Node 24 emits DEP0190 whenever a non-empty args array is combined with
51+
* `shell: true`, because the args are only concatenated, never escaped.
52+
*/
53+
export function buildDevServerSpawn(devCommand: string | undefined): { command: string; args: string[] } {
54+
return { command: devCommand || 'npx tsx watch aws-blocks/scripts/server.ts', args: [] };
55+
}
56+
4757
export interface SandboxDeployArgsOptions {
4858
/** Directory CDK writes stack outputs to (relative to the project root). */
4959
outDir: string;
@@ -353,10 +363,9 @@ export async function startSandbox(options: SandboxOptions) {
353363
console.error(`[CDK Watch] ${data.toString().trim()}`);
354364
});
355365

356-
const devServerCmd = devCommand || `npx tsx watch aws-blocks/scripts/server.ts`;
357-
const [cmd, ...args] = devServerCmd.split(' ');
358-
359-
const devServer = spawnCommand(cmd, args, {
366+
const devServerSpawn = buildDevServerSpawn(devCommand);
367+
368+
const devServer = spawnCommand(devServerSpawn.command, devServerSpawn.args, {
360369
stdio: "inherit",
361370
shell: true,
362371
// Own process group on POSIX so cleanup can signal the whole dev-server

0 commit comments

Comments
 (0)