@zola_do/typeorm 0.2.5 → 0.2.6

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 (2) hide show
  1. package/README.md +382 -29
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,7 +1,20 @@
1
1
  # @zola_do/typeorm
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/@zola_do/typeorm.svg)](https://www.npmjs.com/package/@zola_do/typeorm)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@zola_do/typeorm.svg)](https://www.npmjs.com/package/@zola_do/typeorm)
5
+ [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC)
6
+
3
7
  TypeORM configuration helpers and service for NestJS applications.
4
8
 
9
+ ## Overview
10
+
11
+ `@zola_do/typeorm` provides:
12
+
13
+ - **Environment-based Configuration** — Database settings from environment variables
14
+ - **Auto-entity Discovery** — Automatically loads entities and migrations
15
+ - **DataSource Options** — TypeORM 0.3+ compatible configuration
16
+ - **Config Service** — Injectable service for database access
17
+
5
18
  ## Installation
6
19
 
7
20
  ```bash
@@ -12,65 +25,405 @@ npm install @zola_do/typeorm
12
25
  npm install @zola_do/nestjs-shared
13
26
  ```
14
27
 
15
- ## Usage
28
+ ### Dependencies
29
+
30
+ ```bash
31
+ npm install @nestjs/typeorm typeorm typeorm-extension dotenv
32
+ ```
33
+
34
+ ## Read replicas (TypeORM `replication`)
35
+
36
+ `@zola_do/typeorm` exposes `dataSourceOptions` as a starting point. For read scaling, use TypeORM's [`replication`](https://typeorm.io/data-source-options#postgres--cockroachdb--sap-hana--sql.js) option in the object you pass to `TypeOrmModule.forRoot`: supply `master` (writer) and `slaves` (readers). Environment variables are then modeled in your app (for example `DATABASE_REPLICA_HOSTS` parsed to an array) rather than hard-coded in the library.
37
+
38
+ ## Quick Start
39
+
40
+ ### 1. Configure Environment
41
+
42
+ ```bash
43
+ # .env
44
+ DATABASE_HOST=localhost
45
+ DATABASE_PORT=5432
46
+ DATABASE_NAME=myapp
47
+ DATABASE_USER=postgres
48
+ DATABASE_PASSWORD=secret
49
+ APP_NAME=myapp
50
+ ```
51
+
52
+ ### 2. Register in AppModule
53
+
54
+ ```typescript
55
+ import { Module } from "@nestjs/common";
56
+ import { TypeOrmModule } from "@nestjs/typeorm";
57
+ import { dataSourceOptions } from "@zola_do/typeorm";
58
+
59
+ @Module({
60
+ imports: [TypeOrmModule.forRoot(dataSourceOptions)],
61
+ })
62
+ export class AppModule {}
63
+ ```
64
+
65
+ ### 3. Use Entities
66
+
67
+ ```typescript
68
+ import { CommonEntity } from "@zola_do/nestjs-shared";
69
+ import { Entity, Column } from "typeorm";
70
+
71
+ @Entity("products")
72
+ export class Product extends CommonEntity {
73
+ @Column()
74
+ name: string;
75
+
76
+ @Column("decimal", { precision: 10, scale: 2 })
77
+ price: number;
78
+ }
79
+ ```
80
+
81
+ ## Entity Configuration
16
82
 
17
- ### Configuring the Database
83
+ ### CommonEntity
18
84
 
19
- Use `TypeOrmConfigHelper` or `dataSourceOptions` to configure TypeORM in your `AppModule`:
85
+ All entities should extend `CommonEntity` for consistent audit fields:
86
+
87
+ ```typescript
88
+ import { CommonEntity } from "@zola_do/nestjs-shared";
89
+ import { Entity, Column, PrimaryGeneratedColumn } from "typeorm";
90
+
91
+ @Entity("products")
92
+ export class Product extends CommonEntity {
93
+ @PrimaryGeneratedColumn("uuid")
94
+ id: string;
95
+
96
+ @Column()
97
+ name: string;
98
+ }
99
+ ```
100
+
101
+ ### CommonEntity Fields
102
+
103
+ | Field | Type | Description |
104
+ | ----------- | -------- | -------------------------------- |
105
+ | `id` | `UUID` | Primary key (auto-generated) |
106
+ | `createdAt` | `Date` | Auto-set on creation |
107
+ | `updatedAt` | `Date` | Auto-updated on changes |
108
+ | `createdBy` | `string` | Nullable - user who created |
109
+ | `updatedBy` | `string` | Nullable - user who last updated |
110
+ | `deletedAt` | `Date` | Nullable - soft delete timestamp |
111
+
112
+ ### Entity Patterns
113
+
114
+ #### Basic Entity
115
+
116
+ ```typescript
117
+ @Entity("categories")
118
+ export class Category extends CommonEntity {
119
+ @PrimaryGeneratedColumn("uuid")
120
+ id: string;
121
+
122
+ @Column()
123
+ name: string;
124
+
125
+ @Column({ nullable: true })
126
+ description: string;
127
+
128
+ @OneToMany(() => Product, (product) => product.category)
129
+ products: Product[];
130
+ }
131
+ ```
132
+
133
+ #### Entity with Relations
134
+
135
+ ```typescript
136
+ @Entity("orders")
137
+ export class Order extends CommonEntity {
138
+ @PrimaryGeneratedColumn("uuid")
139
+ id: string;
140
+
141
+ @Column()
142
+ customerId: string;
143
+
144
+ @Column("decimal", { precision: 10, scale: 2 })
145
+ total: number;
146
+
147
+ @Column({ default: "pending" })
148
+ status: string;
149
+
150
+ @ManyToOne(() => Customer, (customer) => customer.orders)
151
+ @JoinColumn({ name: "customerId" })
152
+ customer: Customer;
153
+
154
+ @OneToMany(() => OrderItem, (item) => item.order)
155
+ items: OrderItem[];
156
+ }
157
+ ```
158
+
159
+ #### Entity with Indexes
160
+
161
+ ```typescript
162
+ @Entity("products", {
163
+ indexes: [
164
+ { name: "idx_product_name", columns: ["name"] },
165
+ { name: "idx_product_status_price", columns: ["status", "price"] },
166
+ ],
167
+ })
168
+ export class Product extends CommonEntity {
169
+ @Column()
170
+ name: string;
171
+
172
+ @Column({ default: "active" })
173
+ status: string;
174
+
175
+ @Column("decimal", { precision: 10, scale: 2 })
176
+ price: number;
177
+ }
178
+ ```
179
+
180
+ ## TypeOrmConfigHelper
181
+
182
+ Access individual configuration values:
183
+
184
+ ```typescript
185
+ import { TypeOrmConfigHelper } from "@zola_do/typeorm";
186
+
187
+ console.log(TypeOrmConfigHelper.DATABASE_HOST); // 'localhost'
188
+ console.log(TypeOrmConfigHelper.DATABASE_PORT); // 5432
189
+ console.log(TypeOrmConfigHelper.DATABASE_NAME); // 'myapp'
190
+ console.log(TypeOrmConfigHelper.DATABASE_USER); // 'postgres'
191
+ console.log(TypeOrmConfigHelper.DATABASE_PASSWORD); // 'secret'
192
+ ```
193
+
194
+ ### Config Keys
195
+
196
+ | Key | Type | Description |
197
+ | ------------------- | -------- | ------------------------------------- |
198
+ | `DATABASE_HOST` | `string` | Database host |
199
+ | `DATABASE_PORT` | `number` | Database port |
200
+ | `DATABASE_NAME` | `string` | Database name |
201
+ | `DATABASE_USER` | `string` | Database user |
202
+ | `DATABASE_PASSWORD` | `string` | Database password |
203
+ | `APP_NAME` | `string` | App name (fallback for DATABASE_NAME) |
204
+
205
+ ## TypeOrmService
206
+
207
+ Injectable service for direct database access:
208
+
209
+ ```typescript
210
+ import { Injectable } from "@nestjs/common";
211
+ import { TypeOrmService } from "@zola_do/typeorm";
212
+
213
+ @Injectable()
214
+ export class AnalyticsService {
215
+ constructor(private readonly typeorm: TypeOrmService) {}
216
+
217
+ async getTableStats() {
218
+ return await this.typeorm.query(`
219
+ SELECT
220
+ schemaname,
221
+ relname,
222
+ n_tup_ins as inserts,
223
+ n_tup_upd as updates,
224
+ n_tup_del as deletes
225
+ FROM pg_stat_user_tables
226
+ WHERE schemaname = 'public'
227
+ `);
228
+ }
229
+ }
230
+ ```
231
+
232
+ ## DataSource Options
233
+
234
+ The `dataSourceOptions` object provides full TypeORM configuration:
20
235
 
21
236
  ```typescript
22
- import { Module } from '@nestjs/common';
23
- import { TypeOrmModule } from '@nestjs/typeorm';
24
237
  import { dataSourceOptions } from '@zola_do/typeorm';
25
238
 
239
+ // Full options structure
240
+ {
241
+ type: 'postgres',
242
+ host: 'localhost',
243
+ port: 5432,
244
+ database: 'myapp',
245
+ username: 'postgres',
246
+ password: 'secret',
247
+ entities: ['dist/**/*.entity.js', '**/*.entity.js'],
248
+ migrations: ['dist/**/*.migration.js', '**/*.migration.js'],
249
+ synchronize: false, // Use migrations in production
250
+ logging: process.env.NODE_ENV === 'development',
251
+ // ... more TypeORM options
252
+ }
253
+ ```
254
+
255
+ ### Production Configuration
256
+
257
+ ```typescript
258
+ // app.module.ts
259
+ import { dataSourceOptions } from "@zola_do/typeorm";
260
+
26
261
  @Module({
27
262
  imports: [
28
- TypeOrmModule.forRoot(dataSourceOptions),
29
- // ... other modules
263
+ TypeOrmModule.forRoot({
264
+ ...dataSourceOptions,
265
+ synchronize: false,
266
+ migrationsRun: true,
267
+ logging: ["error", "warn"],
268
+ }),
30
269
  ],
31
270
  })
32
271
  export class AppModule {}
33
272
  ```
34
273
 
35
- ### TypeOrmConfigHelper
274
+ ## Environment Variables
275
+
276
+ | Variable | Description | Default |
277
+ | ------------------- | ---------------------------- | ------------------------ |
278
+ | `DATABASE_HOST` | Database host | `localhost` |
279
+ | `DATABASE_PORT` | Database port | `5432` |
280
+ | `DATABASE_NAME` | Database name | Falls back to `APP_NAME` |
281
+ | `DATABASE_USER` | Database user | `postgres` |
282
+ | `DATABASE_PASSWORD` | Database password | Required in production |
283
+ | `APP_NAME` | Fallback for `DATABASE_NAME` | — |
284
+
285
+ ### Validation Rules
286
+
287
+ - In production (`NODE_ENV === 'production'`), `DATABASE_PASSWORD` is required
288
+ - Either `DATABASE_NAME` or `APP_NAME` must be set
289
+
290
+ ## Auto-Discovery
291
+
292
+ Entities and migrations are auto-discovered:
293
+
294
+ ```typescript
295
+ // dataSourceOptions.entities supports glob patterns
296
+ entities: [
297
+ __dirname + "/../../**/*.entity.js", // Compiled output
298
+ "**/*.entity.js", // Source files
299
+ ];
300
+
301
+ // dataSourceOptions.migrations supports glob patterns
302
+ migrations: [__dirname + "/../../**/*.migration.js"];
303
+ ```
304
+
305
+ ### Entity File Location
306
+
307
+ ```
308
+ src/
309
+ ├── entities/
310
+ │ ├── base.entity.ts
311
+ │ ├── product.entity.ts
312
+ │ └── category.entity.ts
313
+ └── app.module.ts
314
+ ```
315
+
316
+ ## Migrations
317
+
318
+ ### Generate Migration
319
+
320
+ ```bash
321
+ npx typeorm migration:generate -d dist/typeorm/data-source.js src/migrations/ProductColumns
322
+ ```
323
+
324
+ ### Run Migrations
325
+
326
+ ```bash
327
+ npx typeorm migration:run -d dist/typeorm/data-source.js
328
+ ```
36
329
 
37
- Access individual config values:
330
+ ### Create Migration Manually
38
331
 
39
332
  ```typescript
40
- import { TypeOrmConfigHelper } from '@zola_do/typeorm';
333
+ import { MigrationInterface, QueryRunner, Table } from "typeorm";
41
334
 
42
- const host = TypeOrmConfigHelper.DATABASE_HOST;
43
- const port = TypeOrmConfigHelper.DATABASE_PORT;
44
- const database = TypeOrmConfigHelper.DATABASE_NAME;
45
- const username = TypeOrmConfigHelper.DATABASE_USER;
46
- const password = TypeOrmConfigHelper.DATABASE_PASSWORD;
335
+ export class CreateProducts1704064000000 implements MigrationInterface {
336
+ public async up(queryRunner: QueryRunner): Promise<void> {
337
+ await queryRunner.createTable(
338
+ new Table({
339
+ name: "products",
340
+ columns: [
341
+ {
342
+ name: "id",
343
+ type: "uuid",
344
+ isPrimary: true,
345
+ generationStrategy: "uuid",
346
+ },
347
+ { name: "name", type: "varchar" },
348
+ { name: "price", type: "decimal", precision: 10, scale: 2 },
349
+ { name: "created_at", type: "timestamp", default: "now()" },
350
+ { name: "updated_at", type: "timestamp", default: "now()" },
351
+ ],
352
+ }),
353
+ true,
354
+ );
355
+ }
356
+
357
+ public async down(queryRunner: QueryRunner): Promise<void> {
358
+ await queryRunner.dropTable("products");
359
+ }
360
+ }
47
361
  ```
48
362
 
49
- ### TypeOrmService
363
+ ## API Reference
50
364
 
51
- Inject the TypeORM service for direct database access when needed:
365
+ ### Constants
52
366
 
53
367
  ```typescript
54
- import { TypeOrmService } from '@zola_do/typeorm';
368
+ TypeOrmConfigHelper.DATABASE_HOST;
369
+ TypeOrmConfigHelper.DATABASE_PORT;
370
+ TypeOrmConfigHelper.DATABASE_NAME;
371
+ TypeOrmConfigHelper.DATABASE_USER;
372
+ TypeOrmConfigHelper.DATABASE_PASSWORD;
373
+ ```
374
+
375
+ ### DataSource
376
+
377
+ ```typescript
378
+ import { dataSourceOptions } from "@zola_do/typeorm";
379
+ // Type: DataSourceOptions
380
+ ```
381
+
382
+ ### Service
383
+
384
+ ```typescript
385
+ import { TypeOrmService } from "@zola_do/typeorm";
55
386
 
56
387
  @Injectable()
57
- export class SomeService {
388
+ class MyService {
58
389
  constructor(private readonly typeorm: TypeOrmService) {}
390
+
391
+ async query(sql: string, parameters?: any[]) {
392
+ return this.typeorm.query(sql, parameters);
393
+ }
59
394
  }
60
395
  ```
61
396
 
62
- ## Environment Variables
397
+ ## Troubleshooting
398
+
399
+ ### Q: Entities not being loaded?
400
+
401
+ Check glob pattern in `dataSourceOptions.entities`. The pattern should match your compiled `.js` files:
402
+
403
+ ```typescript
404
+ entities: [__dirname + "/../../**/*.entity.js"];
405
+ ```
406
+
407
+ ### Q: Migrations not running?
408
+
409
+ Ensure `migrationsRun: true` in production or run manually:
410
+
411
+ ```bash
412
+ npm run migration:run
413
+ ```
414
+
415
+ ### Q: Connection refused?
416
+
417
+ Verify `DATABASE_HOST` and `DATABASE_PORT` are correct and the database is accessible.
418
+
419
+ ## Related Packages
420
+
421
+ - [@zola_do/crud](../crud) — Uses TypeORM entities
422
+ - [@zola_do/collection-query](../collection-query) — Query builder for TypeORM
63
423
 
64
- | Variable | Description | Default |
65
- |----------|-------------|---------|
66
- | `DATABASE_HOST` | Database host | `localhost` |
67
- | `DATABASE_PORT` | Database port | `5432` |
68
- | `DATABASE_NAME` | Database name | Falls back to `APP_NAME` |
69
- | `DATABASE_USER` | Database user | `postgres` |
70
- | `DATABASE_PASSWORD` | Database password | Required in production |
71
- | `APP_NAME` | Fallback for `DATABASE_NAME` when `DATABASE_NAME` is not set | — |
424
+ ## License
72
425
 
73
- **Note:** In production, `DATABASE_PASSWORD` is required. Either `DATABASE_NAME` or `APP_NAME` must be set.
426
+ ISC
74
427
 
75
428
  ## Community
76
429
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zola_do/typeorm",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
4
4
  "description": "TypeORM configuration for NestJS",
5
5
  "author": "zolaDO",
6
6
  "license": "ISC",