1import fs from 'fs-extra';
2import path from 'path';
3
4import { IOS_DIR } from '../../Constants';
5import { copyFileWithTransformsAsync } from '../../Transforms';
6import { execAll } from '../../Utils';
7import { getVersionedDirectory, getVersionPrefix } from './utils';
8
9// Name of the pod containing versioned modules provider.
10export const MODULES_PROVIDER_POD_NAME = 'ExpoModulesProvider';
11
12// Filename of the provider used by autolinking.
13const MODULES_PROVIDER_FILENAME = 'ExpoModulesProvider.swift';
14
15// Autolinking generates the unversioned provider at this path.
16const UNVERSIONED_MODULES_PROVIDER_PATH = path.join(
17  IOS_DIR,
18  'Pods',
19  'Target Support Files',
20  'Pods-Expo Go-Expo Go (unversioned)',
21  MODULES_PROVIDER_FILENAME
22);
23
24/**
25 * Versions Swift modules provider into ExpoKit directory.
26 */
27export async function versionExpoModulesProviderAsync(sdkNumber: number) {
28  const prefix = getVersionPrefix(sdkNumber);
29  const targetDirectory = path.join(getVersionedDirectory(sdkNumber), MODULES_PROVIDER_POD_NAME);
30
31  await fs.mkdirs(targetDirectory);
32
33  const { content } = await copyFileWithTransformsAsync({
34    sourceFile: MODULES_PROVIDER_FILENAME,
35    sourceDirectory: path.dirname(UNVERSIONED_MODULES_PROVIDER_PATH),
36    targetDirectory,
37    transforms: {
38      content: [
39        {
40          find: /\bimport (Expo|EX|EAS)/g,
41          replaceWith: `import ${prefix}$1`,
42        },
43        {
44          find: /@objc\((Expo|EAS)(.*?)\)/g,
45          replaceWith: `@objc(${prefix}$1$2)`,
46        },
47      ],
48    },
49  });
50
51  const podspecPath = path.join(
52    targetDirectory,
53    `${prefix}${MODULES_PROVIDER_POD_NAME}.podspec.json`
54  );
55  const podspec = {
56    name: `${prefix}${MODULES_PROVIDER_POD_NAME}`,
57    version: '' + sdkNumber,
58    summary: 'Pod containing versioned Swift modules provider',
59    authors: '650 Industries, Inc.',
60    homepage: 'https://expo.dev',
61    license: 'MIT',
62    platforms: {
63      ios: '13.0',
64    },
65    source: {
66      git: 'https://github.com/expo/expo.git',
67    },
68    source_files: MODULES_PROVIDER_FILENAME,
69    pod_target_xcconfig: {
70      DEFINES_MODULE: 'YES',
71    },
72    dependencies: execAll(/\bimport\s+(\w+?)\b/g, content, 1).reduce((acc, match) => {
73      acc[match] = [];
74      return acc;
75    }, {} as Record<string, any[]>),
76  };
77
78  await fs.outputJSON(podspecPath, podspec, { spaces: 2 });
79}
80