Skip to content

Commit

Permalink
feat(templatesList): add templates list for stable and experimental f…
Browse files Browse the repository at this point in the history
…or interactive choices

- add template types and enum
- add conditional template selection
- fix src/new/cli.ts bad eol
  • Loading branch information
joaoneto committed Aug 23, 2023
1 parent 6a79b21 commit c37ca63
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 39 deletions.
1 change: 1 addition & 0 deletions src/@types/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./config";
export * from "./template";
10 changes: 10 additions & 0 deletions src/@types/template.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export enum TemplateEnum {
OPINIONATED = "opinionated",
NON_OPINIONATED = "non-opinionated"
}

export interface Template {
name: TemplateEnum;
description: string;
path: string;
}
5 changes: 4 additions & 1 deletion src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ yargs(hideBin(process.argv))
.example("$0 new expressots-demo -d ./", "Create interactively with path")
.example("$0 new expressots-demo -p yarn -t opinionated", "Create silently")
.example("$0 new expressots-demo -p yarn -t opinionated -d ./", "Create silently with path")
.example("$0 new expressots-demo -p yarn -t opinionated --experimental", "Create with experimental swc build system")
.example(
"$0 new expressots-demo -p yarn -t opinionated --experimental",
"Create using experimental, not battle-tested, features of ExpressoTS",
)
.example("$0 generate service user-create", "Scaffold a service")
.example("$0 info", "Show CLI details")
.demandCommand(1, "You need at least one command before moving on")
Expand Down
20 changes: 4 additions & 16 deletions src/new/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Argv, CommandModule } from "yargs";
import { projectForm } from "./form";

type CommandModuleArgs = {};

const createProject = (): CommandModule<CommandModuleArgs, any> => {
return {
command: "new <project-name> [package-manager] [template] [directory] [experimental]",
Expand Down Expand Up @@ -31,7 +31,7 @@ const createProject = (): CommandModule<CommandModuleArgs, any> => {
alias: "d",
})
.option("experimental", {
describe: "Use experimental traspile with swc",
describe: "Use experimental, not battle-tested, features of ExpressoTS",
type: "boolean",
default: false,
})
Expand All @@ -40,22 +40,10 @@ const createProject = (): CommandModule<CommandModuleArgs, any> => {

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 };

46 changes: 24 additions & 22 deletions src/new/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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",
Expand All @@ -90,7 +87,7 @@ const projectForm = async (projectName: string, args: any[]): Promise<void> => {
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;

Expand All @@ -101,7 +98,7 @@ const projectForm = async (projectName: string, args: any[]): Promise<void> => {
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 {
Expand All @@ -114,7 +111,7 @@ const projectForm = async (projectName: string, args: any[]): Promise<void> => {
answer = {
name: projectName,
packageManager: packageManager,
template: Template[template],
template: template,
experimental: experimental,
confirm: true,
};
Expand All @@ -135,20 +132,25 @@ const projectForm = async (projectName: string, args: any[]): Promise<void> => {
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",
Expand All @@ -169,9 +171,9 @@ const projectForm = async (projectName: string, args: any[]): Promise<void> => {
}

// Hashmap of templates and their directories
const templates: Record<string, unknown> = {
"Non-Opinionated": "non_opinionated",
Opinionated: "opinionated",
const templates: Record<string, TemplateEnum> = {
"Non-Opinionated": TemplateEnum.NON_OPINIONATED,
Opinionated: TemplateEnum.OPINIONATED,
};

if (answer.confirm) {
Expand All @@ -194,9 +196,9 @@ const projectForm = async (projectName: string, args: any[]): Promise<void> => {

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) {
Expand Down
30 changes: 30 additions & 0 deletions src/templates-list.ts
Original file line number Diff line number Diff line change
@@ -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 };

0 comments on commit c37ca63

Please sign in to comment.