UNPKG

@veecode-platform/safira-cli

Version:

Generate a microservice project from your spec.

355 lines (354 loc) 18.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const core_1 = require("@oclif/core"); const color_1 = tslib_1.__importDefault(require("@oclif/color")); const inquirer_1 = tslib_1.__importDefault(require("inquirer")); const database_enum_1 = require("../../database/database-enum"); const database_utils_1 = require("../../database/database-utils"); const spec_discovery_exception_1 = require("../../exception/spec-discovery-exception"); const generate_project_1 = require("../../generate/generate-project"); const java_framework_enum_1 = require("../../generate/java/java-framework-enum"); const java_version_1 = require("../../generate/java/java-version"); const package_manager_enum_1 = require("../../generate/java/package-manager-enum"); const git_commands_1 = require("../../git/git-commands"); const language_support_1 = require("../../language-support"); const properties = tslib_1.__importStar(require("../../properties.json")); const spec_discovery_1 = require("../../safira-globals/spec-discovery"); const safira_utils_1 = require("../../safira-project/safira-utils"); const constants_1 = require("../../utils/commands/constants"); const file_system_utils_1 = require("../../utils/file-system-utils"); const url_utils_1 = require("../../utils/url-utils"); const code_quarkus_service_1 = require("../../generate/java/quarkus/code-quarkus-service"); const exit_codes_1 = require("../../command/exit-codes"); class ProjectNew extends core_1.Command { async run() { const { args, flags } = await this.parse(ProjectNew); const currentPath = file_system_utils_1.FileSystemUtils.getCurrentPath(); const projectName = file_system_utils_1.FileSystemUtils.getHighFolderFromPath(currentPath); if (projectName !== projectName.toLocaleLowerCase()) { console.log(color_1.default.bold.yellow("Consider rename your project to lowercase letters, provide it and try again.")); process.exit(exit_codes_1.ExitCode.operationNotPermitted); } safira_utils_1.SafiraUtils.init(); let openApiFile = ""; try { openApiFile = await spec_discovery_1.SpecDiscovery.discoverSpecs({ projectPath: currentPath }); } catch (error) { if (error instanceof spec_discovery_exception_1.SpecDiscoveryNotFoundException) { console.log(color_1.default.yellow("Insomnia workspace or openapi-swagger.yaml not found in current path.")); const importAnswer = await inquirer_1.default.prompt([{ type: "list", name: "import", message: "Do you want to import it?", choices: constants_1.yesNoList, default: "yes", }, { when: (answers) => answers.import === "yes", type: "input", name: "openapi-file-path", message: "Path to the OpenAPI file:", default: "./openapi-swagger.yaml", validate: (value) => file_system_utils_1.FileSystemUtils.exists(file_system_utils_1.FileSystemUtils.fullPath(value)) ? true : "Please enter a valid path to openapi file", }]); if (importAnswer.import === "no") { console.log(color_1.default.yellow("Please, provide it and try again.")); return; } file_system_utils_1.FileSystemUtils.copyFileSync(importAnswer["openapi-file-path"], `${properties.openapi["spec-name"]}.${properties.openapi.extension}`); openApiFile = `${properties.openapi["spec-name"]}.${properties.openapi.extension}`; } } let answers = await this.showCommonQuestions(args, flags); if (answers["confirm-spec-kong-kubernetes"] === "no") { answers["kong-kubernetes"] = "no"; console.log(color_1.default.yellowBright("The spec does not have Kong for Kubernetes configuration, the configuration will not be generated.")); } const dataBaseAnswer = await this.showDataBaseQuestions(args, flags); if (answers["pull-insomnia-workspace"] === "yes") { try { await git_commands_1.GitCommand.instance.pull(file_system_utils_1.FileSystemUtils.fullPath(answers["insomnia-workspace"])); console.log("pull works"); } catch (error) { this.error(color_1.default.red(error.message)); } } const languageAnswer = Object.keys(language_support_1.LanguageSupportEnum).length > 1 ? await inquirer_1.default.prompt([ { when: !flags.language, type: "list", name: "language", message: "language to use", default: language_support_1.LanguageSupportEnum.java, choices: Object.keys(language_support_1.LanguageSupportEnum), }, ]) : { language: language_support_1.LanguageSupportEnum.java }; if (flags.framework && !flags.language && ["quarkus", "springboot"].includes(flags.framework)) { languageAnswer.language = "java"; } answers = { ...answers, ...languageAnswer }; const language = language_support_1.LanguageSupportEnumHelper.parse(answers.language); const frameworkAnswer = await inquirer_1.default.prompt([ { when: !flags.framework, type: "list", name: "framework", message: "framework to use", choices: language_support_1.LanguageSupportEnumHelper.getLanguageFrameworks(language), }, ]); answers = { ...answers, ...frameworkAnswer, ...dataBaseAnswer }; if (language === language_support_1.LanguageSupportEnum.java) { const framework = java_framework_enum_1.JavaFrameworksEnumHelper.getJavaFrameworksEnumFromString(answers.framework || flags.framework); switch (framework) { case java_framework_enum_1.JavaFrameworksEnum.springboot: answers = { ...answers, ...await this.showSpringBootQuestions(args, flags) }; break; case java_framework_enum_1.JavaFrameworksEnum.quarkus: answers = { ...answers, ...await this.showQuarkusQuestions(args, flags) }; break; default: break; } } const rootProjectPath = (flags["new-project-root"] || answers["new-project-root"] || currentPath)?.trim(); try { core_1.CliUx.ux.action.start("Generating project"); const insomniaPath = (flags["insomnia-workspace"] || answers["insomnia-workspace"])?.trim(); await new generate_project_1.GenerateProjectImpl().newProject({ projectName: projectName, newProjectRoot: rootProjectPath, openapiFilePath: openApiFile, projectDescription: flags["project-description"] || answers["project-description"], language: flags.language || answers.language, framework: flags.framework || answers.framework, javaManagement: package_manager_enum_1.PackageManager[flags["java-pack-manager"] || answers["java-pack-manager"]], javaSpringbootVersion: flags["java-springboot-version"] || answers["java-springboot-version"], javaPackage: (flags["java-package"] || answers["java-package"])?.trim(), javaVersion: flags["java-version"] || answers["java-version"], applicationPort: flags["application-port"] || answers["application-port"], kongKubernetes: (flags["kong-kubernetes"] || answers["kong-kubernetes"]) === "yes", useDataBase: (flags["use-database"] || answers["use-database"]) === "yes", dataBase: database_enum_1.DatabaseEnum[flags.database || answers.database], dataBaseUrl: flags["database-url"] || answers["database-url"], dataBaseUser: flags["database-user"] || answers["database-user"], dataBasePassword: flags["database-password"] || answers["database-password"], quarkusVersion: flags["quarkus-version"] || answers["quarkus-version"], }); } catch (error) { this.log(color_1.default.red(error.message)); core_1.CliUx.ux.action.stop("Failed"); return; } finally { safira_utils_1.SafiraUtils.deleteTmpFolder(); if (core_1.CliUx.ux.action.running) { core_1.CliUx.ux.action.stop(); } } } showCommonQuestions(args, flags) { return inquirer_1.default.prompt([ { when: !flags["project-description"], type: "input", name: "project-description", message: "The description of the new project:", default: "A new project", validate: (value) => value.length > 0 ? true : "Please enter a valid description", }, { when: !flags["application-port"], type: "input", name: "application-port", message: "Application port:", default: "8080", validate: (value) => value > 0 ? true : "Please enter a valid port", }, { when: !flags["kong-kubernetes"], type: "list", name: "kong-kubernetes", message: "Generate Kong for Kubernetes configuration?", choices: constants_1.yesNoList, }, { when: (answers) => (flags["kong-kubernetes"] === "yes" || answers["kong-kubernetes"] === "yes"), type: "list", name: "confirm-spec-kong-kubernetes", message: "The spec have Kong for Kubernetes configuration?", choices: constants_1.yesNoList, }, ]); } showDataBaseQuestions(args, flags) { const choices = database_utils_1.DatabaseUtils.getEnumKeyValueList(); return inquirer_1.default.prompt([ { when: !flags["use-database"], type: "list", name: "use-database", message: "Use database?", choices: constants_1.yesNoList, }, { when: (answers) => (flags["use-database"] === "yes" || answers["use-database"] === "yes") && !flags.database, type: "list", name: "database", message: "Database:", choices: choices, }, { when: (answers) => (flags["use-database"] === "yes" || answers["use-database"] === "yes") && !flags["database-url"], type: "string", name: "database-url", message: "Database URL:", default: "localhost:5432/database", validate: (value) => this._validateDataBaseUrl(value), }, { when: (answers) => (flags["use-database"] === "yes" || answers["use-database"] === "yes") && !flags["database-user"], type: "string", name: "database-user", message: "Database User:", validate: (value) => value.length > 0 ? true : "Please enter a valid user", }, { when: (answers) => (flags["use-database"] === "yes" || answers["use-database"] === "yes") && !flags["database-password"], type: "string", name: "database-password", message: "Database Password:", }, ]); } _validateDataBaseUrl(url) { url = url_utils_1.UrlUtils.removeProtocol(url); const splittedInTwo = url.split(":"); const verifyLocal = splittedInTwo[0]; if (verifyLocal.length === 0 || splittedInTwo.length !== 2) { return "Please enter a valid database URL"; } const splittedInTwoAgain = splittedInTwo[1].split("/"); if (splittedInTwoAgain.length !== 2) { return "Please enter a valid database URL with a port and a database"; } const verifyPort = splittedInTwoAgain[0]; const verifyDataBase = splittedInTwoAgain[1]; if (verifyPort.length === 0) { return "Please enter a valid database URL with a valid port "; } if (verifyDataBase.length === 0) { return "Please enter a valid database URL pointing to a database"; } return true; } showSpringBootQuestions(args, flags) { return inquirer_1.default.prompt([ { when: !flags.language, type: "list", name: "java-version", message: "Java version to use", default: `java${java_version_1.JavaVersion.java11}`, choices: Object.keys(java_version_1.JavaVersion), }, { when: !flags["java-pack-manager"], type: "list", name: "java-pack-manager", message: "java package manager", choices: Object.keys(package_manager_enum_1.PackageManager), }, { when: !flags["java-springboot-version"], type: "input", name: "java-springboot-version", message: "spring boot version", default: "2.5.13", validate: (value) => value.length > 0 ? true : "Please enter a valid Springboot version", }, { when: !flags["java-package"], type: "input", name: "java-package", message: "java package", default: "com.safira.demo", validate: (value) => value.length > 0 ? true : "Please enter a valid Java package", }, ]); } async showQuarkusQuestions(args, flags) { let quarkusVersions = []; try { quarkusVersions = (await code_quarkus_service_1.CodeQuarkusService.instance.getPublicVersions()).map(v => v.key.split(":")[1]); } catch { } return inquirer_1.default.prompt([ { when: !flags["quarkus-version"] && quarkusVersions.length > 0, type: "list", name: "quarkus-version", message: "quarkus version", choices: quarkusVersions, }, { when: !flags.language, type: "list", name: "java-version", message: "Java version to use", default: `java${java_version_1.JavaVersion.java11}`, choices: [java_version_1.JavaVersion.java11, java_version_1.JavaVersion.java17], }, { when: !flags["java-package"], type: "input", name: "java-package", message: "java package", default: "com.safira.demo", validate: (value) => value.length > 0 ? true : "Please enter a valid Java package", }, { when: !flags["java-pack-manager"], type: "list", name: "java-pack-manager", message: "java management", choices: Object.keys(package_manager_enum_1.PackageManager), default: "maven", }, ]); } } exports.default = ProjectNew; ProjectNew.hidden = true; ProjectNew.description = "Create a new project"; ProjectNew.argDescription = "Use '.' to create project into current folder or name of the project to create a new folder.User lowercase letters for the project name."; ProjectNew.examples = [ "<%= config.bin %> <%= command.id %>", "<%= config.bin %> <%= command.id %> app-name", "<%= config.bin %> <%= command.id %> app-name --language java11 --java-pack-manager gradle --application-port 8090", "<%= config.bin %> <%= command.id %> . -create a project in the current folder", ]; ProjectNew.flags = { help: core_1.Flags.help({}), language: core_1.Flags.string({ char: "l", description: "Programming language to use", helpValue: "java" }), framework: core_1.Flags.enum({ char: "f", description: "", options: ["springboot", "quarkus"] }), "project-description": core_1.Flags.string({ description: "The description of the new project." }), "java-pack-manager": core_1.Flags.enum({ description: "Java package management", options: Object.keys(package_manager_enum_1.PackageManager) }), "java-springboot-version": core_1.Flags.string({ description: "Springboot version", helpValue: "2.5.13" }), "java-package": core_1.Flags.string({ description: "Java package", helpValue: "com.safira.demo" }), "java-version": core_1.Flags.enum({ description: "Java version", options: Object.keys(java_version_1.JavaVersion) }), "application-port": core_1.Flags.integer({ description: "Application port", helpValue: "8080" }), "kong-kubernetes": core_1.Flags.enum({ description: "Generate Kong for Kubernetes configuration", options: constants_1.yesNoList }), "use-database": core_1.Flags.enum({ description: "Use database", options: constants_1.yesNoList }), database: core_1.Flags.enum({ description: "The database provider", options: Object.keys(database_enum_1.DatabaseEnum) }), "database-url": core_1.Flags.string({ description: "The url of the database", helpValue: "localhost:5432/database" }), "database-user": core_1.Flags.string({ description: "The user of the database", helpValue: "User" }), "database-password": core_1.Flags.string({ description: "The password of the database", helpValue: "password123" }), "export-spec": core_1.Flags.enum({ description: "Export spec", options: constants_1.yesNoList }), "quarkus-version": core_1.Flags.string({ description: "Quarkus version" }), }; ProjectNew.args = [];