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