@flusys/nestjs-core 9.1.2 → 9.2.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 +39 -6
- package/config/env-config.service.d.ts +4 -2
- package/fesm/229.js +189 -135
- package/fesm/config/index.js +41 -19
- package/fesm/docs/index.js +81 -166
- package/fesm/index.js +1 -1
- package/fesm/migration/index.js +1 -1
- package/fesm/utils/index.js +15 -26
- package/migration/migration.runner.d.ts +10 -1
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -24,14 +24,30 @@ Access typed environment variables via the `envConfig` singleton — no class in
|
|
|
24
24
|
```typescript
|
|
25
25
|
import { envConfig } from '@flusys/nestjs-core';
|
|
26
26
|
|
|
27
|
-
const port = envConfig.getPort(); // number
|
|
28
|
-
const db = envConfig.getTypeOrmConfig(); // { host, port, username, password, database }
|
|
27
|
+
const port = envConfig.getPort(); // number, PORT or 3000
|
|
28
|
+
const db = envConfig.getTypeOrmConfig(); // { type, host, port, username, password, database }
|
|
29
29
|
const jwt = envConfig.getJwtConfig(); // { secret, expiration, refreshSecret, ... }
|
|
30
30
|
const origins = envConfig.getOrigins(); // string[]
|
|
31
31
|
const isProd = envConfig.isProduction(); // boolean
|
|
32
|
-
|
|
32
|
+
|
|
33
|
+
const value = envConfig.tryGetValue('APP_URL'); // string, '' when unset
|
|
34
|
+
const size = envConfig.getNumber('MAX_FILE_SIZE', false) ?? 10; // number | undefined
|
|
35
|
+
const enabled = envConfig.getBoolean('ENABLE_DOMAIN_EVENTS', false); // boolean
|
|
33
36
|
```
|
|
34
37
|
|
|
38
|
+
Parsing rules:
|
|
39
|
+
|
|
40
|
+
| Input | Behaviour |
|
|
41
|
+
| ----- | --------- |
|
|
42
|
+
| Unset, empty or whitespace-only value | Treated as missing: throws `Config error - missing env.KEY` when required, otherwise `''` |
|
|
43
|
+
| `getNumber(key)` (required) | Throws when missing or not a finite number |
|
|
44
|
+
| `getNumber(key, false)` | `undefined` when missing or not a finite number, so `??` defaults apply |
|
|
45
|
+
| `getBoolean` / `useTenantMode` / `DISABLE_HTTP_LOGGING` | Only `true` (any case, surrounding spaces ignored) is `true` |
|
|
46
|
+
| `MODE` | Anything other than `dev` (any case) counts as production |
|
|
47
|
+
| `ALLOW_ORIGINS` | Required; comma-separated, trimmed, empty entries dropped |
|
|
48
|
+
| `DB_TYPE` | One of `mysql`, `postgres`, `mariadb`, `sqlite`, `mssql` (any case, default `mysql`); anything else throws. Default port: postgres 5432, mssql 1433, otherwise 3306 |
|
|
49
|
+
| `ALLOW_ORIGINS`, `PORT`, `MODE`, `DB_*` via `tryGetValue` | Throws `Access denied` - use the dedicated method |
|
|
50
|
+
|
|
35
51
|
---
|
|
36
52
|
|
|
37
53
|
## 2. Migrations
|
|
@@ -39,6 +55,8 @@ const isProd = envConfig.isProduction(); // boolean
|
|
|
39
55
|
### Create `src/persistence/migration.config.ts`
|
|
40
56
|
|
|
41
57
|
```typescript
|
|
58
|
+
import { dirname } from 'path';
|
|
59
|
+
import { fileURLToPath } from 'url';
|
|
42
60
|
import { createMigrationDataSource, IMigrationConfig } from '@flusys/nestjs-core';
|
|
43
61
|
import { envConfig } from '@flusys/nestjs-core/config';
|
|
44
62
|
import { getAuthEntitiesByConfig } from '@flusys/nestjs-auth';
|
|
@@ -53,7 +71,7 @@ const bootstrapConfig = {
|
|
|
53
71
|
export const migrationConfig: IMigrationConfig = {
|
|
54
72
|
defaultDatabaseConfig: envConfig.getTypeOrmConfig(),
|
|
55
73
|
bootstrapAppConfig: bootstrapConfig,
|
|
56
|
-
migrationsPath: `${
|
|
74
|
+
migrationsPath: `${dirname(fileURLToPath(import.meta.url))}/migrations`,
|
|
57
75
|
migrationsTableName: 'migrations',
|
|
58
76
|
entities: [
|
|
59
77
|
...getAuthEntitiesByConfig(bootstrapConfig),
|
|
@@ -78,6 +96,7 @@ export default createMigrationDataSource({
|
|
|
78
96
|
"migration:run": "npm run migration -- run",
|
|
79
97
|
"migration:revert": "npm run migration -- revert",
|
|
80
98
|
"migration:status": "npm run migration -- status",
|
|
99
|
+
"migration:reset": "npm run migration -- reset",
|
|
81
100
|
"migration:run:all": "npm run migration -- run:all",
|
|
82
101
|
"migration:revert:all": "npm run migration -- revert:all",
|
|
83
102
|
"migration:status:all": "npm run migration -- status:all"
|
|
@@ -104,8 +123,21 @@ TENANT_ID=tenant-1 npm run migration:status
|
|
|
104
123
|
npm run migration:run:all
|
|
105
124
|
npm run migration:revert:all
|
|
106
125
|
npm run migration:status:all
|
|
126
|
+
|
|
127
|
+
# Dev only: drop + recreate the database, wipe migration files, generate and run "Init"
|
|
128
|
+
npm run migration:reset
|
|
107
129
|
```
|
|
108
130
|
|
|
131
|
+
CLI rules:
|
|
132
|
+
|
|
133
|
+
- Migration names must start with a letter and contain only letters, digits, `_` or `-` (checked before anything runs, including before `reset` drops the database).
|
|
134
|
+
- Flag values keep everything after the first `=` (`--config=a=b.ts`); an empty `--name=` counts as missing.
|
|
135
|
+
- `TENANT_ID` must match a configured tenant; an unknown id fails instead of falling back to the default database.
|
|
136
|
+
- `run`, `revert`, `status` and every `:all` command exit with code 1 when any database fails. `:all` supports only `run`, `revert` and `status`; each tenant runs independently, so one failing tenant does not stop the others, and every connection is closed even on failure.
|
|
137
|
+
- `reset` refuses to run unless `MODE=dev` or `--force` is passed, and never resets the PostgreSQL `postgres` maintenance database.
|
|
138
|
+
- Without `--config`, the CLI tries `MIGRATION_CONFIG`, then `src/persistence/migration.config.{ts,js}` and `persistence/migration.config.{ts,js}`. A config file that exists but fails to import reports its real error. The module must export `migrationConfig` (or default-export the config object).
|
|
139
|
+
- `ignoreTable` in `IMigrationConfig` removes generated statements that mention runtime-managed tables (for example the entity builder's `eb_<code>` tables).
|
|
140
|
+
|
|
109
141
|
---
|
|
110
142
|
|
|
111
143
|
## 3. Swagger
|
|
@@ -133,7 +165,8 @@ async function bootstrap() {
|
|
|
133
165
|
// Exclude controllers by @ApiTags name
|
|
134
166
|
excludeTags: ['Internal', 'Health'],
|
|
135
167
|
|
|
136
|
-
// Exclude specific paths
|
|
168
|
+
// Exclude specific paths: * matches one path segment, ** matches any depth,
|
|
169
|
+
// every other character (., +, {id}, ...) is literal
|
|
137
170
|
excludePaths: ['/api/auth/internal/*', '/api/health'],
|
|
138
171
|
|
|
139
172
|
// Exclude properties from a DTO schema
|
|
@@ -141,7 +174,7 @@ async function bootstrap() {
|
|
|
141
174
|
{ schemaName: 'CreateUserDto', properties: ['passwordHash', 'salt'] },
|
|
142
175
|
],
|
|
143
176
|
|
|
144
|
-
// Exclude query parameters from specific endpoints
|
|
177
|
+
// Exclude query parameters from specific endpoints (method is case-insensitive)
|
|
145
178
|
excludeQueryParameters: [
|
|
146
179
|
{ pathPattern: '/api/auth/*', method: 'post', parameters: ['debug'] },
|
|
147
180
|
],
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type DatabaseType } from '../interfaces/database.interface.js';
|
|
1
2
|
declare class EnvConfigService {
|
|
2
3
|
private env;
|
|
3
4
|
private restrictedKeys;
|
|
@@ -6,13 +7,14 @@ declare class EnvConfigService {
|
|
|
6
7
|
});
|
|
7
8
|
private getValue;
|
|
8
9
|
tryGetValue(key: string, throwOnMissing?: boolean): string;
|
|
9
|
-
getNumber(key: string, throwOnMissing?:
|
|
10
|
+
getNumber(key: string, throwOnMissing?: true): number;
|
|
11
|
+
getNumber(key: string, throwOnMissing: boolean): number | undefined;
|
|
10
12
|
getBoolean(key: string, throwOnMissing?: boolean): boolean;
|
|
11
13
|
getPort(): number;
|
|
12
14
|
isProduction(): boolean;
|
|
13
15
|
getOrigins(): string[];
|
|
14
16
|
getTypeOrmConfig(): {
|
|
15
|
-
type:
|
|
17
|
+
type: DatabaseType;
|
|
16
18
|
host: string;
|
|
17
19
|
port: number;
|
|
18
20
|
username: string;
|