@flusys/nestjs-core 9.1.1 → 9.2.0

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 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
- public tryGetValue(key: string, throwOnMissing = false): string // get env value
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: `${__dirname}/migrations`,
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 (supports * and ** wildcards)
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?: boolean): number;
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: "mysql" | "postgres" | "mariadb" | "sqlite" | "mssql";
17
+ type: DatabaseType;
16
18
  host: string;
17
19
  port: number;
18
20
  username: string;