diff --git a/src/@types/index.ts b/src/@types/index.ts index 5c62e04..2267c20 100644 --- a/src/@types/index.ts +++ b/src/@types/index.ts @@ -1 +1,2 @@ export * from "./config"; +export * from "./template"; diff --git a/src/@types/template.ts b/src/@types/template.ts new file mode 100644 index 0000000..5b79a74 --- /dev/null +++ b/src/@types/template.ts @@ -0,0 +1,10 @@ +export enum TemplateEnum { + OPINIONATED = "opinionated", + NON_OPINIONATED = "non-opinionated" +} + +export interface Template { + name: TemplateEnum; + description: string; + path: string; +} \ No newline at end of file diff --git a/src/new/cli.ts b/src/new/cli.ts index 91e3129..ccd9426 100644 --- a/src/new/cli.ts +++ b/src/new/cli.ts @@ -2,7 +2,7 @@ import { Argv, CommandModule } from "yargs"; import { projectForm } from "./form"; type CommandModuleArgs = {}; - + const createProject = (): CommandModule => { return { command: "new [package-manager] [template] [directory] [experimental]", @@ -31,7 +31,7 @@ const createProject = (): CommandModule => { alias: "d", }) .option("experimental", { - describe: "Use experimental traspile with swc", + describe: "Use experimental, not battle-tested, features of ExpressoTS", type: "boolean", default: false, }) @@ -40,22 +40,10 @@ const createProject = (): CommandModule => { return yargs; }, - handler: async ({ - projectName, - packageManager, - template, - directory, - experimental, - }) => { - return await projectForm(projectName, [ - packageManager, - template, - directory, - experimental, - ]); + handler: async ({ projectName, packageManager, template, directory, experimental }) => { + return await projectForm(projectName, [packageManager, template, directory, experimental]); }, }; }; export { createProject }; - \ No newline at end of file diff --git a/src/new/form.ts b/src/new/form.ts index 1e41558..a4a330a 100644 --- a/src/new/form.ts +++ b/src/new/form.ts @@ -7,6 +7,8 @@ import fs from "node:fs"; import path from "node:path"; import { centerText } from "../utils/center-text"; import { printError } from "../utils/cli-ui"; +import { TemplateEnum } from "../@types"; +import templateList from "../templates-list"; async function packageManagerInstall({ packageManager, @@ -75,11 +77,6 @@ function changePackageName({ fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2)); } -enum Template { - "non-opinionated" = "Non-Opinionated :: A simple ExpressoTS project.", - opinionated = "Opinionated :: A complete ExpressoTS project with an opinionated structure and features.", -} - const enum PackageManager { npm = "npm", yarn = "yarn", @@ -90,7 +87,7 @@ const projectForm = async (projectName: string, args: any[]): Promise => { let answer: any; const projName: string = projectName; let packageManager: PackageManager | undefined; - let template: keyof typeof Template | undefined; + let template: TemplateEnum | undefined; let directory: string | undefined; let experimental: boolean; @@ -101,7 +98,7 @@ const projectForm = async (projectName: string, args: any[]): Promise => { if (arg === "npm" || arg === "yarn" || arg === "pnpm") { packageManager = arg as PackageManager; } else if (arg === "non-opinionated" || arg === "opinionated") { - template = arg as keyof typeof Template; + template = arg as TemplateEnum; } else if (arg === true) { experimental = arg; } else { @@ -114,7 +111,7 @@ const projectForm = async (projectName: string, args: any[]): Promise => { answer = { name: projectName, packageManager: packageManager, - template: Template[template], + template: template, experimental: experimental, confirm: true, }; @@ -135,20 +132,25 @@ const projectForm = async (projectName: string, args: any[]): Promise => { message: "Package manager", choices: ["npm", "yarn", "pnpm"], }, + { + type: "confirm", + name: "experimental", + message: "Use experimental, not battle-tested, features of ExpressoTS", + default: false, + }, { type: "list", name: "template", message: "Select a template", - choices: [ - "Non-Opinionated :: A simple ExpressoTS project.", - "Opinionated :: A complete ExpressoTS project with an opinionated structure and features.", - ], + when: ({ experimental }) => !experimental, + choices: templateList.stable.map(({ description }) => description), }, { - type: "confirm", - name: "experimental", - message: "Use experimental traspile with swc", - default: false + type: "list", + name: "template", + message: "Select a experimental template", + when: ({ experimental }) => experimental, + choices: templateList.experimental.map(({ description }) => description), }, { type: "confirm", @@ -169,9 +171,9 @@ const projectForm = async (projectName: string, args: any[]): Promise => { } // Hashmap of templates and their directories - const templates: Record = { - "Non-Opinionated": "non_opinionated", - Opinionated: "opinionated", + const templates: Record = { + "Non-Opinionated": TemplateEnum.NON_OPINIONATED, + Opinionated: TemplateEnum.OPINIONATED, }; if (answer.confirm) { @@ -194,9 +196,9 @@ const projectForm = async (projectName: string, args: any[]): Promise => { try { // @todo: new templates, see expressots/expressots PR #79 - const emitter = experimental - ? degit(`expressots/expressots/templates/experimental/${templates[template]}`) - : degit(`expressots/expressots/templates/${templates[template]}`); + const stability = answer.experimental ? "experimental" : "stable"; + const { path } = templateList[stability].find((item) => (item.name = templates[template])); + const emitter = degit(path); await emitter.clone(answer.name); } catch (err: any) { diff --git a/src/templates-list.ts b/src/templates-list.ts new file mode 100644 index 0000000..97ff5b4 --- /dev/null +++ b/src/templates-list.ts @@ -0,0 +1,30 @@ +import { TemplateEnum, Template } from "./@types"; + +const stable: Template[] = [ + { + name: TemplateEnum.OPINIONATED, + description: "Non-Opinionated :: A simple ExpressoTS project.", + path: "expressots/expressots/templates/non_opinionated", + }, + { + name: TemplateEnum.NON_OPINIONATED, + description: "Opinionated :: A complete ExpressoTS project with an opinionated structure and features.", + path: "expressots/expressots/templates/opinionated", + }, +]; + +const experimental: Template[] = [ + { + name: TemplateEnum.OPINIONATED, + description: "Non-Opinionated :: EXPERIMENTAL BUILD - A simple ExpressoTS project.", + path: "expressots/expressots/templates/experimental/non_opinionated", + }, + { + name: TemplateEnum.NON_OPINIONATED, + description: + "Opinionated :: EXPERIMENTAL BUILD - A complete ExpressoTS project with an opinionated structure and features.", + path: "expressots/expressots/templates/experimental/opinionated", + }, +]; + +export default { stable, experimental };