@sasscore/database 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.
- package/README.md +281 -0
- package/dist/connection/index.d.ts +7 -0
- package/dist/connection/index.d.ts.map +1 -0
- package/dist/connection/index.js +7 -0
- package/dist/connection/index.js.map +1 -0
- package/dist/connection/infrastructure/connection.module.d.ts +18 -0
- package/dist/connection/infrastructure/connection.module.d.ts.map +1 -0
- package/dist/connection/infrastructure/connection.module.js +75 -0
- package/dist/connection/infrastructure/connection.module.js.map +1 -0
- package/dist/connection/infrastructure/sequelize.service.d.ts +16 -0
- package/dist/connection/infrastructure/sequelize.service.d.ts.map +1 -0
- package/dist/connection/infrastructure/sequelize.service.js +56 -0
- package/dist/connection/infrastructure/sequelize.service.js.map +1 -0
- package/dist/database.module.d.ts +25 -0
- package/dist/database.module.d.ts.map +1 -0
- package/dist/database.module.js +71 -0
- package/dist/database.module.js.map +1 -0
- package/dist/health/database-health.service.d.ts +12 -0
- package/dist/health/database-health.service.d.ts.map +1 -0
- package/dist/health/database-health.service.js +48 -0
- package/dist/health/database-health.service.js.map +1 -0
- package/dist/health/database-health.types.d.ts +8 -0
- package/dist/health/database-health.types.d.ts.map +1 -0
- package/dist/health/database-health.types.js +2 -0
- package/dist/health/database-health.types.js.map +1 -0
- package/dist/health/health.module.d.ts +3 -0
- package/dist/health/health.module.d.ts.map +1 -0
- package/dist/health/health.module.js +20 -0
- package/dist/health/health.module.js.map +1 -0
- package/dist/health/index.d.ts +12 -0
- package/dist/health/index.d.ts.map +1 -0
- package/dist/health/index.js +9 -0
- package/dist/health/index.js.map +1 -0
- package/dist/health/migration-health.service.d.ts +14 -0
- package/dist/health/migration-health.service.d.ts.map +1 -0
- package/dist/health/migration-health.service.js +43 -0
- package/dist/health/migration-health.service.js.map +1 -0
- package/dist/health/migration-health.types.d.ts +9 -0
- package/dist/health/migration-health.types.d.ts.map +1 -0
- package/dist/health/migration-health.types.js +2 -0
- package/dist/health/migration-health.types.js.map +1 -0
- package/dist/health/outbox-health.service.d.ts +14 -0
- package/dist/health/outbox-health.service.d.ts.map +1 -0
- package/dist/health/outbox-health.service.js +79 -0
- package/dist/health/outbox-health.service.js.map +1 -0
- package/dist/health/outbox-health.types.d.ts +15 -0
- package/dist/health/outbox-health.types.d.ts.map +1 -0
- package/dist/health/outbox-health.types.js +2 -0
- package/dist/health/outbox-health.types.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/migrations/20260826173000-create-outbox-events.d.ts +5 -0
- package/dist/migrations/20260826173000-create-outbox-events.d.ts.map +1 -0
- package/dist/migrations/20260826173000-create-outbox-events.js +102 -0
- package/dist/migrations/20260826173000-create-outbox-events.js.map +1 -0
- package/dist/migrations/create-migration-registry.d.ts +9 -0
- package/dist/migrations/create-migration-registry.d.ts.map +1 -0
- package/dist/migrations/create-migration-registry.js +37 -0
- package/dist/migrations/create-migration-registry.js.map +1 -0
- package/dist/migrations/index.d.ts +7 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +6 -0
- package/dist/migrations/index.js.map +1 -0
- package/dist/migrations/migration-registry.d.ts +4 -0
- package/dist/migrations/migration-registry.d.ts.map +1 -0
- package/dist/migrations/migration-registry.js +4 -0
- package/dist/migrations/migration-registry.js.map +1 -0
- package/dist/migrations/migration-runner.d.ts +27 -0
- package/dist/migrations/migration-runner.d.ts.map +1 -0
- package/dist/migrations/migration-runner.js +135 -0
- package/dist/migrations/migration-runner.js.map +1 -0
- package/dist/migrations/migration.helpers.d.ts +8 -0
- package/dist/migrations/migration.helpers.d.ts.map +1 -0
- package/dist/migrations/migration.helpers.js +9 -0
- package/dist/migrations/migration.helpers.js.map +1 -0
- package/dist/migrations/migration.types.d.ts +26 -0
- package/dist/migrations/migration.types.d.ts.map +1 -0
- package/dist/migrations/migration.types.js +2 -0
- package/dist/migrations/migration.types.js.map +1 -0
- package/dist/models/base.model.d.ts +17 -0
- package/dist/models/base.model.d.ts.map +1 -0
- package/dist/models/base.model.js +56 -0
- package/dist/models/base.model.js.map +1 -0
- package/dist/models/index.d.ts +2 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/models/index.js +2 -0
- package/dist/models/index.js.map +1 -0
- package/dist/outbox/application/outbox.processor.d.ts +20 -0
- package/dist/outbox/application/outbox.processor.d.ts.map +1 -0
- package/dist/outbox/application/outbox.processor.js +66 -0
- package/dist/outbox/application/outbox.processor.js.map +1 -0
- package/dist/outbox/application/outbox.publisher.d.ts +17 -0
- package/dist/outbox/application/outbox.publisher.d.ts.map +1 -0
- package/dist/outbox/application/outbox.publisher.js +33 -0
- package/dist/outbox/application/outbox.publisher.js.map +1 -0
- package/dist/outbox/application/ports/event-dispatcher.port.d.ts +7 -0
- package/dist/outbox/application/ports/event-dispatcher.port.d.ts.map +1 -0
- package/dist/outbox/application/ports/event-dispatcher.port.js +2 -0
- package/dist/outbox/application/ports/event-dispatcher.port.js.map +1 -0
- package/dist/outbox/domain/entities/domain-event.entity.d.ts +11 -0
- package/dist/outbox/domain/entities/domain-event.entity.d.ts.map +1 -0
- package/dist/outbox/domain/entities/domain-event.entity.js +15 -0
- package/dist/outbox/domain/entities/domain-event.entity.js.map +1 -0
- package/dist/outbox/domain/entities/outbox-event.types.d.ts +21 -0
- package/dist/outbox/domain/entities/outbox-event.types.d.ts.map +1 -0
- package/dist/outbox/domain/entities/outbox-event.types.js +2 -0
- package/dist/outbox/domain/entities/outbox-event.types.js.map +1 -0
- package/dist/outbox/domain/index.d.ts +5 -0
- package/dist/outbox/domain/index.d.ts.map +1 -0
- package/dist/outbox/domain/index.js +3 -0
- package/dist/outbox/domain/index.js.map +1 -0
- package/dist/outbox/domain/repositories/outbox.repository.interface.d.ts +13 -0
- package/dist/outbox/domain/repositories/outbox.repository.interface.d.ts.map +1 -0
- package/dist/outbox/domain/repositories/outbox.repository.interface.js +2 -0
- package/dist/outbox/domain/repositories/outbox.repository.interface.js.map +1 -0
- package/dist/outbox/domain/value-objects/event-types.d.ts +19 -0
- package/dist/outbox/domain/value-objects/event-types.d.ts.map +1 -0
- package/dist/outbox/domain/value-objects/event-types.js +18 -0
- package/dist/outbox/domain/value-objects/event-types.js.map +1 -0
- package/dist/outbox/event-dispatcher.d.ts +3 -0
- package/dist/outbox/event-dispatcher.d.ts.map +1 -0
- package/dist/outbox/event-dispatcher.js +3 -0
- package/dist/outbox/event-dispatcher.js.map +1 -0
- package/dist/outbox/event.entity.d.ts +4 -0
- package/dist/outbox/event.entity.d.ts.map +1 -0
- package/dist/outbox/event.entity.js +3 -0
- package/dist/outbox/event.entity.js.map +1 -0
- package/dist/outbox/index.d.ts +19 -0
- package/dist/outbox/index.d.ts.map +1 -0
- package/dist/outbox/index.js +17 -0
- package/dist/outbox/index.js.map +1 -0
- package/dist/outbox/infrastructure/dispatch/event-dispatcher.d.ts +21 -0
- package/dist/outbox/infrastructure/dispatch/event-dispatcher.d.ts.map +1 -0
- package/dist/outbox/infrastructure/dispatch/event-dispatcher.js +55 -0
- package/dist/outbox/infrastructure/dispatch/event-dispatcher.js.map +1 -0
- package/dist/outbox/infrastructure/dispatch/flat-handler.registry.d.ts +13 -0
- package/dist/outbox/infrastructure/dispatch/flat-handler.registry.d.ts.map +1 -0
- package/dist/outbox/infrastructure/dispatch/flat-handler.registry.js +46 -0
- package/dist/outbox/infrastructure/dispatch/flat-handler.registry.js.map +1 -0
- package/dist/outbox/infrastructure/outbox.module.d.ts +13 -0
- package/dist/outbox/infrastructure/outbox.module.d.ts.map +1 -0
- package/dist/outbox/infrastructure/outbox.module.js +53 -0
- package/dist/outbox/infrastructure/outbox.module.js.map +1 -0
- package/dist/outbox/infrastructure/persistence/outbox-event.model.d.ts +106 -0
- package/dist/outbox/infrastructure/persistence/outbox-event.model.d.ts.map +1 -0
- package/dist/outbox/infrastructure/persistence/outbox-event.model.js +186 -0
- package/dist/outbox/infrastructure/persistence/outbox-event.model.js.map +1 -0
- package/dist/outbox/infrastructure/persistence/outbox-persistence.module.d.ts +9 -0
- package/dist/outbox/infrastructure/persistence/outbox-persistence.module.d.ts.map +1 -0
- package/dist/outbox/infrastructure/persistence/outbox-persistence.module.js +25 -0
- package/dist/outbox/infrastructure/persistence/outbox-persistence.module.js.map +1 -0
- package/dist/outbox/infrastructure/persistence/sequelize-outbox.repository.d.ts +24 -0
- package/dist/outbox/infrastructure/persistence/sequelize-outbox.repository.d.ts.map +1 -0
- package/dist/outbox/infrastructure/persistence/sequelize-outbox.repository.js +191 -0
- package/dist/outbox/infrastructure/persistence/sequelize-outbox.repository.js.map +1 -0
- package/dist/outbox/outbox-flat-handler.registry.d.ts +4 -0
- package/dist/outbox/outbox-flat-handler.registry.d.ts.map +1 -0
- package/dist/outbox/outbox-flat-handler.registry.js +4 -0
- package/dist/outbox/outbox-flat-handler.registry.js.map +1 -0
- package/dist/outbox/outbox.constants.d.ts +3 -0
- package/dist/outbox/outbox.constants.d.ts.map +1 -0
- package/dist/outbox/outbox.constants.js +3 -0
- package/dist/outbox/outbox.constants.js.map +1 -0
- package/dist/outbox/outbox.module.d.ts +3 -0
- package/dist/outbox/outbox.module.d.ts.map +1 -0
- package/dist/outbox/outbox.module.js +3 -0
- package/dist/outbox/outbox.module.js.map +1 -0
- package/dist/outbox/outbox.processor.d.ts +4 -0
- package/dist/outbox/outbox.processor.d.ts.map +1 -0
- package/dist/outbox/outbox.processor.js +4 -0
- package/dist/outbox/outbox.processor.js.map +1 -0
- package/dist/outbox/outbox.publisher.d.ts +3 -0
- package/dist/outbox/outbox.publisher.d.ts.map +1 -0
- package/dist/outbox/outbox.publisher.js +3 -0
- package/dist/outbox/outbox.publisher.js.map +1 -0
- package/dist/outbox/outbox.repository.d.ts +3 -0
- package/dist/outbox/outbox.repository.d.ts.map +1 -0
- package/dist/outbox/outbox.repository.js +3 -0
- package/dist/outbox/outbox.repository.js.map +1 -0
- package/dist/providers/database.providers.d.ts +4 -0
- package/dist/providers/database.providers.d.ts.map +1 -0
- package/dist/providers/database.providers.js +25 -0
- package/dist/providers/database.providers.js.map +1 -0
- package/dist/providers/database.tokens.d.ts +43 -0
- package/dist/providers/database.tokens.d.ts.map +1 -0
- package/dist/providers/database.tokens.js +43 -0
- package/dist/providers/database.tokens.js.map +1 -0
- package/dist/providers/index.d.ts +3 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +3 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/repositories/index.d.ts +5 -0
- package/dist/repositories/index.d.ts.map +1 -0
- package/dist/repositories/index.js +4 -0
- package/dist/repositories/index.js.map +1 -0
- package/dist/repositories/main.repository.d.ts +163 -0
- package/dist/repositories/main.repository.d.ts.map +1 -0
- package/dist/repositories/main.repository.js +1120 -0
- package/dist/repositories/main.repository.js.map +1 -0
- package/dist/repositories/repository-execution-mode.enum.d.ts +11 -0
- package/dist/repositories/repository-execution-mode.enum.d.ts.map +1 -0
- package/dist/repositories/repository-execution-mode.enum.js +12 -0
- package/dist/repositories/repository-execution-mode.enum.js.map +1 -0
- package/dist/repositories/repository.types.d.ts +65 -0
- package/dist/repositories/repository.types.d.ts.map +1 -0
- package/dist/repositories/repository.types.js +2 -0
- package/dist/repositories/repository.types.js.map +1 -0
- package/dist/repositories/tenant-scope-mode.enum.d.ts +13 -0
- package/dist/repositories/tenant-scope-mode.enum.d.ts.map +1 -0
- package/dist/repositories/tenant-scope-mode.enum.js +14 -0
- package/dist/repositories/tenant-scope-mode.enum.js.map +1 -0
- package/dist/tenancy/domain/ports/tenant-context.port.d.ts +22 -0
- package/dist/tenancy/domain/ports/tenant-context.port.d.ts.map +1 -0
- package/dist/tenancy/domain/ports/tenant-context.port.js +2 -0
- package/dist/tenancy/domain/ports/tenant-context.port.js.map +1 -0
- package/dist/tenancy/index.d.ts +8 -0
- package/dist/tenancy/index.d.ts.map +1 -0
- package/dist/tenancy/index.js +7 -0
- package/dist/tenancy/index.js.map +1 -0
- package/dist/tenancy/infrastructure/cls-tenant-context.adapter.d.ts +26 -0
- package/dist/tenancy/infrastructure/cls-tenant-context.adapter.d.ts.map +1 -0
- package/dist/tenancy/infrastructure/cls-tenant-context.adapter.js +73 -0
- package/dist/tenancy/infrastructure/cls-tenant-context.adapter.js.map +1 -0
- package/dist/tenancy/infrastructure/tenant-context.module.d.ts +7 -0
- package/dist/tenancy/infrastructure/tenant-context.module.d.ts.map +1 -0
- package/dist/tenancy/infrastructure/tenant-context.module.js +32 -0
- package/dist/tenancy/infrastructure/tenant-context.module.js.map +1 -0
- package/dist/tokens.d.ts +6 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/tokens.js +6 -0
- package/dist/tokens.js.map +1 -0
- package/dist/transaction-manager/application/transaction-manager.service.d.ts +12 -0
- package/dist/transaction-manager/application/transaction-manager.service.d.ts.map +1 -0
- package/dist/transaction-manager/application/transaction-manager.service.js +29 -0
- package/dist/transaction-manager/application/transaction-manager.service.js.map +1 -0
- package/dist/transaction-manager/domain/ports/transaction-manager.port.d.ts +9 -0
- package/dist/transaction-manager/domain/ports/transaction-manager.port.d.ts.map +1 -0
- package/dist/transaction-manager/domain/ports/transaction-manager.port.js +2 -0
- package/dist/transaction-manager/domain/ports/transaction-manager.port.js.map +1 -0
- package/dist/transaction-manager/index.d.ts +7 -0
- package/dist/transaction-manager/index.d.ts.map +1 -0
- package/dist/transaction-manager/index.js +6 -0
- package/dist/transaction-manager/index.js.map +1 -0
- package/dist/types/database-module-options.d.ts +12 -0
- package/dist/types/database-module-options.d.ts.map +1 -0
- package/dist/types/database-module-options.js +2 -0
- package/dist/types/database-module-options.js.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +69 -0
package/README.md
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# `@sasscore/database`
|
|
2
|
+
|
|
3
|
+
Core database infrastructure for NestJS applications built on:
|
|
4
|
+
|
|
5
|
+
- Sequelize
|
|
6
|
+
- PostgreSQL
|
|
7
|
+
- Tenant context
|
|
8
|
+
- Transactions
|
|
9
|
+
- Transactional Outbox
|
|
10
|
+
|
|
11
|
+
The package provides a stable infrastructure boundary between business modules and the underlying database implementation.
|
|
12
|
+
|
|
13
|
+
The database stack is intentionally fixed. This package does not aim to support multiple ORMs.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @sasscore/database
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Peer dependencies: `@nestjs/common`, `@nestjs/core`, `@nestjs/cqrs`, `@nestjs/sequelize`, `nestjs-cls`, `sequelize`, `sequelize-typescript`.
|
|
22
|
+
|
|
23
|
+
## Public API
|
|
24
|
+
|
|
25
|
+
The package exposes a stable root API and dedicated subpath exports.
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { DatabaseModule } from '@sasscore/database';
|
|
29
|
+
|
|
30
|
+
import {
|
|
31
|
+
OutboxPublisher,
|
|
32
|
+
OUTBOX_TOKENS,
|
|
33
|
+
} from '@sasscore/database/outbox';
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Available subpaths:
|
|
37
|
+
|
|
38
|
+
| Subpath | Capability |
|
|
39
|
+
|---------|------------|
|
|
40
|
+
| `@sasscore/database` | `DatabaseModule`, shared tokens, re-exported facades |
|
|
41
|
+
| `@sasscore/database/connection` | Sequelize connection lifecycle |
|
|
42
|
+
| `@sasscore/database/tenancy` | Tenant context port and adapter |
|
|
43
|
+
| `@sasscore/database/transaction-manager` | Transaction boundary |
|
|
44
|
+
| `@sasscore/database/outbox` | Transactional domain-event persistence |
|
|
45
|
+
| `@sasscore/database/health` | Database / migration / outbox health |
|
|
46
|
+
| `@sasscore/database/migrations` | Migration runner and Core outbox schema |
|
|
47
|
+
| `@sasscore/database/models` | `BaseModel` |
|
|
48
|
+
| `@sasscore/database/repositories` | `MainRepository`, tenant scope |
|
|
49
|
+
|
|
50
|
+
See [`PUBLIC_API.md`](./PUBLIC_API.md) for the complete public API contract.
|
|
51
|
+
|
|
52
|
+
## Database module
|
|
53
|
+
|
|
54
|
+
The host application remains responsible for application-specific configuration and lifecycle management.
|
|
55
|
+
|
|
56
|
+
### `DatabaseModule.forRoot(...)`
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import { Module } from '@nestjs/common';
|
|
60
|
+
import { DatabaseModule } from '@sasscore/database';
|
|
61
|
+
|
|
62
|
+
@Module({
|
|
63
|
+
imports: [
|
|
64
|
+
DatabaseModule.forRoot({
|
|
65
|
+
dialect: 'postgres',
|
|
66
|
+
host: process.env.DB_HOST,
|
|
67
|
+
port: process.env.DB_PORT ? Number(process.env.DB_PORT) : undefined,
|
|
68
|
+
database: process.env.DB_NAME ?? process.env.DB_DATABASE,
|
|
69
|
+
username: process.env.DB_USER ?? process.env.DB_USERNAME,
|
|
70
|
+
password: process.env.DB_PASSWORD,
|
|
71
|
+
}),
|
|
72
|
+
],
|
|
73
|
+
})
|
|
74
|
+
export class AppModule {}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Sequelize SQL logging defaults to `false`. Pass `logging: true` to enable.
|
|
78
|
+
|
|
79
|
+
### `DatabaseModule.forRootAsync(...)`
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
import { Module } from '@nestjs/common';
|
|
83
|
+
import { ConfigModule, ConfigService } from '@nestjs/config';
|
|
84
|
+
import { DatabaseModule } from '@sasscore/database';
|
|
85
|
+
|
|
86
|
+
@Module({
|
|
87
|
+
imports: [
|
|
88
|
+
ConfigModule.forRoot({ isGlobal: true }),
|
|
89
|
+
DatabaseModule.forRootAsync({
|
|
90
|
+
inject: [ConfigService],
|
|
91
|
+
useFactory: (config: ConfigService) => ({
|
|
92
|
+
dialect: 'postgres',
|
|
93
|
+
host: config.get<string>('DB_HOST'),
|
|
94
|
+
port: config.get<number>('DB_PORT'),
|
|
95
|
+
database: config.get<string>('DB_NAME') ?? config.get<string>('DB_DATABASE'),
|
|
96
|
+
username: config.get<string>('DB_USER') ?? config.get<string>('DB_USERNAME'),
|
|
97
|
+
password: config.get<string>('DB_PASSWORD'),
|
|
98
|
+
}),
|
|
99
|
+
}),
|
|
100
|
+
],
|
|
101
|
+
})
|
|
102
|
+
export class AppModule {}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
`DatabaseModuleOptions`: `dialect` (`'postgres'`), `host`, `port`, `database`, `username`, `password`, `logging`.
|
|
106
|
+
|
|
107
|
+
## Core capabilities
|
|
108
|
+
|
|
109
|
+
### Connection
|
|
110
|
+
|
|
111
|
+
Provides the Sequelize database connection and connection lifecycle.
|
|
112
|
+
|
|
113
|
+
`@sasscore/database/connection`
|
|
114
|
+
|
|
115
|
+
### Tenant context
|
|
116
|
+
|
|
117
|
+
Provides the tenant context abstraction used by business modules.
|
|
118
|
+
|
|
119
|
+
`@sasscore/database/tenancy`
|
|
120
|
+
|
|
121
|
+
Business modules should depend on `ITenantContext` rather than implementing their own tenant resolution.
|
|
122
|
+
|
|
123
|
+
### Transactions
|
|
124
|
+
|
|
125
|
+
Provides a transaction boundary for application operations.
|
|
126
|
+
|
|
127
|
+
`@sasscore/database/transaction-manager`
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
await this.transactionManager.runInTransaction(async (transaction) => {
|
|
131
|
+
// transactional work
|
|
132
|
+
});
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Outbox
|
|
136
|
+
|
|
137
|
+
Provides transactional domain-event persistence and publishing infrastructure.
|
|
138
|
+
|
|
139
|
+
`@sasscore/database/outbox`
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
await this.transactionManager.runInTransaction(async (transaction) => {
|
|
143
|
+
await this.outboxPublisher.publish(event, { transaction });
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The outbox allows an event to be persisted within the same database transaction as the business operation.
|
|
148
|
+
|
|
149
|
+
### Health
|
|
150
|
+
|
|
151
|
+
Provides database health checks.
|
|
152
|
+
|
|
153
|
+
`@sasscore/database/health`
|
|
154
|
+
|
|
155
|
+
### Migrations
|
|
156
|
+
|
|
157
|
+
The package provides migration infrastructure:
|
|
158
|
+
|
|
159
|
+
- `MigrationDefinition`
|
|
160
|
+
- `MigrationRunner`
|
|
161
|
+
- `createMigrationRegistry`
|
|
162
|
+
- `databaseMigrations`
|
|
163
|
+
|
|
164
|
+
The package owns migrations required by its own infrastructure, such as the Outbox schema.
|
|
165
|
+
|
|
166
|
+
The host application composes package migrations with migrations from other domains:
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
createMigrationRegistry(
|
|
170
|
+
databaseMigrations,
|
|
171
|
+
// iamMigrations,
|
|
172
|
+
// billingMigrations,
|
|
173
|
+
);
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Database lifecycle commands remain the responsibility of the host application. For example:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
npm run db:init
|
|
180
|
+
npm run db:migrate
|
|
181
|
+
npm run db:seed
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Business module boundary
|
|
185
|
+
|
|
186
|
+
Business modules such as IAM, Billing and Commerce should not depend directly on Sequelize, CLS, or database-specific Outbox tables.
|
|
187
|
+
|
|
188
|
+
Instead, they depend on the abstractions provided by this package.
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
constructor(
|
|
192
|
+
private readonly transactionManager: DatabaseTransactionManager,
|
|
193
|
+
private readonly tenantContext: ITenantContext,
|
|
194
|
+
private readonly outboxPublisher: OutboxPublisher,
|
|
195
|
+
) {}
|
|
196
|
+
|
|
197
|
+
await this.transactionManager.runInTransaction(async (transaction) => {
|
|
198
|
+
const companyId = this.tenantContext.getCompanyId();
|
|
199
|
+
|
|
200
|
+
await this.outboxPublisher.publish(event, { transaction });
|
|
201
|
+
});
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
This keeps database implementation details behind the infrastructure boundary.
|
|
205
|
+
|
|
206
|
+
## Architecture
|
|
207
|
+
|
|
208
|
+
```text
|
|
209
|
+
Business Contexts
|
|
210
|
+
│
|
|
211
|
+
▼
|
|
212
|
+
@sasscore/database
|
|
213
|
+
│
|
|
214
|
+
├── Connection
|
|
215
|
+
├── Tenant Context
|
|
216
|
+
├── Transactions
|
|
217
|
+
├── Outbox
|
|
218
|
+
├── Health
|
|
219
|
+
├── Models
|
|
220
|
+
└── Repositories
|
|
221
|
+
│
|
|
222
|
+
▼
|
|
223
|
+
Sequelize
|
|
224
|
+
│
|
|
225
|
+
▼
|
|
226
|
+
PostgreSQL
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Package structure
|
|
230
|
+
|
|
231
|
+
The package is organized around infrastructure capabilities:
|
|
232
|
+
|
|
233
|
+
```text
|
|
234
|
+
database/
|
|
235
|
+
├── connection/
|
|
236
|
+
├── tenancy/
|
|
237
|
+
├── transaction-manager/
|
|
238
|
+
├── outbox/
|
|
239
|
+
├── health/
|
|
240
|
+
├── models/
|
|
241
|
+
├── repositories/
|
|
242
|
+
├── migrations/
|
|
243
|
+
├── types/
|
|
244
|
+
├── database.module.ts
|
|
245
|
+
├── tokens.ts
|
|
246
|
+
└── index.ts
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
The directory structure is an implementation detail. Consumers should use the documented public exports rather than importing internal files.
|
|
250
|
+
|
|
251
|
+
## Public API contract
|
|
252
|
+
|
|
253
|
+
The supported public API is defined by:
|
|
254
|
+
|
|
255
|
+
- package root exports
|
|
256
|
+
- documented subpath exports
|
|
257
|
+
- [`PUBLIC_API.md`](./PUBLIC_API.md)
|
|
258
|
+
|
|
259
|
+
Internal implementation files are not part of the public contract.
|
|
260
|
+
|
|
261
|
+
What changed between versions: [`CHANGELOG.md`](./CHANGELOG.md).
|
|
262
|
+
|
|
263
|
+
## Build
|
|
264
|
+
|
|
265
|
+
The package can be built independently:
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
npm run build
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
The package must compile independently from the host application's domain modules and infrastructure.
|
|
272
|
+
|
|
273
|
+
## Tests
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
npm test
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
From the API repo: `npm run test:pkg:database`.
|
|
280
|
+
|
|
281
|
+
Integration / host-level database health checks may be provided by the consuming application.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sasscore/database/connection
|
|
3
|
+
*/
|
|
4
|
+
export { DATABASE_TOKENS } from '../tokens.js';
|
|
5
|
+
export { DatabaseConnectionModule } from './infrastructure/connection.module.js';
|
|
6
|
+
export { SequelizeService } from './infrastructure/sequelize.service.js';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../connection/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AACjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sasscore/database/connection
|
|
3
|
+
*/
|
|
4
|
+
export { DATABASE_TOKENS } from '../tokens.js';
|
|
5
|
+
export { DatabaseConnectionModule } from './infrastructure/connection.module.js';
|
|
6
|
+
export { SequelizeService } from './infrastructure/sequelize.service.js';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../connection/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AACjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { DynamicModule } from '@nestjs/common';
|
|
2
|
+
import type { Model, ModelCtor } from 'sequelize-typescript';
|
|
3
|
+
import type { DatabaseModuleOptions } from '../../types/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* Database connection capability — public entry for business modules.
|
|
6
|
+
*
|
|
7
|
+
* Host apps that already bootstrap Sequelize (e.g. monolith `UniversalDatabaseModule`)
|
|
8
|
+
* can call {@link DatabaseConnectionModule.forRoot} with empty options — only
|
|
9
|
+
* {@link SequelizeService} is registered against the existing connection.
|
|
10
|
+
*
|
|
11
|
+
* Standalone / future package consumers pass connection options to wire
|
|
12
|
+
* `SequelizeModule.forRoot` from this package.
|
|
13
|
+
*/
|
|
14
|
+
export declare class DatabaseConnectionModule {
|
|
15
|
+
static forRoot(options?: DatabaseModuleOptions): DynamicModule;
|
|
16
|
+
static forFeature(models: ModelCtor<Model>[], connection?: string): DynamicModule;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=connection.module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.module.d.ts","sourceRoot":"","sources":["../../../connection/infrastructure/connection.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAkB,MAAM,gBAAgB,CAAC;AAE/D,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAE7D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAGlE;;;;;;;;;GASG;AACH,qBAEa,wBAAwB;IACnC,MAAM,CAAC,OAAO,CAAC,OAAO,GAAE,qBAA0B,GAAG,aAAa;IA4ClE,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,aAAa;CAOlF"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var DatabaseConnectionModule_1;
|
|
8
|
+
import { Global, Module } from '@nestjs/common';
|
|
9
|
+
import { SequelizeModule } from '@nestjs/sequelize';
|
|
10
|
+
import { DATABASE_TOKENS } from '../../providers/database.tokens.js';
|
|
11
|
+
import { SequelizeService } from './sequelize.service.js';
|
|
12
|
+
/**
|
|
13
|
+
* Database connection capability — public entry for business modules.
|
|
14
|
+
*
|
|
15
|
+
* Host apps that already bootstrap Sequelize (e.g. monolith `UniversalDatabaseModule`)
|
|
16
|
+
* can call {@link DatabaseConnectionModule.forRoot} with empty options — only
|
|
17
|
+
* {@link SequelizeService} is registered against the existing connection.
|
|
18
|
+
*
|
|
19
|
+
* Standalone / future package consumers pass connection options to wire
|
|
20
|
+
* `SequelizeModule.forRoot` from this package.
|
|
21
|
+
*/
|
|
22
|
+
let DatabaseConnectionModule = DatabaseConnectionModule_1 = class DatabaseConnectionModule {
|
|
23
|
+
static forRoot(options = {}) {
|
|
24
|
+
const hasConnectionOptions = options.host != null ||
|
|
25
|
+
options.database != null ||
|
|
26
|
+
options.username != null ||
|
|
27
|
+
options.port != null;
|
|
28
|
+
const imports = hasConnectionOptions
|
|
29
|
+
? [
|
|
30
|
+
SequelizeModule.forRoot({
|
|
31
|
+
dialect: options.dialect ?? 'postgres',
|
|
32
|
+
host: options.host,
|
|
33
|
+
port: options.port,
|
|
34
|
+
database: options.database,
|
|
35
|
+
username: options.username,
|
|
36
|
+
password: options.password,
|
|
37
|
+
autoLoadModels: true,
|
|
38
|
+
synchronize: false,
|
|
39
|
+
logging: options.logging ?? false,
|
|
40
|
+
}),
|
|
41
|
+
]
|
|
42
|
+
: [];
|
|
43
|
+
return {
|
|
44
|
+
module: DatabaseConnectionModule_1,
|
|
45
|
+
global: true,
|
|
46
|
+
imports,
|
|
47
|
+
providers: [
|
|
48
|
+
SequelizeService,
|
|
49
|
+
{
|
|
50
|
+
provide: DATABASE_TOKENS.SEQUELIZE,
|
|
51
|
+
useFactory: (sequelizeService) => sequelizeService.getSequelize(),
|
|
52
|
+
inject: [SequelizeService],
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
exports: [
|
|
56
|
+
SequelizeService,
|
|
57
|
+
DATABASE_TOKENS.SEQUELIZE,
|
|
58
|
+
...(imports.length ? [SequelizeModule] : []),
|
|
59
|
+
],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
static forFeature(models, connection) {
|
|
63
|
+
return {
|
|
64
|
+
module: DatabaseConnectionModule_1,
|
|
65
|
+
imports: [SequelizeModule.forFeature(models, connection)],
|
|
66
|
+
exports: [SequelizeModule],
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
DatabaseConnectionModule = DatabaseConnectionModule_1 = __decorate([
|
|
71
|
+
Global(),
|
|
72
|
+
Module({})
|
|
73
|
+
], DatabaseConnectionModule);
|
|
74
|
+
export { DatabaseConnectionModule };
|
|
75
|
+
//# sourceMappingURL=connection.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.module.js","sourceRoot":"","sources":["../../../connection/infrastructure/connection.module.ts"],"names":[],"mappings":";;;;;;;AAAA,OAAO,EAAiB,MAAM,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAErE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D;;;;;;;;;GASG;AAGI,IAAM,wBAAwB,gCAA9B,MAAM,wBAAwB;IACnC,MAAM,CAAC,OAAO,CAAC,UAAiC,EAAE;QAChD,MAAM,oBAAoB,GACxB,OAAO,CAAC,IAAI,IAAI,IAAI;YACpB,OAAO,CAAC,QAAQ,IAAI,IAAI;YACxB,OAAO,CAAC,QAAQ,IAAI,IAAI;YACxB,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC;QAEvB,MAAM,OAAO,GAAG,oBAAoB;YAClC,CAAC,CAAC;gBACE,eAAe,CAAC,OAAO,CAAC;oBACtB,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,UAAU;oBACtC,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,cAAc,EAAE,IAAI;oBACpB,WAAW,EAAE,KAAK;oBAClB,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,KAAK;iBAClC,CAAC;aACH;YACH,CAAC,CAAC,EAAE,CAAC;QAEP,OAAO;YACL,MAAM,EAAE,0BAAwB;YAChC,MAAM,EAAE,IAAI;YACZ,OAAO;YACP,SAAS,EAAE;gBACT,gBAAgB;gBAChB;oBACE,OAAO,EAAE,eAAe,CAAC,SAAS;oBAClC,UAAU,EAAE,CAAC,gBAAkC,EAAE,EAAE,CACjD,gBAAgB,CAAC,YAAY,EAAE;oBACjC,MAAM,EAAE,CAAC,gBAAgB,CAAC;iBAC3B;aACF;YACD,OAAO,EAAE;gBACP,gBAAgB;gBAChB,eAAe,CAAC,SAAS;gBACzB,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;aAC7C;SACF,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,MAA0B,EAAE,UAAmB;QAC/D,OAAO;YACL,MAAM,EAAE,0BAAwB;YAChC,OAAO,EAAE,CAAC,eAAe,CAAC,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YACzD,OAAO,EAAE,CAAC,eAAe,CAAC;SAC3B,CAAC;IACJ,CAAC;CACF,CAAA;AApDY,wBAAwB;IAFpC,MAAM,EAAE;IACR,MAAM,CAAC,EAAE,CAAC;GACE,wBAAwB,CAoDpC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Sequelize, Model } from 'sequelize-typescript';
|
|
2
|
+
/**
|
|
3
|
+
* Thin Sequelize facade for package consumers.
|
|
4
|
+
* Requires Nest `SequelizeModule` to be registered by the host (or {@link DatabaseConnectionModule.forRoot}).
|
|
5
|
+
*/
|
|
6
|
+
export declare class SequelizeService {
|
|
7
|
+
private readonly sequelize;
|
|
8
|
+
constructor(sequelize: Sequelize);
|
|
9
|
+
getSequelize(): Sequelize;
|
|
10
|
+
transaction<T>(callback: (transaction: never) => Promise<T>): Promise<T>;
|
|
11
|
+
getModel<T extends Model>(modelName: string): unknown;
|
|
12
|
+
query(sql: string, options?: unknown): Promise<unknown>;
|
|
13
|
+
healthCheck(): Promise<boolean>;
|
|
14
|
+
close(): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=sequelize.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sequelize.service.d.ts","sourceRoot":"","sources":["../../../connection/infrastructure/sequelize.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAExD;;;GAGG;AACH,qBACa,gBAAgB;IAGzB,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,SAAS;IAGvC,YAAY,IAAI,SAAS;IAInB,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,WAAW,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAI9E,QAAQ,CAAC,CAAC,SAAS,KAAK,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAI/C,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAIvD,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAS/B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import { Injectable } from '@nestjs/common';
|
|
14
|
+
import { InjectConnection } from '@nestjs/sequelize';
|
|
15
|
+
import { Sequelize } from 'sequelize-typescript';
|
|
16
|
+
/**
|
|
17
|
+
* Thin Sequelize facade for package consumers.
|
|
18
|
+
* Requires Nest `SequelizeModule` to be registered by the host (or {@link DatabaseConnectionModule.forRoot}).
|
|
19
|
+
*/
|
|
20
|
+
let SequelizeService = class SequelizeService {
|
|
21
|
+
sequelize;
|
|
22
|
+
constructor(sequelize) {
|
|
23
|
+
this.sequelize = sequelize;
|
|
24
|
+
}
|
|
25
|
+
getSequelize() {
|
|
26
|
+
return this.sequelize;
|
|
27
|
+
}
|
|
28
|
+
async transaction(callback) {
|
|
29
|
+
return this.sequelize.transaction(callback);
|
|
30
|
+
}
|
|
31
|
+
getModel(modelName) {
|
|
32
|
+
return this.sequelize.models[modelName];
|
|
33
|
+
}
|
|
34
|
+
async query(sql, options) {
|
|
35
|
+
return this.sequelize.query(sql, options);
|
|
36
|
+
}
|
|
37
|
+
async healthCheck() {
|
|
38
|
+
try {
|
|
39
|
+
await this.sequelize.authenticate();
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
async close() {
|
|
47
|
+
await this.sequelize.close();
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
SequelizeService = __decorate([
|
|
51
|
+
Injectable(),
|
|
52
|
+
__param(0, InjectConnection()),
|
|
53
|
+
__metadata("design:paramtypes", [Sequelize])
|
|
54
|
+
], SequelizeService);
|
|
55
|
+
export { SequelizeService };
|
|
56
|
+
//# sourceMappingURL=sequelize.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sequelize.service.js","sourceRoot":"","sources":["../../../connection/infrastructure/sequelize.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAS,MAAM,sBAAsB,CAAC;AAExD;;;GAGG;AAEI,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;IAGR;IAFnB,YAEmB,SAAoB;QAApB,cAAS,GAAT,SAAS,CAAW;IACpC,CAAC;IAEJ,YAAY;QACV,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,WAAW,CAAI,QAA4C;QAC/D,OAAO,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,QAA8D,CAAC,CAAC;IACpG,CAAC;IAED,QAAQ,CAAkB,SAAiB;QACzC,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,GAAW,EAAE,OAAiB;QACxC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,OAAgB,CAAC,CAAC;IACrD,CAAC;IAED,KAAK,CAAC,WAAW;QACf,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;CACF,CAAA;AAlCY,gBAAgB;IAD5B,UAAU,EAAE;IAGR,WAAA,gBAAgB,EAAE,CAAA;qCACS,SAAS;GAH5B,gBAAgB,CAkC5B"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { DynamicModule } from '@nestjs/common';
|
|
2
|
+
import type { DatabaseModuleOptions } from './types/index.js';
|
|
3
|
+
export type { DatabaseModuleOptions } from './types/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* Aggregates database package capabilities for app bootstrap.
|
|
6
|
+
*
|
|
7
|
+
* Consumer (e.g. kit client):
|
|
8
|
+
* ```typescript
|
|
9
|
+
* @Module({ imports: [DatabaseModule.forRoot({ ... })] })
|
|
10
|
+
* export class AppModule {}
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export declare class DatabaseDomainModule {
|
|
14
|
+
/**
|
|
15
|
+
* Single entry point — connection, health, outbox stay inside the package.
|
|
16
|
+
*/
|
|
17
|
+
static forRoot(options?: DatabaseModuleOptions): DynamicModule;
|
|
18
|
+
static forRootAsync(options: {
|
|
19
|
+
useFactory: (...args: never[]) => DatabaseModuleOptions | Promise<DatabaseModuleOptions>;
|
|
20
|
+
inject?: Array<string | symbol | (new (...args: never[]) => unknown)>;
|
|
21
|
+
}): DynamicModule;
|
|
22
|
+
}
|
|
23
|
+
/** @sasscore/database root export alias */
|
|
24
|
+
export { DatabaseDomainModule as DatabaseModule };
|
|
25
|
+
//# sourceMappingURL=database.module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.module.d.ts","sourceRoot":"","sources":["../database.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAU,MAAM,gBAAgB,CAAC;AAIvD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAE9D,YAAY,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAE9D;;;;;;;;GAQG;AACH,qBACa,oBAAoB;IAC/B;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,OAAO,GAAE,qBAA0B,GAAG,aAAa;IAiBlE,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE;QAC3B,UAAU,EAAE,CACV,GAAG,IAAI,EAAE,KAAK,EAAE,KACb,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;QAC5D,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC;KACvE,GAAG,aAAa;CAuBlB;AAED,2CAA2C;AAC3C,OAAO,EAAE,oBAAoB,IAAI,cAAc,EAAE,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var DatabaseDomainModule_1;
|
|
8
|
+
import { Module } from '@nestjs/common';
|
|
9
|
+
import { DatabaseConnectionModule } from './connection/index.js';
|
|
10
|
+
import { DatabaseHealthModule } from './health/health.module.js';
|
|
11
|
+
import { DatabaseOutboxModule } from './outbox/infrastructure/outbox.module.js';
|
|
12
|
+
/**
|
|
13
|
+
* Aggregates database package capabilities for app bootstrap.
|
|
14
|
+
*
|
|
15
|
+
* Consumer (e.g. kit client):
|
|
16
|
+
* ```typescript
|
|
17
|
+
* @Module({ imports: [DatabaseModule.forRoot({ ... })] })
|
|
18
|
+
* export class AppModule {}
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
let DatabaseDomainModule = DatabaseDomainModule_1 = class DatabaseDomainModule {
|
|
22
|
+
/**
|
|
23
|
+
* Single entry point — connection, health, outbox stay inside the package.
|
|
24
|
+
*/
|
|
25
|
+
static forRoot(options = {}) {
|
|
26
|
+
return {
|
|
27
|
+
module: DatabaseDomainModule_1,
|
|
28
|
+
global: true,
|
|
29
|
+
imports: [
|
|
30
|
+
DatabaseConnectionModule.forRoot(options),
|
|
31
|
+
DatabaseHealthModule,
|
|
32
|
+
DatabaseOutboxModule,
|
|
33
|
+
],
|
|
34
|
+
exports: [
|
|
35
|
+
DatabaseConnectionModule,
|
|
36
|
+
DatabaseHealthModule,
|
|
37
|
+
DatabaseOutboxModule,
|
|
38
|
+
],
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
static forRootAsync(options) {
|
|
42
|
+
return {
|
|
43
|
+
module: DatabaseDomainModule_1,
|
|
44
|
+
global: true,
|
|
45
|
+
imports: [
|
|
46
|
+
DatabaseConnectionModule.forRoot(),
|
|
47
|
+
DatabaseHealthModule,
|
|
48
|
+
DatabaseOutboxModule,
|
|
49
|
+
],
|
|
50
|
+
exports: [
|
|
51
|
+
DatabaseConnectionModule,
|
|
52
|
+
DatabaseHealthModule,
|
|
53
|
+
DatabaseOutboxModule,
|
|
54
|
+
],
|
|
55
|
+
providers: [
|
|
56
|
+
{
|
|
57
|
+
provide: 'DATABASE_MODULE_OPTIONS',
|
|
58
|
+
useFactory: options.useFactory,
|
|
59
|
+
inject: (options.inject ?? []),
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
DatabaseDomainModule = DatabaseDomainModule_1 = __decorate([
|
|
66
|
+
Module({})
|
|
67
|
+
], DatabaseDomainModule);
|
|
68
|
+
export { DatabaseDomainModule };
|
|
69
|
+
/** @sasscore/database root export alias */
|
|
70
|
+
export { DatabaseDomainModule as DatabaseModule };
|
|
71
|
+
//# sourceMappingURL=database.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.module.js","sourceRoot":"","sources":["../database.module.ts"],"names":[],"mappings":";;;;;;;AAAA,OAAO,EAAiB,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,0CAA0C,CAAC;AAKhF;;;;;;;;GAQG;AAEI,IAAM,oBAAoB,4BAA1B,MAAM,oBAAoB;IAC/B;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,UAAiC,EAAE;QAChD,OAAO;YACL,MAAM,EAAE,sBAAoB;YAC5B,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE;gBACP,wBAAwB,CAAC,OAAO,CAAC,OAAO,CAAC;gBACzC,oBAAoB;gBACpB,oBAAoB;aACrB;YACD,OAAO,EAAE;gBACP,wBAAwB;gBACxB,oBAAoB;gBACpB,oBAAoB;aACrB;SACF,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,OAKnB;QACC,OAAO;YACL,MAAM,EAAE,sBAAoB;YAC5B,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE;gBACP,wBAAwB,CAAC,OAAO,EAAE;gBAClC,oBAAoB;gBACpB,oBAAoB;aACrB;YACD,OAAO,EAAE;gBACP,wBAAwB;gBACxB,oBAAoB;gBACpB,oBAAoB;aACrB;YACD,SAAS,EAAE;gBACT;oBACE,OAAO,EAAE,yBAAyB;oBAClC,UAAU,EAAE,OAAO,CAAC,UAAU;oBAC9B,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAY;iBAC1C;aACF;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AAjDY,oBAAoB;IADhC,MAAM,CAAC,EAAE,CAAC;GACE,oBAAoB,CAiDhC;;AAED,2CAA2C;AAC3C,OAAO,EAAE,oBAAoB,IAAI,cAAc,EAAE,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Sequelize } from 'sequelize-typescript';
|
|
2
|
+
import type { DatabaseHealthResult } from './database-health.types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Package capability: probe Sequelize / PostgreSQL connectivity.
|
|
5
|
+
* No HTTP — host apps expose this via their own controllers.
|
|
6
|
+
*/
|
|
7
|
+
export declare class DatabaseHealth {
|
|
8
|
+
private readonly sequelize;
|
|
9
|
+
constructor(sequelize: Sequelize);
|
|
10
|
+
check(): Promise<DatabaseHealthResult>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=database-health.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-health.service.d.ts","sourceRoot":"","sources":["../../health/database-health.service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAEvE;;;GAGG;AACH,qBACa,cAAc;IAGvB,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,SAAS;IAGjC,KAAK,IAAI,OAAO,CAAC,oBAAoB,CAAC;CAkB7C"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import { Inject, Injectable } from '@nestjs/common';
|
|
14
|
+
import { DATABASE_TOKENS } from '../providers/database.tokens.js';
|
|
15
|
+
/**
|
|
16
|
+
* Package capability: probe Sequelize / PostgreSQL connectivity.
|
|
17
|
+
* No HTTP — host apps expose this via their own controllers.
|
|
18
|
+
*/
|
|
19
|
+
let DatabaseHealth = class DatabaseHealth {
|
|
20
|
+
sequelize;
|
|
21
|
+
constructor(sequelize) {
|
|
22
|
+
this.sequelize = sequelize;
|
|
23
|
+
}
|
|
24
|
+
async check() {
|
|
25
|
+
const startedAt = Date.now();
|
|
26
|
+
try {
|
|
27
|
+
await this.sequelize.authenticate();
|
|
28
|
+
return {
|
|
29
|
+
status: 'up',
|
|
30
|
+
latencyMs: Date.now() - startedAt,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
return {
|
|
35
|
+
status: 'down',
|
|
36
|
+
latencyMs: Date.now() - startedAt,
|
|
37
|
+
error: error instanceof Error ? error.message : 'Database connection failed',
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
DatabaseHealth = __decorate([
|
|
43
|
+
Injectable(),
|
|
44
|
+
__param(0, Inject(DATABASE_TOKENS.SEQUELIZE)),
|
|
45
|
+
__metadata("design:paramtypes", [Function])
|
|
46
|
+
], DatabaseHealth);
|
|
47
|
+
export { DatabaseHealth };
|
|
48
|
+
//# sourceMappingURL=database-health.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-health.service.js","sourceRoot":"","sources":["../../health/database-health.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAGlE;;;GAGG;AAEI,IAAM,cAAc,GAApB,MAAM,cAAc;IAGN;IAFnB,YAEmB,SAAoB;QAApB,cAAS,GAAT,SAAS,CAAW;IACpC,CAAC;IAEJ,KAAK,CAAC,KAAK;QACT,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC;YACpC,OAAO;gBACL,MAAM,EAAE,IAAI;gBACZ,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;aAClC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,MAAM,EAAE,MAAM;gBACd,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;gBACjC,KAAK,EACH,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,4BAA4B;aACxE,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAA;AAxBY,cAAc;IAD1B,UAAU,EAAE;IAGR,WAAA,MAAM,CAAC,eAAe,CAAC,SAAS,CAAC,CAAA;;GAFzB,cAAc,CAwB1B"}
|