1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3    return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5Object.defineProperty(exports, "__esModule", { value: true });
6exports.createExampleApp = void 0;
7const spawn_async_1 = __importDefault(require("@expo/spawn-async"));
8const fs_extra_1 = __importDefault(require("fs-extra"));
9const path_1 = __importDefault(require("path"));
10const packageManager_1 = require("./packageManager");
11const utils_1 = require("./utils");
12// These dependencies will be removed from the example app (`expo init` adds them)
13const DEPENDENCIES_TO_REMOVE = ['expo-status-bar', 'expo-splash-screen'];
14/**
15 * Initializes a new Expo project as an example app.
16 */
17async function createExampleApp(data, targetDir, packageManager) {
18    // Package name for the example app
19    const exampleProjectSlug = `${data.project.slug}-example`;
20    // `expo init` creates a new folder with the same name as the project slug
21    const appTmpPath = path_1.default.join(targetDir, exampleProjectSlug);
22    // Path to the target example dir
23    const appTargetPath = path_1.default.join(targetDir, 'example');
24    if (!(await fs_extra_1.default.pathExists(appTargetPath))) {
25        // The template doesn't include the example app, so just skip this phase
26        return;
27    }
28    await (0, utils_1.newStep)('Initializing the example app', async (step) => {
29        await (0, spawn_async_1.default)(packageManager, ['create', 'expo-app', '--', exampleProjectSlug, '--template', 'blank-typescript', '--yes'], {
30            cwd: targetDir,
31            stdio: 'ignore',
32        });
33        step.succeed('Initialized the example app');
34    });
35    await (0, utils_1.newStep)('Configuring the example app', async (step) => {
36        // "example" folder already exists and contains template files,
37        // that should replace these created by `expo init`.
38        await moveFiles(appTargetPath, appTmpPath);
39        // Cleanup the "example" dir
40        await fs_extra_1.default.rmdir(appTargetPath);
41        // Clean up the ".git" from example app
42        // note, this directory has contents, rmdir will throw
43        await fs_extra_1.default.remove(path_1.default.join(appTmpPath, '.git'));
44        // Move the temporary example app to "example" dir
45        await fs_extra_1.default.rename(appTmpPath, appTargetPath);
46        await addMissingAppConfigFields(appTargetPath, data);
47        step.succeed('Configured the example app');
48    });
49    await prebuildExampleApp(appTargetPath);
50    await modifyPackageJson(appTargetPath);
51    await (0, utils_1.newStep)('Installing dependencies in the example app', async (step) => {
52        await (0, packageManager_1.installDependencies)(packageManager, appTargetPath);
53        await podInstall(appTargetPath);
54        step.succeed('Installed dependencies in the example app');
55    });
56}
57exports.createExampleApp = createExampleApp;
58/**
59 * Copies files from one directory to another.
60 */
61async function moveFiles(fromPath, toPath) {
62    for (const file of await fs_extra_1.default.readdir(fromPath)) {
63        await fs_extra_1.default.move(path_1.default.join(fromPath, file), path_1.default.join(toPath, file), {
64            overwrite: true,
65        });
66    }
67}
68/**
69 * Adds missing configuration that are required to run `expo prebuild`.
70 */
71async function addMissingAppConfigFields(appPath, data) {
72    const appConfigPath = path_1.default.join(appPath, 'app.json');
73    const appConfig = await fs_extra_1.default.readJson(appConfigPath);
74    const appId = `${data.project.package}.example`;
75    // Android package name needs to be added to app.json
76    if (!appConfig.expo.android) {
77        appConfig.expo.android = {};
78    }
79    appConfig.expo.android.package = appId;
80    // Specify iOS bundle identifier
81    if (!appConfig.expo.ios) {
82        appConfig.expo.ios = {};
83    }
84    appConfig.expo.ios.bundleIdentifier = appId;
85    await fs_extra_1.default.writeJson(appConfigPath, appConfig, {
86        spaces: 2,
87    });
88}
89/**
90 * Applies necessary changes to **package.json** of the example app.
91 * It means setting the autolinking config and removing unnecessary dependencies.
92 */
93async function modifyPackageJson(appPath) {
94    const packageJsonPath = path_1.default.join(appPath, 'package.json');
95    const packageJson = await fs_extra_1.default.readJson(packageJsonPath);
96    if (!packageJson.expo) {
97        packageJson.expo = {};
98    }
99    // Set the native modules dir to the root folder,
100    // so that the autolinking can detect and link the module.
101    packageJson.expo.autolinking = {
102        nativeModulesDir: '..',
103    };
104    // Remove unnecessary dependencies
105    for (const dependencyToRemove of DEPENDENCIES_TO_REMOVE) {
106        delete packageJson.dependencies[dependencyToRemove];
107    }
108    await fs_extra_1.default.writeJson(packageJsonPath, packageJson, {
109        spaces: 2,
110    });
111}
112/**
113 * Runs `expo prebuild` in the example app.
114 */
115async function prebuildExampleApp(exampleAppPath) {
116    await (0, utils_1.newStep)('Prebuilding the example app', async (step) => {
117        await (0, spawn_async_1.default)('expo', ['prebuild', '--no-install'], {
118            cwd: exampleAppPath,
119            stdio: ['ignore', 'ignore', 'pipe'],
120        });
121        step.succeed('Prebuilt the example app');
122    });
123}
124/**
125 * Runs `pod install` in the iOS project at the given path.
126 */
127async function podInstall(appPath) {
128    await (0, spawn_async_1.default)('pod', ['install'], {
129        cwd: path_1.default.join(appPath, 'ios'),
130        stdio: ['ignore', 'ignore', 'pipe'],
131    });
132}
133//# sourceMappingURL=createExampleApp.js.map