@sharangyawali/sg-cli 0.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.

Potentially problematic release.


This version of @sharangyawali/sg-cli might be problematic. Click here for more details.

Files changed (79) hide show
  1. package/.prettierignore +1 -0
  2. package/README.md +0 -0
  3. package/bin/cli.js +3 -0
  4. package/package.json +27 -0
  5. package/src/commands/create-new.command.js +52 -0
  6. package/src/commands/generate.command.js +57 -0
  7. package/src/index.js +14 -0
  8. package/src/new-app-generator/app-module.generator.js +15 -0
  9. package/src/new-app-generator/app.generator.js +21 -0
  10. package/src/new-app-generator/application.generator.js +27 -0
  11. package/src/new-app-generator/common.generator.js +27 -0
  12. package/src/new-app-generator/domain.generator.js +34 -0
  13. package/src/new-app-generator/env-example.generator.js +25 -0
  14. package/src/new-app-generator/infra.generator.js +210 -0
  15. package/src/new-app-generator/main.generator.js +16 -0
  16. package/src/new-app-generator/package.generator.js +42 -0
  17. package/src/new-app-generator/tsconfig.generator.js +15 -0
  18. package/src/new-module-handler/controller.handlers.js +70 -0
  19. package/src/new-module-handler/datasources.handlers.js +37 -0
  20. package/src/new-module-handler/entity.handlers.js +75 -0
  21. package/src/new-module-handler/module.handlers.js +17 -0
  22. package/src/new-module-handler/repositories.handlers.js +87 -0
  23. package/src/new-module-handler/service.handlers.js +97 -0
  24. package/src/new-module-handler/usecase.handlers.js +67 -0
  25. package/src/utils/format.js +20 -0
  26. package/src/utils/get-ejs-files.js +9 -0
  27. package/src/utils/get-folders.js +8 -0
  28. package/src/utils/get-relative-path.js +7 -0
  29. package/src/utils/has-directory.js +10 -0
  30. package/src/utils/install-packages.js +19 -0
  31. package/src/utils/update-files.js +194 -0
  32. package/src/utils/write-file.js +12 -0
  33. package/templates/app/env.example.ejs +9 -0
  34. package/templates/app/package.json.ejs +12 -0
  35. package/templates/app/src/app.module.ejs +11 -0
  36. package/templates/app/src/application/application.module.ejs +11 -0
  37. package/templates/app/src/application/dto/index.ejs +0 -0
  38. package/templates/app/src/application/services/index.ejs +1 -0
  39. package/templates/app/src/application/services/service.module.ejs +8 -0
  40. package/templates/app/src/application/usecases/index.ejs +1 -0
  41. package/templates/app/src/application/usecases/usecase.module.ejs +8 -0
  42. package/templates/app/src/common/decorators/index.ejs +0 -0
  43. package/templates/app/src/common/enum/index.ejs +0 -0
  44. package/templates/app/src/common/helpers/index.ejs +0 -0
  45. package/templates/app/src/common/interfaces/index.ejs +0 -0
  46. package/templates/app/src/common/types/condition.d.ejs +3 -0
  47. package/templates/app/src/common/types/index.ejs +4 -0
  48. package/templates/app/src/common/types/pagination.d.ejs +34 -0
  49. package/templates/app/src/common/types/relation.d.ejs +3 -0
  50. package/templates/app/src/common/types/transactional.d.ejs +4 -0
  51. package/templates/app/src/domain/datasource/datasource.ejs +5 -0
  52. package/templates/app/src/domain/datasource/index.ejs +1 -0
  53. package/templates/app/src/domain/entities/base.entity.ejs +18 -0
  54. package/templates/app/src/domain/entities/index.ejs +1 -0
  55. package/templates/app/src/domain/repositories/generic.repository.ejs +25 -0
  56. package/templates/app/src/domain/repositories/index.ejs +1 -0
  57. package/templates/app/src/domain/services/index.ejs +0 -0
  58. package/templates/app/src/domain/usecase/base.usecase.ejs +3 -0
  59. package/templates/app/src/domain/usecase/index.ejs +1 -0
  60. package/templates/app/src/infra/controllers/controller.module.ejs +9 -0
  61. package/templates/app/src/infra/controllers/demo/demo-controller.module.ejs +7 -0
  62. package/templates/app/src/infra/controllers/demo/demo.controller.ejs +9 -0
  63. package/templates/app/src/infra/datasource/[database]/[database].datasource.ejs +15 -0
  64. package/templates/app/src/infra/datasource/[database]/[database].module.ejs +16 -0
  65. package/templates/app/src/infra/datasource/[database]/entities/base.entity.ejs +53 -0
  66. package/templates/app/src/infra/datasource/[database]/entities/index.ejs +1 -0
  67. package/templates/app/src/infra/datasource/[database]/providers/[database].provider.ejs +30 -0
  68. package/templates/app/src/infra/datasource/[database]/providers/index.ejs +1 -0
  69. package/templates/app/src/infra/datasource/[database]/repositories/[database]-generic.repository.ejs +117 -0
  70. package/templates/app/src/infra/datasource/[database]/repositories/index.ejs +1 -0
  71. package/templates/app/src/infra/datasource/datasource.module.ejs +7 -0
  72. package/templates/app/src/infra/infra.module.ejs +13 -0
  73. package/templates/app/src/infra/server/filters/index.ejs +0 -0
  74. package/templates/app/src/infra/server/guard/index.ejs +0 -0
  75. package/templates/app/src/infra/server/interceptor/index.ejs +0 -0
  76. package/templates/app/src/infra/server/middleware/index.ejs +0 -0
  77. package/templates/app/src/infra/server/server.module.ejs +7 -0
  78. package/templates/app/src/main.ejs +10 -0
  79. package/templates/app/tsconfig.json.ejs +31 -0
@@ -0,0 +1,11 @@
1
+ import { Module } from '@sharangyawali/sg-app';
2
+ import { InfraModule } from './infra/infra.module';
3
+ import { ApplicationModule } from './application/application.module';
4
+
5
+ @Module({
6
+ imports: [
7
+ InfraModule,
8
+ ApplicationModule
9
+ ],
10
+ })
11
+ export class AppModule { }
@@ -0,0 +1,11 @@
1
+ import { Module } from "@sharangyawali/sg-app";
2
+ import { ServiceModule } from "./services";
3
+ import { UseCaseModule } from "./usecases";
4
+
5
+ @Module({
6
+ imports: [
7
+ ServiceModule,
8
+ UseCaseModule,
9
+ ]
10
+ })
11
+ export class ApplicationModule { }
File without changes
@@ -0,0 +1 @@
1
+ export * from './service.module';
@@ -0,0 +1,8 @@
1
+ import { Module } from '@sharangyawali/sg-app';
2
+
3
+ @Module({
4
+ providers: [
5
+ // Services
6
+ ],
7
+ })
8
+ export class ServiceModule { }
@@ -0,0 +1 @@
1
+ export * from './usecase.module';
@@ -0,0 +1,8 @@
1
+ import { Module } from "@sharangyawali/sg-app";
2
+
3
+ @Module({
4
+ imports: [
5
+ // UseCase modules
6
+ ],
7
+ })
8
+ export class UseCaseModule { }
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,3 @@
1
+ export type ConditionType = {
2
+ [key: string]: any | any[];
3
+ };
@@ -0,0 +1,4 @@
1
+ export * from './pagination';
2
+ export * from './relation';
3
+ export * from './condition';
4
+ export * from './transactional';
@@ -0,0 +1,34 @@
1
+ export interface PaginationOptions {
2
+ page?: number;
3
+ limit?: number;
4
+ sortBy?: string;
5
+ sortOrder?: 'ASC' | 'DESC';
6
+ }
7
+
8
+ export interface PaginationMeta {
9
+ currentPage: number;
10
+ itemsPerPage: number;
11
+ totalItems: number;
12
+ totalPages: number;
13
+ hasNextPage: boolean;
14
+ hasPreviousPage: boolean;
15
+ }
16
+
17
+ export interface PaginatedResponse<T> {
18
+ data: T[];
19
+ meta: PaginationMeta;
20
+ }
21
+
22
+ export interface RequestPagination {
23
+ page?: number;
24
+ limit?: number;
25
+ }
26
+
27
+ export type ResponsePagination<T> = {
28
+ data: T[];
29
+ page: number;
30
+ count: number;
31
+ total: number;
32
+ next: number | null;
33
+ prev: number | null;
34
+ };
@@ -0,0 +1,3 @@
1
+ export type RelationType = {
2
+ [key: string]: boolean | RelationType;
3
+ };
@@ -0,0 +1,4 @@
1
+ export interface Transactional {
2
+ release(): Promise<void>;
3
+ query(query: string, parameters?: any[]): Promise<any>;
4
+ }
@@ -0,0 +1,5 @@
1
+ import { DataSource } from 'typeorm';
2
+
3
+ export abstract class IDatasource {
4
+ datasource: DataSource;
5
+ }
@@ -0,0 +1 @@
1
+ export * from './datasource';
@@ -0,0 +1,18 @@
1
+ export abstract class BaseEntity {
2
+ id: string;
3
+ createdAt: Date;
4
+ updatedAt: Date | null;
5
+ deletedAt: Date | null;
6
+
7
+ static get InjectableString(): string {
8
+ return (
9
+ this.name
10
+ .replace(/(A-Z)/g, ' $1')
11
+ .replace(/entity/gi, '')
12
+ .trim()
13
+ .split(' ')
14
+ .join('_')
15
+ .toUpperCase() + '_REPOSITORY'
16
+ );
17
+ }
18
+ }
@@ -0,0 +1 @@
1
+ export * from './base.entity';
@@ -0,0 +1,25 @@
1
+ import { ConditionType, PaginatedResponse, PaginationOptions, RelationType, Transactional } from "../../common/types";
2
+
3
+ export interface GenericRepository<T> {
4
+ create(item: T): Promise<T>;
5
+ update(condition: ConditionType, item: object): Promise<T>;
6
+ getAll(
7
+ condition?: ConditionType,
8
+ relations?: RelationType[] | RelationType,
9
+ ): Promise<T[]>;
10
+ getPaginated(
11
+ condition?: ConditionType,
12
+ relations?: RelationType[] | RelationType,
13
+ pagination?: PaginationOptions,
14
+ ): Promise<PaginatedResponse<T>>;
15
+ getOneOrFalse(
16
+ condition: ConditionType,
17
+ relations?: RelationType[] | RelationType,
18
+ ): Promise<T | false>;
19
+ withTransaction<R>(operation: (transactional: Transactional) => Promise<R>): Promise<R>;
20
+ saveWithRunner(queryRunner: Transactional, item: T): Promise<T>;
21
+ saveMultipleWithRunner(
22
+ queryRunner: Transactional,
23
+ item: T[],
24
+ ): Promise<T[]>;
25
+ }
@@ -0,0 +1 @@
1
+ export * from './generic.repository';
File without changes
@@ -0,0 +1,3 @@
1
+ export interface IBaseUsecase<T> {
2
+ execute(...args: any): Promise<T>;
3
+ }
@@ -0,0 +1 @@
1
+ export * from './base.usecase';
@@ -0,0 +1,9 @@
1
+ import { Module } from '@sharangyawali/sg-app';
2
+ import { DemoControllerModule } from './demo/demo-controller.module';
3
+
4
+ @Module({
5
+ imports: [
6
+ DemoControllerModule
7
+ ],
8
+ })
9
+ export class ControllerModule { }
@@ -0,0 +1,7 @@
1
+ import { Module } from "@sharangyawali/sg-app";
2
+ import { DemoController } from "./demo.controller";
3
+
4
+ @Module({
5
+ controllers: [DemoController]
6
+ })
7
+ export class DemoControllerModule { }
@@ -0,0 +1,9 @@
1
+ import { Get, RestController } from "@sharangyawali/sg-app";
2
+
3
+ @RestController('demo')
4
+ export class DemoController {
5
+ @Get('hello')
6
+ hello(): string {
7
+ return "Hello World!!"
8
+ }
9
+ }
@@ -0,0 +1,15 @@
1
+ import { Component, Inject } from "@sharangyawali/sg-app";
2
+ import { IDatasource } from "../../../domain/datasource";
3
+ import { DataSource } from "typeorm";
4
+ import { DATA_SOURCE_<%= DATABASE %> } from "./providers";
5
+
6
+ @Component()
7
+ export class <%= Database %>DataSource implements IDatasource {
8
+ public datasource: DataSource;
9
+ constructor(
10
+ @Inject(DATA_SOURCE_<%= DATABASE %>)
11
+ private _datasource: DataSource,
12
+ ) {
13
+ this.datasource = this._datasource;
14
+ }
15
+ }
@@ -0,0 +1,16 @@
1
+ import { <%= Database %>DataSource } from './<%= database %>.datasource';
2
+ import { Module, Scope } from '@sharangyawali/sg-app';
3
+ import { IDatasource } from '../../../domain/datasource';
4
+ import { <%= database %>Providers } from './providers';
5
+
6
+ @Module({
7
+ providers: [
8
+ ...<%= database %>Providers,
9
+ {
10
+ token: IDatasource,
11
+ scope: Scope.SINGLETON,
12
+ useClass: <%= Database %>DataSource,
13
+ },
14
+ ],
15
+ })
16
+ export class <%= Database %>Module { }
@@ -0,0 +1,53 @@
1
+ import {
2
+ AfterUpdate,
3
+ Column,
4
+ CreateDateColumn,
5
+ PrimaryGeneratedColumn,
6
+ UpdateDateColumn,
7
+ } from 'typeorm';
8
+
9
+ export abstract class BaseEntity {
10
+ @PrimaryGeneratedColumn('uuid')
11
+ id: string;
12
+
13
+ @CreateDateColumn({
14
+ type: 'timestamp',
15
+ default: () => 'CURRENT_TIMESTAMP',
16
+ })
17
+ createdAt: Date;
18
+
19
+ @UpdateDateColumn({
20
+ nullable: true,
21
+ type: 'timestamp',
22
+ default: null,
23
+ })
24
+ updatedAt: Date;
25
+
26
+ @Column({
27
+ type: 'timestamp',
28
+ nullable: true,
29
+ default: null,
30
+ })
31
+ deletedAt: Date;
32
+
33
+ @AfterUpdate()
34
+ afterUpdate() {
35
+ this.updatedAt = new Date();
36
+ }
37
+
38
+ softDelete() {
39
+ this.deletedAt = new Date();
40
+ }
41
+
42
+ static get InjectableString(): string {
43
+ return (
44
+ this.name
45
+ .replace(/(A-Z)/g, ' $1')
46
+ .replace(/entity/gi, '')
47
+ .trim()
48
+ .split(' ')
49
+ .join('_')
50
+ .toUpperCase() + '_REPOSITORY'
51
+ );
52
+ }
53
+ }
@@ -0,0 +1 @@
1
+ export * from './base.entity';
@@ -0,0 +1,30 @@
1
+ import { DataSource, DataSourceOptions } from 'typeorm';
2
+ import { AppLogger, ConfigService, ModuleProvider, Scope } from '@sharangyawali/sg-app';
3
+ export const DATA_SOURCE_<%= DATABASE %> = 'DATA_SOURCE_<%= DATABASE %>';
4
+ export const <%= database %>Providers: ModuleProvider[] = [
5
+ {
6
+ token: DATA_SOURCE_<%= DATABASE %>,
7
+ scope: Scope.SINGLETON,
8
+ inject: [ConfigService, AppLogger],
9
+ useFactory: async (
10
+ config: ConfigService,
11
+ logger: AppLogger,
12
+ ) => {
13
+ const configs: DataSourceOptions = {
14
+ type: '<%= database %>',
15
+ host: config.get('<%= DATABASE %>_HOST'),
16
+ port: Number(config.get('<%= DATABASE %>_PORT')),
17
+ username: config.get('<%= DATABASE %>_USER'),
18
+ password: config.get('<%= DATABASE %>_PASSWORD'),
19
+ database: config.get('<%= DATABASE %>_DB'),
20
+ synchronize: false,
21
+ logging: false,
22
+ entities: [__dirname + '/../../**/**/*.<%= database %>.entity{.ts,.js}'],
23
+ };
24
+ const dataSource = new DataSource(configs);
25
+ await dataSource.initialize();
26
+ logger.log('Database successfully connected ');
27
+ return dataSource;
28
+ },
29
+ },
30
+ ];
@@ -0,0 +1 @@
1
+ export * from './<%= database %>.provider';
@@ -0,0 +1,117 @@
1
+ import { Component } from "@sharangyawali/sg-app";
2
+ import { GenericRepository } from "../../../../domain/repositories";
3
+ import { DataSource, QueryRunner, Repository } from "typeorm";
4
+ import { ConditionType, PaginatedResponse, PaginationOptions, RelationType, Transactional } from "../../../../common/types";
5
+
6
+ @Component()
7
+ export class <%= Database %>GenericRepository<T> implements GenericRepository<T> {
8
+ protected _repository: Repository<T>;
9
+ protected _tableName: string;
10
+
11
+ constructor(
12
+ repository: Repository<T>,
13
+ protected readonly dataSource: DataSource,
14
+ protected readonly tableName: string,
15
+ ) {
16
+ this._repository = repository;
17
+ this._tableName = tableName;
18
+ }
19
+
20
+
21
+ async create(item: T): Promise<T> {
22
+ return this._repository.save(item);
23
+ }
24
+
25
+ async update(condition: ConditionType, item: object): Promise<T> {
26
+ await this._repository.update({ ...condition } as any, item)
27
+ return this._repository.findOneBy({ ...condition } as any);
28
+ }
29
+
30
+ async getAll(
31
+ condition?: ConditionType,
32
+ relations?: RelationType[] | RelationType,
33
+ ): Promise<T[]> {
34
+ return this._repository.find({
35
+ where: { ...condition as any },
36
+ relations: { ...relations } as any,
37
+ });
38
+ }
39
+
40
+ async getPaginated(
41
+ condition: ConditionType,
42
+ relations: RelationType[] | RelationType = {},
43
+ pagination?: PaginationOptions,
44
+ ): Promise<PaginatedResponse<T>> {
45
+ const page = pagination?.page || 1;
46
+ const limit = pagination?.limit || 10;
47
+ const skip = (page - 1) * limit;
48
+
49
+ const [data, total] = await this._repository.findAndCount({
50
+ where: { ...condition as any },
51
+ skip,
52
+ take: limit,
53
+ relations: { ...relations } as any,
54
+ order: {
55
+ [pagination?.sortBy || 'id']: pagination?.sortOrder || 'DESC',
56
+ } as any,
57
+ });
58
+
59
+ const totalPages = Math.ceil(total / limit);
60
+
61
+ return {
62
+ data,
63
+ meta: {
64
+ currentPage: page,
65
+ itemsPerPage: limit,
66
+ totalItems: total,
67
+ totalPages,
68
+ hasNextPage: page < totalPages,
69
+ hasPreviousPage: page > 1,
70
+ },
71
+ };
72
+ }
73
+
74
+ async getOneOrFalse(condition: object, relations?: RelationType[] | RelationType,): Promise<false | T> {
75
+ try {
76
+ const item = await this._repository.findOne({
77
+ where: { ...condition },
78
+ relations: { ...relations as any }
79
+ });
80
+ return item || false;
81
+ } catch (error) {
82
+ console.log(error);
83
+ return false;
84
+ }
85
+ }
86
+
87
+ async withTransaction<R>(
88
+ operation: (queryRunner: Transactional) => Promise<R>,
89
+ ): Promise<R> {
90
+ const queryRunner = this.dataSource.createQueryRunner();
91
+ await queryRunner.connect();
92
+ await queryRunner.startTransaction();
93
+
94
+ try {
95
+ const result = await operation(queryRunner);
96
+ await queryRunner.commitTransaction();
97
+ return result;
98
+ } catch (err) {
99
+ await queryRunner.rollbackTransaction();
100
+ throw err;
101
+ } finally {
102
+ await queryRunner.release();
103
+ }
104
+ }
105
+ saveWithRunner(
106
+ queryRunner: QueryRunner,
107
+ item: T,
108
+ ): Promise<T> {
109
+ return queryRunner.manager.getRepository(this._tableName).save(item);
110
+ }
111
+ saveMultipleWithRunner(
112
+ queryRunner: QueryRunner,
113
+ item: T[],
114
+ ): Promise<T[]> {
115
+ return queryRunner.manager.getRepository(this._tableName).save(item);
116
+ }
117
+ }
@@ -0,0 +1 @@
1
+ export * from './<%= database %>-generic.repository';
@@ -0,0 +1,7 @@
1
+ import { Module } from '@sharangyawali/sg-app';
2
+ import { <%= Database %>Module } from './<%= database %>/<%= database %>.module';
3
+
4
+ @Module({
5
+ imports: [<%= Database %>Module],
6
+ })
7
+ export class DataSourceModule { }
@@ -0,0 +1,13 @@
1
+ import { Module } from "@sharangyawali/sg-app";
2
+ import { ServerModule } from "./server/server.module";
3
+ import { DataSourceModule } from "./datasource/datasource.module";
4
+ import { ControllerModule } from "./controllers/controller.module";
5
+
6
+ @Module({
7
+ imports: [
8
+ ServerModule,
9
+ DataSourceModule,
10
+ ControllerModule,
11
+ ],
12
+ })
13
+ export class InfraModule { }
File without changes
@@ -0,0 +1,7 @@
1
+ import { Module } from "@sharangyawali/sg-app";
2
+
3
+ @Module({
4
+ providers: [
5
+ ],
6
+ })
7
+ export class ServerModule { }
@@ -0,0 +1,10 @@
1
+ import { AppLogger, ConfigService, container, SGFactory } from '@sharangyawali/sg-app';
2
+ import { AppModule } from './app.module';
3
+ async function bootstrap() {
4
+ const app = new SGFactory().create(AppModule, { cors: true });
5
+ const logger = await container.resolve(AppLogger);
6
+ const config: ConfigService = await container.resolve(ConfigService);
7
+ const port = Number(config.get('APP_PORT')) || 8000;
8
+ await app.listen(port, () => logger.log(`Listening on port ${port}`));
9
+ }
10
+ bootstrap();
@@ -0,0 +1,31 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es2023",
4
+ "module": "commonjs",
5
+ "noEmit": false,
6
+ "allowArbitraryExtensions": true,
7
+ "rootDir": "./src",
8
+ "outDir": "./dist",
9
+ "strict": true,
10
+ "esModuleInterop": true,
11
+ "skipLibCheck": true,
12
+ "forceConsistentCasingInFileNames": false,
13
+ "resolveJsonModule": true,
14
+ "strictPropertyInitialization": false,
15
+ "experimentalDecorators": true,
16
+ "emitDecoratorMetadata": true,
17
+ "declaration": true,
18
+ "allowSyntheticDefaultImports": true,
19
+ "baseUrl": "./",
20
+ "paths": {
21
+ "*": ["src/*"]
22
+ },
23
+ "incremental": true,
24
+ "strictNullChecks": false,
25
+ "noImplicitAny": false,
26
+ "strictBindCallApply": false,
27
+ "noFallthroughCasesInSwitch": false
28
+ },
29
+ "include": ["src/**/*.ts"],
30
+ "exclude": ["node_modules", "dist"]
31
+ }