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 }
19): Promise<Partial<Record<Platform, BundleOutput>>> {
20  const projectConfig = getConfig(projectRoot, { skipSDKVersionRequirement: true });
21  const { exp } = projectConfig;
22
23  const bundles = await bundleAsync(
24    projectRoot,
25    exp,
26    {
27      // If not legacy, ignore the target option to prevent warnings from being thrown.
28      resetCache: publishOptions.resetCache,
29      maxWorkers: publishOptions.maxWorkers,
30      logger: {
31        info(tag: unknown, message: string) {
32          Log.log(message);
33        },
34        error(tag: unknown, message: string) {
35          Log.error(message);
36        },
37      } as any,
38      quiet: false,
39    },
40    bundleOptions.platforms.map((platform: Platform) => ({
41      platform,
42      entryPoint: getEntryWithServerRoot(projectRoot, projectConfig, platform),
43      dev: bundleOptions.dev,
44    }))
45  );
46
47  // { ios: bundle, android: bundle }
48  return bundleOptions.platforms.reduce<Partial<Record<Platform, BundleOutput>>>(
49    (prev, platform, index) => ({
50      ...prev,
51      [platform]: bundles[index],
52    }),
53    {}
54  );
55}
56