/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */ import { execSync } from 'child_process' ; import fs from 'fs' ; import path from 'path' ; import copyProjectTemplateAndReplace from './copyProjectTemplateAndReplace' ; import { logger } from '@react-native-community/cli-tools' ; import * as PackageManager from '../packageManager' ; param destPath param newProjectName param template async function createProjectFromTemplate ( destPath , newProjectName , template ) { const templatePath = path . dirname ( require . resolve ( 'react-native/template' ) ) ; copyProjectTemplateAndReplace ( templatePath , destPath , newProjectName ) ; if ( template === undefined ) { return ; } await createFromRemoteTemplate ( template , destPath , newProjectName ) ; } /**
 * The following formats are supported for the template:
 * - 'demo' -> Fetch the package react-native-template-demo from npm
 * - git://..., http://..., file://... or any other URL supported by npm
 */ async function createFromRemoteTemplate ( template , destPath , newProjectName ) { let installPackage ; let templateName ; if ( template . includes ( ':/' ) ) { installPackage = template ; templateName = template . substr ( template . lastIndexOf ( '/' ) + 1 ) ; } else { installPackage = `react-native-template-${ template }` ; templateName = installPackage ; } logger . info ( `Fetching template ${ installPackage }...` ) ; try { await PackageManager . install ( [ installPackage ] , { root : destPath } ) ; const templatePath = path . resolve ( 'node_modules' , templateName ) ; copyProjectTemplateAndReplace ( templatePath , destPath , newProjectName , { ignorePaths : [ 'package.json' , 'dependencies.json' , 'devDependencies.json' , ] , } ) ; await installTemplateDependencies ( templatePath , destPath ) ; await installTemplateDevDependencies ( templatePath , destPath ) ; } finally { try { await PackageManager . uninstall ( [ templateName ] , { root : destPath } ) ; } catch ( err ) { logger . warn ( `Failed to clean up template temp files in node_modules/${ templateName }. ` + 'This is not a critical error, you can work on your app.' ) ; } } } async function installTemplateDependencies ( templatePath , root ) { const dependenciesJsonPath = path . resolve ( templatePath , 'dependencies.json' ) ; logger . info ( 'Adding dependencies for the project...' ) ; if ( ! fs . existsSync ( dependenciesJsonPath ) ) { logger . info ( 'No additional dependencies.' ) ; return ; } let dependencies ; try { dependencies = require ( dependenciesJsonPath ) ; } catch ( err ) { throw new Error ( `Could not parse the template's dependencies.json: ${ err . message }` ) ; } const dependenciesToInstall = Object . keys ( dependencies ) . map ( ( depName ) => `${ depName }@${ dependencies [ depName ] }` ) ; await PackageManager . install ( dependenciesToInstall , { root } ) ; logger . info ( "Linking native dependencies into the project's build files..." ) ; execSync ( 'react-native link' , { cwd : root , stdio : 'inherit' } ) ; } async function installTemplateDevDependencies ( templatePath , root ) { const devDependenciesJsonPath = path . resolve ( templatePath , 'devDependencies.json' ) ; logger . info ( 'Adding develop dependencies for the project...' ) ; if ( ! fs . existsSync ( devDependenciesJsonPath ) ) { logger . info ( 'No additional develop dependencies.' ) ; return ; } let dependencies ; try { dependencies = require ( devDependenciesJsonPath ) ; } catch ( err ) { throw new Error ( `Could not parse the template's devDependencies.json: ${ err . message }` ) ; } const dependenciesToInstall = Object . keys ( dependencies ) . map ( ( depName ) => `${ depName }@${ dependencies [ depName ] }` ) ; await PackageManager . installDev ( dependenciesToInstall , { root } ) ; } export { createProjectFromTemplate } ;