@flusys/nestjs-core 1.1.0-beta → 1.2.0-rc.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.
Files changed (61) hide show
  1. package/README.md +136 -162
  2. package/cjs/config/env-config.service.js +14 -10
  3. package/cjs/docs/docs.config.js +99 -15
  4. package/cjs/docs/index.js +0 -1
  5. package/cjs/index.js +0 -1
  6. package/cjs/interfaces/base-entity.interface.js +5 -3
  7. package/cjs/interfaces/database.interface.js +1 -3
  8. package/cjs/migration/datasource.factory.js +1 -3
  9. package/cjs/migration/index.js +0 -12
  10. package/cjs/migration/migration.cli.js +1 -17
  11. package/cjs/migration/migration.runner.js +37 -65
  12. package/cjs/utils/datasource-config.builder.js +2 -14
  13. package/config/env-config.service.d.ts +3 -1
  14. package/docs/docs.config.d.ts +8 -0
  15. package/docs/index.d.ts +0 -1
  16. package/fesm/config/env-config.service.js +14 -10
  17. package/fesm/docs/docs.config.js +89 -15
  18. package/fesm/docs/index.js +0 -1
  19. package/fesm/index.js +0 -2
  20. package/fesm/interfaces/app-config.interfaces.js +1 -3
  21. package/fesm/interfaces/base-entity.interface.js +5 -5
  22. package/fesm/interfaces/database.interface.js +1 -5
  23. package/fesm/migration/cli.js +1 -20
  24. package/fesm/migration/datasource.factory.js +3 -20
  25. package/fesm/migration/index.js +0 -14
  26. package/fesm/migration/migration.cli.js +1 -17
  27. package/fesm/migration/migration.runner.js +43 -132
  28. package/fesm/utils/datasource-config.builder.js +2 -13
  29. package/index.d.ts +0 -1
  30. package/interfaces/app-config.interfaces.d.ts +1 -0
  31. package/interfaces/base-entity.interface.d.ts +2 -2
  32. package/interfaces/database.interface.d.ts +2 -1
  33. package/package.json +9 -9
  34. package/utils/datasource-config.builder.d.ts +0 -1
  35. package/cjs/docs/docs.setup.js +0 -14
  36. package/cjs/seeders/base-seeder.js +0 -95
  37. package/cjs/seeders/cli.js +0 -398
  38. package/cjs/seeders/data-generator.js +0 -247
  39. package/cjs/seeders/entity-reader.js +0 -168
  40. package/cjs/seeders/index.js +0 -77
  41. package/cjs/seeders/seed-config.js +0 -101
  42. package/cjs/seeders/seed-runner.js +0 -320
  43. package/cjs/seeders/template-generator.js +0 -297
  44. package/docs/docs.setup.d.ts +0 -3
  45. package/fesm/docs/docs.setup.js +0 -4
  46. package/fesm/seeders/base-seeder.js +0 -110
  47. package/fesm/seeders/cli.js +0 -366
  48. package/fesm/seeders/data-generator.js +0 -249
  49. package/fesm/seeders/entity-reader.js +0 -170
  50. package/fesm/seeders/index.js +0 -11
  51. package/fesm/seeders/seed-config.js +0 -85
  52. package/fesm/seeders/seed-runner.js +0 -323
  53. package/fesm/seeders/template-generator.js +0 -257
  54. package/seeders/base-seeder.d.ts +0 -14
  55. package/seeders/cli.d.ts +0 -3
  56. package/seeders/data-generator.d.ts +0 -15
  57. package/seeders/entity-reader.d.ts +0 -45
  58. package/seeders/index.d.ts +0 -7
  59. package/seeders/seed-config.d.ts +0 -11
  60. package/seeders/seed-runner.d.ts +0 -47
  61. package/seeders/template-generator.d.ts +0 -16
package/README.md CHANGED
@@ -1,197 +1,171 @@
1
- # Core Package Guide
1
+ # @flusys/nestjs-core
2
2
 
3
- > **Package:** `@flusys/nestjs-core`
4
- > **Type:** Pure TypeScript utilities (Zero NestJS dependencies)
3
+ Foundation infrastructure for NestJS applications — environment config, TypeORM migrations, and Swagger setup.
5
4
 
6
- Foundation layer providing type-safe configuration, database utilities, migration CLI, seeders, and Swagger setup.
5
+ [![npm version](https://img.shields.io/npm/v/@flusys/nestjs-core.svg)](https://www.npmjs.com/package/@flusys/nestjs-core)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
7
 
8
- ## Package Architecture
8
+ ---
9
9
 
10
+ ## Installation
11
+
12
+ ```bash
13
+ npm install @flusys/nestjs-core
14
+ npm install typeorm typeorm-naming-strategies dotenv
15
+ npm install -D ts-node tsconfig-paths
10
16
  ```
11
- nestjs-core/src/
12
- ├── config/
13
- │ └── env-config.service.ts # Environment configuration singleton
14
- ├── constants/
15
- │ └── database.constants.ts # MODULE_OPTIONS, DEFAULT_TENANT_HEADER
16
- ├── interfaces/
17
- │ ├── app-config.interfaces.ts # IBootstrapAppConfig, IDynamicModuleConfig
18
- │ ├── base-entity.interface.ts # IBaseEntity, ISoftDeletable, ITimestampable
19
- │ ├── database.interface.ts # IDatabaseConfig, ITenantDatabaseConfig
20
- │ └── migration.interface.ts # IMigrationConfig, IMigrationResult
21
- ├── utils/
22
- │ └── datasource-config.builder.ts
23
- ├── migration/
24
- │ ├── cli.ts, migration.cli.ts, datasource.factory.ts, migration.runner.ts
25
- ├── seeders/
26
- │ ├── cli.ts, base-seeder.ts, seed-runner.ts, seed-config.ts
27
- │ ├── entity-reader.ts, data-generator.ts, template-generator.ts
28
- ├── docs/
29
- │ ├── docs.config.ts, docs.setup.ts
30
- └── index.ts
31
- ```
32
17
 
33
- ## Environment Configuration
18
+ ---
19
+
20
+ ## 1. Environment Config
21
+
22
+ Access typed environment variables via the `envConfig` singleton — no class instantiation needed.
34
23
 
35
24
  ```typescript
36
- import { envConfig } from '@flusys/nestjs-core/config';
25
+ import { envConfig } from '@flusys/nestjs-core';
26
+
27
+ const port = envConfig.getPort(); // number
28
+ const db = envConfig.getTypeOrmConfig(); // { host, port, username, password, database }
29
+ const jwt = envConfig.getJwtConfig(); // { secret, expiration, refreshSecret, ... }
30
+ const origins = envConfig.getOrigins(); // string[]
31
+ const isProd = envConfig.isProduction(); // boolean
32
+ public tryGetValue(key: string, throwOnMissing = false): string // get env value
37
33
  ```
38
34
 
39
- | Method | Description |
40
- |--------|-------------|
41
- | `tryGetValue(key)` | Get env value (throws for restricted keys) |
42
- | `getNumber(key)` | Get env value as number |
43
- | `getBoolean(key)` | Get env value as boolean |
44
- | `getPort()` | Get PORT (default: 3000) |
45
- | `isProduction()` | Check if MODE !== 'DEV' |
46
- | `getFrontendUrl()` | Get FRONTEND_URL |
47
- | `getOrigins()` | Get ALLOW_ORIGINS as array |
48
- | `getTypeOrmConfig()` | Get database config |
49
- | `getJwtConfig()` | Get JWT config |
50
- | `getRedisUrl()` | Get Redis connection URL |
51
- | `getMailConfig()` | Get mail configuration |
52
- | `getTenantId()` | Get TENANT_ID |
53
- | `useTenantMode()` | Check USE_TENANT_MODE |
54
- | `getLogConfig()` | Get logging configuration |
55
- | `getEnv()` | Get all env vars as Record |
56
-
57
- ## Database Interfaces
35
+ ---
36
+
37
+ ## 2. Migrations
38
+
39
+ ### Create `src/persistence/migration.config.ts`
58
40
 
59
41
  ```typescript
60
- interface IDatabaseConfig {
61
- type: 'mysql' | 'postgres' | 'mariadb' | 'sqlite' | 'mssql';
62
- host?: string; port?: number; username?: string; password?: string; database?: string;
63
- }
42
+ import { createMigrationDataSource, IMigrationConfig } from '@flusys/nestjs-core';
43
+ import { envConfig } from '@flusys/nestjs-core/config';
44
+ import { getAuthEntitiesByConfig } from '@flusys/nestjs-auth';
45
+ import { getIAMEntitiesByConfig } from '@flusys/nestjs-iam';
46
+
47
+ const bootstrapConfig = {
48
+ databaseMode: 'single' as const,
49
+ enableCompanyFeature: true,
50
+ permissionMode: 'FULL' as const,
51
+ };
52
+
53
+ export const migrationConfig: IMigrationConfig = {
54
+ defaultDatabaseConfig: envConfig.getTypeOrmConfig(),
55
+ bootstrapAppConfig: bootstrapConfig,
56
+ migrationsPath: `${__dirname}/migrations`,
57
+ migrationsTableName: 'migrations',
58
+ entities: [
59
+ ...getAuthEntitiesByConfig(bootstrapConfig),
60
+ ...getIAMEntitiesByConfig(bootstrapConfig),
61
+ ],
62
+ };
64
63
 
65
- interface ITenantDatabaseConfig {
66
- id: string; database: string; name?: string;
67
- host?: string; port?: number; username?: string; password?: string;
68
- enableCompanyFeature?: boolean;
69
- permissionMode?: 'FULL' | 'RBAC' | 'DIRECT';
70
- }
64
+ // Required for TypeORM CLI
65
+ export default createMigrationDataSource({
66
+ config: migrationConfig,
67
+ tenantId: process.env.TENANT_ID,
68
+ });
69
+ ```
71
70
 
72
- interface IBootstrapAppConfig {
73
- databaseMode: 'single' | 'multi-tenant';
74
- enableCompanyFeature: boolean;
75
- permissionMode?: 'FULL' | 'RBAC' | 'DIRECT';
71
+ ### Add scripts to `package.json`
72
+
73
+ ```json
74
+ {
75
+ "scripts": {
76
+ "migration": "ts-node -r tsconfig-paths/register ./node_modules/@flusys/nestjs-core/migration/cli --config=src/persistence/migration.config.ts",
77
+ "migration:generate": "npm run migration -- generate",
78
+ "migration:run": "npm run migration -- run",
79
+ "migration:revert": "npm run migration -- revert",
80
+ "migration:status": "npm run migration -- status",
81
+ "migration:run:all": "npm run migration -- run:all",
82
+ "migration:revert:all": "npm run migration -- revert:all",
83
+ "migration:status:all": "npm run migration -- status:all"
84
+ }
76
85
  }
77
86
  ```
78
87
 
79
- ## Migration CLI
88
+ ### Run
80
89
 
81
90
  ```bash
82
- npm run migration:generate --name=CreateUsers
91
+ # Single database
92
+ npm run migration:generate -- --name=CreateUsersTable
83
93
  npm run migration:run
84
94
  npm run migration:revert
85
95
  npm run migration:status
86
- TENANT_ID=tenant1 npm run migration:run # specific tenant
87
- npm run migration:run:all # all tenants
88
- ```
89
96
 
90
- ```typescript
91
- import { runMigrationCli, createMigrationDataSource } from '@flusys/nestjs-core/migration';
92
- ```
97
+ # Tenant-specific (prefix with TENANT_ID)
98
+ TENANT_ID=tenant-1 npm run migration:generate -- --name=CreateUsersTable
99
+ TENANT_ID=tenant-1 npm run migration:run
100
+ TENANT_ID=tenant-1 npm run migration:revert
101
+ TENANT_ID=tenant-1 npm run migration:status
93
102
 
94
- ## Seed System
95
-
96
- ```bash
97
- npm run seed:generate
98
- npm run seed:run -- --entity=User --count=100
99
- npm run seed:clear
100
- npm run seed:status
103
+ # All tenants at once
104
+ npm run migration:run:all
105
+ npm run migration:revert:all
106
+ npm run migration:status:all
101
107
  ```
102
108
 
103
- ```typescript
104
- import { BaseSeeder, SeedRunner } from '@flusys/nestjs-core/seeders';
105
-
106
- class UserSeeder extends BaseSeeder<User> {
107
- constructor(ds: DataSource) { super(ds, User); }
108
- async generate(count: number): Promise<User[]> {
109
- const users = [];
110
- for (let i = 0; i < count; i++) {
111
- users.push(this.repository.create({ email: faker.internet.email() }));
112
- }
113
- return this.repository.save(users);
114
- }
115
- }
109
+ ---
116
110
 
117
- const runner = new SeedRunner(dataSource);
118
- runner.registerCustomSeeder('User', new UserSeeder(dataSource));
119
- await runner.runAll({ count: 50, clear: true });
120
- ```
111
+ ## 3. Swagger
121
112
 
122
- ## Swagger Documentation
113
+ `setupSwaggerDocs` and `setupModuleSwaggerDocs` accept the same `IModuleSwaggerOptions` shape.
123
114
 
124
115
  ```typescript
116
+ import { NestFactory } from '@nestjs/core';
125
117
  import { setupSwaggerDocs, setupModuleSwaggerDocs } from '@flusys/nestjs-core/docs';
126
-
127
- setupModuleSwaggerDocs(app, [
128
- { title: 'Auth API', path: 'auth/docs', bearerAuth: true },
129
- { title: 'Admin API', path: 'admin/docs', excludeTags: ['public'] },
130
- ]);
131
- ```
132
-
133
- ### Conditional Schema Exclusion
134
-
135
- ```typescript
136
- setupModuleSwaggerDocs(app, [{
137
- title: 'Auth API',
138
- path: 'auth/docs',
139
- excludeSchemaProperties: enableCompanyFeature ? undefined : [
140
- { schemaName: 'LoginResponseDto', properties: ['company', 'branch'] },
141
- ],
142
- }]);
143
- ```
144
-
145
- ## API Reference
146
-
147
- ```typescript
148
- // Interfaces
149
- import {
150
- IDatabaseConfig, ITenantDatabaseConfig, IBootstrapAppConfig,
151
- IDynamicModuleConfig, IDataSourceServiceOptions,
152
- IMigrationConfig, IMigrationResult,
153
- IBaseEntity, ISoftDeletable, ITimestampable, IOrderable,
154
- } from '@flusys/nestjs-core';
155
-
156
- // Constants
157
- import { MODULE_OPTIONS, DEFAULT_TENANT_HEADER } from '@flusys/nestjs-core';
158
-
159
- // Config
160
- import { envConfig } from '@flusys/nestjs-core/config';
161
-
162
- // Utils
163
- import {
164
- buildDataSourceOptions, getDatabaseForTenant,
165
- resolveEntities, getActiveTenants,
166
- } from '@flusys/nestjs-core/utils';
167
-
168
- // Migration
169
- import {
170
- createMigrationDataSource, initializeDataSource, runMigrationCli,
171
- generateMigration, runMigrations, revertMigration, migrationStatus,
172
- } from '@flusys/nestjs-core/migration';
173
-
174
- // Seeders
175
- import {
176
- BaseSeeder, SeedRunner, EntityReader, DataGenerator,
177
- seedConfig, runSeedCli,
178
- } from '@flusys/nestjs-core/seeders';
179
-
180
- // Swagger
181
- import {
182
- setupSwaggerDocs, setupModuleSwaggerDocs,
183
- IModuleSwaggerOptions, ISchemaPropertyExclusion,
184
- } from '@flusys/nestjs-core/docs';
118
+ import { AuthModule } from '@flusys/nestjs-auth';
119
+
120
+ async function bootstrap() {
121
+ const app = await NestFactory.create(AppModule);
122
+
123
+ // All available options (one entry showing every field)
124
+ setupModuleSwaggerDocs(app, [
125
+ {
126
+ title: 'Auth API', // required
127
+ description: 'Auth endpoints', // required
128
+ version: '1.0', // optional, default '1.0'
129
+ path: 'api/docs/auth', // required — URL where docs are served
130
+ bearerAuth: true, // adds Authorization header to Swagger UI
131
+ modules: [AuthModule], // scope to specific NestJS modules only
132
+
133
+ // Exclude controllers by @ApiTags name
134
+ excludeTags: ['Internal', 'Health'],
135
+
136
+ // Exclude specific paths (supports * and ** wildcards)
137
+ excludePaths: ['/api/auth/internal/*', '/api/health'],
138
+
139
+ // Exclude properties from a DTO schema
140
+ excludeSchemaProperties: [
141
+ { schemaName: 'CreateUserDto', properties: ['passwordHash', 'salt'] },
142
+ ],
143
+
144
+ // Exclude query parameters from specific endpoints
145
+ excludeQueryParameters: [
146
+ { pathPattern: '/api/auth/*', method: 'post', parameters: ['debug'] },
147
+ ],
148
+
149
+ // Exclude named examples from responses
150
+ excludeExamples: [
151
+ { pathPattern: '/api/auth/login', examples: ['AdminExample'] },
152
+ ],
153
+
154
+ // Add a custom header to every request in Swagger UI
155
+ globalHeaders: [
156
+ { name: 'x-tenant-id', description: 'Tenant identifier', required: false, example: 'tenant-1' },
157
+ ],
158
+ },
159
+
160
+ // Minimal entry
161
+ { title: 'IAM API', description: 'Roles and permissions', path: 'api/docs/iam' },
162
+ ]);
163
+
164
+ await app.listen(3000);
165
+ }
185
166
  ```
186
167
 
187
- ## Dependencies
188
-
189
- - `dotenv` - Environment variable loading
190
- - `typeorm` - Migration/seeder utilities
191
- - `@faker-js/faker` - Seed data generation
192
168
 
193
- **No NestJS dependencies** - Can be used in any TypeScript project.
194
-
195
- ---
169
+ ## License
196
170
 
197
- **Last Updated:** 2026-02-16
171
+ MIT © FLUSYS
@@ -85,24 +85,25 @@ let EnvConfigService = class EnvConfigService {
85
85
  return this.getValue(key, throwOnMissing).toLowerCase() === 'true';
86
86
  }
87
87
  getPort() {
88
- return this.getNumber('PORT', false);
88
+ return this.getNumber('PORT', false) || 3000;
89
89
  }
90
90
  isProduction() {
91
91
  return this.getValue('MODE', false).toUpperCase() !== 'DEV';
92
92
  }
93
- getFrontendUrl() {
94
- return this.getValue('FRONTEND_URL');
95
- }
96
93
  getOrigins() {
97
94
  const origins = this.getValue('ALLOW_ORIGINS');
98
95
  return origins ? origins.split(',').map((o)=>o.trim()) : [];
99
96
  }
100
97
  getTypeOrmConfig() {
98
+ const type = this.getValue('DB_TYPE', false) || 'mysql';
99
+ const defaultPort = type === 'postgres' ? 5432 : 3306;
101
100
  return {
102
- host: this.getValue('DB_HOST'),
103
- port: this.getNumber('DB_PORT'),
104
- username: this.getValue('DB_USER'),
105
- password: this.getValue('DB_PASSWORD')
101
+ type,
102
+ host: this.getValue('DB_HOST', false) || 'localhost',
103
+ port: this.getNumber('DB_PORT', false) || defaultPort,
104
+ username: this.getValue('DB_USER', false) || 'root',
105
+ password: this.getValue('DB_PASSWORD', false) || '',
106
+ database: this.getValue('DB_NAME', false) || 'flusys_main'
106
107
  };
107
108
  }
108
109
  getJwtConfig() {
@@ -133,7 +134,8 @@ let EnvConfigService = class EnvConfigService {
133
134
  dir: this.getValue('LOG_DIR', false) || 'logs',
134
135
  level: this.getValue('LOG_LEVEL', false) || (this.isProduction() ? 'info' : 'debug'),
135
136
  maxSize: this.getValue('LOG_MAX_SIZE', false) || '20m',
136
- maxFiles: this.getValue('LOG_MAX_FILES', false) || '14d'
137
+ maxFiles: this.getValue('LOG_MAX_FILES', false) || '14d',
138
+ disableHttpLogging: this.getValue('DISABLE_HTTP_LOGGING', false).toLowerCase() === 'true'
137
139
  };
138
140
  }
139
141
  getEnv() {
@@ -148,10 +150,12 @@ let EnvConfigService = class EnvConfigService {
148
150
  ALLOW_ORIGINS: 'getOrigins',
149
151
  PORT: 'getPort',
150
152
  MODE: 'isProduction',
153
+ DB_TYPE: 'getTypeOrmConfig',
151
154
  DB_HOST: 'getTypeOrmConfig',
152
155
  DB_PORT: 'getTypeOrmConfig',
153
156
  DB_USER: 'getTypeOrmConfig',
154
- DB_PASSWORD: 'getTypeOrmConfig'
157
+ DB_PASSWORD: 'getTypeOrmConfig',
158
+ DB_NAME: 'getTypeOrmConfig'
155
159
  };
156
160
  }
157
161
  };
@@ -2,16 +2,22 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
- Object.defineProperty(exports, "setupModuleSwaggerDocs", {
6
- enumerable: true,
7
- get: function() {
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: Object.getOwnPropertyDescriptor(all, name).get
9
+ });
10
+ }
11
+ _export(exports, {
12
+ get setupModuleSwaggerDocs () {
8
13
  return setupModuleSwaggerDocs;
14
+ },
15
+ get setupSwaggerDocs () {
16
+ return setupSwaggerDocs;
9
17
  }
10
18
  });
11
19
  const _swagger = require("@nestjs/swagger");
12
- /**
13
- * Filter OpenAPI document to exclude schema properties
14
- */ function filterSchemaProperties(document, exclusions) {
20
+ function filterSchemaProperties(document, exclusions) {
15
21
  if (!exclusions?.length || !document.components?.schemas) {
16
22
  return document;
17
23
  }
@@ -46,9 +52,7 @@ const _swagger = require("@nestjs/swagger");
46
52
  }
47
53
  };
48
54
  }
49
- /**
50
- * Filter OpenAPI document to exclude query parameters from specific endpoints
51
- */ function filterQueryParameters(document, exclusions) {
55
+ function filterQueryParameters(document, exclusions) {
52
56
  if (!exclusions?.length || !document.paths) {
53
57
  return document;
54
58
  }
@@ -94,18 +98,87 @@ const _swagger = require("@nestjs/swagger");
94
98
  paths: filteredPaths
95
99
  };
96
100
  }
97
- /**
98
- * Check if a path matches a pattern (supports wildcards)
99
- */ function pathMatchesPattern(path, pattern) {
101
+ function filterExamples(document, exclusions) {
102
+ if (!exclusions?.length || !document.paths) {
103
+ return document;
104
+ }
105
+ const filteredPaths = {};
106
+ for (const [path, pathItem] of Object.entries(document.paths)){
107
+ const filteredPathItem = {};
108
+ for (const [method, operation] of Object.entries(pathItem)){
109
+ // Skip non-operation properties
110
+ if (!operation || typeof operation !== 'object') {
111
+ filteredPathItem[method] = operation;
112
+ continue;
113
+ }
114
+ // Check if this endpoint matches any exclusion pattern
115
+ const matchingExclusions = exclusions.filter((exclusion)=>{
116
+ const pathMatches = pathMatchesPattern(path, exclusion.pathPattern);
117
+ const methodMatches = !exclusion.method || exclusion.method === method;
118
+ return pathMatches && methodMatches;
119
+ });
120
+ if (matchingExclusions.length > 0) {
121
+ // Collect all examples to exclude
122
+ const examplesToExclude = new Set();
123
+ matchingExclusions.forEach((exclusion)=>{
124
+ exclusion.examples.forEach((example)=>examplesToExclude.add(example));
125
+ });
126
+ // Deep clone the operation to avoid mutating original
127
+ const filteredOperation = JSON.parse(JSON.stringify(operation));
128
+ // Filter examples from responses
129
+ if (filteredOperation.responses) {
130
+ for (const [statusCode, response] of Object.entries(filteredOperation.responses)){
131
+ const responseObj = response;
132
+ if (responseObj?.content) {
133
+ const content = responseObj.content;
134
+ for (const [mediaType, mediaTypeObj] of Object.entries(content)){
135
+ const media = mediaTypeObj;
136
+ if (media?.examples && typeof media.examples === 'object') {
137
+ const examples = media.examples;
138
+ for (const exampleName of examplesToExclude){
139
+ delete examples[exampleName];
140
+ }
141
+ }
142
+ }
143
+ }
144
+ }
145
+ }
146
+ filteredPathItem[method] = filteredOperation;
147
+ } else {
148
+ filteredPathItem[method] = operation;
149
+ }
150
+ }
151
+ filteredPaths[path] = filteredPathItem;
152
+ }
153
+ return {
154
+ ...document,
155
+ paths: filteredPaths
156
+ };
157
+ }
158
+ function pathMatchesPattern(path, pattern) {
100
159
  // Convert wildcard pattern to regex
101
160
  const regexPattern = pattern.replace(/\*/g, '[^/]+') // * matches any characters except /
102
161
  .replace(/\*\*/g, '.*'); // ** matches any characters including /
103
162
  const regex = new RegExp(`^${regexPattern}$`);
104
163
  return regex.test(path);
105
164
  }
106
- /**
107
- * Filter OpenAPI document to exclude paths and tags based on excludeTags
108
- */ function filterDocumentByTags(document, excludeTags) {
165
+ function filterPaths(document, excludePaths) {
166
+ if (!excludePaths?.length || !document.paths) {
167
+ return document;
168
+ }
169
+ const filteredPaths = {};
170
+ for (const [path, pathItem] of Object.entries(document.paths)){
171
+ const isExcluded = excludePaths.some((pattern)=>pathMatchesPattern(path, pattern));
172
+ if (!isExcluded) {
173
+ filteredPaths[path] = pathItem;
174
+ }
175
+ }
176
+ return {
177
+ ...document,
178
+ paths: filteredPaths
179
+ };
180
+ }
181
+ function filterDocumentByTags(document, excludeTags) {
109
182
  if (!excludeTags?.length) {
110
183
  return document;
111
184
  }
@@ -175,6 +248,10 @@ function setupModuleSwaggerDocs(app, configs) {
175
248
  include: config.modules
176
249
  } : {};
177
250
  let document = _swagger.SwaggerModule.createDocument(app, builder.build(), createDocOptions);
251
+ // Filter out excluded paths
252
+ if (config.excludePaths?.length) {
253
+ document = filterPaths(document, config.excludePaths);
254
+ }
178
255
  // Filter out excluded tags
179
256
  if (config.excludeTags?.length) {
180
257
  document = filterDocumentByTags(document, config.excludeTags);
@@ -187,6 +264,13 @@ function setupModuleSwaggerDocs(app, configs) {
187
264
  if (config.excludeQueryParameters?.length) {
188
265
  document = filterQueryParameters(document, config.excludeQueryParameters);
189
266
  }
267
+ // Filter out excluded examples
268
+ if (config.excludeExamples?.length) {
269
+ document = filterExamples(document, config.excludeExamples);
270
+ }
190
271
  _swagger.SwaggerModule.setup(config.path, app, document);
191
272
  });
192
273
  }
274
+ function setupSwaggerDocs(app, ...modules) {
275
+ setupModuleSwaggerDocs(app, modules);
276
+ }
package/cjs/docs/index.js CHANGED
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
5
  _export_star(require("./docs.config"), exports);
6
- _export_star(require("./docs.setup"), exports);
7
6
  function _export_star(from, to) {
8
7
  Object.keys(from).forEach(function(k) {
9
8
  if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
package/cjs/index.js CHANGED
@@ -7,7 +7,6 @@ _export_star(require("./interfaces"), exports);
7
7
  _export_star(require("./constants"), exports);
8
8
  _export_star(require("./utils"), exports);
9
9
  _export_star(require("./migration"), exports);
10
- _export_star(require("./seeders"), exports);
11
10
  _export_star(require("./config"), exports);
12
11
  function _export_star(from, to) {
13
12
  Object.keys(from).forEach(function(k) {
@@ -1,7 +1,9 @@
1
1
  /**
2
- * Base Entity Interface
3
- * All entities should implement this for consistency
4
- */ "use strict";
2
+ * Entity Contract Interfaces
3
+ *
4
+ * These interfaces define the standard fields that entities should have.
5
+ * Use them as contracts when implementing new entities.
6
+ */ /** Base entity with UUID, timestamps, and soft delete */ "use strict";
5
7
  Object.defineProperty(exports, "__esModule", {
6
8
  value: true
7
9
  });
@@ -1,6 +1,4 @@
1
- /**
2
- * Supported database types
3
- */ "use strict";
1
+ "use strict";
4
2
  Object.defineProperty(exports, "__esModule", {
5
3
  value: true
6
4
  });
@@ -22,10 +22,9 @@ const _datasourceconfigbuilder = require("../utils/datasource-config.builder");
22
22
  function createMigrationDataSource(options) {
23
23
  const { config, tenantId } = options;
24
24
  const { database, tenant, tenantConfig } = (0, _datasourceconfigbuilder.getDatabaseForTenant)(config, tenantId);
25
- // Log target info
26
25
  console.log(`\n📦 Database: ${database}${tenant ? ` [${tenant.name}]` : ' [default]'}`);
27
26
  console.log(`📁 Migrations: migrations/${tenantId || 'default'}/`);
28
- if (config.bootstrapAppConfig?.databaseMode == 'multi-tenant' && !tenantId && config.tenants && config.tenants.length > 0) {
27
+ if (config.bootstrapAppConfig?.databaseMode === 'multi-tenant' && !tenantId && config.tenants && config.tenants.length > 0) {
29
28
  console.log(`\n💡 Multi-tenant mode. Available tenants:`);
30
29
  config.tenants.forEach((t)=>console.log(` - TENANT_ID=${t.id} → ${t.database}`));
31
30
  }
@@ -40,7 +39,6 @@ function createMigrationDataSource(options) {
40
39
  ...config.defaultDatabaseConfig,
41
40
  database
42
41
  };
43
- // Resolve entities based on tenant config
44
42
  const entities = (0, _datasourceconfigbuilder.resolveEntities)(config, tenantConfig);
45
43
  const dsOptions = (0, _datasourceconfigbuilder.buildDataSourceOptions)(dbConfig, entities, (0, _datasourceconfigbuilder.getMigrationsGlobPattern)(config.migrationsPath, tenantId), config.migrationsTableName);
46
44
  return new _typeorm.DataSource({
@@ -1,15 +1,3 @@
1
- /**
2
- * Migration Module Exports
3
- *
4
- * Public API for TypeORM migration management in single and multi-tenant databases.
5
- *
6
- * Main exports:
7
- * - createMigrationDataSource: Create DataSource for migrations
8
- * - initializeDataSource: Create and initialize DataSource
9
- * - runMigrationCli: Programmatic CLI execution
10
- *
11
- * The CLI entry point is at ./cli.ts (used by npm scripts)
12
- */ // DataSource factory for migration config files
13
1
  "use strict";
14
2
  Object.defineProperty(exports, "__esModule", {
15
3
  value: true
@@ -53,23 +53,7 @@ function _interop_require_wildcard(obj, nodeInterop) {
53
53
  }
54
54
  return newObj;
55
55
  }
56
- /**
57
- * Migration CLI Service
58
- *
59
- * Handles migration command execution for single and multi-tenant databases.
60
- *
61
- * Commands:
62
- * - generate: Create new migration
63
- * - run: Execute pending migrations
64
- * - revert: Rollback last migration
65
- * - status: Check migration status
66
- * - run:all/revert:all/status:all: Batch operations for all tenants
67
- *
68
- * Configuration:
69
- * - TENANT_ID: Target tenant (optional, defaults to default database)
70
- * - --config=<path>: Migration config file path
71
- * - --datasource=<path>: DataSource file path for TypeORM CLI
72
- */ function showHelp() {
56
+ function showHelp() {
73
57
  console.log(`
74
58
  Migration CLI
75
59