nestjs-ddd-cli 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +138 -0
  3. package/dist/commands/generate-all.d.ts +2 -0
  4. package/dist/commands/generate-all.d.ts.map +1 -0
  5. package/dist/commands/generate-all.js +144 -0
  6. package/dist/commands/generate-all.js.map +1 -0
  7. package/dist/commands/generate-entity.d.ts +2 -0
  8. package/dist/commands/generate-entity.d.ts.map +1 -0
  9. package/dist/commands/generate-entity.js +97 -0
  10. package/dist/commands/generate-entity.js.map +1 -0
  11. package/dist/commands/generate-module.d.ts +2 -0
  12. package/dist/commands/generate-module.d.ts.map +1 -0
  13. package/dist/commands/generate-module.js +111 -0
  14. package/dist/commands/generate-module.js.map +1 -0
  15. package/dist/commands/generate-usecase.d.ts +2 -0
  16. package/dist/commands/generate-usecase.d.ts.map +1 -0
  17. package/dist/commands/generate-usecase.js +84 -0
  18. package/dist/commands/generate-usecase.js.map +1 -0
  19. package/dist/index.d.ts +3 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +72 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/templates/command/create-command.hbs +27 -0
  24. package/dist/templates/controller/controller.hbs +43 -0
  25. package/dist/templates/dto/create-dto.hbs +18 -0
  26. package/dist/templates/entity/entity.hbs +19 -0
  27. package/dist/templates/index/index-export.hbs +9 -0
  28. package/dist/templates/mapper/mapper.hbs +31 -0
  29. package/dist/templates/module/module.hbs +25 -0
  30. package/dist/templates/orm-entity/orm-entity.hbs +10 -0
  31. package/dist/templates/repository/repository.hbs +54 -0
  32. package/dist/templates/usecase/create-usecase.hbs +14 -0
  33. package/dist/utils/file.utils.d.ts +27 -0
  34. package/dist/utils/file.utils.d.ts.map +1 -0
  35. package/dist/utils/file.utils.js +96 -0
  36. package/dist/utils/file.utils.js.map +1 -0
  37. package/dist/utils/naming.utils.d.ts +8 -0
  38. package/dist/utils/naming.utils.d.ts.map +1 -0
  39. package/dist/utils/naming.utils.js +47 -0
  40. package/dist/utils/naming.utils.js.map +1 -0
  41. package/package.json +65 -0
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const commander_1 = require("commander");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const generate_module_1 = require("./commands/generate-module");
10
+ const generate_entity_1 = require("./commands/generate-entity");
11
+ const generate_usecase_1 = require("./commands/generate-usecase");
12
+ const generate_all_1 = require("./commands/generate-all");
13
+ const program = new commander_1.Command();
14
+ program
15
+ .name('ddd')
16
+ .description('CLI for generating NestJS DDD boilerplate code')
17
+ .version('1.0.0');
18
+ program
19
+ .command('generate <type> <name>')
20
+ .alias('g')
21
+ .description('Generate boilerplate code')
22
+ .option('-m, --module <module>', 'Module name')
23
+ .option('-p, --path <path>', 'Base path for generation', process.cwd())
24
+ .option('--skip-orm', 'Skip ORM entity generation')
25
+ .option('--skip-mapper', 'Skip mapper generation')
26
+ .option('--skip-repo', 'Skip repository generation')
27
+ .option('--with-events', 'Include domain events')
28
+ .option('--with-queries', 'Include query handlers')
29
+ .action(async (type, name, options) => {
30
+ try {
31
+ switch (type.toLowerCase()) {
32
+ case 'module':
33
+ await (0, generate_module_1.generateModule)(name, options);
34
+ break;
35
+ case 'entity':
36
+ await (0, generate_entity_1.generateEntity)(name, options);
37
+ break;
38
+ case 'usecase':
39
+ case 'use-case':
40
+ await (0, generate_usecase_1.generateUseCase)(name, options);
41
+ break;
42
+ case 'all':
43
+ await (0, generate_all_1.generateAll)(name, options);
44
+ break;
45
+ default:
46
+ console.error(chalk_1.default.red(`Unknown type: ${type}`));
47
+ console.log(chalk_1.default.yellow('Available types: module, entity, usecase, all'));
48
+ process.exit(1);
49
+ }
50
+ }
51
+ catch (error) {
52
+ console.error(chalk_1.default.red('Error:'), error.message);
53
+ process.exit(1);
54
+ }
55
+ });
56
+ program
57
+ .command('scaffold <entityName>')
58
+ .alias('s')
59
+ .description('Generate complete CRUD scaffolding for an entity')
60
+ .option('-m, --module <module>', 'Module name (will be created if not exists)')
61
+ .option('-p, --path <path>', 'Base path for generation', process.cwd())
62
+ .action(async (entityName, options) => {
63
+ try {
64
+ await (0, generate_all_1.generateAll)(entityName, { ...options, complete: true });
65
+ }
66
+ catch (error) {
67
+ console.error(chalk_1.default.red('Error:'), error.message);
68
+ process.exit(1);
69
+ }
70
+ });
71
+ program.parse();
72
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { CommandHandler, ICommandHandler } from "@nestjs/cqrs";
2
+ import { Create{{entityNamePascal}}UseCase } from "@modules/{{moduleNameKebab}}/application/domain/usecases/create-{{entityNameKebab}}.use-case";
3
+ import { Create{{entityNamePascal}}Dto } from "@modules/{{moduleNameKebab}}/application/dto/requests/create-{{entityNameKebab}}.dto";
4
+
5
+ export class Create{{entityNamePascal}}Command {
6
+ // Add your command properties here
7
+ // They should match your entity properties in camelCase
8
+
9
+ constructor(
10
+ data: Create{{entityNamePascal}}Dto,
11
+ public readonly contextId: string, // e.g., userId, tenantId
12
+ ) {
13
+ // Transform snake_case DTO to camelCase command properties
14
+ // Example: this.propertyName = data.property_name;
15
+ }
16
+ }
17
+
18
+ @CommandHandler(Create{{entityNamePascal}}Command)
19
+ export class Create{{entityNamePascal}}Handler
20
+ implements ICommandHandler<Create{{entityNamePascal}}Command>
21
+ {
22
+ constructor(private readonly useCase: Create{{entityNamePascal}}UseCase) {}
23
+
24
+ async execute(command: Create{{entityNamePascal}}Command) {
25
+ return this.useCase.execute(command);
26
+ }
27
+ }
@@ -0,0 +1,43 @@
1
+ import { Body, Controller, Get, Param, Post, Delete, Put } from "@nestjs/common";
2
+ import { CommandBus, QueryBus } from "@nestjs/cqrs";
3
+ import { Create{{entityNamePascal}}Command } from "@modules/{{moduleNameKebab}}/application/commands/create-{{entityNameKebab}}.command";
4
+ import { Create{{entityNamePascal}}Dto } from "@modules/{{moduleNameKebab}}/application/dto/requests/create-{{entityNameKebab}}.dto";
5
+
6
+ @Controller("{{entityNamePluralKebab}}")
7
+ export class {{entityNamePascal}}Controller {
8
+ constructor(
9
+ private readonly commandBus: CommandBus,
10
+ private readonly queryBus: QueryBus,
11
+ ) {}
12
+
13
+ @Post()
14
+ create(@Body() dto: Create{{entityNamePascal}}Dto) {
15
+ const contextId = "extracted-from-token"; // TODO: Get from auth decorator
16
+ const command = new Create{{entityNamePascal}}Command(dto, contextId);
17
+ return this.commandBus.execute(command);
18
+ }
19
+
20
+ @Get()
21
+ findAll() {
22
+ // TODO: Implement query handler
23
+ throw new Error("Not implemented");
24
+ }
25
+
26
+ @Get(":id")
27
+ findOne(@Param("id") id: string) {
28
+ // TODO: Implement query handler
29
+ throw new Error("Not implemented");
30
+ }
31
+
32
+ @Put(":id")
33
+ update(@Param("id") id: string, @Body() dto: any) {
34
+ // TODO: Implement update command
35
+ throw new Error("Not implemented");
36
+ }
37
+
38
+ @Delete(":id")
39
+ delete(@Param("id") id: string) {
40
+ // TODO: Implement delete command
41
+ throw new Error("Not implemented");
42
+ }
43
+ }
@@ -0,0 +1,18 @@
1
+ import { ApiProperty } from "@nestjs/swagger";
2
+ import {
3
+ IsDefined,
4
+ IsNotEmpty,
5
+ IsString,
6
+ IsNumber,
7
+ IsUUID,
8
+ } from "class-validator";
9
+
10
+ export class Create{{entityNamePascal}}Dto {
11
+ // Add your DTO properties here in snake_case
12
+ // Example:
13
+ // @ApiProperty()
14
+ // @IsString()
15
+ // @IsNotEmpty()
16
+ // @IsDefined()
17
+ // property_name: string;
18
+ }
@@ -0,0 +1,19 @@
1
+ import {
2
+ BaseDomainEntity,
3
+ BaseDomainEntityProps,
4
+ } from "@core/entities/base-domain.entity";
5
+
6
+ export interface {{entityNamePascal}}EntityProps extends BaseDomainEntityProps {
7
+ // Add your domain properties here
8
+ // Example: name: string;
9
+ }
10
+
11
+ export class {{entityNamePascal}}Entity extends BaseDomainEntity {
12
+ // Add your domain properties here
13
+ // Example: name: string;
14
+
15
+ constructor(props: {{entityNamePascal}}EntityProps) {
16
+ super();
17
+ Object.assign(this, props);
18
+ }
19
+ }
@@ -0,0 +1,9 @@
1
+ {{#each exports}}
2
+ import { {{this.name}} } from "./{{this.file}}";
3
+ {{/each}}
4
+
5
+ export const {{arrayName}} = [
6
+ {{#each exports}}
7
+ {{this.name}},
8
+ {{/each}}
9
+ ];
@@ -0,0 +1,31 @@
1
+ import { BaseMapper } from "@core/mappers/base.mapper";
2
+ import { {{entityNamePascal}}OrmEntity } from "@modules/{{moduleNameKebab}}/infrastructure/orm-entities/{{entityNameKebab}}.orm-entity";
3
+ import { {{entityNamePascal}}Entity } from "@modules/{{moduleNameKebab}}/application/domain/entities/{{entityNameKebab}}.entity";
4
+ import { Injectable } from "@nestjs/common";
5
+
6
+ @Injectable()
7
+ export class {{entityNamePascal}}Mapper extends BaseMapper<
8
+ {{entityNamePascal}}Entity,
9
+ {{entityNamePascal}}OrmEntity
10
+ > {
11
+ toOrmEntity(domainEntity: {{entityNamePascal}}Entity): {{entityNamePascal}}OrmEntity {
12
+ this.validateDomainEntity(domainEntity);
13
+
14
+ const ormEntity = new {{entityNamePascal}}OrmEntity(domainEntity.id);
15
+ ormEntity.id = domainEntity.id;
16
+ // Map your properties from camelCase to snake_case
17
+ // Example: ormEntity.property_name = domainEntity.propertyName;
18
+
19
+ return ormEntity;
20
+ }
21
+
22
+ toDomainEntity(ormEntity: {{entityNamePascal}}OrmEntity): {{entityNamePascal}}Entity {
23
+ const entity = new {{entityNamePascal}}Entity({
24
+ id: ormEntity.id,
25
+ // Map your properties from snake_case to camelCase
26
+ // Example: propertyName: ormEntity.property_name,
27
+ });
28
+
29
+ return entity;
30
+ }
31
+ }
@@ -0,0 +1,25 @@
1
+ import { Module } from "@nestjs/common";
2
+ import { CqrsModule } from "@nestjs/cqrs";
3
+ import { Repositories } from "@modules/{{moduleNameKebab}}/infrastructure/repositories";
4
+ import { Queries } from "@modules/{{moduleNameKebab}}/application/queries";
5
+ import { Mappers } from "@modules/{{moduleNameKebab}}/infrastructure/mappers";
6
+ import { UseCases } from "@modules/{{moduleNameKebab}}/application/domain/usecases";
7
+ import { Controllers } from "@modules/{{moduleNameKebab}}/application/controllers";
8
+ import { CommandHandlers } from "@modules/{{moduleNameKebab}}/application/commands";
9
+ import { OrmEntities } from "@modules/{{moduleNameKebab}}/infrastructure/orm-entities";
10
+ import { TypeOrmModule } from "@nestjs/typeorm";
11
+ import { Services } from "@modules/{{moduleNameKebab}}/application/domain/services";
12
+
13
+ @Module({
14
+ imports: [TypeOrmModule.forFeature([...OrmEntities]), CqrsModule],
15
+ providers: [
16
+ ...CommandHandlers,
17
+ ...Queries,
18
+ ...Repositories,
19
+ ...Mappers,
20
+ ...UseCases,
21
+ ...Services,
22
+ ],
23
+ controllers: [...Controllers],
24
+ })
25
+ export class {{moduleName}}Module {}
@@ -0,0 +1,10 @@
1
+ import { BaseOrmEntity } from "@core/infrastructure/persistence/orm-entities/base.orm-entity";
2
+ import { Column, Entity } from "typeorm";
3
+
4
+ @Entity("{{tableName}}")
5
+ export class {{entityNamePascal}}OrmEntity extends BaseOrmEntity {
6
+ // Add your columns here
7
+ // Example:
8
+ // @Column()
9
+ // property_name: string;
10
+ }
@@ -0,0 +1,54 @@
1
+ import { InjectRepository } from "@nestjs/typeorm";
2
+ import { Repository } from "typeorm";
3
+ import { {{entityNamePascal}}Mapper } from "@modules/{{moduleNameKebab}}/infrastructure/mappers/{{entityNameKebab}}.mapper";
4
+ import { {{entityNamePascal}}OrmEntity } from "@modules/{{moduleNameKebab}}/infrastructure/orm-entities/{{entityNameKebab}}.orm-entity";
5
+ import { {{entityNamePascal}}Entity } from "@modules/{{moduleNameKebab}}/application/domain/entities/{{entityNameKebab}}.entity";
6
+ import { Injectable } from "@nestjs/common";
7
+
8
+ @Injectable()
9
+ export class {{entityNamePascal}}Repository {
10
+ constructor(
11
+ @InjectRepository({{entityNamePascal}}OrmEntity)
12
+ private readonly repository: Repository<{{entityNamePascal}}OrmEntity>,
13
+ private readonly mapper: {{entityNamePascal}}Mapper,
14
+ ) {}
15
+
16
+ async create(entity: {{entityNamePascal}}Entity): Promise<{{entityNamePascal}}Entity> {
17
+ const ormEntity = this.mapper.toOrmEntity(entity);
18
+ const savedOrmEntity = await this.repository.save(ormEntity);
19
+ return this.mapper.toDomainEntity(savedOrmEntity);
20
+ }
21
+
22
+ async findById(id: string): Promise<{{entityNamePascal}}Entity | null> {
23
+ const ormEntity = await this.repository.findOne({
24
+ where: { id },
25
+ });
26
+ if (!ormEntity) {
27
+ return null;
28
+ }
29
+ return this.mapper.toDomainEntity(ormEntity);
30
+ }
31
+
32
+ async findAll(): Promise<{{entityNamePascal}}Entity[]> {
33
+ const ormEntities = await this.repository.find();
34
+ if (!ormEntities) {
35
+ return [];
36
+ }
37
+ return ormEntities.map((ormEntity) =>
38
+ this.mapper.toDomainEntity(ormEntity),
39
+ );
40
+ }
41
+
42
+ async update(
43
+ id: string,
44
+ entity: {{entityNamePascal}}Entity,
45
+ ): Promise<{{entityNamePascal}}Entity> {
46
+ const ormEntity = this.mapper.toOrmEntity(entity);
47
+ await this.repository.update(id, ormEntity);
48
+ return entity;
49
+ }
50
+
51
+ async delete(id: string): Promise<void> {
52
+ await this.repository.delete(id);
53
+ }
54
+ }
@@ -0,0 +1,14 @@
1
+ import { {{entityNamePascal}}Entity } from "@modules/{{moduleNameKebab}}/application/domain/entities/{{entityNameKebab}}.entity";
2
+ import { {{entityNamePascal}}Repository } from "@modules/{{moduleNameKebab}}/infrastructure/repositories/{{entityNameKebab}}.repository";
3
+ import { Create{{entityNamePascal}}Command } from "@modules/{{moduleNameKebab}}/application/commands/create-{{entityNameKebab}}.command";
4
+ import { Injectable } from "@nestjs/common";
5
+
6
+ @Injectable()
7
+ export class Create{{entityNamePascal}}UseCase {
8
+ constructor(private readonly repository: {{entityNamePascal}}Repository) {}
9
+
10
+ async execute(command: Create{{entityNamePascal}}Command) {
11
+ const entity = new {{entityNamePascal}}Entity(command);
12
+ return this.repository.create(entity);
13
+ }
14
+ }
@@ -0,0 +1,27 @@
1
+ export interface TemplateData {
2
+ entityName: string;
3
+ entityNamePascal: string;
4
+ entityNameCamel: string;
5
+ entityNameKebab: string;
6
+ entityNameSnake: string;
7
+ entityNamePlural: string;
8
+ entityNamePluralKebab: string;
9
+ tableName: string;
10
+ moduleName: string;
11
+ moduleNameKebab: string;
12
+ properties?: Array<{
13
+ name: string;
14
+ type: string;
15
+ isRequired: boolean;
16
+ isRelation: boolean;
17
+ }>;
18
+ }
19
+ export declare function prepareTemplateData(entityName: string, moduleName: string): TemplateData;
20
+ export declare function ensureDir(dirPath: string): Promise<void>;
21
+ export declare function fileExists(filePath: string): Promise<boolean>;
22
+ export declare function writeFile(filePath: string, content: string): Promise<void>;
23
+ export declare function readTemplate(templatePath: string): Promise<string>;
24
+ export declare function compileTemplate(template: string, data: TemplateData): string;
25
+ export declare function generateFromTemplate(templatePath: string, outputPath: string, data: TemplateData): Promise<void>;
26
+ export declare function getModulePath(basePath: string, moduleName: string): string;
27
+ //# sourceMappingURL=file.utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.utils.d.ts","sourceRoot":"","sources":["../../src/utils/file.utils.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,KAAK,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,OAAO,CAAC;QACpB,UAAU,EAAE,OAAO,CAAC;KACrB,CAAC,CAAC;CACJ;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,YAAY,CAaxF;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9D;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOnE;AAED,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGhF;AAED,wBAAsB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAExE;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,MAAM,CAG5E;AAED,wBAAsB,oBAAoB,CACxC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAIf;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAE1E"}
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.prepareTemplateData = prepareTemplateData;
40
+ exports.ensureDir = ensureDir;
41
+ exports.fileExists = fileExists;
42
+ exports.writeFile = writeFile;
43
+ exports.readTemplate = readTemplate;
44
+ exports.compileTemplate = compileTemplate;
45
+ exports.generateFromTemplate = generateFromTemplate;
46
+ exports.getModulePath = getModulePath;
47
+ const fs = __importStar(require("fs-extra"));
48
+ const path = __importStar(require("path"));
49
+ const handlebars_1 = __importDefault(require("handlebars"));
50
+ const naming_utils_1 = require("./naming.utils");
51
+ function prepareTemplateData(entityName, moduleName) {
52
+ return {
53
+ entityName,
54
+ entityNamePascal: (0, naming_utils_1.toPascalCase)(entityName),
55
+ entityNameCamel: (0, naming_utils_1.toCamelCase)(entityName),
56
+ entityNameKebab: (0, naming_utils_1.toKebabCase)(entityName),
57
+ entityNameSnake: (0, naming_utils_1.toSnakeCase)(entityName),
58
+ entityNamePlural: (0, naming_utils_1.toPlural)((0, naming_utils_1.toPascalCase)(entityName)),
59
+ entityNamePluralKebab: (0, naming_utils_1.toKebabCase)((0, naming_utils_1.toPlural)(entityName)),
60
+ tableName: (0, naming_utils_1.toTableName)(entityName),
61
+ moduleName,
62
+ moduleNameKebab: (0, naming_utils_1.toKebabCase)(moduleName),
63
+ };
64
+ }
65
+ async function ensureDir(dirPath) {
66
+ await fs.ensureDir(dirPath);
67
+ }
68
+ async function fileExists(filePath) {
69
+ try {
70
+ await fs.access(filePath);
71
+ return true;
72
+ }
73
+ catch {
74
+ return false;
75
+ }
76
+ }
77
+ async function writeFile(filePath, content) {
78
+ await ensureDir(path.dirname(filePath));
79
+ await fs.writeFile(filePath, content, 'utf-8');
80
+ }
81
+ async function readTemplate(templatePath) {
82
+ return fs.readFile(templatePath, 'utf-8');
83
+ }
84
+ function compileTemplate(template, data) {
85
+ const compiledTemplate = handlebars_1.default.compile(template);
86
+ return compiledTemplate(data);
87
+ }
88
+ async function generateFromTemplate(templatePath, outputPath, data) {
89
+ const template = await readTemplate(templatePath);
90
+ const content = compileTemplate(template, data);
91
+ await writeFile(outputPath, content);
92
+ }
93
+ function getModulePath(basePath, moduleName) {
94
+ return path.join(basePath, 'src', 'modules', (0, naming_utils_1.toKebabCase)(moduleName));
95
+ }
96
+ //# sourceMappingURL=file.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.utils.js","sourceRoot":"","sources":["../../src/utils/file.utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwBA,kDAaC;AAED,8BAEC;AAED,gCAOC;AAED,8BAGC;AAED,oCAEC;AAED,0CAGC;AAED,oDAQC;AAED,sCAEC;AA9ED,6CAA+B;AAC/B,2CAA6B;AAC7B,4DAAoC;AACpC,iDAA4G;AAqB5G,SAAgB,mBAAmB,CAAC,UAAkB,EAAE,UAAkB;IACxE,OAAO;QACL,UAAU;QACV,gBAAgB,EAAE,IAAA,2BAAY,EAAC,UAAU,CAAC;QAC1C,eAAe,EAAE,IAAA,0BAAW,EAAC,UAAU,CAAC;QACxC,eAAe,EAAE,IAAA,0BAAW,EAAC,UAAU,CAAC;QACxC,eAAe,EAAE,IAAA,0BAAW,EAAC,UAAU,CAAC;QACxC,gBAAgB,EAAE,IAAA,uBAAQ,EAAC,IAAA,2BAAY,EAAC,UAAU,CAAC,CAAC;QACpD,qBAAqB,EAAE,IAAA,0BAAW,EAAC,IAAA,uBAAQ,EAAC,UAAU,CAAC,CAAC;QACxD,SAAS,EAAE,IAAA,0BAAW,EAAC,UAAU,CAAC;QAClC,UAAU;QACV,eAAe,EAAE,IAAA,0BAAW,EAAC,UAAU,CAAC;KACzC,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,SAAS,CAAC,OAAe;IAC7C,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC;AAEM,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,SAAS,CAAC,QAAgB,EAAE,OAAe;IAC/D,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IACxC,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AACjD,CAAC;AAEM,KAAK,UAAU,YAAY,CAAC,YAAoB;IACrD,OAAO,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED,SAAgB,eAAe,CAAC,QAAgB,EAAE,IAAkB;IAClE,MAAM,gBAAgB,GAAG,oBAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACtD,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC;AAEM,KAAK,UAAU,oBAAoB,CACxC,YAAoB,EACpB,UAAkB,EAClB,IAAkB;IAElB,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,YAAY,CAAC,CAAC;IAClD,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAChD,MAAM,SAAS,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AACvC,CAAC;AAED,SAAgB,aAAa,CAAC,QAAgB,EAAE,UAAkB;IAChE,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,IAAA,0BAAW,EAAC,UAAU,CAAC,CAAC,CAAC;AACxE,CAAC"}
@@ -0,0 +1,8 @@
1
+ export declare function toPascalCase(str: string): string;
2
+ export declare function toCamelCase(str: string): string;
3
+ export declare function toKebabCase(str: string): string;
4
+ export declare function toSnakeCase(str: string): string;
5
+ export declare function toPlural(str: string): string;
6
+ export declare function toSingular(str: string): string;
7
+ export declare function toTableName(entityName: string): string;
8
+ //# sourceMappingURL=naming.utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming.utils.d.ts","sourceRoot":"","sources":["../../src/utils/naming.utils.ts"],"names":[],"mappings":"AAEA,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAKhD;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG/C;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK/C;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK/C;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAItD"}
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.toPascalCase = toPascalCase;
7
+ exports.toCamelCase = toCamelCase;
8
+ exports.toKebabCase = toKebabCase;
9
+ exports.toSnakeCase = toSnakeCase;
10
+ exports.toPlural = toPlural;
11
+ exports.toSingular = toSingular;
12
+ exports.toTableName = toTableName;
13
+ const pluralize_1 = __importDefault(require("pluralize"));
14
+ function toPascalCase(str) {
15
+ return str
16
+ .split(/[-_ ]/)
17
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
18
+ .join('');
19
+ }
20
+ function toCamelCase(str) {
21
+ const pascal = toPascalCase(str);
22
+ return pascal.charAt(0).toLowerCase() + pascal.slice(1);
23
+ }
24
+ function toKebabCase(str) {
25
+ return str
26
+ .replace(/([a-z])([A-Z])/g, '$1-$2')
27
+ .replace(/[\s_]+/g, '-')
28
+ .toLowerCase();
29
+ }
30
+ function toSnakeCase(str) {
31
+ return str
32
+ .replace(/([a-z])([A-Z])/g, '$1_$2')
33
+ .replace(/[\s-]+/g, '_')
34
+ .toLowerCase();
35
+ }
36
+ function toPlural(str) {
37
+ return (0, pluralize_1.default)(str);
38
+ }
39
+ function toSingular(str) {
40
+ return pluralize_1.default.singular(str);
41
+ }
42
+ function toTableName(entityName) {
43
+ const singular = toSingular(entityName);
44
+ const snakeCase = toSnakeCase(singular);
45
+ return toPlural(snakeCase);
46
+ }
47
+ //# sourceMappingURL=naming.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming.utils.js","sourceRoot":"","sources":["../../src/utils/naming.utils.ts"],"names":[],"mappings":";;;;;AAEA,oCAKC;AAED,kCAGC;AAED,kCAKC;AAED,kCAKC;AAED,4BAEC;AAED,gCAEC;AAED,kCAIC;AAxCD,0DAAkC;AAElC,SAAgB,YAAY,CAAC,GAAW;IACtC,OAAO,GAAG;SACP,KAAK,CAAC,OAAO,CAAC;SACd,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;SACvE,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED,SAAgB,WAAW,CAAC,GAAW;IACrC,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IACjC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED,SAAgB,WAAW,CAAC,GAAW;IACrC,OAAO,GAAG;SACP,OAAO,CAAC,iBAAiB,EAAE,OAAO,CAAC;SACnC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,WAAW,EAAE,CAAC;AACnB,CAAC;AAED,SAAgB,WAAW,CAAC,GAAW;IACrC,OAAO,GAAG;SACP,OAAO,CAAC,iBAAiB,EAAE,OAAO,CAAC;SACnC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,WAAW,EAAE,CAAC;AACnB,CAAC;AAED,SAAgB,QAAQ,CAAC,GAAW;IAClC,OAAO,IAAA,mBAAS,EAAC,GAAG,CAAC,CAAC;AACxB,CAAC;AAED,SAAgB,UAAU,CAAC,GAAW;IACpC,OAAO,mBAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AACjC,CAAC;AAED,SAAgB,WAAW,CAAC,UAAkB;IAC5C,MAAM,QAAQ,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IACxC,MAAM,SAAS,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IACxC,OAAO,QAAQ,CAAC,SAAS,CAAC,CAAC;AAC7B,CAAC"}
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "nestjs-ddd-cli",
3
+ "version": "1.0.1",
4
+ "description": "CLI for generating NestJS DDD boilerplate code",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "ddd": "./dist/index.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc && cp -r src/templates dist/",
11
+ "dev": "ts-node src/index.ts",
12
+ "link": "npm run build && npm link",
13
+ "unlink": "npm unlink -g nestjs-ddd-cli",
14
+ "prepublishOnly": "npm run clean && npm run build",
15
+ "clean": "rm -rf dist",
16
+ "test": "echo \"No test specified\" && exit 0"
17
+ },
18
+ "keywords": [
19
+ "nestjs",
20
+ "ddd",
21
+ "cli",
22
+ "generator",
23
+ "domain-driven-design",
24
+ "cqrs",
25
+ "boilerplate",
26
+ "scaffolding",
27
+ "typescript",
28
+ "nestjs-cli"
29
+ ],
30
+ "author": "Ben Ouattara ben.ouattara@outlook.com",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/eshe-huli/nestjs-ddd-cli"
34
+ },
35
+ "bugs": {
36
+ "url": "https://github.com/eshe-huli/nestjs-ddd-cli/issues"
37
+ },
38
+ "homepage": "https://github.com/eshe-huli/nestjs-ddd-cli#readme",
39
+ "engines": {
40
+ "node": ">=14.0.0"
41
+ },
42
+ "files": [
43
+ "dist",
44
+ "README.md",
45
+ "LICENSE"
46
+ ],
47
+ "license": "MIT",
48
+ "dependencies": {
49
+ "@nestjs/cqrs": "^11.0.3",
50
+ "chalk": "^4.1.2",
51
+ "commander": "^11.1.0",
52
+ "fs-extra": "^11.2.0",
53
+ "handlebars": "^4.7.8",
54
+ "inquirer": "^8.2.6",
55
+ "pluralize": "^8.0.0"
56
+ },
57
+ "devDependencies": {
58
+ "@types/fs-extra": "^11.0.4",
59
+ "@types/inquirer": "^9.0.7",
60
+ "@types/node": "^20.10.5",
61
+ "@types/pluralize": "^0.0.33",
62
+ "ts-node": "^10.9.2",
63
+ "typescript": "^5.3.3"
64
+ }
65
+ }