( files: readonly string[], extractOpts: ExtractOpts )
| 263 | * matters for some `format` |
| 264 | */ |
| 265 | export async function extract( |
| 266 | files: readonly string[], |
| 267 | extractOpts: ExtractOpts |
| 268 | ): Promise<string> { |
| 269 | const {throws, readFromStdin, signal, ...opts} = extractOpts |
| 270 | // When throws is not explicitly true, we want to collect partial results |
| 271 | const shouldThrow = throws === true |
| 272 | // Pass throws option to transformer for per-message error handling |
| 273 | const optsWithThrows = { |
| 274 | ...opts, |
| 275 | throws: shouldThrow, |
| 276 | onMsgError: !shouldThrow |
| 277 | ? (_: string, e: Error) => warn(e.message) |
| 278 | : undefined, |
| 279 | } |
| 280 | |
| 281 | if (!signal?.aborted && canExtractWithNative(files, opts, readFromStdin)) { |
| 282 | return extractWithNative(files, { |
| 283 | additionalComponentNames: [ |
| 284 | '$formatMessage', |
| 285 | ...(opts.additionalComponentNames || []), |
| 286 | ], |
| 287 | additionalFunctionNames: opts.additionalFunctionNames, |
| 288 | flatten: opts.flatten, |
| 289 | format: typeof opts.format === 'string' ? opts.format : undefined, |
| 290 | idInterpolationPattern: opts.idInterpolationPattern, |
| 291 | preserveWhitespace: opts.preserveWhitespace, |
| 292 | throws: shouldThrow, |
| 293 | }) |
| 294 | } |
| 295 | |
| 296 | let rawResults: Array<ExtractionResult | undefined> = [] |
| 297 | try { |
| 298 | if (readFromStdin) { |
| 299 | debug(`Reading input from stdin`) |
| 300 | // Read from stdin |
| 301 | if (process.stdin.isTTY) { |
| 302 | warn('Reading source file from TTY.') |
| 303 | } |
| 304 | const stdinSource = await getStdinAsString() |
| 305 | rawResults = [await processFile(stdinSource, 'dummy', optsWithThrows)] |
| 306 | } else { |
| 307 | // Use Promise.allSettled when throws is not explicitly true to collect partial results |
| 308 | if (!shouldThrow) { |
| 309 | const settledResults = await Promise.allSettled( |
| 310 | files.map(async fn => { |
| 311 | debug('Extracting file:', fn) |
| 312 | const source = await readFile(fn, {encoding: 'utf8', signal}) |
| 313 | return processFile(source, fn, optsWithThrows) |
| 314 | }) |
| 315 | ) |
| 316 | rawResults = settledResults.map(result => { |
| 317 | if (result.status === 'fulfilled') { |
| 318 | return result.value |
| 319 | } else { |
| 320 | warn(String(result.reason)) |
| 321 | return undefined |
| 322 | } |
no test coverage detected