* Run a command to completion, forwarding its stdout/stderr to the dev output * sink so it gets the per-service log prefix. Resolves stdout for parsing.
(
cmd: string,
args: string[],
out: DevOutput,
opts: { quiet?: boolean } = {}
)
| 111 | * sink so it gets the per-service log prefix. Resolves stdout for parsing. |
| 112 | */ |
| 113 | function runForwarded( |
| 114 | cmd: string, |
| 115 | args: string[], |
| 116 | out: DevOutput, |
| 117 | opts: { quiet?: boolean } = {} |
| 118 | ): Promise<{ stdout: string }> { |
| 119 | return new Promise((resolve, reject) => { |
| 120 | const child = spawn(cmd, args, { stdio: ['ignore', 'pipe', 'pipe'] }); |
| 121 | let stdout = ''; |
| 122 | let stderr = ''; |
| 123 | child.stdout?.on('data', (chunk: Buffer) => { |
| 124 | stdout += chunk.toString(); |
| 125 | if (!opts.quiet) { |
| 126 | if (out.onStdout) { |
| 127 | out.onStdout(chunk); |
| 128 | } else { |
| 129 | process.stderr.write(chunk.toString()); |
| 130 | } |
| 131 | } |
| 132 | }); |
| 133 | child.stderr?.on('data', (chunk: Buffer) => { |
| 134 | stderr += chunk.toString(); |
| 135 | if (!opts.quiet) { |
| 136 | if (out.onStderr) { |
| 137 | out.onStderr(chunk); |
| 138 | } else { |
| 139 | process.stderr.write(chunk.toString()); |
| 140 | } |
| 141 | } |
| 142 | }); |
| 143 | child.on('error', (err: NodeJS.ErrnoException) => { |
| 144 | if (err.code === 'ENOENT') { |
| 145 | reject( |
| 146 | new Error( |
| 147 | `Command not found: \`${cmd}\`. Ensure \`${cmd}\` is installed ` + |
| 148 | 'and on your PATH (Docker is required for `vercel dev` with ' + |
| 149 | 'container services).' |
| 150 | ) |
| 151 | ); |
| 152 | return; |
| 153 | } |
| 154 | reject(err); |
| 155 | }); |
| 156 | child.on('close', code => { |
| 157 | if (code === 0) { |
| 158 | resolve({ stdout }); |
| 159 | } else { |
| 160 | const detail = stderr.trim().split('\n').slice(-5).join('\n'); |
| 161 | reject( |
| 162 | new Error( |
| 163 | `\`${cmd} ${args.join(' ')}\` exited with code ${code}` + |
| 164 | (detail ? `\n${detail}` : '') |
| 165 | ) |
| 166 | ); |
| 167 | } |
| 168 | }); |
| 169 | }); |
| 170 | } |
no test coverage detected