UNPKG

@tsed/cli

Version:
251 lines (250 loc) 9.98 kB
var GenerateCmd_1; import { __decorate, __metadata } from "tslib"; import { basename, dirname, join } from "node:path"; import { Command, Inject, inject, ProjectPackageJson } from "@tsed/cli-core"; import { normalizePath } from "@tsed/normalize-path"; import { kebabCase, pascalCase } from "change-case"; import { globbySync } from "globby"; import { ProjectConvention } from "../../interfaces/ProjectConvention.js"; import { ClassNamePipe } from "../../pipes/ClassNamePipe.js"; import { OutputFilePathPipe } from "../../pipes/OutputFilePathPipe.js"; import { RoutePipe } from "../../pipes/RoutePipe.js"; import { ProvidersInfoService } from "../../services/ProvidersInfoService.js"; import { SrcRendererService } from "../../services/Renderer.js"; import { fillImports } from "../../utils/fillImports.js"; import { getFrameworksPrompt } from "../init/prompts/getFeaturesPrompt.js"; import { PROVIDER_TYPES } from "./ProviderTypes.js"; const DECORATOR_TYPES = [ { name: "Class decorator", value: "class" }, { name: "Ts.ED middleware and its decorator", value: "middleware" }, { name: "Ts.ED endpoint decorator", value: "endpoint" }, { name: "Ts.ED property decorator", value: "prop" }, { name: "Ts.ED parameter decorator", value: "param" }, { name: "Vanilla Method decorator", value: "method" }, { name: "Vanilla Property decorator", value: "property" }, { name: "Vanilla Parameter decorator", value: "parameter" }, { name: "Generic decorator", value: "generic" } ]; const searchFactory = (list) => { return (state, keyword) => { if (keyword) { return list.filter((item) => item.name.toLowerCase().includes(keyword.toLowerCase())); } return list; }; }; let GenerateCmd = GenerateCmd_1 = class GenerateCmd { constructor(providersList) { this.providersList = providersList; this.srcRenderService = inject(SrcRendererService); this.projectPackageJson = inject(ProjectPackageJson); PROVIDER_TYPES.forEach((info) => { this.providersList.add({ ...info }, GenerateCmd_1); }); } $prompt(initialOptions) { const getName = (state) => initialOptions.name || pascalCase(state.name || initialOptions.name || state.type || initialOptions.type); const proposedProviders = this.providersList.findProviders(initialOptions.type); return [ { type: "autocomplete", name: "type", message: "Which type of provider?", default: initialOptions.type, when: () => proposedProviders.length > 1, source: searchFactory(proposedProviders) }, { type: "input", name: "name", message: "Which name?", default: getName, when: !initialOptions.name }, { ...getFrameworksPrompt(), message: "Which platform?", type: "list", name: "platform", when(state) { return ["server"].includes(state.type || initialOptions.type); } }, { type: "input", name: "route", message: "Which route?", when(state) { return !!(["controller", "server"].includes(state.type || initialOptions.type) || initialOptions.route); }, default: (state) => { return state.type === "server" ? "/rest" : this.routePipe.transform(getName(state)); } }, { type: "list", name: "directory", message: "Which directory?", when(state) { return ["controller"].includes(state.type || initialOptions.type) || initialOptions.directory; }, choices: this.getDirectories("controllers") }, { type: "autocomplete", name: "templateType", message: (state) => `Which type of ${state.type || initialOptions.type}?`, when(state) { return !!(["decorator"].includes(state.type || initialOptions.type) || initialOptions.templateType); }, source: searchFactory(DECORATOR_TYPES) }, { type: "list", name: "middlewarePosition", message: () => `The middleware should be called:`, choices: [ { name: "Before the endpoint", value: "before" }, { name: "After the endpoint", value: "after" } ], when(state) { return !!((["decorator"].includes(state.type || initialOptions.type) && ["middleware"].includes(state.templateType)) || initialOptions.middlewarePosition); } } ]; } $mapContext(ctx) { const { name = "" } = ctx; let { type = "" } = ctx; type = type.toLowerCase(); if (ctx.name === "prisma" && ctx.name) { type = "prisma.service"; } const symbolName = this.classNamePipe.transform({ name, type, format: ProjectConvention.DEFAULT }); const symbolParamName = kebabCase(symbolName); return fillImports({ ...ctx, type, route: ctx.route ? this.routePipe.transform(ctx.route) : "", symbolName, symbolParamName, symbolPath: normalizePath(this.outputFilePathPipe.transform({ name, type, subDir: ctx.directory })), symbolPathBasename: normalizePath(this.classNamePipe.transform({ name, type })), platformSymbol: ctx.platform && pascalCase(`Platform ${ctx.platform}`) }); } $exec(ctx) { const { symbolPath } = ctx; if (this.providersList.isMyProvider(ctx.type, GenerateCmd_1)) { const type = [ctx.type, ctx.templateType].filter(Boolean).join("."); let template = `generate/${type}.hbs`; if (ctx.type === "server") { template = `generate/server/${ctx.platform}/server.hbs`; } return [ { title: `Generate ${ctx.type} file to '${symbolPath}.ts'`, task: () => { if (ctx.type === "server") { return this.srcRenderService.render(template, ctx, { baseDir: "generate", basename: `${symbolPath}.ts`, replaces: [`server/${ctx.platform}`] }); } return this.srcRenderService.render(template, ctx, { output: `${symbolPath}.ts` }); } }, { title: `Update bin/index`, skip() { return ctx.type !== "command"; }, task: () => { return this.srcRenderService.update("bin/index.ts", [ { type: "import", content: `import {${ctx.symbolName}} from "./${basename(symbolPath)}.js";` }, { type: "insert-after", pattern: /commands: \[/, content: ` ${ctx.symbolName}` } ]); } } ]; } return []; } getDirectories(dir) { const directories = globbySync("**/*", { cwd: join(this.srcRenderService.rootDir, dir), ignore: ["__*"] }); const set = new Set(directories.map((dir) => { return dirname(dir); })); set.delete("."); return [...set]; } }; __decorate([ Inject(), __metadata("design:type", ClassNamePipe) ], GenerateCmd.prototype, "classNamePipe", void 0); __decorate([ Inject(), __metadata("design:type", OutputFilePathPipe) ], GenerateCmd.prototype, "outputFilePathPipe", void 0); __decorate([ Inject(), __metadata("design:type", RoutePipe) ], GenerateCmd.prototype, "routePipe", void 0); GenerateCmd = GenerateCmd_1 = __decorate([ Command({ name: "generate", alias: "g", description: "Generate a new provider class", args: { type: { description: "Type of the provider (Injectable, Controller, Pipe, etc...)", type: String }, name: { description: "Name of the class", type: String } }, options: { "--route <route>": { type: String, description: "The route for the controller generated file" }, "-d, --directory <directory>": { description: "Directory where the file must be generated", type: String }, "-t, --template-type <templateType>": { description: "Directory where the file must be generated", type: String }, "-m, --middleware-position <templateType>": { description: "Middleware position (before, after)", type: String } } }), __metadata("design:paramtypes", [ProvidersInfoService]) ], GenerateCmd); export { GenerateCmd };