Skip to content

fix: unable to create project from scoped package template #3933

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lib/definitions/project.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,11 @@ interface ITemplateData {
* The whole content of package.json file
*/
templatePackageJsonContent: ITemplatePackageJsonContent;

/**
* The version of the package used for creating the application.
*/
version: string;
}

interface ITemplatePackageJsonContent extends IBasePluginData {
Expand Down
14 changes: 11 additions & 3 deletions lib/services/project-templates-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,16 @@ export class ProjectTemplatesService implements IProjectTemplatesService {
originalTemplateName = constants.RESERVED_TEMPLATE_NAMES["default"];
}

// support <reserved_name>@<version> syntax
const [name, version] = originalTemplateName.split("@");
// support <reserved_name>@<version> syntax, for example [email protected]
// support <scoped_package_name>@<version> syntax, for example @nativescript/[email protected]
const lastIndexOfAtSign = originalTemplateName.lastIndexOf("@");
let name = originalTemplateName;
let version = "";
if (lastIndexOfAtSign > 0) {
name = originalTemplateName.substr(0, lastIndexOfAtSign);
version = originalTemplateName.substr(lastIndexOfAtSign + 1);
}

const templateName = constants.RESERVED_TEMPLATE_NAMES[name.toLowerCase()] || name;
const fullTemplateName = version ? `${templateName}@${version}` : templateName;
const templatePackageJsonContent = await this.getTemplatePackageJsonContent(fullTemplateName);
Expand Down Expand Up @@ -49,7 +57,7 @@ export class ProjectTemplatesService implements IProjectTemplatesService {
});
}

return { templateName, templatePath, templateVersion, templatePackageJsonContent };
return { templateName, templatePath, templateVersion, templatePackageJsonContent, version };
}

private async getTemplateVersion(templateName: string): Promise<string> {
Expand Down
37 changes: 37 additions & 0 deletions test/project-templates-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,5 +220,42 @@ describe("project-templates-service", () => {
});

});

describe("uses correct version", () => {
[
{
name: "is correct when package version is passed",
templateName: "[email protected]",
expectedVersion: "1.0.0",
expectedTemplateName: "some-template"
},
{
name: "is correct when reserved package name with version is passed",
templateName: "[email protected]",
expectedVersion: "1.0.0",
expectedTemplateName: "tns-template-hello-world-ts"
},
{
name: "is correct when scoped package name without version is passed",
templateName: "@nativescript/vue-template",
expectedVersion: "",
expectedTemplateName: "@nativescript/vue-template"
},
{
name: "is correct when scoped package name with version is passed",
templateName: "@nativescript/[email protected]",
expectedVersion: "1.0.0",
expectedTemplateName: "@nativescript/vue-template"
}
].forEach(testCase => {
it(testCase.name, async () => {
const testInjector = createTestInjector();
const projectTemplatesService = testInjector.resolve<IProjectTemplatesService>("projectTemplatesService");
const { version, templateName } = await projectTemplatesService.prepareTemplate(testCase.templateName, "tempFolder");
assert.strictEqual(version, testCase.expectedVersion);
assert.strictEqual(templateName, testCase.expectedTemplateName);
});
});
});
});
});