diff --git a/lib/services/project-templates-service.ts b/lib/services/project-templates-service.ts index 0e20e8b653..11505972d6 100644 --- a/lib/services/project-templates-service.ts +++ b/lib/services/project-templates-service.ts @@ -1,4 +1,5 @@ import * as path from "path"; +import * as semver from "semver"; import * as constants from "../constants"; import { performanceLog } from "../common/decorators"; import { @@ -9,6 +10,7 @@ import { import { IPackageInstallationManager, INodePackageManager, + IStaticConfig, } from "../declarations"; import { IFileSystem, @@ -26,7 +28,8 @@ export class ProjectTemplatesService implements IProjectTemplatesService { private $logger: ILogger, private $packageInstallationManager: IPackageInstallationManager, private $pacoteService: IPacoteService, - private $packageManager: INodePackageManager + private $packageManager: INodePackageManager, + private $staticConfig: IStaticConfig ) {} @performanceLog() @@ -45,11 +48,11 @@ export class ProjectTemplatesService implements IProjectTemplatesService { constants.RESERVED_TEMPLATE_NAMES[templateNameParts.name] || templateNameParts.name; - const version = - templateNameParts.version || - (await this.$packageInstallationManager.getLatestCompatibleVersionSafe( - templateValue - )); + const version = await this.getDesiredVersion( + templateValue, + templateNameParts.version + ); + const fullTemplateName = await this.$packageManager.getPackageFullName({ name: templateValue, version: version, @@ -116,5 +119,25 @@ export class ProjectTemplatesService implements IProjectTemplatesService { ); } } + + private async getDesiredVersion( + templateName: string, + defaultVersion?: string + ) { + if (defaultVersion) { + return defaultVersion; + } + + try { + const cliMajorVersion = semver.parse( + semver.coerce(this.$staticConfig.version) + ).major; + return `^${cliMajorVersion}.0.0`; + } catch (err) { + return this.$packageInstallationManager.getLatestCompatibleVersionSafe( + templateName + ); + } + } } injector.register("projectTemplatesService", ProjectTemplatesService); diff --git a/test/project-templates-service.ts b/test/project-templates-service.ts index cde26f30d7..10abc12520 100644 --- a/test/project-templates-service.ts +++ b/test/project-templates-service.ts @@ -16,7 +16,6 @@ import { IAnalyticsService, IFileSystem } from "../lib/common/declarations"; import { IEventActionData } from "../lib/common/definitions/google-analytics"; const nativeScriptValidatedTemplatePath = "nsValidatedTemplatePath"; -const compatibleTemplateVersion = "1.2.3"; function createTestInjector( configuration: { @@ -33,6 +32,7 @@ function createTestInjector( exists: (pathToCheck: string) => false, readJson: (pathToFile: string) => configuration.packageJsonContent || {}, }); + injector.register("staticConfig", { version: "8.0.0" }); class NpmStub extends stubs.NodePackageManagerStub { public async install( @@ -70,9 +70,6 @@ function createTestInjector( return Promise.resolve(nativeScriptValidatedTemplatePath); } - async getLatestCompatibleVersionSafe(packageName: string): Promise { - return compatibleTemplateVersion; - } } injector.register("packageInstallationManager", NpmInstallationManagerStub); @@ -275,7 +272,7 @@ describe("project-templates-service", () => { { name: "is correct when scoped package name without version is passed", templateName: "@nativescript/vue-template", - expectedVersion: compatibleTemplateVersion, + expectedVersion: "^8.0.0", expectedTemplateName: "@nativescript/vue-template", }, {