1import chalk from 'chalk';
2import * as fs from 'fs-extra';
3import * as path from 'path';
4
5import { PACKAGES_DIR, EXPO_DIR } from '../Constants';
6import configureModule from './configureModule';
7import fetchTemplate from './fetchTemplate';
8import promptQuestionsAsync from './promptQuestionsAsync';
9
10const TEMPLATE_PACKAGE_NAME = 'expo-module-template';
11
12export default async function generateModuleAsync(
13  newModuleProjectDir: string,
14  options: { template?: string; useLocalTemplate?: boolean }
15) {
16  console.log(
17    `Creating new unimodule under ${chalk.magenta(path.relative(EXPO_DIR, newModuleProjectDir))}...`
18  );
19
20  let templatePath: string | undefined;
21
22  if (options.template) {
23    console.log(`Using custom module template: ${chalk.blue(options.template)}`);
24    templatePath = options.template;
25  } else if (options.useLocalTemplate) {
26    templatePath = path.join(PACKAGES_DIR, TEMPLATE_PACKAGE_NAME);
27
28    console.log(
29      `Using local module template from ${chalk.blue(path.relative(EXPO_DIR, templatePath))}`
30    );
31  }
32
33  const newModulePathFromArgv = newModuleProjectDir && path.resolve(newModuleProjectDir);
34  const newModuleName = newModulePathFromArgv && path.basename(newModulePathFromArgv);
35  const newModuleParentPath = newModulePathFromArgv
36    ? path.dirname(newModulePathFromArgv)
37    : process.cwd();
38
39  const configuration = await promptQuestionsAsync(newModuleName);
40  const newModulePath = path.resolve(newModuleParentPath, configuration.npmModuleName);
41  if (fs.existsSync(newModulePath)) {
42    throw new Error(`Module '${newModulePath}' already exists!`);
43  }
44
45  await fetchTemplate(newModulePath, templatePath);
46
47  await configureModule(newModulePath, configuration);
48}
49