| 288 | } |
| 289 | |
| 290 | export function runNextCommand( |
| 291 | argv: string[], |
| 292 | options: NextOptions = {} |
| 293 | ): Promise<{ |
| 294 | code: number | null |
| 295 | signal: NodeJS.Signals | null |
| 296 | stdout: string |
| 297 | stderr: string |
| 298 | }> { |
| 299 | const nextDir = path.dirname(require.resolve('next/package')) |
| 300 | const nextBin = path.join(nextDir, 'dist/bin/next') |
| 301 | const cwd = options.cwd || nextDir |
| 302 | // Let Next.js decide the environment |
| 303 | const env: NodeJS.ProcessEnv = { |
| 304 | ...process.env, |
| 305 | // @ts-ignore packages/next/types/global.d.ts should allow undefined NODE_ENV |
| 306 | NODE_ENV: undefined as NodeJS.ProcessEnv['NODE_ENV'], |
| 307 | __NEXT_TEST_MODE: 'true', |
| 308 | ...options.env, |
| 309 | } |
| 310 | |
| 311 | return new Promise((resolve, reject) => { |
| 312 | debugPrint(`Running command "next ${argv.join(' ')}"`) |
| 313 | const instance = spawn( |
| 314 | 'node', |
| 315 | [...(options.nodeArgs || []), '--no-deprecation', nextBin, ...argv], |
| 316 | { |
| 317 | ...options.spawnOptions, |
| 318 | cwd, |
| 319 | env, |
| 320 | stdio: ['ignore', 'pipe', 'pipe'], |
| 321 | } |
| 322 | ) |
| 323 | |
| 324 | if (typeof options.instance === 'function') { |
| 325 | options.instance(instance) |
| 326 | } |
| 327 | |
| 328 | let mergedStdio = '' |
| 329 | |
| 330 | let stderrOutput = '' |
| 331 | if (options.stderr || options.onStderr) { |
| 332 | instance.stderr!.on('data', function (chunk) { |
| 333 | mergedStdio += chunk |
| 334 | stderrOutput += chunk |
| 335 | |
| 336 | if (options.stderr === 'log') { |
| 337 | debugPrint(chunk.toString()) |
| 338 | } |
| 339 | if (typeof options.onStderr === 'function') { |
| 340 | options.onStderr(chunk.toString()) |
| 341 | } |
| 342 | }) |
| 343 | } else { |
| 344 | instance.stderr!.on('data', function (chunk) { |
| 345 | mergedStdio += chunk |
| 346 | }) |
| 347 | } |