@flusys/nestjs-core 1.1.0 → 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 (37) hide show
  1. package/README.md +113 -581
  2. package/cjs/config/env-config.service.js +13 -9
  3. package/cjs/docs/docs.config.js +25 -15
  4. package/cjs/index.js +0 -1
  5. package/config/env-config.service.d.ts +3 -1
  6. package/docs/docs.config.d.ts +1 -0
  7. package/fesm/config/env-config.service.js +13 -9
  8. package/fesm/docs/docs.config.js +27 -21
  9. package/fesm/index.js +0 -2
  10. package/index.d.ts +0 -1
  11. package/interfaces/base-entity.interface.d.ts +0 -3
  12. package/interfaces/database.interface.d.ts +1 -1
  13. package/package.json +8 -8
  14. package/cjs/seeders/base-seeder.js +0 -76
  15. package/cjs/seeders/cli.js +0 -291
  16. package/cjs/seeders/data-generator.js +0 -215
  17. package/cjs/seeders/entity-reader.js +0 -151
  18. package/cjs/seeders/field-patterns.js +0 -176
  19. package/cjs/seeders/index.js +0 -85
  20. package/cjs/seeders/seed-config.js +0 -62
  21. package/cjs/seeders/seed-runner.js +0 -314
  22. package/fesm/seeders/base-seeder.js +0 -66
  23. package/fesm/seeders/cli.js +0 -249
  24. package/fesm/seeders/data-generator.js +0 -210
  25. package/fesm/seeders/entity-reader.js +0 -153
  26. package/fesm/seeders/field-patterns.js +0 -147
  27. package/fesm/seeders/index.js +0 -7
  28. package/fesm/seeders/seed-config.js +0 -35
  29. package/fesm/seeders/seed-runner.js +0 -317
  30. package/seeders/base-seeder.d.ts +0 -14
  31. package/seeders/cli.d.ts +0 -3
  32. package/seeders/data-generator.d.ts +0 -15
  33. package/seeders/entity-reader.d.ts +0 -44
  34. package/seeders/field-patterns.d.ts +0 -12
  35. package/seeders/index.d.ts +0 -7
  36. package/seeders/seed-config.d.ts +0 -12
  37. package/seeders/seed-runner.d.ts +0 -48
@@ -90,19 +90,20 @@ let EnvConfigService = class EnvConfigService {
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
  };
@@ -17,9 +17,7 @@ _export(exports, {
17
17
  }
18
18
  });
19
19
  const _swagger = require("@nestjs/swagger");
20
- /**
21
- * Filter OpenAPI document to exclude schema properties
22
- */ function filterSchemaProperties(document, exclusions) {
20
+ function filterSchemaProperties(document, exclusions) {
23
21
  if (!exclusions?.length || !document.components?.schemas) {
24
22
  return document;
25
23
  }
@@ -54,9 +52,7 @@ const _swagger = require("@nestjs/swagger");
54
52
  }
55
53
  };
56
54
  }
57
- /**
58
- * Filter OpenAPI document to exclude query parameters from specific endpoints
59
- */ function filterQueryParameters(document, exclusions) {
55
+ function filterQueryParameters(document, exclusions) {
60
56
  if (!exclusions?.length || !document.paths) {
61
57
  return document;
62
58
  }
@@ -102,9 +98,7 @@ const _swagger = require("@nestjs/swagger");
102
98
  paths: filteredPaths
103
99
  };
104
100
  }
105
- /**
106
- * Filter OpenAPI document to exclude examples from endpoint responses
107
- */ function filterExamples(document, exclusions) {
101
+ function filterExamples(document, exclusions) {
108
102
  if (!exclusions?.length || !document.paths) {
109
103
  return document;
110
104
  }
@@ -161,18 +155,30 @@ const _swagger = require("@nestjs/swagger");
161
155
  paths: filteredPaths
162
156
  };
163
157
  }
164
- /**
165
- * Check if a path matches a pattern (supports wildcards)
166
- */ function pathMatchesPattern(path, pattern) {
158
+ function pathMatchesPattern(path, pattern) {
167
159
  // Convert wildcard pattern to regex
168
160
  const regexPattern = pattern.replace(/\*/g, '[^/]+') // * matches any characters except /
169
161
  .replace(/\*\*/g, '.*'); // ** matches any characters including /
170
162
  const regex = new RegExp(`^${regexPattern}$`);
171
163
  return regex.test(path);
172
164
  }
173
- /**
174
- * Filter OpenAPI document to exclude paths and tags based on excludeTags
175
- */ 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) {
176
182
  if (!excludeTags?.length) {
177
183
  return document;
178
184
  }
@@ -242,6 +248,10 @@ function setupModuleSwaggerDocs(app, configs) {
242
248
  include: config.modules
243
249
  } : {};
244
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
+ }
245
255
  // Filter out excluded tags
246
256
  if (config.excludeTags?.length) {
247
257
  document = filterDocumentByTags(document, config.excludeTags);
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) {
@@ -10,13 +10,14 @@ declare class EnvConfigService {
10
10
  getBoolean(key: string, throwOnMissing?: boolean): boolean;
11
11
  getPort(): number;
12
12
  isProduction(): boolean;
13
- getFrontendUrl(): string;
14
13
  getOrigins(): string[];
15
14
  getTypeOrmConfig(): {
15
+ type: "mysql" | "postgres" | "mariadb" | "sqlite" | "mssql";
16
16
  host: string;
17
17
  port: number;
18
18
  username: string;
19
19
  password: string;
20
+ database: string;
20
21
  };
21
22
  getJwtConfig(): {
22
23
  secret: string;
@@ -36,6 +37,7 @@ declare class EnvConfigService {
36
37
  level: string;
37
38
  maxSize: string;
38
39
  maxFiles: string;
40
+ disableHttpLogging: boolean;
39
41
  };
40
42
  getEnv(): Record<string, string>;
41
43
  }
@@ -31,6 +31,7 @@ export interface IModuleSwaggerOptions {
31
31
  excludeSchemaProperties?: ISchemaPropertyExclusion[];
32
32
  excludeQueryParameters?: IQueryParameterExclusion[];
33
33
  excludeExamples?: IExampleExclusion[];
34
+ excludePaths?: string[];
34
35
  }
35
36
  export declare function setupModuleSwaggerDocs(app: INestApplication, configs: IModuleSwaggerOptions[]): void;
36
37
  export declare function setupSwaggerDocs(app: INestApplication, ...modules: IModuleSwaggerOptions[]): void;
@@ -39,19 +39,20 @@ let EnvConfigService = class EnvConfigService {
39
39
  isProduction() {
40
40
  return this.getValue('MODE', false).toUpperCase() !== 'DEV';
41
41
  }
42
- getFrontendUrl() {
43
- return this.getValue('FRONTEND_URL');
44
- }
45
42
  getOrigins() {
46
43
  const origins = this.getValue('ALLOW_ORIGINS');
47
44
  return origins ? origins.split(',').map((o)=>o.trim()) : [];
48
45
  }
49
46
  getTypeOrmConfig() {
47
+ const type = this.getValue('DB_TYPE', false) || 'mysql';
48
+ const defaultPort = type === 'postgres' ? 5432 : 3306;
50
49
  return {
51
- host: this.getValue('DB_HOST'),
52
- port: this.getNumber('DB_PORT'),
53
- username: this.getValue('DB_USER'),
54
- password: this.getValue('DB_PASSWORD')
50
+ type,
51
+ host: this.getValue('DB_HOST', false) || 'localhost',
52
+ port: this.getNumber('DB_PORT', false) || defaultPort,
53
+ username: this.getValue('DB_USER', false) || 'root',
54
+ password: this.getValue('DB_PASSWORD', false) || '',
55
+ database: this.getValue('DB_NAME', false) || 'flusys_main'
55
56
  };
56
57
  }
57
58
  getJwtConfig() {
@@ -82,7 +83,8 @@ let EnvConfigService = class EnvConfigService {
82
83
  dir: this.getValue('LOG_DIR', false) || 'logs',
83
84
  level: this.getValue('LOG_LEVEL', false) || (this.isProduction() ? 'info' : 'debug'),
84
85
  maxSize: this.getValue('LOG_MAX_SIZE', false) || '20m',
85
- maxFiles: this.getValue('LOG_MAX_FILES', false) || '14d'
86
+ maxFiles: this.getValue('LOG_MAX_FILES', false) || '14d',
87
+ disableHttpLogging: this.getValue('DISABLE_HTTP_LOGGING', false).toLowerCase() === 'true'
86
88
  };
87
89
  }
88
90
  getEnv() {
@@ -97,10 +99,12 @@ let EnvConfigService = class EnvConfigService {
97
99
  ALLOW_ORIGINS: 'getOrigins',
98
100
  PORT: 'getPort',
99
101
  MODE: 'isProduction',
102
+ DB_TYPE: 'getTypeOrmConfig',
100
103
  DB_HOST: 'getTypeOrmConfig',
101
104
  DB_PORT: 'getTypeOrmConfig',
102
105
  DB_USER: 'getTypeOrmConfig',
103
- DB_PASSWORD: 'getTypeOrmConfig'
106
+ DB_PASSWORD: 'getTypeOrmConfig',
107
+ DB_NAME: 'getTypeOrmConfig'
104
108
  };
105
109
  }
106
110
  };
@@ -1,7 +1,5 @@
1
1
  import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
2
- /**
3
- * Filter OpenAPI document to exclude schema properties
4
- */ function filterSchemaProperties(document, exclusions) {
2
+ function filterSchemaProperties(document, exclusions) {
5
3
  if (!exclusions?.length || !document.components?.schemas) {
6
4
  return document;
7
5
  }
@@ -36,9 +34,7 @@ import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
36
34
  }
37
35
  };
38
36
  }
39
- /**
40
- * Filter OpenAPI document to exclude query parameters from specific endpoints
41
- */ function filterQueryParameters(document, exclusions) {
37
+ function filterQueryParameters(document, exclusions) {
42
38
  if (!exclusions?.length || !document.paths) {
43
39
  return document;
44
40
  }
@@ -84,9 +80,7 @@ import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
84
80
  paths: filteredPaths
85
81
  };
86
82
  }
87
- /**
88
- * Filter OpenAPI document to exclude examples from endpoint responses
89
- */ function filterExamples(document, exclusions) {
83
+ function filterExamples(document, exclusions) {
90
84
  if (!exclusions?.length || !document.paths) {
91
85
  return document;
92
86
  }
@@ -143,18 +137,30 @@ import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
143
137
  paths: filteredPaths
144
138
  };
145
139
  }
146
- /**
147
- * Check if a path matches a pattern (supports wildcards)
148
- */ function pathMatchesPattern(path, pattern) {
140
+ function pathMatchesPattern(path, pattern) {
149
141
  // Convert wildcard pattern to regex
150
142
  const regexPattern = pattern.replace(/\*/g, '[^/]+') // * matches any characters except /
151
143
  .replace(/\*\*/g, '.*'); // ** matches any characters including /
152
144
  const regex = new RegExp(`^${regexPattern}$`);
153
145
  return regex.test(path);
154
146
  }
155
- /**
156
- * Filter OpenAPI document to exclude paths and tags based on excludeTags
157
- */ function filterDocumentByTags(document, excludeTags) {
147
+ function filterPaths(document, excludePaths) {
148
+ if (!excludePaths?.length || !document.paths) {
149
+ return document;
150
+ }
151
+ const filteredPaths = {};
152
+ for (const [path, pathItem] of Object.entries(document.paths)){
153
+ const isExcluded = excludePaths.some((pattern)=>pathMatchesPattern(path, pattern));
154
+ if (!isExcluded) {
155
+ filteredPaths[path] = pathItem;
156
+ }
157
+ }
158
+ return {
159
+ ...document,
160
+ paths: filteredPaths
161
+ };
162
+ }
163
+ function filterDocumentByTags(document, excludeTags) {
158
164
  if (!excludeTags?.length) {
159
165
  return document;
160
166
  }
@@ -197,9 +203,7 @@ import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
197
203
  tags: filteredTags
198
204
  };
199
205
  }
200
- /**
201
- * Setup Swagger documentation for multiple modules
202
- */ export function setupModuleSwaggerDocs(app, configs) {
206
+ export function setupModuleSwaggerDocs(app, configs) {
203
207
  configs.forEach((config)=>{
204
208
  const builder = new DocumentBuilder().setTitle(config.title).setDescription(config.description).setVersion(config.version || '1.0');
205
209
  // Add bearer auth
@@ -226,6 +230,10 @@ import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
226
230
  include: config.modules
227
231
  } : {};
228
232
  let document = SwaggerModule.createDocument(app, builder.build(), createDocOptions);
233
+ // Filter out excluded paths
234
+ if (config.excludePaths?.length) {
235
+ document = filterPaths(document, config.excludePaths);
236
+ }
229
237
  // Filter out excluded tags
230
238
  if (config.excludeTags?.length) {
231
239
  document = filterDocumentByTags(document, config.excludeTags);
@@ -245,8 +253,6 @@ import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
245
253
  SwaggerModule.setup(config.path, app, document);
246
254
  });
247
255
  }
248
- /**
249
- * Setup Swagger docs with variadic module configs
250
- */ export function setupSwaggerDocs(app, ...modules) {
256
+ export function setupSwaggerDocs(app, ...modules) {
251
257
  setupModuleSwaggerDocs(app, modules);
252
258
  }
package/fesm/index.js CHANGED
@@ -6,7 +6,5 @@ export * from './constants';
6
6
  export * from './utils';
7
7
  // Migration
8
8
  export * from './migration';
9
- // Seeders
10
- export * from './seeders';
11
9
  // Config
12
10
  export * from './config';
package/index.d.ts CHANGED
@@ -2,5 +2,4 @@ export * from './interfaces';
2
2
  export * from './constants';
3
3
  export * from './utils';
4
4
  export * from './migration';
5
- export * from './seeders';
6
5
  export * from './config';
@@ -14,9 +14,6 @@ export interface ITimestampable {
14
14
  export interface IOrderable {
15
15
  serial?: number | null;
16
16
  }
17
- export interface IMetadata {
18
- metadata?: Record<string, any> | null;
19
- }
20
17
  export interface ICompanyOwned {
21
18
  companyId?: string | null;
22
19
  }
@@ -31,5 +31,5 @@ export interface IDataSourceBuildOptions {
31
31
  migrations: string[];
32
32
  migrationsTableName: string;
33
33
  synchronize: boolean;
34
- namingStrategy?: any;
34
+ namingStrategy?: unknown;
35
35
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flusys/nestjs-core",
3
- "version": "1.1.0",
3
+ "version": "1.2.0-rc.1",
4
4
  "description": "Core types, interfaces, and constants for Flusys NestJS packages",
5
5
  "main": "cjs/index.js",
6
6
  "module": "fesm/index.js",
@@ -62,14 +62,14 @@
62
62
  },
63
63
  "peerDependencies": {
64
64
  "@faker-js/faker": "^10.0.0",
65
- "@nestjs/common": "^10.0.0 || ^11.0.0",
66
- "@nestjs/config": "^3.0.0 || ^4.0.0",
67
- "@nestjs/core": "^10.0.0 || ^11.0.0",
68
- "@nestjs/swagger": "^7.0.0 || ^11.0.0",
69
- "@nestjs/typeorm": "^10.0.0 || ^11.0.0",
70
- "dotenv": "^16.0.0",
65
+ "@nestjs/common": "^11.0.0",
66
+ "@nestjs/config": "^4.0.0",
67
+ "@nestjs/core": "^11.0.0",
68
+ "@nestjs/swagger": "^11.0.0",
69
+ "@nestjs/typeorm": "^11.0.0",
70
+ "dotenv": "^17.0.0",
71
71
  "typeorm": "^0.3.0",
72
- "typeorm-naming-strategies": "^4.0.0"
72
+ "typeorm-naming-strategies": "^4.1.0"
73
73
  },
74
74
  "dependencies": {}
75
75
  }
@@ -1,76 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- Object.defineProperty(exports, "BaseSeeder", {
6
- enumerable: true,
7
- get: function() {
8
- return BaseSeeder;
9
- }
10
- });
11
- function _define_property(obj, key, value) {
12
- if (key in obj) {
13
- Object.defineProperty(obj, key, {
14
- value: value,
15
- enumerable: true,
16
- configurable: true,
17
- writable: true
18
- });
19
- } else {
20
- obj[key] = value;
21
- }
22
- return obj;
23
- }
24
- let BaseSeeder = class BaseSeeder {
25
- async clear(hard = false) {
26
- const hasSoftDelete = this.metadata.deleteDateColumn !== undefined;
27
- if (hard || !hasSoftDelete) {
28
- await this.repository.clear();
29
- } else {
30
- await this.repository.createQueryBuilder().softDelete().where('id IS NOT NULL').execute();
31
- }
32
- }
33
- async count(includeDeleted = false) {
34
- const hasSoftDelete = this.metadata.deleteDateColumn !== undefined;
35
- if (hasSoftDelete && !includeDeleted) {
36
- return this.repository.count({
37
- where: {
38
- deletedAt: null
39
- }
40
- });
41
- }
42
- return this.repository.count();
43
- }
44
- async isEmpty() {
45
- return await this.count() === 0;
46
- }
47
- getEntityName() {
48
- return this.metadata.tableName;
49
- }
50
- async withTransaction(operation) {
51
- const queryRunner = this.dataSource.createQueryRunner();
52
- await queryRunner.connect();
53
- await queryRunner.startTransaction();
54
- try {
55
- const transactionalRepo = queryRunner.manager.getRepository(this.entity);
56
- const result = await operation(transactionalRepo);
57
- await queryRunner.commitTransaction();
58
- return result;
59
- } catch (error) {
60
- await queryRunner.rollbackTransaction();
61
- throw error;
62
- } finally{
63
- await queryRunner.release();
64
- }
65
- }
66
- constructor(dataSource, entity){
67
- _define_property(this, "dataSource", void 0);
68
- _define_property(this, "entity", void 0);
69
- _define_property(this, "repository", void 0);
70
- _define_property(this, "metadata", void 0);
71
- this.dataSource = dataSource;
72
- this.entity = entity;
73
- this.repository = dataSource.getRepository(entity);
74
- this.metadata = this.repository.metadata;
75
- }
76
- };