1import { getConfig, Platform, ProjectTarget } from '@expo/config';
2
3import * as Log from '../log';
4import { getEntryWithServerRoot } from '../start/server/middleware/ManifestMiddleware';
5import { bundleAsync, BundleOutput } from './fork-bundleAsync';
6
7export type PublishOptions = {
8  releaseChannel?: string;
9  target?: ProjectTarget;
10  resetCache?: boolean;
11  maxWorkers?: number;
12};
13
14// TODO: Reduce layers of indirection
15export async function createBundlesAsync(
16  projectRoot: string,
17  publishOptions: PublishOptions = {},
18  bundleOptions: { platforms: Platform[]; dev?: boolean; minify?: boolean }
19): Promise<Partial<Record<Platform, BundleOutput>>> {
20  if (!bundleOptions.platforms.length) {
21    return {};
22  }
23  const projectConfig = getConfig(projectRoot, { skipSDKVersionRequirement: true });
24  const { exp } = projectConfig;
25
26  const bundles = await bundleAsync(
27    projectRoot,
28    exp,
29    {
30      // If not legacy, ignore the target option to prevent warnings from being thrown.
31      resetCache: publishOptions.resetCache,
32      maxWorkers: publishOptions.maxWorkers,
33      logger: {
34        info(tag: unknown, message: string) {
35          Log.log(message);
36        },
37        error(tag: unknown, message: string) {
38          Log.error(message);
39        },
40      } as any,
41      quiet: false,
42    },
43    bundleOptions.platforms.map((platform: Platform) => ({
44      platform,
45      entryPoint: getEntryWithServerRoot(projectRoot, projectConfig, platform),
46      minify: bundleOptions.minify,
47      dev: bundleOptions.dev,
48    }))
49  );
50
51  // { ios: bundle, android: bundle }
52  return bundleOptions.platforms.reduce<Partial<Record<Platform, BundleOutput>>>(
53    (prev, platform, index) => ({
54      ...prev,
55      [platform]: bundles[index],
56    }),
57    {}
58  );
59}
60