UNPKG

nativescript

Version:

Command-line interface for building NativeScript projects

195 lines • 9.69 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ProjectService = void 0; const constants = require("../constants"); const path = require("path"); const simple_git_1 = require("simple-git"); const decorators_1 = require("../common/decorators"); const constants_1 = require("../constants"); const decorators_2 = require("../common/decorators"); const yok_1 = require("../common/yok"); class ProjectService { constructor($options, $hooksService, $packageManager, $errors, $fs, $logger, $pacoteService, $projectDataService, $projectConfigService, $projectHelper, $projectNameService, $projectTemplatesService, $tempService, $staticConfig, $childProcess) { this.$options = $options; this.$hooksService = $hooksService; this.$packageManager = $packageManager; this.$errors = $errors; this.$fs = $fs; this.$logger = $logger; this.$pacoteService = $pacoteService; this.$projectDataService = $projectDataService; this.$projectConfigService = $projectConfigService; this.$projectHelper = $projectHelper; this.$projectNameService = $projectNameService; this.$projectTemplatesService = $projectTemplatesService; this.$tempService = $tempService; this.$staticConfig = $staticConfig; this.$childProcess = $childProcess; } async validateProjectName(opts) { let projectName = opts.projectName; if (!projectName) { this.$errors.failWithHelp("You must specify <App name> when creating a new project."); } projectName = await this.$projectNameService.ensureValidName(projectName, { force: opts.force, }); const projectDir = this.getValidProjectDir(opts.pathToProject, projectName); if (this.$fs.exists(projectDir) && !this.$fs.isEmptyDir(projectDir)) { this.$errors.fail("Path already exists and is not empty %s", projectDir); } return projectName; } async createProject(projectOptions) { const projectName = await this.validateProjectName({ projectName: projectOptions.projectName, force: projectOptions.force, pathToProject: projectOptions.pathToProject, }); const projectDir = this.getValidProjectDir(projectOptions.pathToProject, projectName); this.$fs.createDirectory(projectDir); const appId = projectOptions.appId || this.$projectHelper.generateDefaultAppId(projectName, constants.DEFAULT_APP_IDENTIFIER_PREFIX); this.$logger.trace(`Creating a new NativeScript project with name ${projectName} and id ${appId} at location ${projectDir}`); const projectCreationData = await this.createProjectCore({ template: projectOptions.template, projectDir, ignoreScripts: projectOptions.ignoreScripts, appId: appId, projectName, }); // can pass --no-git to skip creating a git repo // useful in monorepos where we're creating // sub projects in an existing git repo. if (this.$options.git) { try { if (!this.$options.force) { const git = (0, simple_git_1.default)(projectDir); if (await git.checkIsRepo()) { // throwing here since we're catching below. throw new Error("Already part of a git repository."); } } await this.$childProcess.exec(`git init ${projectDir}`); await this.$childProcess.exec(`git -C ${projectDir} add --all`); await this.$childProcess.exec(`git -C ${projectDir} commit --no-verify -m "init"`); } catch (err) { this.$logger.trace("Unable to initialize git repository. Error is: ", err); } } this.$logger.trace(`Project ${projectName} was successfully created.`); return projectCreationData; } isValidNativeScriptProject(pathToProject) { try { const projectData = this.$projectDataService.getProjectData(pathToProject); return (!!projectData && !!projectData.projectDir && !!(projectData.projectIdentifiers.ios && projectData.projectIdentifiers.android)); } catch (e) { return false; } } getValidProjectDir(pathToProject, projectName) { const selectedPath = path.resolve(pathToProject || "."); const projectDir = path.join(selectedPath, projectName); return projectDir; } async createProjectCore(projectCreationSettings) { const { template, projectDir, appId, projectName, ignoreScripts, } = projectCreationSettings; try { const templateData = await this.$projectTemplatesService.prepareTemplate(template, projectDir); await this.extractTemplate(projectDir, templateData); this.alterPackageJsonData(projectCreationSettings); this.$projectConfigService.writeDefaultConfig(projectDir, appId); await this.ensureAppResourcesExist(projectDir); // Install devDependencies and execute all scripts: await this.$packageManager.install(projectDir, projectDir, { disableNpmInstall: false, frameworkPath: null, ignoreScripts, }); } catch (err) { this.$fs.deleteDirectory(projectDir); throw err; } await this.$hooksService.executeAfterHooks(constants_1.Hooks.createProject, { hookArgs: projectCreationSettings, }); return { projectName, projectDir }; } async extractTemplate(projectDir, templateData) { this.$fs.ensureDirectoryExists(projectDir); const fullTemplateName = templateData.version ? `${templateData.templateName}@${templateData.version}` : templateData.templateName; await this.$pacoteService.extractPackage(fullTemplateName, projectDir); } async ensureAppResourcesExist(projectDir) { const projectData = this.$projectDataService.getProjectData(projectDir); const appResourcesDestinationPath = projectData.getAppResourcesDirectoryPath(projectDir); if (!this.$fs.exists(appResourcesDestinationPath)) { this.$logger.trace("Project does not have App_Resources - fetching from default template."); this.$fs.createDirectory(appResourcesDestinationPath); const tempDir = await this.$tempService.mkdirSync("ns-default-template"); // the template installed doesn't have App_Resources -> get from a default template await this.$pacoteService.extractPackage(constants.RESERVED_TEMPLATE_NAMES["default"], tempDir); const templateProjectData = this.$projectDataService.getProjectData(tempDir); const templateAppResourcesDir = templateProjectData.getAppResourcesDirectoryPath(tempDir); this.$fs.copyFile(path.join(templateAppResourcesDir, "*"), appResourcesDestinationPath); } } alterPackageJsonData(projectCreationSettings) { const { projectDir, projectName } = projectCreationSettings; const projectFilePath = path.join(projectDir, this.$staticConfig.PROJECT_FILE_NAME); let packageJsonData = this.$fs.readJson(projectFilePath); // clean up keys from the template package.json that we don't care about. Object.keys(packageJsonData).forEach((key) => { if (key.startsWith("_") || constants.TemplatesV2PackageJsonKeysToRemove.includes(key)) { delete packageJsonData[key]; } }); // this is used to ensure the order of keys is consistent, the blanks are filled in from the template const packageJsonSchema = { name: projectName, main: "", version: "1.0.0", private: true, dependencies: {}, devDependencies: {}, // anythign else would go below }; packageJsonData = Object.assign(packageJsonSchema, packageJsonData); this.$fs.writeJson(projectFilePath, packageJsonData); } } exports.ProjectService = ProjectService; __decorate([ (0, decorators_1.exported)("projectService"), (0, decorators_2.performanceLog)() ], ProjectService.prototype, "createProject", null); __decorate([ (0, decorators_1.exported)("projectService") ], ProjectService.prototype, "isValidNativeScriptProject", null); __decorate([ (0, decorators_2.performanceLog)() ], ProjectService.prototype, "extractTemplate", null); __decorate([ (0, decorators_2.performanceLog)() ], ProjectService.prototype, "ensureAppResourcesExist", null); __decorate([ (0, decorators_2.performanceLog)() ], ProjectService.prototype, "alterPackageJsonData", null); yok_1.injector.register("projectService", ProjectService); //# sourceMappingURL=project-service.js.map