11import * as constants from "../constants" ;
22import * as path from "path" ;
33import * as shelljs from "shelljs" ;
4+ import { format } from "util" ;
45import { exported } from "../common/decorators" ;
56import { Hooks } from "../constants" ;
67
@@ -11,6 +12,7 @@ export class ProjectService implements IProjectService {
1112 private $errors : IErrors ,
1213 private $fs : IFileSystem ,
1314 private $logger : ILogger ,
15+ private $pacoteService : IPacoteService ,
1416 private $projectDataService : IProjectDataService ,
1517 private $projectHelper : IProjectHelper ,
1618 private $projectNameService : IProjectNameService ,
@@ -21,7 +23,6 @@ export class ProjectService implements IProjectService {
2123 @exported ( "projectService" )
2224 public async createProject ( projectOptions : IProjectSettings ) : Promise < ICreateProjectData > {
2325 let projectName = projectOptions . projectName ;
24- let selectedTemplate = projectOptions . template ;
2526
2627 if ( ! projectName ) {
2728 this . $errors . fail ( "You must specify <App name> when creating a new project." ) ;
@@ -41,11 +42,8 @@ export class ProjectService implements IProjectService {
4142 const appId = projectOptions . appId || this . $projectHelper . generateDefaultAppId ( projectName , constants . DEFAULT_APP_IDENTIFIER_PREFIX ) ;
4243 this . createPackageJson ( projectDir , appId ) ;
4344 this . $logger . trace ( `Creating a new NativeScript project with name ${ projectName } and id ${ appId } at location ${ projectDir } ` ) ;
44- if ( ! selectedTemplate ) {
45- selectedTemplate = constants . RESERVED_TEMPLATE_NAMES [ "default" ] ;
46- }
4745
48- const projectCreationData = await this . createProjectCore ( { template : selectedTemplate , projectDir, ignoreScripts : projectOptions . ignoreScripts , appId : appId , projectName } ) ;
46+ const projectCreationData = await this . createProjectCore ( { template : projectOptions . template , projectDir, ignoreScripts : projectOptions . ignoreScripts , appId : appId , projectName } ) ;
4947
5048 this . $logger . printMarkdown ( "Project `%s` was successfully created." , projectCreationData . projectName ) ;
5149
@@ -56,20 +54,25 @@ export class ProjectService implements IProjectService {
5654 const { template, projectDir, appId, projectName, ignoreScripts } = projectCreationSettings ;
5755
5856 try {
59- const { templatePath, templateVersion } = await this . $projectTemplatesService . prepareTemplate ( template , projectDir ) ;
60- await this . extractTemplate ( projectDir , templatePath , templateVersion ) ;
57+ const templateData = await this . $projectTemplatesService . prepareTemplate ( template , projectDir ) ;
58+ const templatePackageJsonContent = templateData . templatePackageJsonContent ;
59+ const templateVersion = templateData . templateVersion ;
6160
62- await this . ensureAppResourcesExist ( projectDir ) ;
61+ await this . extractTemplate ( projectDir , templateData ) ;
6362
64- const templatePackageJsonData = this . getDataFromJson ( templatePath ) ;
63+ if ( templateVersion === constants . TemplateVersions . v2 ) {
64+ this . alterPackageJsonData ( projectDir , appId ) ;
65+ }
6566
66- if ( ! ( templatePackageJsonData && templatePackageJsonData . dependencies && templatePackageJsonData . dependencies [ constants . TNS_CORE_MODULES_NAME ] ) ) {
67- await this . $npmInstallationManager . install ( constants . TNS_CORE_MODULES_NAME , projectDir , { dependencyType : "save" } ) ;
67+ await this . ensureAppResourcesExist ( projectDir ) ;
68+
69+ if ( ! ( templatePackageJsonContent && templatePackageJsonContent . dependencies && templatePackageJsonContent . dependencies [ constants . TNS_CORE_MODULES_NAME ] ) ) {
70+ await this . addTnsCoreModules ( projectDir ) ;
6871 }
6972
7073 if ( templateVersion === constants . TemplateVersions . v1 ) {
71- this . mergeProjectAndTemplateProperties ( projectDir , templatePackageJsonData ) ; // merging dependencies from template (dev && prod)
72- this . removeMergedDependencies ( projectDir , templatePackageJsonData ) ;
74+ this . mergeProjectAndTemplateProperties ( projectDir , templatePackageJsonContent ) ; // merging dependencies from template (dev && prod)
75+ this . removeMergedDependencies ( projectDir , templatePackageJsonContent ) ;
7376 }
7477
7578 // Install devDependencies and execute all scripts:
@@ -79,12 +82,8 @@ export class ProjectService implements IProjectService {
7982 ignoreScripts
8083 } ) ;
8184
82- const templatePackageJsonPath = templateVersion === constants . TemplateVersions . v2 ? path . join ( projectDir , constants . PACKAGE_JSON_FILE_NAME ) : path . join ( templatePath , constants . PACKAGE_JSON_FILE_NAME ) ;
83- const templatePackageJson = this . $fs . readJson ( templatePackageJsonPath ) ;
84-
85- await this . $npm . uninstall ( templatePackageJson . name , { save : true } , projectDir ) ;
86- if ( templateVersion === constants . TemplateVersions . v2 ) {
87- this . alterPackageJsonData ( projectDir , appId ) ;
85+ if ( templateVersion === constants . TemplateVersions . v1 ) {
86+ await this . $npm . uninstall ( templatePackageJsonContent . name , { save : true } , projectDir ) ;
8887 }
8988 } catch ( err ) {
9089 this . $fs . deleteDirectory ( projectDir ) ;
@@ -109,40 +108,27 @@ export class ProjectService implements IProjectService {
109108 }
110109 }
111110
112- private getDataFromJson ( templatePath : string ) : any {
113- const templatePackageJsonPath = path . join ( templatePath , constants . PACKAGE_JSON_FILE_NAME ) ;
114- if ( this . $fs . exists ( templatePackageJsonPath ) ) {
115- const templatePackageJsonData = this . $fs . readJson ( templatePackageJsonPath ) ;
116- return templatePackageJsonData ;
117- } else {
118- this . $logger . trace ( `Template ${ templatePath } does not have ${ constants . PACKAGE_JSON_FILE_NAME } file.` ) ;
119- }
120-
121- return null ;
122- }
123-
124- private async extractTemplate ( projectDir : string , realTemplatePath : string , templateVersion : string ) : Promise < void > {
111+ private async extractTemplate ( projectDir : string , templateData : ITemplateData ) : Promise < void > {
125112 this . $fs . ensureDirectoryExists ( projectDir ) ;
126113
127- this . $logger . trace ( `Template version is ${ templateVersion } ` ) ;
128- let destinationDir = "" ;
129- switch ( templateVersion ) {
114+ switch ( templateData . templateVersion ) {
130115 case constants . TemplateVersions . v1 :
131116 const projectData = this . $projectDataService . getProjectData ( projectDir ) ;
132- const appDestinationPath = projectData . getAppDirectoryPath ( projectDir ) ;
133- this . $fs . createDirectory ( appDestinationPath ) ;
134- destinationDir = appDestinationPath ;
117+ const destinationDirectory = projectData . getAppDirectoryPath ( projectDir ) ;
118+ this . $fs . createDirectory ( destinationDirectory ) ;
119+
120+ this . $logger . trace ( `Copying application from '${ templateData . templatePath } ' into '${ destinationDirectory } '.` ) ;
121+ shelljs . cp ( '-R' , path . join ( templateData . templatePath , "*" ) , destinationDirectory ) ;
122+
123+ this . $fs . createDirectory ( path . join ( projectDir , "platforms" ) ) ;
135124 break ;
136125 case constants . TemplateVersions . v2 :
126+ await this . $pacoteService . extractPackage ( templateData . templateName , projectDir ) ;
127+ break ;
137128 default :
138- destinationDir = projectDir ;
129+ this . $errors . failWithoutHelp ( format ( constants . ProjectTemplateErrors . InvalidTemplateVersionStringFormat , templateData . templateName , templateData . templateVersion ) ) ;
139130 break ;
140131 }
141-
142- this . $logger . trace ( `Copying application from '${ realTemplatePath } ' into '${ destinationDir } '.` ) ;
143- shelljs . cp ( '-R' , path . join ( realTemplatePath , "*" ) , destinationDir ) ;
144-
145- this . $fs . createDirectory ( path . join ( projectDir , "platforms" ) ) ;
146132 }
147133
148134 private async ensureAppResourcesExist ( projectDir : string ) : Promise < void > {
@@ -154,36 +140,7 @@ export class ProjectService implements IProjectService {
154140 this . $fs . createDirectory ( appResourcesDestinationPath ) ;
155141
156142 // the template installed doesn't have App_Resources -> get from a default template
157- const defaultTemplateName = constants . RESERVED_TEMPLATE_NAMES [ "default" ] ;
158- await this . $npm . install ( defaultTemplateName , projectDir , {
159- save : true ,
160- disableNpmInstall : false ,
161- frameworkPath : null ,
162- ignoreScripts : false
163- } ) ;
164-
165- const defaultTemplatePath = path . join ( projectDir , constants . NODE_MODULES_FOLDER_NAME , defaultTemplateName ) ;
166- const defaultTemplateVersion = this . $projectTemplatesService . getTemplateVersion ( defaultTemplatePath ) ;
167-
168- let defaultTemplateAppResourcesPath : string = null ;
169- switch ( defaultTemplateVersion ) {
170- case constants . TemplateVersions . v1 :
171- defaultTemplateAppResourcesPath = path . join ( projectDir ,
172- constants . NODE_MODULES_FOLDER_NAME ,
173- defaultTemplateName ,
174- constants . APP_RESOURCES_FOLDER_NAME ) ;
175- break ;
176- case constants . TemplateVersions . v2 :
177- default :
178- const defaultTemplateProjectData = this . $projectDataService . getProjectData ( defaultTemplatePath ) ;
179- defaultTemplateAppResourcesPath = defaultTemplateProjectData . appResourcesDirectoryPath ;
180- }
181-
182- if ( defaultTemplateAppResourcesPath && this . $fs . exists ( defaultTemplateAppResourcesPath ) ) {
183- shelljs . cp ( '-R' , defaultTemplateAppResourcesPath , appPath ) ;
184- }
185-
186- await this . $npm . uninstall ( defaultTemplateName , { save : true } , projectDir ) ;
143+ await this . $pacoteService . extractPackage ( constants . RESERVED_TEMPLATE_NAMES [ "default" ] , appPath , { filter : ( name : string , entry : any ) => entry . path . indexOf ( constants . APP_RESOURCES_FOLDER_NAME ) !== - 1 } ) ;
187144 }
188145 }
189146
@@ -271,5 +228,15 @@ export class ProjectService implements IProjectService {
271228 private setAppId ( projectDir : string , projectId : string ) : void {
272229 this . $projectDataService . setNSValue ( projectDir , "id" , projectId ) ;
273230 }
231+
232+ private async addTnsCoreModules ( projectDir : string ) : Promise < void > {
233+ const projectFilePath = path . join ( projectDir , this . $staticConfig . PROJECT_FILE_NAME ) ;
234+ const packageJsonData = this . $fs . readJson ( projectFilePath ) ;
235+
236+ const version = await this . $npmInstallationManager . getLatestCompatibleVersion ( constants . TNS_CORE_MODULES_NAME ) ;
237+ packageJsonData . dependencies [ constants . TNS_CORE_MODULES_NAME ] = version ;
238+
239+ this . $fs . writeJson ( projectFilePath , packageJsonData ) ;
240+ }
274241}
275242$injector . register ( "projectService" , ProjectService ) ;
0 commit comments