1import type { BundleOutput } from '@expo/dev-server';
2import path from 'path';
3
4export type BundlePlatform = 'android' | 'ios';
5
6type PlatformMetadataAsset = { path: string; ext: string };
7
8type PlatformMetadata = { bundle: string; assets: PlatformMetadataAsset[] };
9
10type FileMetadata = {
11  [key in BundlePlatform]: PlatformMetadata;
12};
13
14export function createMetadataJson({
15  bundles,
16  fileNames,
17}: {
18  bundles: Partial<Record<BundlePlatform, Pick<BundleOutput, 'assets'>>>;
19  fileNames: Record<string, string>;
20}): {
21  version: 0;
22  bundler: 'metro';
23  fileMetadata: FileMetadata;
24} {
25  // Build metadata.json
26  return {
27    version: 0,
28    bundler: 'metro',
29    fileMetadata: Object.entries(bundles).reduce<Record<string, Partial<PlatformMetadata>>>(
30      (metadata, [platform, bundle]) => ({
31        ...metadata,
32        [platform]: {
33          // Get the filename for each platform's bundle.
34          bundle: path.join('bundles', fileNames[platform]!),
35          // Collect all of the assets and convert them to the serial format.
36          assets: bundle.assets
37            .map((asset) =>
38              // Each asset has multiple hashes which we convert and then flatten.
39              asset.fileHashes?.map((hash) => ({
40                path: path.join('assets', hash),
41                ext: asset.type,
42              }))
43            )
44            .filter(Boolean)
45            .flat(),
46        },
47      }),
48      {}
49    ) as FileMetadata,
50  };
51}
52