nestjs-typeorm3-kit 0.1.2 → 0.1.4
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.
package/README.md
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# nestjs-typeorm3-kit
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/nestjs-typeorm3-kit) 
|
|
4
|
+
|
|
5
|
+
## [Node.js] nestjs-typeorm3-kit
|
|
6
|
+
|
|
7
|
+
### Installation
|
|
8
|
+
|
|
9
|
+
#### NPM
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install nestjs-typeorm3-kit typeorm-transactional
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
#### Yarn
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
yarn add nestjs-typeorm3-kit typeorm-transactional
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
#### pnpm
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pnpm add nestjs-typeorm3-kit typeorm-transactional
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
#### bun
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
bun add nestjs-typeorm3-kit typeorm-transactional
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Config after install
|
|
34
|
+
|
|
35
|
+
#### Use @DefEntityRepository
|
|
36
|
+
|
|
37
|
+
For using `@DefEntityRepository` instead of `@EntityRepository` of typeorm 0.2, you need to add the following code in `main.ts` or `app.module.ts`:
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
import { TypeOrmModule } from "@nestjs/typeorm";
|
|
41
|
+
|
|
42
|
+
TypeOrmModule.forRootAsync({
|
|
43
|
+
useFactory: () => ({
|
|
44
|
+
type: "postgres",
|
|
45
|
+
host: "localhost",
|
|
46
|
+
port: 5432,
|
|
47
|
+
username: "postgres",
|
|
48
|
+
password: "Abc12345",
|
|
49
|
+
database: "primary_db",
|
|
50
|
+
entities: [join(__dirname, "./domains/primary/**/*.entity.{ts,js}")],
|
|
51
|
+
synchronize: true,
|
|
52
|
+
autoLoadEntities: true,
|
|
53
|
+
retryAttempts: 2,
|
|
54
|
+
retryDelay: 1000,
|
|
55
|
+
}),
|
|
56
|
+
dataSourceFactory: async (options: DataSourceOptions) => {
|
|
57
|
+
if (!options) {
|
|
58
|
+
throw new Error("Invalid options passed");
|
|
59
|
+
}
|
|
60
|
+
return addTransactionalDataSource({
|
|
61
|
+
dataSource: new DataSource(options),
|
|
62
|
+
name: PRIMARY_CONNECTION,
|
|
63
|
+
});
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
#### create Repository module Use @DefRepositoryModule
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
import { Module } from "@nestjs/common";
|
|
72
|
+
import { join } from "path";
|
|
73
|
+
|
|
74
|
+
import { PRIMARY_CONNECTION } from "~/common/constants";
|
|
75
|
+
import { DefRepositoryModule } from "nestjs-typeorm3-kit";
|
|
76
|
+
@Module({
|
|
77
|
+
imports: [
|
|
78
|
+
DefRepositoryModule.forRootAsync({
|
|
79
|
+
useFactory: () => ({
|
|
80
|
+
globPattern: join(__dirname, "./**/*.repo.{ts,js}"),
|
|
81
|
+
dataSource: PRIMARY_CONNECTION,
|
|
82
|
+
}),
|
|
83
|
+
}),
|
|
84
|
+
],
|
|
85
|
+
exports: [DefRepositoryModule],
|
|
86
|
+
})
|
|
87
|
+
export class PrimaryRepoModule {}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
or
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
import { Module } from "@nestjs/common";
|
|
94
|
+
import { join } from "path";
|
|
95
|
+
|
|
96
|
+
import { PRIMARY_CONNECTION } from "~/common/constants";
|
|
97
|
+
import { DefRepositoryModule } from "nestjs-typeorm3-kit";
|
|
98
|
+
@Module({
|
|
99
|
+
imports: [
|
|
100
|
+
DefRepositoryModule.forFeature([BookRepo, PhotoRepo], PRIMARY_CONNECTION),
|
|
101
|
+
],
|
|
102
|
+
exports: [DefRepositoryModule],
|
|
103
|
+
})
|
|
104
|
+
export class PrimaryRepoModule {}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
#### Use @DefTransaction
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
import { Injectable } from "@nestjs/common";
|
|
111
|
+
import { DefTransaction, InjectRepo } from "nestjs-typeorm3-kit";
|
|
112
|
+
import { PhotoRepo } from "~/domains/primary/photo/photo.repo";
|
|
113
|
+
import { BookRepo } from "~/domains/primary/book/book.repo";
|
|
114
|
+
|
|
115
|
+
const PRIMARY_CONNECTION = "default";
|
|
116
|
+
const SECONDARY_CONNECTION = "secondary_db";
|
|
117
|
+
@Injectable()
|
|
118
|
+
export class DemoService {
|
|
119
|
+
constructor(
|
|
120
|
+
readonly photoRepo: PhotoRepo,
|
|
121
|
+
@InjectRepo(BookRepo, PRIMARY_CONNECTION)
|
|
122
|
+
readonly bookRepo: BookRepo
|
|
123
|
+
) {}
|
|
124
|
+
|
|
125
|
+
@DefTransaction()
|
|
126
|
+
create(body: any) {
|
|
127
|
+
return this.photoRepo.save(body);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// secondary connection
|
|
132
|
+
@Injectable()
|
|
133
|
+
export class DemoService {
|
|
134
|
+
constructor(
|
|
135
|
+
@InjectRepo(ExampleRepo, SECONDARY_CONNECTION)
|
|
136
|
+
readonly exampleRepo: ExampleRepo,
|
|
137
|
+
@InjectRepo(DataLogRepo, SECONDARY_CONNECTION)
|
|
138
|
+
readonly dataLogRepo: DataLogRepo
|
|
139
|
+
) {}
|
|
140
|
+
|
|
141
|
+
@DefTransaction({ connectionName: SECONDARY_CONNECTION })
|
|
142
|
+
create(body: any) {
|
|
143
|
+
return this.photoRepo.save(body);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### Use wraper Controller and ChildModule
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
import { DefController } from "nestjs-typeorm3-kit";
|
|
152
|
+
|
|
153
|
+
@Controller("demo")
|
|
154
|
+
export class DemoController {
|
|
155
|
+
constructor(private readonly demoService: DemoService) {}
|
|
156
|
+
|
|
157
|
+
@DefGet()
|
|
158
|
+
list(@Query() query: any) {
|
|
159
|
+
return this.demoService.list(query);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
@DefPost()
|
|
163
|
+
create(@Body() body: any) {
|
|
164
|
+
return this.demoService.create(body);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// child module suport prefix route and API TAG swagger
|
|
169
|
+
@ChildModule({
|
|
170
|
+
prefix: REFIX_MODULE.client,
|
|
171
|
+
imports: [PrimaryRepoModule, SecondaryRepoModule],
|
|
172
|
+
providers: [DemoService, ExampleService],
|
|
173
|
+
controllers: [ExampleController, DemoController],
|
|
174
|
+
})
|
|
175
|
+
export class ClientModule implements NestModule {
|
|
176
|
+
configure(consumer: MiddlewareConsumer) {}
|
|
177
|
+
}
|
|
178
|
+
// setup swagger beautiful in main.ts
|
|
179
|
+
// main.ts
|
|
180
|
+
import { NestFactory } from "@nestjs/core";
|
|
181
|
+
import { AppModule } from "./app.module";
|
|
182
|
+
import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger";
|
|
183
|
+
import { getFromContainer, MetadataStorage } from "class-validator";
|
|
184
|
+
import { SchemasObject } from "@nestjs/swagger/dist/interfaces/open-api-spec.interface";
|
|
185
|
+
|
|
186
|
+
import { validationMetadatasToSchemas } from "class-validator-jsonschema";
|
|
187
|
+
import { setupTransactionContext } from "nestjs-typeorm3-kit";
|
|
188
|
+
import { INestApplication } from "@nestjs/common";
|
|
189
|
+
|
|
190
|
+
const configSwagger = (app: INestApplication) => {
|
|
191
|
+
const options = new DocumentBuilder()
|
|
192
|
+
.setTitle("SWAGGER_TITLE")
|
|
193
|
+
.setDescription("SWAGGER_DESCRIPTION")
|
|
194
|
+
.setVersion("SWAGGER_VERSION")
|
|
195
|
+
.addSecurity("bearer", {
|
|
196
|
+
type: "http",
|
|
197
|
+
scheme: "bearer",
|
|
198
|
+
bearerFormat: "JWT",
|
|
199
|
+
})
|
|
200
|
+
.build();
|
|
201
|
+
|
|
202
|
+
const document = SwaggerModule.createDocument(app as any, options, {
|
|
203
|
+
// extraModels: [PageResponse]
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// Creating all the swagger schemas based on the class-validator decorators
|
|
207
|
+
const metadatas = (getFromContainer(MetadataStorage) as any)
|
|
208
|
+
.validationMetadatas;
|
|
209
|
+
const targetSchemas = document.components.schemas || {};
|
|
210
|
+
const schemasBinding = validationMetadatasToSchemas(metadatas) || {};
|
|
211
|
+
|
|
212
|
+
Object.keys(schemasBinding).forEach((key) => {
|
|
213
|
+
const value = schemasBinding[key] as SchemasObject;
|
|
214
|
+
if (!targetSchemas[key]) {
|
|
215
|
+
Object.assign(targetSchemas, { key: value });
|
|
216
|
+
} else {
|
|
217
|
+
const targetValue = targetSchemas[key] as SchemasObject;
|
|
218
|
+
|
|
219
|
+
Object.assign(targetValue.properties, value.properties);
|
|
220
|
+
targetValue.required = value.required;
|
|
221
|
+
Object.assign(targetSchemas, { key: targetValue });
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
document.components.schemas = Object.assign({}, targetSchemas);
|
|
225
|
+
SwaggerModule.setup("swagger", app as any, document);
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
async function bootstrap() {
|
|
229
|
+
setupTransactionContext();
|
|
230
|
+
const app = await NestFactory.create(AppModule);
|
|
231
|
+
const port = process.env.PORT || 3000;
|
|
232
|
+
app.enableCors({ origin: "*" });
|
|
233
|
+
configSwagger(app);
|
|
234
|
+
await app.listen(port);
|
|
235
|
+
console.log(
|
|
236
|
+
`Server start on port ${port}. Open http://localhost:${port} to see results`
|
|
237
|
+
);
|
|
238
|
+
console.log(`API DOCUMENT Open http://localhost:${port}/swagger`);
|
|
239
|
+
console.log(`API DOCUMENT JSON Open http://localhost:${port}/swagger-json`);
|
|
240
|
+
console.log("TIMEZONE: ", process.env.TZ);
|
|
241
|
+
}
|
|
242
|
+
bootstrap();
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
#### Example
|
|
246
|
+
|
|
247
|
+
[Example](./example)
|
|
248
|
+
|
|
249
|
+
### Full document in wiki github
|
|
250
|
+
|
|
251
|
+
[FULL DOCUMENT](https://x302502.github.io/nestjs-typeorm3-kit/)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/transaction/setup/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/transaction/setup/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,0BAA0B,EAC3B,MAAM,uBAAuB,CAAC;AAC/B,wBAAgB,uBAAuB,SAEtC;AAED,OAAO,EAAE,0BAA0B,EAAE,CAAC"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.addTransactionalDataSource = void 0;
|
|
3
4
|
exports.setupTransactionContext = setupTransactionContext;
|
|
4
5
|
const typeorm_transactional_1 = require("typeorm-transactional");
|
|
6
|
+
Object.defineProperty(exports, "addTransactionalDataSource", { enumerable: true, get: function () { return typeorm_transactional_1.addTransactionalDataSource; } });
|
|
5
7
|
function setupTransactionContext() {
|
|
6
8
|
(0, typeorm_transactional_1.initializeTransactionalContext)();
|
|
7
9
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/transaction/setup/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/transaction/setup/index.ts"],"names":[],"mappings":";;;AAIA,0DAEC;AAND,iEAG+B;AAKtB,2GANP,kDAA0B,OAMO;AAJnC,SAAgB,uBAAuB;IACrC,IAAA,sDAA8B,GAAE,CAAC;AACnC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nestjs-typeorm3-kit",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "NestJS utilities for TypeORM v0.3+",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -38,12 +38,14 @@
|
|
|
38
38
|
"libphonenumber-js": "^1.10.20",
|
|
39
39
|
"reflect-metadata": ">=0.1.13",
|
|
40
40
|
"rxjs": ">=7.2.0",
|
|
41
|
-
"typeorm": ">=0.3.0"
|
|
41
|
+
"typeorm": ">=0.3.0",
|
|
42
|
+
"typeorm-transactional": ">=0.5.0"
|
|
42
43
|
},
|
|
43
44
|
"devDependencies": {
|
|
44
45
|
"@nestjs/common": "^11.1.3",
|
|
45
46
|
"@nestjs/core": "^11.1.3",
|
|
46
47
|
"@nestjs/swagger": "^11.2.0",
|
|
48
|
+
"@nestjs/testing": "^11.1.3",
|
|
47
49
|
"@nestjs/typeorm": "^11.0.0",
|
|
48
50
|
"@types/jest": "^30.0.0",
|
|
49
51
|
"class-transformer": "^0.5.1",
|
|
@@ -55,6 +57,7 @@
|
|
|
55
57
|
"prettier": "^3.6.2",
|
|
56
58
|
"reflect-metadata": "^0.2.2",
|
|
57
59
|
"rimraf": "^6.0.1",
|
|
60
|
+
"rxjs": "^7.8.2",
|
|
58
61
|
"ts-jest": "^29.4.0",
|
|
59
62
|
"typedoc": "^0.28.6",
|
|
60
63
|
"typedoc-github-wiki-theme": "^2.1.0",
|