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