diff --git a/src/actions/generate/generate.actions.ts b/src/actions/generate/generate.actions.ts new file mode 100644 index 0000000..fae6def --- /dev/null +++ b/src/actions/generate/generate.actions.ts @@ -0,0 +1,86 @@ +import ora from 'ora'; +import { Action } from '../abstract.action'; +import { GenerateActionOptions } from './generate.types'; +import { execa } from 'execa'; + +import fs from 'fs'; +import path from 'path'; + +export class GenerateAction extends Action { + private options: GenerateActionOptions; + + constructor(options: GenerateActionOptions) { + super('[GENERATE-ACTION]'); + this.options = options; + } + + updateIndexTs = async (name: string) => { + const filePath = path.join('shared-ui/src', 'index.ts'); + let content = await fs.promises.readFile(filePath, 'utf8'); + // add new line to the end of the file + content += `\nexport * from './lib/${name}/${name}.component';`; + await fs.promises.writeFile(filePath, content, 'utf8'); + }; + + addNewComponentToTsConfig = async (name: string) => { + const filePath = path.join('tsconfig.base.json'); + const content = await fs.promises.readFile(filePath, 'utf8'); + // Update tsconfig.base.json to add the new component in compilerOptions.paths array + const json = JSON.parse(content); + const COMPONENT_PATH = `shared-ui/src/lib/${name}/${name}.component`; + json.compilerOptions.paths[`@todo/${name}`] = [COMPONENT_PATH]; + await fs.promises.writeFile( + filePath, + JSON.stringify(json, null, 2), + 'utf8', + ); + }; + + generateComponent = async (name: string) => { + const spinner = ora(); + spinner.start('Generating component'); + // generate new shared ui component + await execa('npx', [ + 'nx', + 'generate', + '@nx/angular:component', + name, + '--directory', + `shared-ui/src/lib/${name}`, + '--nameAndDirectoryFormat', + 'as-provided', + ]); + // export the component from the index.ts file + await this.updateIndexTs(name); + // add new component to tsconfig.base.json + await this.addNewComponentToTsConfig(name); + spinner.succeed(); + }; + + async execute() { + try { + this.logger.info('Generating...'); + const { type, name, filePath } = this.options; + switch (type) { + case 'component': + await this.generateComponent(name); + break; + case 'service': + this.logger.warning('Unimplemented'); + break; + case 'mongo-schema': + if (!filePath) { + throw new Error('File path is required'); + } + this.logger.warning('Unimplemented'); + // await generateMongoSchema({ + // name, + // filePath, + // }); + break; + } + } catch (error) { + this.logger.error(error); + } + } +} diff --git a/src/actions/generate/generate.types.ts b/src/actions/generate/generate.types.ts new file mode 100644 index 0000000..bf82ad9 --- /dev/null +++ b/src/actions/generate/generate.types.ts @@ -0,0 +1,7 @@ +export type GeneratorType = 'component' | 'service' | 'mongo-schema'; + +export type GenerateActionOptions = { + type: GeneratorType; + name: string; + filePath?: string; +}; diff --git a/src/commands/generate.command.ts b/src/commands/generate.command.ts new file mode 100644 index 0000000..1c3e4a9 --- /dev/null +++ b/src/commands/generate.command.ts @@ -0,0 +1,11 @@ +import { Command } from 'commander'; +import { GenerateAction } from '../actions/generate/generate.actions'; + +export default new Command('generate') + .description('Generate a new Mantis feature') + .argument('', 'The type of thing to generate') + .argument('', 'The name of the thing to generate') + .option('-p, --path ', 'The path to the file') + .action(async (type, name, options) => { + await new GenerateAction({ type, name, filePath: options.path }).execute(); + }); diff --git a/src/mantis-app.ts b/src/mantis-app.ts index defdfdf..49c5bb4 100644 --- a/src/mantis-app.ts +++ b/src/mantis-app.ts @@ -4,6 +4,7 @@ import { welcome } from './utils/welcome.helper'; import packageJson from '../package.json'; import initCommand from './commands/init.command'; import startCommand from './commands/start.command'; +import generateCommand from './commands/generate.command'; const logger = new OrbitLogger('[BOOTSTRAP]'); @@ -33,6 +34,7 @@ const bootstrap = async () => { program.addCommand(initCommand); program.addCommand(startCommand); + program.addCommand(generateCommand); await program.parseAsync(process.argv);