@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.
- package/.prettierignore +1 -0
- package/README.md +0 -0
- package/bin/cli.js +3 -0
- package/package.json +27 -0
- package/src/commands/create-new.command.js +52 -0
- package/src/commands/generate.command.js +57 -0
- package/src/index.js +14 -0
- package/src/new-app-generator/app-module.generator.js +15 -0
- package/src/new-app-generator/app.generator.js +21 -0
- package/src/new-app-generator/application.generator.js +27 -0
- package/src/new-app-generator/common.generator.js +27 -0
- package/src/new-app-generator/domain.generator.js +34 -0
- package/src/new-app-generator/env-example.generator.js +25 -0
- package/src/new-app-generator/infra.generator.js +210 -0
- package/src/new-app-generator/main.generator.js +16 -0
- package/src/new-app-generator/package.generator.js +42 -0
- package/src/new-app-generator/tsconfig.generator.js +15 -0
- package/src/new-module-handler/controller.handlers.js +70 -0
- package/src/new-module-handler/datasources.handlers.js +37 -0
- package/src/new-module-handler/entity.handlers.js +75 -0
- package/src/new-module-handler/module.handlers.js +17 -0
- package/src/new-module-handler/repositories.handlers.js +87 -0
- package/src/new-module-handler/service.handlers.js +97 -0
- package/src/new-module-handler/usecase.handlers.js +67 -0
- package/src/utils/format.js +20 -0
- package/src/utils/get-ejs-files.js +9 -0
- package/src/utils/get-folders.js +8 -0
- package/src/utils/get-relative-path.js +7 -0
- package/src/utils/has-directory.js +10 -0
- package/src/utils/install-packages.js +19 -0
- package/src/utils/update-files.js +194 -0
- package/src/utils/write-file.js +12 -0
- package/templates/app/env.example.ejs +9 -0
- package/templates/app/package.json.ejs +12 -0
- package/templates/app/src/app.module.ejs +11 -0
- package/templates/app/src/application/application.module.ejs +11 -0
- package/templates/app/src/application/dto/index.ejs +0 -0
- package/templates/app/src/application/services/index.ejs +1 -0
- package/templates/app/src/application/services/service.module.ejs +8 -0
- package/templates/app/src/application/usecases/index.ejs +1 -0
- package/templates/app/src/application/usecases/usecase.module.ejs +8 -0
- package/templates/app/src/common/decorators/index.ejs +0 -0
- package/templates/app/src/common/enum/index.ejs +0 -0
- package/templates/app/src/common/helpers/index.ejs +0 -0
- package/templates/app/src/common/interfaces/index.ejs +0 -0
- package/templates/app/src/common/types/condition.d.ejs +3 -0
- package/templates/app/src/common/types/index.ejs +4 -0
- package/templates/app/src/common/types/pagination.d.ejs +34 -0
- package/templates/app/src/common/types/relation.d.ejs +3 -0
- package/templates/app/src/common/types/transactional.d.ejs +4 -0
- package/templates/app/src/domain/datasource/datasource.ejs +5 -0
- package/templates/app/src/domain/datasource/index.ejs +1 -0
- package/templates/app/src/domain/entities/base.entity.ejs +18 -0
- package/templates/app/src/domain/entities/index.ejs +1 -0
- package/templates/app/src/domain/repositories/generic.repository.ejs +25 -0
- package/templates/app/src/domain/repositories/index.ejs +1 -0
- package/templates/app/src/domain/services/index.ejs +0 -0
- package/templates/app/src/domain/usecase/base.usecase.ejs +3 -0
- package/templates/app/src/domain/usecase/index.ejs +1 -0
- package/templates/app/src/infra/controllers/controller.module.ejs +9 -0
- package/templates/app/src/infra/controllers/demo/demo-controller.module.ejs +7 -0
- package/templates/app/src/infra/controllers/demo/demo.controller.ejs +9 -0
- package/templates/app/src/infra/datasource/[database]/[database].datasource.ejs +15 -0
- package/templates/app/src/infra/datasource/[database]/[database].module.ejs +16 -0
- package/templates/app/src/infra/datasource/[database]/entities/base.entity.ejs +53 -0
- package/templates/app/src/infra/datasource/[database]/entities/index.ejs +1 -0
- package/templates/app/src/infra/datasource/[database]/providers/[database].provider.ejs +30 -0
- package/templates/app/src/infra/datasource/[database]/providers/index.ejs +1 -0
- package/templates/app/src/infra/datasource/[database]/repositories/[database]-generic.repository.ejs +117 -0
- package/templates/app/src/infra/datasource/[database]/repositories/index.ejs +1 -0
- package/templates/app/src/infra/datasource/datasource.module.ejs +7 -0
- package/templates/app/src/infra/infra.module.ejs +13 -0
- package/templates/app/src/infra/server/filters/index.ejs +0 -0
- package/templates/app/src/infra/server/guard/index.ejs +0 -0
- package/templates/app/src/infra/server/interceptor/index.ejs +0 -0
- package/templates/app/src/infra/server/middleware/index.ejs +0 -0
- package/templates/app/src/infra/server/server.module.ejs +7 -0
- package/templates/app/src/main.ejs +10 -0
- package/templates/app/tsconfig.json.ejs +31 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {
|
|
2
|
+
addDatabaseProvider,
|
|
3
|
+
updateDataSourceDomain,
|
|
4
|
+
updateDBDataSource,
|
|
5
|
+
} from "../utils/update-files.js";
|
|
6
|
+
import path from "path";
|
|
7
|
+
|
|
8
|
+
async function handleDataSourceDomain(className) {
|
|
9
|
+
const root = path.join(process.cwd(), "src/domain/datasource/datasource.ts");
|
|
10
|
+
await updateDataSourceDomain(root, className);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async function handleDBDataSource(className, dbName) {
|
|
14
|
+
const root = path.join(
|
|
15
|
+
process.cwd(),
|
|
16
|
+
"src/infra/datasource",
|
|
17
|
+
dbName,
|
|
18
|
+
`${dbName}.datasource.ts`
|
|
19
|
+
);
|
|
20
|
+
await updateDBDataSource(root, className, dbName);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function handleDatabaseProvider(className, dbName) {
|
|
24
|
+
const root = path.join(
|
|
25
|
+
process.cwd(),
|
|
26
|
+
"src/infra/datasource",
|
|
27
|
+
dbName,
|
|
28
|
+
`providers/${dbName}.provider.ts`
|
|
29
|
+
);
|
|
30
|
+
await addDatabaseProvider(root, `${dbName}Providers`, className, dbName);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function handleDatasources(className, dbName) {
|
|
34
|
+
await handleDatabaseProvider(className, dbName);
|
|
35
|
+
await handleDataSourceDomain(className);
|
|
36
|
+
await handleDBDataSource(className, dbName);
|
|
37
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { updateIndex } from "../utils/update-files.js";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import ejs from "ejs";
|
|
4
|
+
import { writeFile } from "../utils/write-file.js";
|
|
5
|
+
|
|
6
|
+
async function handleDomainEntity(fileName, className) {
|
|
7
|
+
const root = path.join(
|
|
8
|
+
process.cwd(),
|
|
9
|
+
"src/domain/entities",
|
|
10
|
+
`${fileName}.entity.ts`
|
|
11
|
+
);
|
|
12
|
+
const contents = await ejs.render(
|
|
13
|
+
`
|
|
14
|
+
import { BaseEntity } from "./base.entity";
|
|
15
|
+
|
|
16
|
+
export class <%= className %>Entity extends BaseEntity{
|
|
17
|
+
|
|
18
|
+
}
|
|
19
|
+
`,
|
|
20
|
+
{
|
|
21
|
+
className: className,
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
async: true,
|
|
25
|
+
}
|
|
26
|
+
);
|
|
27
|
+
await writeFile(root, contents);
|
|
28
|
+
await updateIndex(
|
|
29
|
+
path.join(process.cwd(), "src/domain/entities", `index.ts`),
|
|
30
|
+
`./${fileName}.entity`
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function handleDatasourceEntity(fileName, className, dbName) {
|
|
35
|
+
const root = path.join(
|
|
36
|
+
process.cwd(),
|
|
37
|
+
"src/infra/datasource",
|
|
38
|
+
dbName,
|
|
39
|
+
`entities/${fileName}.${dbName}.entity.ts`
|
|
40
|
+
);
|
|
41
|
+
const contents = await ejs.render(
|
|
42
|
+
`
|
|
43
|
+
import { Entity } from "typeorm";
|
|
44
|
+
import { BaseEntity } from "./base.entity";
|
|
45
|
+
import { <%= className %>Entity } from "../../../../domain/entities";
|
|
46
|
+
|
|
47
|
+
@Entity('<%= entity %>')
|
|
48
|
+
export class <%= className %><%= Database %>Entity extends BaseEntity implements <%= className %>Entity{
|
|
49
|
+
|
|
50
|
+
}
|
|
51
|
+
`,
|
|
52
|
+
{
|
|
53
|
+
className: className,
|
|
54
|
+
entity: className.toLowerCase(),
|
|
55
|
+
Database: dbName.charAt(0).toUpperCase() + dbName.slice(1),
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
async: true,
|
|
59
|
+
}
|
|
60
|
+
);
|
|
61
|
+
await writeFile(root, contents);
|
|
62
|
+
await updateIndex(
|
|
63
|
+
path.join(
|
|
64
|
+
process.cwd(),
|
|
65
|
+
"src/infra/datasource",
|
|
66
|
+
`${dbName}/entities`,
|
|
67
|
+
`index.ts`
|
|
68
|
+
),
|
|
69
|
+
`./${fileName}.${dbName}.entity`
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
export async function handleEntity(fileName, className, dbName) {
|
|
73
|
+
await handleDomainEntity(fileName, className);
|
|
74
|
+
await handleDatasourceEntity(fileName, className, dbName);
|
|
75
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { handleController } from "./controller.handlers.js";
|
|
2
|
+
import { handleDatasources } from "./datasources.handlers.js";
|
|
3
|
+
import { handleEntity } from "./entity.handlers.js";
|
|
4
|
+
import { handleRepository } from "./repositories.handlers.js";
|
|
5
|
+
import { serviceHandler } from "./service.handlers.js";
|
|
6
|
+
import { handleUseCase } from "./usecase.handlers.js";
|
|
7
|
+
|
|
8
|
+
export async function handleModule(className, fileName, dbName) {
|
|
9
|
+
if (dbName) {
|
|
10
|
+
await handleEntity(fileName, className, dbName);
|
|
11
|
+
await handleRepository(fileName, className, dbName);
|
|
12
|
+
await handleDatasources(className, dbName);
|
|
13
|
+
}
|
|
14
|
+
await serviceHandler(className, fileName, dbName);
|
|
15
|
+
await handleUseCase(className, fileName);
|
|
16
|
+
await handleController(className, fileName);
|
|
17
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { updateIndex } from "../utils/update-files.js";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import ejs from "ejs";
|
|
4
|
+
import { writeFile } from "../utils/write-file.js";
|
|
5
|
+
|
|
6
|
+
async function handleDomainRepository(fileName, className) {
|
|
7
|
+
const root = path.join(
|
|
8
|
+
process.cwd(),
|
|
9
|
+
"src/domain/repositories",
|
|
10
|
+
`${fileName}.repository.ts`
|
|
11
|
+
);
|
|
12
|
+
const contents = await ejs.render(
|
|
13
|
+
`
|
|
14
|
+
import { <%= className %>Entity } from "../entities";
|
|
15
|
+
import { GenericRepository } from "./generic.repository";
|
|
16
|
+
|
|
17
|
+
export interface I<%= className %>Repository extends GenericRepository<<%= className %>Entity> {
|
|
18
|
+
|
|
19
|
+
}
|
|
20
|
+
`,
|
|
21
|
+
{
|
|
22
|
+
className: className,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
async: true,
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
await writeFile(root, contents);
|
|
29
|
+
await updateIndex(
|
|
30
|
+
path.join(process.cwd(), "src/domain/repositories", `index.ts`),
|
|
31
|
+
`./${fileName}.repository`
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function handleDatasourceRepository(fileName, className, dbName) {
|
|
36
|
+
const root = path.join(
|
|
37
|
+
process.cwd(),
|
|
38
|
+
"src/infra/datasource",
|
|
39
|
+
dbName,
|
|
40
|
+
`repositories/${fileName}.${dbName}.repository.ts`
|
|
41
|
+
);
|
|
42
|
+
const contents = await ejs.render(
|
|
43
|
+
`
|
|
44
|
+
import { DataSource, Repository } from "typeorm";
|
|
45
|
+
import { <%= className %>Entity } from "../../../../domain/entities";
|
|
46
|
+
import { I<%= className %>Repository } from "../../../../domain/repositories";
|
|
47
|
+
import { <%= Database %>GenericRepository } from "./<%= database %>-generic.repository";
|
|
48
|
+
import { <%= className %><%= Database %>Entity } from "../entities";
|
|
49
|
+
import { Inject } from "@sharangyawali/sg-app";
|
|
50
|
+
import { DATA_SOURCE_<%= DATABASE %> } from "../providers";
|
|
51
|
+
|
|
52
|
+
export class <%= className %><%= Database %>RepositoryImp extends <%= Database %>GenericRepository<<%= className %>Entity> implements I<%= className %>Repository {
|
|
53
|
+
constructor(
|
|
54
|
+
protected readonly repo: Repository<<%= className %><%= Database %>Entity>,
|
|
55
|
+
@Inject(DATA_SOURCE_<%= DATABASE %>)
|
|
56
|
+
protected readonly dataSource: DataSource,
|
|
57
|
+
) {
|
|
58
|
+
super(repo, dataSource, '<%= entity %>');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
`,
|
|
62
|
+
{
|
|
63
|
+
className: className,
|
|
64
|
+
entity: className.toLowerCase(),
|
|
65
|
+
database: dbName,
|
|
66
|
+
DATABASE: dbName.toUpperCase(),
|
|
67
|
+
Database: dbName.charAt(0).toUpperCase() + dbName.slice(1),
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
async: true,
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
await writeFile(root, contents);
|
|
74
|
+
await updateIndex(
|
|
75
|
+
path.join(
|
|
76
|
+
process.cwd(),
|
|
77
|
+
"src/infra/datasource",
|
|
78
|
+
`${dbName}/repositories`,
|
|
79
|
+
`index.ts`
|
|
80
|
+
),
|
|
81
|
+
`./${fileName}.${dbName}.repository`
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
export async function handleRepository(fileName, className, dbName) {
|
|
85
|
+
await handleDomainRepository(fileName, className);
|
|
86
|
+
await handleDatasourceRepository(fileName, className, dbName);
|
|
87
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { updateIndex, updateModulesProviders } from "../utils/update-files.js";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import ejs from "ejs";
|
|
4
|
+
import { writeFile } from "../utils/write-file.js";
|
|
5
|
+
|
|
6
|
+
async function handleServiceDomain(className, fileName) {
|
|
7
|
+
const root = path.join(
|
|
8
|
+
process.cwd(),
|
|
9
|
+
"src/domain/services",
|
|
10
|
+
`${fileName}.service.ts`,
|
|
11
|
+
);
|
|
12
|
+
const contents = await ejs.render(
|
|
13
|
+
`
|
|
14
|
+
export interface I<%= className %>Service{
|
|
15
|
+
|
|
16
|
+
}
|
|
17
|
+
`,
|
|
18
|
+
{
|
|
19
|
+
className: className,
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
async: true,
|
|
23
|
+
},
|
|
24
|
+
);
|
|
25
|
+
await writeFile(root, contents);
|
|
26
|
+
await updateIndex(
|
|
27
|
+
path.join(process.cwd(), "src/domain/services", `index.ts`),
|
|
28
|
+
`./${fileName}.service`,
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function handleApplicationService(className, fileName, dbName) {
|
|
33
|
+
const root = path.join(
|
|
34
|
+
process.cwd(),
|
|
35
|
+
"src/application/services",
|
|
36
|
+
`${fileName}.service.ts`,
|
|
37
|
+
);
|
|
38
|
+
let contents;
|
|
39
|
+
if (dbName) {
|
|
40
|
+
contents = await ejs.render(
|
|
41
|
+
`
|
|
42
|
+
import { Component, Inject } from "@sharangyawali/sg-app";
|
|
43
|
+
import {I<%= className %>Service} from "../../domain/services";
|
|
44
|
+
import { I<%= className %>Repository } from "../../domain/repositories";
|
|
45
|
+
import { IDatasource } from "../../domain/datasource";
|
|
46
|
+
|
|
47
|
+
@Component()
|
|
48
|
+
export class <%= className %>ServiceImp implements I<%= className %>Service{
|
|
49
|
+
private readonly repo: I<%= className %>Repository;
|
|
50
|
+
constructor(
|
|
51
|
+
@Inject(IDatasource)
|
|
52
|
+
private _datasource:IDatasource
|
|
53
|
+
) {
|
|
54
|
+
this.repo=_datasource.${className.toLowerCase()}Repo
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
`,
|
|
58
|
+
{
|
|
59
|
+
className,
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
async: true,
|
|
63
|
+
},
|
|
64
|
+
);
|
|
65
|
+
} else {
|
|
66
|
+
contents = await ejs.render(
|
|
67
|
+
`
|
|
68
|
+
import { Inject } from "@sharangyawali/sg-app";
|
|
69
|
+
import {I<%= className %>Service} from "../../domain/services";
|
|
70
|
+
|
|
71
|
+
export class <%= className %>ServiceImp implements I<%= className %>Service{}
|
|
72
|
+
`,
|
|
73
|
+
{
|
|
74
|
+
className,
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
async: true,
|
|
78
|
+
},
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
await writeFile(root, contents);
|
|
82
|
+
await updateIndex(
|
|
83
|
+
path.join(process.cwd(), "src/application/services", `index.ts`),
|
|
84
|
+
`./${fileName}.service`,
|
|
85
|
+
);
|
|
86
|
+
await updateModulesProviders(
|
|
87
|
+
path.join(process.cwd(), "src/application/services", `service.module.ts`),
|
|
88
|
+
"ServiceModule",
|
|
89
|
+
`./${fileName}.service`,
|
|
90
|
+
`${className}ServiceImp`,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export async function serviceHandler(className, fileName, dbName) {
|
|
95
|
+
await handleServiceDomain(className, fileName);
|
|
96
|
+
await handleApplicationService(className, fileName, dbName);
|
|
97
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { updateIndex, updateModulesProviders } from "../utils/update-files.js";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import ejs from "ejs";
|
|
4
|
+
import { writeFile } from "../utils/write-file.js";
|
|
5
|
+
|
|
6
|
+
async function handleNewUseCaseModule(className, fileName) {
|
|
7
|
+
const root = path.join(
|
|
8
|
+
process.cwd(),
|
|
9
|
+
"src/application/usecases",
|
|
10
|
+
fileName,
|
|
11
|
+
`${fileName}.usecase.module.ts`,
|
|
12
|
+
);
|
|
13
|
+
const contents = await ejs.render(
|
|
14
|
+
`
|
|
15
|
+
import { Module } from "@sharangyawali/sg-app";
|
|
16
|
+
|
|
17
|
+
@Module({
|
|
18
|
+
providers: []
|
|
19
|
+
})
|
|
20
|
+
export class <%= className %>UseCaseModule { }
|
|
21
|
+
`,
|
|
22
|
+
{
|
|
23
|
+
className: className,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
async: true,
|
|
27
|
+
},
|
|
28
|
+
);
|
|
29
|
+
await writeFile(root, contents);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function handleNewImport(className, fileName) {
|
|
33
|
+
const root = path.join(
|
|
34
|
+
process.cwd(),
|
|
35
|
+
"src/application/usecases",
|
|
36
|
+
fileName,
|
|
37
|
+
`index.ts`,
|
|
38
|
+
);
|
|
39
|
+
const contents = await ejs.render(
|
|
40
|
+
`
|
|
41
|
+
export * from './<%= fileName %>.usecase.module';
|
|
42
|
+
`,
|
|
43
|
+
{
|
|
44
|
+
fileName,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
async: true,
|
|
48
|
+
},
|
|
49
|
+
);
|
|
50
|
+
await writeFile(root, contents);
|
|
51
|
+
await updateIndex(
|
|
52
|
+
path.join(process.cwd(), "src/application/usecases", `index.ts`),
|
|
53
|
+
`./${fileName}`,
|
|
54
|
+
);
|
|
55
|
+
await updateModulesProviders(
|
|
56
|
+
path.join(process.cwd(), "src/application/usecases", `usecase.module.ts`),
|
|
57
|
+
"UseCaseModule",
|
|
58
|
+
`./${fileName}`,
|
|
59
|
+
`${className}UseCaseModule`,
|
|
60
|
+
true,
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export async function handleUseCase(className, fileName) {
|
|
65
|
+
await handleNewUseCaseModule(className, fileName);
|
|
66
|
+
await handleNewImport(className, fileName);
|
|
67
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import prettier from "prettier";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
|
|
4
|
+
export async function format(content, filePath) {
|
|
5
|
+
const options = await prettier.resolveConfig(process.cwd());
|
|
6
|
+
return prettier.format(content, {
|
|
7
|
+
...options,
|
|
8
|
+
filepath: filePath,
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export async function prettify(filePath) {
|
|
13
|
+
const source = fs.readFileSync(filePath, "utf8");
|
|
14
|
+
const config = await prettier.resolveConfig(filePath);
|
|
15
|
+
const formatted = await prettier.format(source, {
|
|
16
|
+
...config,
|
|
17
|
+
filepath: filePath,
|
|
18
|
+
});
|
|
19
|
+
fs.writeFileSync(filePath, formatted);
|
|
20
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { spawn } from "child_process";
|
|
2
|
+
import path from "path";
|
|
3
|
+
|
|
4
|
+
export async function installPackages(appName, pkg) {
|
|
5
|
+
return new Promise((resolve, reject) => {
|
|
6
|
+
const npmCmd = process.platform === "win32" ? "npm.cmd" : "npm";
|
|
7
|
+
const directory = path.join(process.cwd(), appName);
|
|
8
|
+
const child = spawn(npmCmd, ["i", ...pkg], {
|
|
9
|
+
cwd: directory,
|
|
10
|
+
shell: true,
|
|
11
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
child.on("close", (code) => {
|
|
15
|
+
if (code === 0) resolve();
|
|
16
|
+
else reject(new Error(`npm install exited with code ${code}\n${stderr}`));
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { Project, StructureKind, SyntaxKind } from "ts-morph";
|
|
2
|
+
import { prettify } from "./format.js";
|
|
3
|
+
function checkDublicateImport(sourceFile, moduleSpecifier, namedImports) {
|
|
4
|
+
return sourceFile
|
|
5
|
+
.getImportDeclarations()
|
|
6
|
+
.find(
|
|
7
|
+
(i) =>
|
|
8
|
+
(i.getModuleSpecifier =
|
|
9
|
+
moduleSpecifier && i.getNamedImports == namedImports),
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export async function updateIndex(indexFilePath, importPath) {
|
|
14
|
+
const project = new Project({
|
|
15
|
+
tsConfigFilePath: "tsconfig.json",
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const sourceFile = project.getSourceFileOrThrow(indexFilePath);
|
|
19
|
+
sourceFile.addExportDeclaration({
|
|
20
|
+
moduleSpecifier: importPath,
|
|
21
|
+
});
|
|
22
|
+
await sourceFile.save();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export async function updateDataSourceDomain(providerPath, className) {
|
|
26
|
+
const project = new Project({
|
|
27
|
+
tsConfigFilePath: "tsconfig.json",
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const sourceFile = project.getSourceFileOrThrow(providerPath);
|
|
31
|
+
sourceFile.addImportDeclaration({
|
|
32
|
+
moduleSpecifier: "../repositories",
|
|
33
|
+
namedImports: `I${className}Repository`,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const datasourceClass = sourceFile.getClassOrThrow("IDatasource");
|
|
37
|
+
|
|
38
|
+
datasourceClass.addProperty({
|
|
39
|
+
name: `${className.toLowerCase()}Repo`,
|
|
40
|
+
type: `I${className}Repository`,
|
|
41
|
+
hasExclamationToken: false,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
await sourceFile.save();
|
|
45
|
+
prettify(providerPath);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export async function updateModulesProviders(
|
|
49
|
+
path,
|
|
50
|
+
className,
|
|
51
|
+
moduleSpecifier,
|
|
52
|
+
providerName,
|
|
53
|
+
isImport,
|
|
54
|
+
) {
|
|
55
|
+
const project = new Project({
|
|
56
|
+
tsConfigFilePath: "tsconfig.json",
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const sourceFile = project.getSourceFileOrThrow(path);
|
|
60
|
+
sourceFile.addImportDeclaration({
|
|
61
|
+
moduleSpecifier,
|
|
62
|
+
namedImports: providerName,
|
|
63
|
+
});
|
|
64
|
+
const moduleClass = sourceFile.getClassOrThrow(className);
|
|
65
|
+
const moduleDecorator = moduleClass.getDecorator("Module");
|
|
66
|
+
const moduleOptions = moduleDecorator.getArguments()[0];
|
|
67
|
+
const providersArray = moduleOptions
|
|
68
|
+
.asKindOrThrow(SyntaxKind.ObjectLiteralExpression)
|
|
69
|
+
.getProperty(isImport ? "imports" : "providers");
|
|
70
|
+
if (providersArray) {
|
|
71
|
+
const providers = providersArray.getInitializer();
|
|
72
|
+
if (providers) {
|
|
73
|
+
providers.addElement(providerName);
|
|
74
|
+
}
|
|
75
|
+
} else {
|
|
76
|
+
moduleOptions.addPropertyAssignment({
|
|
77
|
+
name: isImport ? "imports" : "providers",
|
|
78
|
+
initializer: `[${providerName}]`,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
await sourceFile.save();
|
|
82
|
+
prettify(path);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export async function updateDBDataSource(providerPath, className, dbName) {
|
|
86
|
+
const project = new Project({
|
|
87
|
+
tsConfigFilePath: "tsconfig.json",
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const sourceFile = project.getSourceFileOrThrow(providerPath);
|
|
91
|
+
sourceFile.addImportDeclaration({
|
|
92
|
+
moduleSpecifier: "../../../domain/repositories",
|
|
93
|
+
namedImports: `I${className}Repository`,
|
|
94
|
+
});
|
|
95
|
+
sourceFile.addImportDeclaration({
|
|
96
|
+
moduleSpecifier: "../../../domain/entities",
|
|
97
|
+
namedImports: `${className}Entity`,
|
|
98
|
+
});
|
|
99
|
+
sourceFile.addImportDeclaration({
|
|
100
|
+
moduleSpecifier: "./entities",
|
|
101
|
+
namedImports: `${className}${dbName.charAt(0).toUpperCase() + dbName.slice(1)}Entity`,
|
|
102
|
+
});
|
|
103
|
+
sourceFile.addImportDeclaration({
|
|
104
|
+
moduleSpecifier: "./repositories",
|
|
105
|
+
namedImports: `${className}${dbName.charAt(0).toUpperCase() + dbName.slice(1)}RepositoryImp`,
|
|
106
|
+
});
|
|
107
|
+
const dublicate = checkDublicateImport(sourceFile, "typeorm", "Repository");
|
|
108
|
+
if (!dublicate)
|
|
109
|
+
sourceFile.addImportDeclaration({
|
|
110
|
+
moduleSpecifier: "typeorm",
|
|
111
|
+
namedImports: "Repository",
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const datasourceClass = sourceFile.getClassOrThrow(
|
|
115
|
+
`${dbName.charAt(0).toUpperCase() + dbName.slice(1)}DataSource`,
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
datasourceClass.addProperty({
|
|
119
|
+
name: `public ${className.toLowerCase()}Repo`,
|
|
120
|
+
type: `I${className}Repository`,
|
|
121
|
+
hasExclamationToken: false,
|
|
122
|
+
});
|
|
123
|
+
const [constructor] = datasourceClass.getConstructors();
|
|
124
|
+
constructor.addParameter({
|
|
125
|
+
name: `private _${className.toLowerCase()}Repo`,
|
|
126
|
+
type: `Repository<${className}${dbName.charAt(0).toUpperCase() + dbName.slice(1)}Entity>`,
|
|
127
|
+
decorators: [
|
|
128
|
+
{
|
|
129
|
+
name: "Inject",
|
|
130
|
+
arguments: [`${className}Entity.InjectableString`],
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
});
|
|
134
|
+
constructor.addStatements([
|
|
135
|
+
`this.${className.toLowerCase()}Repo = new ${className}${dbName.charAt(0).toUpperCase() + dbName.slice(1)}RepositoryImp(
|
|
136
|
+
this._${className.toLowerCase()}Repo,
|
|
137
|
+
this._datasource
|
|
138
|
+
)`,
|
|
139
|
+
]);
|
|
140
|
+
|
|
141
|
+
await sourceFile.save();
|
|
142
|
+
prettify(providerPath);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export async function addDatabaseProvider(
|
|
146
|
+
providerPath,
|
|
147
|
+
providerVariable,
|
|
148
|
+
className,
|
|
149
|
+
dbName,
|
|
150
|
+
) {
|
|
151
|
+
const project = new Project({
|
|
152
|
+
tsConfigFilePath: "tsconfig.json",
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
const sourceFile = project.getSourceFileOrThrow(providerPath);
|
|
156
|
+
|
|
157
|
+
sourceFile.addImportDeclaration({
|
|
158
|
+
moduleSpecifier: "../../../../domain/entities",
|
|
159
|
+
namedImports: `${className}Entity`,
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
sourceFile.addImportDeclaration({
|
|
163
|
+
moduleSpecifier: "../entities",
|
|
164
|
+
namedImports: `${className}${dbName.charAt(0).toUpperCase() + dbName.slice(1)}Entity`,
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
const declaration =
|
|
168
|
+
sourceFile.getVariableDeclarationOrThrow(providerVariable);
|
|
169
|
+
|
|
170
|
+
const providers = declaration.getInitializerIfKindOrThrow(
|
|
171
|
+
SyntaxKind.ArrayLiteralExpression,
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
providers.addElement((writer) => {
|
|
175
|
+
writer
|
|
176
|
+
.write("{")
|
|
177
|
+
.indent(() => {
|
|
178
|
+
writer.writeLine(`token: ${className}Entity.InjectableString,`);
|
|
179
|
+
writer.writeLine(`scope: Scope.SINGLETON,`);
|
|
180
|
+
writer.writeLine(`useFactory(datasource: DataSource) {`);
|
|
181
|
+
writer.indent(() => {
|
|
182
|
+
writer.writeLine(
|
|
183
|
+
`return datasource?.getRepository(${className}${dbName.charAt(0).toUpperCase() + dbName.slice(1)}Entity);`,
|
|
184
|
+
);
|
|
185
|
+
});
|
|
186
|
+
writer.writeLine("},");
|
|
187
|
+
writer.writeLine(`inject: [DATA_SOURCE_${dbName.toUpperCase()}],`);
|
|
188
|
+
})
|
|
189
|
+
.write("}");
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
await sourceFile.save();
|
|
193
|
+
prettify(providerPath);
|
|
194
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import fs from "fs-extra";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { format } from "./format.js";
|
|
4
|
+
|
|
5
|
+
export async function writeFile(filePath, content, excludeFormat) {
|
|
6
|
+
await fs.ensureDir(path.dirname(filePath));
|
|
7
|
+
let formatted;
|
|
8
|
+
if (!excludeFormat) formatted = await format(content, filePath);
|
|
9
|
+
else formatted = content;
|
|
10
|
+
|
|
11
|
+
await fs.writeFile(filePath, formatted);
|
|
12
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#APPLICATION
|
|
2
|
+
APP_PORT = "<< APP_PORT HERE >>"
|
|
3
|
+
|
|
4
|
+
#DATABASE
|
|
5
|
+
<%= DATABASE %>_HOST = "<< <%= DATABASE %>_HOST HERE >>"
|
|
6
|
+
<%= DATABASE %>_PORT = "<< <%= DATABASE %>_PORT HERE >>"
|
|
7
|
+
<%= DATABASE %>_USER = "<< <%= DATABASE %>_USER HERE >>"
|
|
8
|
+
<%= DATABASE %>_PASSWORD = "<< <%= DATABASE %>_PASSWORD HERE >>"
|
|
9
|
+
<%= DATABASE %>_DB = "<< <%= DATABASE %>_DB HERE >>"
|