nativescript
Version:
Command-line interface for building NativeScript projects
423 lines • 18.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CreateProjectCommand = void 0;
const constants = require("../constants");
const path = require("path");
const helpers_1 = require("../common/helpers");
const yok_1 = require("../common/yok");
const color_1 = require("../color");
class CreateProjectCommand {
constructor($projectService, $logger, $errors, $options, $prompter, $stringParameter) {
this.$projectService = $projectService;
this.$logger = $logger;
this.$errors = $errors;
this.$options = $options;
this.$prompter = $prompter;
this.$stringParameter = $stringParameter;
this.enableHooks = false;
this.allowedParameters = [this.$stringParameter];
this.isInteractionIntroShown = false;
}
async execute(args) {
const interactiveAdverbs = ["First", "Next", "Finally"];
const getNextInteractiveAdverb = () => {
return interactiveAdverbs.shift() || "Next";
};
if ((this.$options.tsc ||
this.$options.ng ||
this.$options.vue ||
this.$options.react ||
this.$options.solid ||
this.$options.svelte ||
this.$options.js) &&
this.$options.template) {
this.$errors.failWithHelp("You cannot use a flavor option like --ng, --vue, --react, --solid, --svelte, --tsc and --js together with --template.");
}
let projectName = args[0];
let selectedTemplate;
if (this.$options["vision-ng"] ||
(this.$options.vision && this.$options.ng)) {
selectedTemplate = constants.RESERVED_TEMPLATE_NAMES["vision-ng"];
}
else if (this.$options["vision-react"] ||
(this.$options.vision && this.$options.react)) {
selectedTemplate = constants.RESERVED_TEMPLATE_NAMES["vision-react"];
}
else if (this.$options["vision-solid"] ||
(this.$options.vision && this.$options.solid)) {
selectedTemplate = constants.RESERVED_TEMPLATE_NAMES["vision-solid"];
}
else if (this.$options["vision-svelte"] ||
(this.$options.vision && this.$options.svelte)) {
selectedTemplate = constants.RESERVED_TEMPLATE_NAMES["vision-svelte"];
}
else if (this.$options["vision-vue"] ||
(this.$options.vision && (this.$options.vue || this.$options.vuejs))) {
selectedTemplate = constants.RESERVED_TEMPLATE_NAMES["vision-vue"];
}
else if ((this.$options.vue || this.$options.vuejs) &&
this.$options.tsc) {
selectedTemplate = "@nativescript/template-blank-vue-ts";
}
else if (this.$options.vision) {
selectedTemplate = constants.RESERVED_TEMPLATE_NAMES["vision"];
}
else if (this.$options.js) {
selectedTemplate = constants.JAVASCRIPT_NAME;
}
else if (this.$options.tsc) {
selectedTemplate = constants.TYPESCRIPT_NAME;
}
else if (this.$options.ng) {
selectedTemplate = constants.ANGULAR_NAME;
}
else if (this.$options.vue || this.$options.vuejs) {
selectedTemplate = constants.VUE_NAME;
}
else if (this.$options.solid) {
selectedTemplate = constants.SOLID_NAME;
}
else if (this.$options.react) {
selectedTemplate = constants.REACT_NAME;
}
else if (this.$options.svelte) {
selectedTemplate = constants.SVELTE_NAME;
}
else {
selectedTemplate = this.$options.template;
}
if (!projectName && (0, helpers_1.isInteractive)()) {
this.printInteractiveCreationIntroIfNeeded();
projectName = await this.$prompter.getString(`${getNextInteractiveAdverb()}, what will be the name of your app?`, { allowEmpty: false });
this.$logger.info();
}
projectName = await this.$projectService.validateProjectName({
projectName: projectName,
force: this.$options.force,
pathToProject: this.$options.path,
});
if (!selectedTemplate && (0, helpers_1.isInteractive)()) {
this.printInteractiveCreationIntroIfNeeded();
selectedTemplate = await this.interactiveFlavorAndTemplateSelection(getNextInteractiveAdverb(), getNextInteractiveAdverb());
}
this.createdProjectData = await this.$projectService.createProject({
projectName: projectName,
template: selectedTemplate,
appId: this.$options.appid,
pathToProject: this.$options.path,
// its already validated above
force: true,
ignoreScripts: this.$options.ignoreScripts,
});
}
async interactiveFlavorAndTemplateSelection(flavorAdverb, templateAdverb) {
const selectedFlavor = await this.interactiveFlavorSelection(flavorAdverb);
const selectedTemplate = await this.interactiveTemplateSelection(selectedFlavor, templateAdverb);
return selectedTemplate;
}
async interactiveFlavorSelection(adverb) {
const flavorSelection = await this.$prompter.promptForDetailedChoice(`${adverb}, which style of NativeScript project would you like to use:`, [
{
key: constants.NgFlavorName,
description: "Learn more at https://nativescript.org/angular",
},
{
key: constants.ReactFlavorName,
description: "Learn more at https://github.com/shirakaba/react-nativescript",
},
{
key: constants.VueFlavorName,
description: "Learn more at https://nativescript.org/vue",
},
{
key: constants.SolidFlavorName,
description: "Learn more at https://www.solidjs.com",
},
{
key: constants.SvelteFlavorName,
description: "Learn more at https://svelte-native.technology",
},
{
key: constants.TsFlavorName,
description: "Learn more at https://nativescript.org/typescript",
},
{
key: constants.JsFlavorName,
description: "Use NativeScript without any framework",
},
]);
return flavorSelection;
}
printInteractiveCreationIntroIfNeeded() {
if (!this.isInteractionIntroShown) {
this.isInteractionIntroShown = true;
this.$logger.info();
this.$logger.printMarkdown(`# Let’s create a NativeScript app!`);
this.$logger.printMarkdown(`
Answer the following questions to help us build the right app for you. (Note: you
can skip this prompt next time using the --template option, or using --ng, --react, --solid, --svelte, --vue, --ts, or --js flags.)
`);
}
}
async interactiveTemplateSelection(flavorSelection, adverb) {
const selectedFlavorTemplates = [];
let selectedTemplate;
switch (flavorSelection) {
case constants.NgFlavorName: {
selectedFlavorTemplates.push(...this.getNgTemplates());
break;
}
case constants.ReactFlavorName: {
selectedFlavorTemplates.push(...this.getReactTemplates());
break;
}
case constants.VueFlavorName: {
selectedFlavorTemplates.push(...this.getVueTemplates());
break;
}
case constants.SolidFlavorName: {
selectedFlavorTemplates.push(...this.getSolidTemplates());
break;
}
case constants.SvelteFlavorName: {
selectedFlavorTemplates.push(...this.getSvelteTemplates());
break;
}
case constants.TsFlavorName: {
selectedFlavorTemplates.push(...this.getTsTemplates());
break;
}
case constants.JsFlavorName: {
selectedFlavorTemplates.push(...this.getJsTemplates());
break;
}
}
if (selectedFlavorTemplates.length > 1) {
this.$logger.info();
const templateChoices = selectedFlavorTemplates.map((template) => {
return { key: template.key, description: template.description };
});
const selectedTemplateKey = await this.$prompter.promptForDetailedChoice(`${adverb}, which template would you like to start from:`, templateChoices);
selectedTemplate = selectedFlavorTemplates.find((t) => t.key === selectedTemplateKey).value;
}
else {
selectedTemplate = selectedFlavorTemplates[0].value;
}
return selectedTemplate;
}
getJsTemplates() {
const templates = [
{
key: CreateProjectCommand.HelloWorldTemplateKey,
value: constants.RESERVED_TEMPLATE_NAMES.javascript,
description: CreateProjectCommand.HelloWorldTemplateDescription,
},
{
key: CreateProjectCommand.DrawerTemplateKey,
value: "@nativescript/template-drawer-navigation",
description: CreateProjectCommand.DrawerTemplateDescription,
},
{
key: CreateProjectCommand.TabsTemplateKey,
value: "@nativescript/template-tab-navigation",
description: CreateProjectCommand.TabsTemplateDescription,
},
];
return templates;
}
getTsTemplates() {
const templates = [
{
key: CreateProjectCommand.HelloWorldTemplateKey,
value: constants.RESERVED_TEMPLATE_NAMES.typescript,
description: CreateProjectCommand.HelloWorldTemplateDescription,
},
{
key: CreateProjectCommand.DrawerTemplateKey,
value: "@nativescript/template-drawer-navigation-ts",
description: CreateProjectCommand.DrawerTemplateDescription,
},
{
key: CreateProjectCommand.TabsTemplateKey,
value: "@nativescript/template-tab-navigation-ts",
description: CreateProjectCommand.TabsTemplateDescription,
},
{
key: CreateProjectCommand.BlankVisionTemplateKey,
value: "@nativescript/template-hello-world-ts-vision",
description: CreateProjectCommand.BlankVisionTemplateDescription,
},
];
return templates;
}
getNgTemplates() {
const templates = [
{
key: CreateProjectCommand.HelloWorldTemplateKey,
value: constants.RESERVED_TEMPLATE_NAMES.angular,
description: CreateProjectCommand.HelloWorldTemplateDescription,
},
{
key: CreateProjectCommand.DrawerTemplateKey,
value: "@nativescript/template-drawer-navigation-ng",
description: CreateProjectCommand.DrawerTemplateDescription,
},
{
key: CreateProjectCommand.TabsTemplateKey,
value: "@nativescript/template-tab-navigation-ng",
description: CreateProjectCommand.TabsTemplateDescription,
},
{
key: CreateProjectCommand.BlankVisionTemplateKey,
value: "@nativescript/template-hello-world-ng-vision",
description: CreateProjectCommand.BlankVisionTemplateDescription,
},
];
return templates;
}
getReactTemplates() {
const templates = [
{
key: CreateProjectCommand.HelloWorldTemplateKey,
value: constants.RESERVED_TEMPLATE_NAMES.react,
description: CreateProjectCommand.HelloWorldTemplateDescription,
},
{
key: CreateProjectCommand.BlankVisionTemplateKey,
value: "@nativescript/template-blank-react-vision",
description: CreateProjectCommand.BlankVisionTemplateDescription,
},
];
return templates;
}
getSolidTemplates() {
const templates = [
{
key: CreateProjectCommand.HelloWorldTemplateKey,
value: constants.RESERVED_TEMPLATE_NAMES.solid,
description: CreateProjectCommand.HelloWorldTemplateDescription,
},
{
key: `${CreateProjectCommand.HelloWorldTemplateKey} using TypeScript`,
value: constants.RESERVED_TEMPLATE_NAMES.solidts,
description: `${CreateProjectCommand.HelloWorldTemplateDescription} using TypeScript`,
},
{
key: CreateProjectCommand.BlankVisionTemplateKey,
value: "@nativescript/template-blank-solid-vision",
description: CreateProjectCommand.BlankVisionTemplateDescription,
},
];
return templates;
}
getSvelteTemplates() {
const templates = [
{
key: CreateProjectCommand.HelloWorldTemplateKey,
value: constants.RESERVED_TEMPLATE_NAMES.svelte,
description: CreateProjectCommand.HelloWorldTemplateDescription,
},
{
key: CreateProjectCommand.BlankVisionTemplateKey,
value: "@nativescript/template-blank-svelte-vision",
description: CreateProjectCommand.BlankVisionTemplateDescription,
},
];
return templates;
}
getVueTemplates() {
const templates = [
{
key: CreateProjectCommand.BlankTemplateKey,
value: "@nativescript/template-blank-vue",
description: CreateProjectCommand.BlankTemplateDescription,
},
{
key: CreateProjectCommand.BlankTsTemplateKey,
value: "@nativescript/template-blank-vue-ts",
description: CreateProjectCommand.BlankTsTemplateDescription,
},
{
key: CreateProjectCommand.DrawerTemplateKey,
value: "@nativescript/template-drawer-navigation-vue",
description: CreateProjectCommand.DrawerTemplateDescription,
},
{
key: CreateProjectCommand.TabsTemplateKey,
value: "@nativescript/template-tab-navigation-vue",
description: CreateProjectCommand.TabsTemplateDescription,
},
{
key: CreateProjectCommand.BlankVisionTemplateKey,
value: "@nativescript/template-blank-vue-vision",
description: CreateProjectCommand.BlankVisionTemplateDescription,
},
];
return templates;
}
async postCommandAction(args) {
const { projectDir, projectName } = this.createdProjectData;
const relativePath = path.relative(process.cwd(), projectDir);
const greyDollarSign = color_1.color.grey("$");
this.$logger.clearScreen();
let runDebugNotes = [];
if (this.$options.vision ||
this.$options["vision-ng"] ||
this.$options["vision-react"] ||
this.$options["vision-solid"] ||
this.$options["vision-svelte"] ||
this.$options["vision-vue"]) {
runDebugNotes = [
`Run the project on Vision Pro with:`,
"",
` ${greyDollarSign} ${color_1.color.green("ns run visionos --no-hmr")}`,
];
}
else {
runDebugNotes = [
`Run the project on multiple devices:`,
"",
` ${greyDollarSign} ${color_1.color.green("ns run ios")}`,
` ${greyDollarSign} ${color_1.color.green("ns run android")}`,
"",
"Debug the project with Chrome DevTools:",
"",
` ${greyDollarSign} ${color_1.color.green("ns debug ios")}`,
` ${greyDollarSign} ${color_1.color.green("ns debug android")}`,
];
}
this.$logger.info([
[
color_1.color.green(`Project`),
color_1.color.cyan(projectName),
color_1.color.green(`was successfully created.`),
].join(" "),
"",
`Now you can navigate to your project with ${color_1.color.cyan(`cd ${relativePath}`)} and then:`,
"",
...runDebugNotes,
``,
`For more options consult the docs or run ${color_1.color.green("ns --help")}`,
"",
].join("\n"));
// todo: add back ns preview
// this.$logger.printMarkdown(
// `After that you can preview it on device by executing \`$ ns preview\``
// );
}
}
exports.CreateProjectCommand = CreateProjectCommand;
CreateProjectCommand.BlankTemplateKey = "Blank";
CreateProjectCommand.BlankTemplateDescription = "A blank app";
CreateProjectCommand.BlankTsTemplateKey = "Blank Typescript";
CreateProjectCommand.BlankTsTemplateDescription = "A blank typescript app";
CreateProjectCommand.BlankVisionTemplateKey = "visionOS";
CreateProjectCommand.BlankVisionTemplateDescription = "A visionOS app";
CreateProjectCommand.HelloWorldTemplateKey = "Hello World";
CreateProjectCommand.HelloWorldTemplateDescription = "A Hello World app";
CreateProjectCommand.DrawerTemplateKey = "SideDrawer";
CreateProjectCommand.DrawerTemplateDescription = "An app with pre-built pages that uses a drawer for navigation";
CreateProjectCommand.TabsTemplateKey = "Tabs";
CreateProjectCommand.TabsTemplateDescription = "An app with pre-built pages that uses tabs for navigation";
yok_1.injector.registerCommand("create", CreateProjectCommand);
//# sourceMappingURL=create-project.js.map