text: /**
   * Copyright (c) 2015-present, Facebook, Inc.
   *
   * This source code is licensed under the MIT license found in the
   * LICENSE file in the root directory of this source tree.
   *
   * @flow
   * @format
   */
  
  'use strict';
  
  const Server = require('../../Server');
  
  const relativizeSourceMapInline = require('../../lib/relativizeSourceMap');
  const writeFile = require('./writeFile');
  
  import type {OutputOptions, RequestOptions} from '../types.flow';
  import type {MetroSourceMap} from 'metro-source-map';
  
  function buildBundle(
    packagerClient: Server,
    requestOptions: RequestOptions,
  ): Promise<{code: string, map: string}> {
    return packagerClient.build({
      ...Server.DEFAULT_BUNDLE_OPTIONS,
      ...requestOptions,
      bundleType: 'bundle',
    });
  }
  
  function relativateSerializedMap(
    map: string,
    sourceMapSourcesRoot: string,
  ): string {
    const sourceMap = (JSON.parse(map): MetroSourceMap);
    relativizeSourceMapInline(sourceMap, sourceMapSourcesRoot);
    return JSON.stringify(sourceMap);
  }
  
  async function saveBundleAndMap(
    bundle: {code: string, map: string},
    options: OutputOptions,
    log: (...args: Array<string>) => void,
  ): Promise<mixed> {
    const {
      bundleOutput,
      bundleEncoding: encoding,
      sourcemapOutput,
      sourcemapSourcesRoot,
    } = options;
  
    const writeFns = [];
  
    writeFns.push(async () => {
      log('Writing bundle output to:', bundleOutput);
      await writeFile(bundleOutput, bundle.code, encoding);
      log('Done writing bundle output');
    });
  
    if (sourcemapOutput) {
      let {map} = bundle;
      if (sourcemapSourcesRoot !== undefined) {
        log('start relativating source map');
        map = relativateSerializedMap(map, sourcemapSourcesRoot);
        log('finished relativating');
      }
  
      writeFns.push(async () => {
        log('Writing sourcemap output to:', sourcemapOutput);
        await writeFile(sourcemapOutput, map, null);
        log('Done writing sourcemap output');
      });
    }
  
    // Wait until everything is written to disk.
    await Promise.all(writeFns.map(cb => cb()));
  }
  
  exports.build = buildBundle;
  exports.save = saveBundleAndMap;
  exports.formatName = 'bundle';
  