@flusys/nestjs-shared 0.1.0-alpha.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/cjs/classes-index.js +46 -0
- package/cjs/constants-index.js +1 -0
- package/cjs/decorators-index.js +1 -0
- package/cjs/dtos-index.js +1 -0
- package/cjs/entities-index.js +1 -0
- package/cjs/exceptions-index.js +1 -0
- package/cjs/guards-index.js +22 -0
- package/cjs/index.js +151 -0
- package/cjs/interceptors-index.js +106 -0
- package/cjs/interfaces-index.js +1 -0
- package/cjs/middlewares-index.js +22 -0
- package/cjs/modules-index.js +106 -0
- package/cjs/utils-index.js +1 -0
- package/classes/api-controller.class.d.ts +30 -0
- package/classes/api-service.class.d.ts +72 -0
- package/classes/hybrid-cache.class.d.ts +10 -0
- package/classes/index.d.ts +6 -0
- package/classes/request-scoped-api.service.d.ts +13 -0
- package/classes/winston-logger-adapter.class.d.ts +20 -0
- package/classes/winston.logger.class.d.ts +2 -0
- package/constants/index.d.ts +10 -0
- package/decorators/api-response.decorator.d.ts +3 -0
- package/decorators/current-user.decorator.d.ts +1 -0
- package/decorators/index.d.ts +4 -0
- package/decorators/public.decorator.d.ts +1 -0
- package/decorators/require-permission.decorator.d.ts +4 -0
- package/dtos/delete.dto.d.ts +4 -0
- package/dtos/filter-and-pagination.dto.d.ts +13 -0
- package/dtos/identity-response.dto.d.ts +9 -0
- package/dtos/index.d.ts +5 -0
- package/dtos/pagination.dto.d.ts +4 -0
- package/dtos/response-payload.dto.d.ts +63 -0
- package/entities/identity.d.ts +9 -0
- package/entities/index.d.ts +2 -0
- package/entities/user-root.d.ts +19 -0
- package/exceptions/index.d.ts +1 -0
- package/exceptions/permission.exception.d.ts +10 -0
- package/fesm/classes-index.js +46 -0
- package/fesm/constants-index.js +1 -0
- package/fesm/decorators-index.js +1 -0
- package/fesm/dtos-index.js +1 -0
- package/fesm/entities-index.js +1 -0
- package/fesm/exceptions-index.js +1 -0
- package/fesm/guards-index.js +22 -0
- package/fesm/index.js +151 -0
- package/fesm/interceptors-index.js +106 -0
- package/fesm/interfaces-index.js +0 -0
- package/fesm/middlewares-index.js +22 -0
- package/fesm/modules-index.js +106 -0
- package/fesm/utils-index.js +1 -0
- package/guards/index.d.ts +2 -0
- package/guards/jwt-auth.guard.d.ts +10 -0
- package/guards/permission.guard.d.ts +18 -0
- package/index.d.ts +12 -0
- package/interceptors/delete-empty-id-from-body.interceptor.d.ts +5 -0
- package/interceptors/idempotency.interceptor.d.ts +10 -0
- package/interceptors/index.d.ts +8 -0
- package/interceptors/query-performance.interceptor.d.ts +8 -0
- package/interceptors/response-meta.interceptor.d.ts +5 -0
- package/interceptors/set-create-by-on-body.interceptor.d.ts +5 -0
- package/interceptors/set-delete-by-on-body.interceptor.d.ts +5 -0
- package/interceptors/set-update-by-on-body.interceptor.d.ts +5 -0
- package/interceptors/slug.interceptor.d.ts +7 -0
- package/interfaces/api.interface.d.ts +14 -0
- package/interfaces/base-query.interface.d.ts +7 -0
- package/interfaces/identity.interface.d.ts +9 -0
- package/interfaces/index.d.ts +6 -0
- package/interfaces/logged-user-info.interface.d.ts +11 -0
- package/interfaces/logger.interface.d.ts +7 -0
- package/interfaces/permission.interface.d.ts +17 -0
- package/middlewares/index.d.ts +1 -0
- package/middlewares/logger.middleware.d.ts +23 -0
- package/modules/cache/cache.module.d.ts +4 -0
- package/modules/datasource/datasource.module.d.ts +18 -0
- package/modules/datasource/index.d.ts +2 -0
- package/modules/datasource/multi-tenant-datasource.service.d.ts +45 -0
- package/modules/index.d.ts +4 -0
- package/modules/utils/utils.module.d.ts +2 -0
- package/modules/utils/utils.service.d.ts +21 -0
- package/package.json +100 -0
- package/utils/error-handler.util.d.ts +24 -0
- package/utils/index.d.ts +1 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
var __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf;var __hasOwnProp=Object.prototype.hasOwnProperty;var __defNormalProp=(obj,key,value)=>key in obj?__defProp(obj,key,{enumerable:true,configurable:true,writable:true,value}):obj[key]=value;var __name=(target,value)=>__defProp(target,"name",{value,configurable:true});var __require=(x=>typeof require!=="undefined"?require:typeof Proxy!=="undefined"?new Proxy(x,{get:(a,b)=>(typeof require!=="undefined"?require:a)[b]}):x)(function(x){if(typeof require!=="undefined")return require.apply(this,arguments);throw Error('Dynamic require of "'+x+'" is not supported')});var __commonJS=(cb,mod)=>function __require2(){return mod||(0,cb[__getOwnPropNames(cb)[0]])((mod={exports:{}}).exports,mod),mod.exports};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from==="object"||typeof from==="function"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:true}):target,mod));var __decorateClass=(decorators,target,key,kind)=>{var result=kind>1?void 0:kind?__getOwnPropDesc(target,key):target;for(var i=decorators.length-1,decorator;i>=0;i--)if(decorator=decorators[i])result=(kind?decorator(target,key,result):decorator(result))||result;if(kind&&result)__defProp(target,key,result);return result};var __decorateParam=(index,decorator)=>(target,key)=>decorator(target,key,index);var __publicField=(obj,key,value)=>__defNormalProp(obj,typeof key!=="symbol"?key+"":key,value);var require_snake_naming_strategy=__commonJS({"node_modules/typeorm-naming-strategies/snake-naming.strategy.js"(exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.SnakeNamingStrategy=void 0;var typeorm_1=__require("typeorm");var StringUtils_1=__require("typeorm/util/StringUtils");var SnakeNamingStrategy2=class extends typeorm_1.DefaultNamingStrategy{static{__name(this,"SnakeNamingStrategy")}tableName(className,customName){return customName?customName:StringUtils_1.snakeCase(className)}columnName(propertyName,customName,embeddedPrefixes){return StringUtils_1.snakeCase(embeddedPrefixes.concat("").join("_"))+(customName?customName:StringUtils_1.snakeCase(propertyName))}relationName(propertyName){return StringUtils_1.snakeCase(propertyName)}joinColumnName(relationName,referencedColumnName){return StringUtils_1.snakeCase(relationName+"_"+referencedColumnName)}joinTableName(firstTableName,secondTableName,firstPropertyName,secondPropertyName){return StringUtils_1.snakeCase(firstTableName+"_"+firstPropertyName.replace(/\./gi,"_")+"_"+secondTableName)}joinTableColumnName(tableName,propertyName,columnName){return StringUtils_1.snakeCase(tableName+"_"+(columnName?columnName:propertyName))}classTableInheritanceParentColumnName(parentTableName,parentTableIdPropertyName){return StringUtils_1.snakeCase(parentTableName+"_"+parentTableIdPropertyName)}eagerJoinRelationAlias(alias,propertyPath){return alias+"__"+propertyPath.replace(".","_")}};exports.SnakeNamingStrategy=SnakeNamingStrategy2}});var require_typeorm_naming_strategies=__commonJS({"node_modules/typeorm-naming-strategies/index.js"(exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.SnakeNamingStrategy=void 0;var snake_naming_strategy_1=require_snake_naming_strategy();Object.defineProperty(exports,"SnakeNamingStrategy",{enumerable:true,get:__name(function(){return snake_naming_strategy_1.SnakeNamingStrategy},"get")})}});import{HybridCache}from"@flusys/nestjs-shared/classes";import{CACHE_INSTANCE}from"@flusys/nestjs-shared/constants";import{Module}from"@nestjs/common";var CacheModule=class{static forRoot(isGlobal=true,memoryTtl=6e4,memorySize=5e3){return{module:CacheModule,global:isGlobal,providers:[{provide:CACHE_INSTANCE,useFactory:__name(()=>new HybridCache(memoryTtl,memorySize),"useFactory")}],exports:[CACHE_INSTANCE]}}};__name(CacheModule,"CacheModule");CacheModule=__decorateClass([Module({})],CacheModule);import{MODULE_OPTIONS as MODULE_OPTIONS2}from"@flusys/nestjs-core";import{Module as Module2}from"@nestjs/common";var import_typeorm_naming_strategies=__toESM(require_typeorm_naming_strategies());import{DEFAULT_TENANT_HEADER,MODULE_OPTIONS}from"@flusys/nestjs-core";import{BadRequestException,Inject,Injectable,Logger,Optional,Scope}from"@nestjs/common";import{REQUEST}from"@nestjs/core";import{DataSource}from"typeorm";var MultiTenantDataSourceService=class{constructor(options,request){this.options=options;this.request=request;this.initializeFromOptions()}logger=new Logger(this.constructor.name);tenantHeader=DEFAULT_TENANT_HEADER;initializeFromOptions(){if(!this.options)return;if(!MultiTenantDataSourceService.initialized){this.registerTenants();MultiTenantDataSourceService.initialized=true}}registerTenants(){this.options?.tenants?.forEach(tenant=>{MultiTenantDataSourceService.tenantsRegistry.set(tenant.id,tenant)})}setTenantHeader(header){this.tenantHeader=header}getDatabaseMode(){return this.options?.bootstrapAppConfig?.databaseMode??"single"}isMultiTenant(){return this.getDatabaseMode()==="multi-tenant"}getCurrentTenantId(){if(!this.request)return null;const tenantId=this.request.headers[this.tenantHeader];if(!tenantId)return null;if(!/^[a-zA-Z0-9_-]+$/.test(tenantId)){throw new BadRequestException("Invalid tenant ID format. Only alphanumeric characters, hyphens, and underscores are allowed.")}return tenantId}getCurrentTenant(){const tenantId=this.getCurrentTenantId();return tenantId?this.getTenant(tenantId):null}getTenant(tenantId){return MultiTenantDataSourceService.tenantsRegistry.get(tenantId)??null}getAllTenants(){return Array.from(MultiTenantDataSourceService.tenantsRegistry.values())}getActiveTenants(){return this.getAllTenants()}async getDataSource(){return this.isMultiTenant()?this.getTenantDataSource():this.getSingleDataSource()}async getDataSourceForTenant(tenantId){const tenant=this.getTenant(tenantId);if(!tenant){throw new Error(`Tenant '${tenantId}' not found`)}return this.getOrCreateTenantConnection(tenant)}setDataSource(dataSource){MultiTenantDataSourceService.singleDataSource=dataSource}async getRepository(entity){const dataSource=await this.getDataSource();return dataSource.getRepository(entity)}async getRepositoryForTenant(entity,tenantId){const dataSource=await this.getDataSourceForTenant(tenantId);return dataSource.getRepository(entity)}async withTenant(tenantId,callback){const dataSource=await this.getDataSourceForTenant(tenantId);return callback(dataSource)}async forAllTenants(callback){const results=new Map;for(const tenant of this.getActiveTenants()){try{const dataSource=await this.getOrCreateTenantConnection(tenant);results.set(tenant.id,await callback(tenant,dataSource))}catch(error){this.logger.error(`Error processing tenant ${tenant.id}: ${error}`)}}return results}registerTenant(tenant){MultiTenantDataSourceService.tenantsRegistry.set(tenant.id,tenant)}async removeTenant(tenantId){await this.closeTenantConnection(tenantId);MultiTenantDataSourceService.tenantsRegistry.delete(tenantId)}async closeTenantConnection(tenantId){const connection=MultiTenantDataSourceService.tenantConnections.get(tenantId);if(connection?.isInitialized){await connection.destroy();MultiTenantDataSourceService.tenantConnections.delete(tenantId);this.logger.log(`Closed connection for tenant: ${tenantId}`)}}async onModuleDestroy(){for(const[tenantId]of MultiTenantDataSourceService.tenantConnections){await this.closeTenantConnection(tenantId)}}static reset(){MultiTenantDataSourceService.initialized=false;MultiTenantDataSourceService.singleDataSource=null;MultiTenantDataSourceService.singleConnectionLock=null;MultiTenantDataSourceService.tenantConnections.clear();MultiTenantDataSourceService.tenantsRegistry.clear();MultiTenantDataSourceService.connectionLocks.clear()}async getSingleDataSource(){if(MultiTenantDataSourceService.singleDataSource?.isInitialized){return MultiTenantDataSourceService.singleDataSource}if(MultiTenantDataSourceService.singleConnectionLock){return MultiTenantDataSourceService.singleConnectionLock}const config=this.getDefaultDatabaseConfig();if(!config){throw new Error("No database config available. Provide defaultDatabaseConfig or tenantDefaultDatabaseConfig.")}const connectionPromise=this.createDataSourceFromConfig(config);MultiTenantDataSourceService.singleConnectionLock=connectionPromise;try{const dataSource=await connectionPromise;MultiTenantDataSourceService.singleDataSource=dataSource;return dataSource}finally{MultiTenantDataSourceService.singleConnectionLock=null}}async getTenantDataSource(){const tenant=this.getCurrentTenant();if(!tenant){throw new Error(`Tenant not found. Ensure '${this.tenantHeader}' header is set.`)}return this.getOrCreateTenantConnection(tenant)}async getOrCreateTenantConnection(tenant){const existing=MultiTenantDataSourceService.tenantConnections.get(tenant.id);if(existing?.isInitialized){return existing}const pendingConnection=MultiTenantDataSourceService.connectionLocks.get(tenant.id);if(pendingConnection){return pendingConnection}const config=this.buildTenantDatabaseConfig(tenant);const connectionPromise=this.createDataSourceFromConfig(config);MultiTenantDataSourceService.connectionLocks.set(tenant.id,connectionPromise);try{const dataSource=await connectionPromise;MultiTenantDataSourceService.tenantConnections.set(tenant.id,dataSource);this.logger.log(`Created connection for tenant: ${tenant.id}`);return dataSource}finally{MultiTenantDataSourceService.connectionLocks.delete(tenant.id)}}getDefaultDatabaseConfig(){return this.options?.defaultDatabaseConfig??this.options?.tenantDefaultDatabaseConfig}buildTenantDatabaseConfig(tenant){const defaultConfig=this.getDefaultDatabaseConfig();if(!defaultConfig){throw new Error("No default database config for multi-tenant mode.")}return{type:defaultConfig.type,host:tenant.host??defaultConfig.host,port:tenant.port??defaultConfig.port,username:tenant.username??defaultConfig.username,password:tenant.password??defaultConfig.password,database:tenant.database}}async createDataSourceFromConfig(config,entities=[]){const dataSource=new DataSource({type:config.type,host:config.host,port:config.port,username:config.username,password:config.password,database:config.database,entities,synchronize:false,namingStrategy:new import_typeorm_naming_strategies.SnakeNamingStrategy});if(!dataSource.isInitialized){await dataSource.initialize()}return dataSource}};__name(MultiTenantDataSourceService,"MultiTenantDataSourceService");__publicField(MultiTenantDataSourceService,"tenantConnections",new Map);__publicField(MultiTenantDataSourceService,"singleDataSource",null);__publicField(MultiTenantDataSourceService,"tenantsRegistry",new Map);__publicField(MultiTenantDataSourceService,"initialized",false);__publicField(MultiTenantDataSourceService,"connectionLocks",new Map);__publicField(MultiTenantDataSourceService,"singleConnectionLock",null);MultiTenantDataSourceService=__decorateClass([Injectable({scope:Scope.REQUEST}),__decorateParam(0,Optional()),__decorateParam(0,Inject(MODULE_OPTIONS)),__decorateParam(1,Optional()),__decorateParam(1,Inject(REQUEST))],MultiTenantDataSourceService);var DataSourceModule=class{static forRoot(options){const{global=false,...moduleOptions}=options;return{module:DataSourceModule,global,providers:[{provide:MODULE_OPTIONS2,useValue:moduleOptions},MultiTenantDataSourceService],exports:[MODULE_OPTIONS2,MultiTenantDataSourceService]}}static forRootAsync(asyncOptions){const{global=false,imports=[]}=asyncOptions;return{module:DataSourceModule,global,imports,providers:[...this.createAsyncProviders(asyncOptions),MultiTenantDataSourceService],exports:[MODULE_OPTIONS2,MultiTenantDataSourceService]}}static forFeature(){return{module:DataSourceModule,providers:[MultiTenantDataSourceService],exports:[MultiTenantDataSourceService]}}static createAsyncProviders(options){if(options.useFactory){return[{provide:MODULE_OPTIONS2,useFactory:options.useFactory,inject:options.inject||[]}]}if(options.useClass){return[{provide:options.useClass,useClass:options.useClass},{provide:MODULE_OPTIONS2,useFactory:__name(async factory=>factory.createOptions(),"useFactory"),inject:[options.useClass]}]}if(options.useExisting){return[{provide:MODULE_OPTIONS2,useFactory:__name(async factory=>factory.createOptions(),"useFactory"),inject:[options.useExisting]}]}return[{provide:MODULE_OPTIONS2,useValue:{}}]}};__name(DataSourceModule,"DataSourceModule");DataSourceModule=__decorateClass([Module2({})],DataSourceModule);import{Global,Module as Module3}from"@nestjs/common";import{Injectable as Injectable2}from"@nestjs/common";import{isEmail}from"class-validator";var UtilsService=class{constructor(){}getCacheKey(entityName,params,entityId,tenantId){const tenantPrefix=tenantId?`tenant_${tenantId}_`:"";if(entityId)return`${tenantPrefix}entity_${entityName}_id_${entityId}${params?"_select_"+JSON.stringify(params):""}`;return`${tenantPrefix}entity_${entityName}_all_${JSON.stringify(params)}`}async trackCacheKey(cacheKey,entityName,cacheManager,entityId,tenantId){const tenantPrefix=tenantId?`tenant_${tenantId}_`:"";try{if(entityId){const trackingKey=`${tenantPrefix}entity_${entityName}_id_${entityId}_keys`;const idKeys=await cacheManager.get(trackingKey)||[];if(!idKeys.includes(cacheKey))idKeys.push(cacheKey);await cacheManager.set(trackingKey,idKeys)}else{const trackingKey=`${tenantPrefix}entity_${entityName}_keys`;const allKeys=await cacheManager.get(trackingKey)||[];if(!allKeys.includes(cacheKey))allKeys.push(cacheKey);await cacheManager.set(trackingKey,allKeys)}}catch(error){console.error(`Cache tracking failed for ${entityName}:`,error)}}async clearCache(entityName,cacheManager,entityId,tenantId){const tenantPrefix=tenantId?`tenant_${tenantId}_`:"";try{if(entityId){const trackingKey=`${tenantPrefix}entity_${entityName}_id_${entityId}_keys`;const idKeys=await cacheManager.get(trackingKey)||[];await Promise.allSettled(idKeys.map(key=>cacheManager.del(key)));await cacheManager.del(trackingKey)}else{const trackingKey=`${tenantPrefix}entity_${entityName}_keys`;const keySet=await cacheManager.get(trackingKey)||[];await Promise.allSettled(keySet.map(key=>cacheManager.del(key)));await cacheManager.del(trackingKey)}}catch(error){console.error(`Cache invalidation failed for ${entityName}:`,error)}}checkPhoneOrEmail(value){if(isEmail(value)){return{value,type:"email"}}const phoneMatch=value.match(/^((\+880)|0)?(13|15|16|17|18|19)\d{8}$/);if(phoneMatch){let phone=phoneMatch[0];if(!phone.startsWith("+88")){phone="+88"+phone}return{value:phone,type:"phone"}}return{value:null,type:null}}transformToSlug(value,salt){const slug=value?.trim().replace(/[^A-Z0-9]+/gi,"-").toLowerCase();return salt?`${slug}-${this.getRandomInt(1,100)}`:slug}getRandomInt(min,max){return Math.floor(Math.random()*(max-min+1))+min}generateRandomId(length){const characters="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";let result="";for(let i=0;i<length;i++){result+=characters.charAt(Math.floor(Math.random()*characters.length))}return result}getRandomOtpCode(){return Math.floor(Math.random()*(9999-1e3+1))+1e3}extractColumnNameFromError(detail){const match=detail.match(/\((.*?)\)=\((.*?)\)/);return{columnName:match?match[1]:"unknown",value:match?match[2]:"unknown"}}getOtpEmailFormat(otp,userName){return`
|
|
2
|
+
<!DOCTYPE html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
|
7
|
+
<title>Your OTP Code</title>
|
|
8
|
+
<style>
|
|
9
|
+
body {
|
|
10
|
+
font-family: Arial, sans-serif;
|
|
11
|
+
background-color: #f4f4f7;
|
|
12
|
+
margin: 0;
|
|
13
|
+
padding: 0;
|
|
14
|
+
}
|
|
15
|
+
.email-container {
|
|
16
|
+
max-width: 500px;
|
|
17
|
+
margin: 40px auto;
|
|
18
|
+
background-color: #ffffff;
|
|
19
|
+
padding: 30px;
|
|
20
|
+
border-radius: 8px;
|
|
21
|
+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
|
|
22
|
+
text-align: center;
|
|
23
|
+
}
|
|
24
|
+
h1 {
|
|
25
|
+
color: #333;
|
|
26
|
+
}
|
|
27
|
+
p {
|
|
28
|
+
font-size: 16px;
|
|
29
|
+
color: #555;
|
|
30
|
+
}
|
|
31
|
+
.otp-box {
|
|
32
|
+
display: inline-block;
|
|
33
|
+
margin: 20px 0;
|
|
34
|
+
padding: 14px 28px;
|
|
35
|
+
font-size: 24px;
|
|
36
|
+
letter-spacing: 6px;
|
|
37
|
+
background-color: #007BFF;
|
|
38
|
+
color: white;
|
|
39
|
+
border-radius: 8px;
|
|
40
|
+
font-weight: bold;
|
|
41
|
+
}
|
|
42
|
+
</style>
|
|
43
|
+
</head>
|
|
44
|
+
<body>
|
|
45
|
+
<div class="email-container">
|
|
46
|
+
<p>Hi ${userName||"Sir/Madam"},</p>
|
|
47
|
+
<p>Use the code below to verify your identity:</p>
|
|
48
|
+
<div class="otp-box">${otp}</div>
|
|
49
|
+
<p>This OTP is valid for a limited time. Do not share it with anyone.</p>
|
|
50
|
+
<p>If you didn\u2019t request this, please ignore this email.</p>
|
|
51
|
+
</div>
|
|
52
|
+
</body>
|
|
53
|
+
</html>
|
|
54
|
+
`}getResetPasswordEmailFormat(resetLink,userName){return`
|
|
55
|
+
<!DOCTYPE html>
|
|
56
|
+
<html lang="en">
|
|
57
|
+
<head>
|
|
58
|
+
<meta charset="UTF-8" />
|
|
59
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
|
60
|
+
<title>Reset Your Password</title>
|
|
61
|
+
<style>
|
|
62
|
+
body {
|
|
63
|
+
font-family: Arial, sans-serif;
|
|
64
|
+
background-color: #f4f4f7;
|
|
65
|
+
margin: 0;
|
|
66
|
+
padding: 0;
|
|
67
|
+
}
|
|
68
|
+
.email-container {
|
|
69
|
+
max-width: 500px;
|
|
70
|
+
margin: 40px auto;
|
|
71
|
+
background-color: #ffffff;
|
|
72
|
+
padding: 30px;
|
|
73
|
+
border-radius: 8px;
|
|
74
|
+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
|
|
75
|
+
text-align: center;
|
|
76
|
+
}
|
|
77
|
+
h1 {
|
|
78
|
+
color: #333;
|
|
79
|
+
}
|
|
80
|
+
p {
|
|
81
|
+
font-size: 16px;
|
|
82
|
+
color: #555;
|
|
83
|
+
}
|
|
84
|
+
.reset-button {
|
|
85
|
+
display: inline-block;
|
|
86
|
+
margin: 20px 0;
|
|
87
|
+
padding: 14px 28px;
|
|
88
|
+
font-size: 16px;
|
|
89
|
+
background-color: #007BFF;
|
|
90
|
+
color: #ffffff !important;
|
|
91
|
+
text-decoration: none;
|
|
92
|
+
border-radius: 6px;
|
|
93
|
+
font-weight: bold;
|
|
94
|
+
}
|
|
95
|
+
</style>
|
|
96
|
+
</head>
|
|
97
|
+
<body>
|
|
98
|
+
<div class="email-container">
|
|
99
|
+
<p>Hi ${userName||"Sir/Madam"},</p>
|
|
100
|
+
<p>We received a request to reset your password. Click the button below to reset it:</p>
|
|
101
|
+
<a href="${resetLink}" class="reset-button" target="_blank">Reset Password</a>
|
|
102
|
+
<p>If you didn\u2019t request a password reset, you can safely ignore this email.</p>
|
|
103
|
+
</div>
|
|
104
|
+
</body>
|
|
105
|
+
</html>
|
|
106
|
+
`}};__name(UtilsService,"UtilsService");UtilsService=__decorateClass([Injectable2()],UtilsService);var UtilsModule=class{};__name(UtilsModule,"UtilsModule");UtilsModule=__decorateClass([Global(),Module3({imports:[],providers:[UtilsService],exports:[UtilsService]})],UtilsModule);export{CacheModule,DataSourceModule,MultiTenantDataSourceService,UtilsModule,UtilsService};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var __defProp=Object.defineProperty;var __name=(target,value)=>__defProp(target,"name",{value,configurable:true});var ErrorHandler=class{static{__name(this,"ErrorHandler")}static getErrorMessage(error){if(error instanceof Error){return error.message}if(typeof error==="string"){return error}return"Unknown error occurred"}static getErrorStack(error){if(error instanceof Error){return error.stack}return void 0}static createErrorContext(error,context){const errorContext={error:{message:this.getErrorMessage(error)}};if(error instanceof Error){errorContext.error.stack=error.stack;errorContext.error.name=error.name}if(context&&Object.keys(context).length>0){errorContext.context=context}return errorContext}static logError(logger,error,operation,context){const errorContext=this.createErrorContext(error,{operation,...context});const errorMessage=`Failed to ${operation}: ${errorContext.error.message}`;const loggerContext=logger.context||"ErrorHandler";logger.error(errorMessage,errorContext.error.stack,loggerContext,errorContext)}static rethrowError(error){if(error instanceof Error){throw error}throw new Error(`Unexpected error: ${String(error)}`)}};export{ErrorHandler};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ExecutionContext } from '@nestjs/common';
|
|
2
|
+
import { Reflector } from '@nestjs/core';
|
|
3
|
+
declare const JwtAuthGuard_base: import("@nestjs/passport").Type<import("@nestjs/passport").IAuthGuard>;
|
|
4
|
+
export declare class JwtAuthGuard extends JwtAuthGuard_base {
|
|
5
|
+
private reflector;
|
|
6
|
+
constructor(reflector: Reflector);
|
|
7
|
+
canActivate(context: ExecutionContext): boolean | Promise<boolean> | import("rxjs").Observable<boolean>;
|
|
8
|
+
handleRequest(err: any, user: any): any;
|
|
9
|
+
}
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
|
2
|
+
import { Reflector } from '@nestjs/core';
|
|
3
|
+
import { HybridCache } from '../classes/hybrid-cache.class';
|
|
4
|
+
import { ILogger } from '../interfaces/logger.interface';
|
|
5
|
+
import { PermissionGuardConfig } from '../interfaces/permission.interface';
|
|
6
|
+
export declare class PermissionGuard implements CanActivate {
|
|
7
|
+
private readonly reflector;
|
|
8
|
+
private readonly cache?;
|
|
9
|
+
private readonly config;
|
|
10
|
+
private readonly logger;
|
|
11
|
+
constructor(reflector: Reflector, cache?: HybridCache, config?: PermissionGuardConfig, logger?: ILogger);
|
|
12
|
+
canActivate(context: ExecutionContext): Promise<boolean>;
|
|
13
|
+
private normalizePermissionConfig;
|
|
14
|
+
private isNestedCondition;
|
|
15
|
+
private evaluateCondition;
|
|
16
|
+
private getUserPermissions;
|
|
17
|
+
private hasPermission;
|
|
18
|
+
}
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export * from './classes';
|
|
2
|
+
export * from './constants';
|
|
3
|
+
export * from './decorators';
|
|
4
|
+
export * from './dtos';
|
|
5
|
+
export * from './entities';
|
|
6
|
+
export * from './exceptions';
|
|
7
|
+
export * from './guards';
|
|
8
|
+
export * from './interceptors';
|
|
9
|
+
export * from './interfaces';
|
|
10
|
+
export * from './middlewares';
|
|
11
|
+
export * from './modules';
|
|
12
|
+
export * from './utils';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
export declare class DeleteEmptyIdFromBodyInterceptor implements NestInterceptor {
|
|
4
|
+
intercept<T = any>(context: ExecutionContext, next: CallHandler<T>): Observable<T>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { HybridCache } from '../classes/hybrid-cache.class';
|
|
4
|
+
export declare class IdempotencyInterceptor implements NestInterceptor {
|
|
5
|
+
private readonly cache?;
|
|
6
|
+
private readonly CACHE_TTL;
|
|
7
|
+
private readonly PROCESSING_MARKER;
|
|
8
|
+
constructor(cache?: HybridCache);
|
|
9
|
+
intercept<T = any>(context: ExecutionContext, next: CallHandler<T>): Promise<Observable<T>>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './delete-empty-id-from-body.interceptor';
|
|
2
|
+
export * from './idempotency.interceptor';
|
|
3
|
+
export * from './query-performance.interceptor';
|
|
4
|
+
export * from './response-meta.interceptor';
|
|
5
|
+
export * from './set-create-by-on-body.interceptor';
|
|
6
|
+
export * from './set-delete-by-on-body.interceptor';
|
|
7
|
+
export * from './set-update-by-on-body.interceptor';
|
|
8
|
+
export * from './slug.interceptor';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
export declare class QueryPerformanceInterceptor implements NestInterceptor {
|
|
4
|
+
private readonly logger;
|
|
5
|
+
private readonly threshold;
|
|
6
|
+
constructor(threshold?: number);
|
|
7
|
+
intercept(context: ExecutionContext, next: CallHandler): Observable<any>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
export declare class ResponseMetaInterceptor implements NestInterceptor {
|
|
4
|
+
intercept<T = any>(context: ExecutionContext, next: CallHandler<T>): Observable<T>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
export declare class SetCreatedByOnBody implements NestInterceptor {
|
|
4
|
+
intercept<T = any>(context: ExecutionContext, next: CallHandler<T>): Observable<T>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
export declare class SetDeletedByOnBody implements NestInterceptor {
|
|
4
|
+
intercept<T = any>(context: ExecutionContext, next: CallHandler<T>): Observable<T>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
export declare class SetUpdateByOnBody implements NestInterceptor {
|
|
4
|
+
intercept<T = any>(context: ExecutionContext, next: CallHandler<T>): Observable<T>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { UtilsService } from '../modules/utils/utils.service';
|
|
4
|
+
export declare class Slug implements NestInterceptor {
|
|
5
|
+
utilsService: UtilsService;
|
|
6
|
+
intercept<T = any>(context: ExecutionContext, next: CallHandler<T>): Observable<T>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { DeleteDto, FilterAndPaginationDto } from '@flusys/nestjs-shared/dtos';
|
|
2
|
+
import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
|
|
3
|
+
export interface IService<CreateDtoT, UpdateDtoT, InterfaceT> {
|
|
4
|
+
insert(addDto: CreateDtoT, user: ILoggedUserInfo | null): Promise<InterfaceT>;
|
|
5
|
+
insertMany(addDto: Array<CreateDtoT>, user: ILoggedUserInfo | null): Promise<Array<InterfaceT>>;
|
|
6
|
+
findById(id: string, user: ILoggedUserInfo | null, select?: string[]): Promise<InterfaceT>;
|
|
7
|
+
getAll(search: string, filterAndPaginationDto: FilterAndPaginationDto, user: ILoggedUserInfo | null): Promise<{
|
|
8
|
+
data: Array<InterfaceT>;
|
|
9
|
+
total: number;
|
|
10
|
+
}>;
|
|
11
|
+
update(updateDto: UpdateDtoT, user: ILoggedUserInfo | null): Promise<InterfaceT>;
|
|
12
|
+
updateMany(updateDto: Array<UpdateDtoT>, user: ILoggedUserInfo | null): Promise<Array<InterfaceT>>;
|
|
13
|
+
delete(deleteDto: DeleteDto, user: ILoggedUserInfo | null): Promise<null>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface ILogger {
|
|
2
|
+
log(message: string, context?: string, ...args: any[]): void;
|
|
3
|
+
error(message: string, trace?: string, context?: string, ...args: any[]): void;
|
|
4
|
+
warn(message: string, context?: string, ...args: any[]): void;
|
|
5
|
+
debug(message: string, context?: string, ...args: any[]): void;
|
|
6
|
+
verbose(message: string, context?: string, ...args: any[]): void;
|
|
7
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type PermissionOperator = 'and' | 'or';
|
|
2
|
+
export interface PermissionCondition {
|
|
3
|
+
permissions?: string[];
|
|
4
|
+
operator: PermissionOperator;
|
|
5
|
+
children?: PermissionCondition[];
|
|
6
|
+
}
|
|
7
|
+
export interface LegacyPermissionConfig {
|
|
8
|
+
permissions: string[];
|
|
9
|
+
operator: PermissionOperator;
|
|
10
|
+
}
|
|
11
|
+
export type PermissionConfig = PermissionCondition | LegacyPermissionConfig | string[];
|
|
12
|
+
export interface PermissionGuardConfig {
|
|
13
|
+
enableCompanyFeature?: boolean;
|
|
14
|
+
cacheKeyPrefix?: string;
|
|
15
|
+
userPermissionKeyFormat?: string;
|
|
16
|
+
companyPermissionKeyFormat?: string;
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './logger.middleware';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { NestMiddleware } from '@nestjs/common';
|
|
2
|
+
import { Request, Response, NextFunction } from 'express';
|
|
3
|
+
import { AsyncLocalStorage } from 'async_hooks';
|
|
4
|
+
export interface IRequestContext {
|
|
5
|
+
requestId: string;
|
|
6
|
+
tenantId?: string;
|
|
7
|
+
userId?: string;
|
|
8
|
+
companyId?: string;
|
|
9
|
+
startTime: number;
|
|
10
|
+
}
|
|
11
|
+
export declare const requestContext: AsyncLocalStorage<IRequestContext>;
|
|
12
|
+
export declare const getRequestId: () => string | undefined;
|
|
13
|
+
export declare const getTenantId: () => string | undefined;
|
|
14
|
+
export declare const getUserId: () => string | undefined;
|
|
15
|
+
export declare const getCompanyId: () => string | undefined;
|
|
16
|
+
export declare const setUserId: (userId: string) => void;
|
|
17
|
+
export declare const setCompanyId: (companyId: string) => void;
|
|
18
|
+
export declare class LoggerMiddleware implements NestMiddleware {
|
|
19
|
+
private readonly logger;
|
|
20
|
+
use(req: Request, res: Response, next: NextFunction): void;
|
|
21
|
+
private logRequest;
|
|
22
|
+
private logResponse;
|
|
23
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { IAsyncModuleOptions, IDataSourceServiceOptions, IModuleOptionsFactory } from '@flusys/nestjs-core';
|
|
2
|
+
import { DynamicModule, Type } from '@nestjs/common';
|
|
3
|
+
export interface DataSourceModuleOptions extends IDataSourceServiceOptions {
|
|
4
|
+
global?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface DataSourceOptionsFactory extends IModuleOptionsFactory<IDataSourceServiceOptions> {
|
|
7
|
+
createOptions(): Promise<IDataSourceServiceOptions> | IDataSourceServiceOptions;
|
|
8
|
+
}
|
|
9
|
+
export interface DataSourceModuleAsyncOptions extends IAsyncModuleOptions<IDataSourceServiceOptions> {
|
|
10
|
+
useClass?: Type<DataSourceOptionsFactory>;
|
|
11
|
+
useExisting?: Type<DataSourceOptionsFactory>;
|
|
12
|
+
}
|
|
13
|
+
export declare class DataSourceModule {
|
|
14
|
+
static forRoot(options: DataSourceModuleOptions): DynamicModule;
|
|
15
|
+
static forRootAsync(asyncOptions: DataSourceModuleAsyncOptions): DynamicModule;
|
|
16
|
+
static forFeature(): DynamicModule;
|
|
17
|
+
private static createAsyncProviders;
|
|
18
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { DatabaseMode, IDatabaseConfig, IDataSourceServiceOptions, ITenantDatabaseConfig } from '@flusys/nestjs-core';
|
|
2
|
+
import { Logger, OnModuleDestroy } from '@nestjs/common';
|
|
3
|
+
import { Request } from 'express';
|
|
4
|
+
import { DataSource, EntityTarget, ObjectLiteral, Repository } from 'typeorm';
|
|
5
|
+
export declare class MultiTenantDataSourceService implements OnModuleDestroy {
|
|
6
|
+
protected readonly options?: IDataSourceServiceOptions;
|
|
7
|
+
protected readonly request?: Request;
|
|
8
|
+
protected readonly logger: Logger;
|
|
9
|
+
protected static readonly tenantConnections: Map<string, DataSource>;
|
|
10
|
+
protected static singleDataSource: DataSource | null;
|
|
11
|
+
protected static readonly tenantsRegistry: Map<string, ITenantDatabaseConfig>;
|
|
12
|
+
protected static initialized: boolean;
|
|
13
|
+
protected static readonly connectionLocks: Map<string, Promise<DataSource>>;
|
|
14
|
+
protected static singleConnectionLock: Promise<DataSource> | null;
|
|
15
|
+
protected tenantHeader: string;
|
|
16
|
+
constructor(options?: IDataSourceServiceOptions, request?: Request);
|
|
17
|
+
private initializeFromOptions;
|
|
18
|
+
private registerTenants;
|
|
19
|
+
setTenantHeader(header: string): void;
|
|
20
|
+
getDatabaseMode(): DatabaseMode;
|
|
21
|
+
isMultiTenant(): boolean;
|
|
22
|
+
getCurrentTenantId(): string | null;
|
|
23
|
+
getCurrentTenant(): ITenantDatabaseConfig | null;
|
|
24
|
+
getTenant(tenantId: string): ITenantDatabaseConfig | null;
|
|
25
|
+
getAllTenants(): ITenantDatabaseConfig[];
|
|
26
|
+
getActiveTenants(): ITenantDatabaseConfig[];
|
|
27
|
+
getDataSource(): Promise<DataSource>;
|
|
28
|
+
getDataSourceForTenant(tenantId: string): Promise<DataSource>;
|
|
29
|
+
setDataSource(dataSource: DataSource): void;
|
|
30
|
+
getRepository<T extends ObjectLiteral>(entity: EntityTarget<T>): Promise<Repository<T>>;
|
|
31
|
+
getRepositoryForTenant<T extends ObjectLiteral>(entity: EntityTarget<T>, tenantId: string): Promise<Repository<T>>;
|
|
32
|
+
withTenant<T>(tenantId: string, callback: (ds: DataSource) => Promise<T>): Promise<T>;
|
|
33
|
+
forAllTenants<T>(callback: (tenant: ITenantDatabaseConfig, ds: DataSource) => Promise<T>): Promise<Map<string, T>>;
|
|
34
|
+
registerTenant(tenant: ITenantDatabaseConfig): void;
|
|
35
|
+
removeTenant(tenantId: string): Promise<void>;
|
|
36
|
+
closeTenantConnection(tenantId: string): Promise<void>;
|
|
37
|
+
onModuleDestroy(): Promise<void>;
|
|
38
|
+
static reset(): void;
|
|
39
|
+
protected getSingleDataSource(): Promise<DataSource>;
|
|
40
|
+
protected getTenantDataSource(): Promise<DataSource>;
|
|
41
|
+
protected getOrCreateTenantConnection(tenant: ITenantDatabaseConfig): Promise<DataSource>;
|
|
42
|
+
protected getDefaultDatabaseConfig(): IDatabaseConfig | undefined;
|
|
43
|
+
protected buildTenantDatabaseConfig(tenant: ITenantDatabaseConfig): IDatabaseConfig;
|
|
44
|
+
protected createDataSourceFromConfig(config: IDatabaseConfig, entities?: any[]): Promise<DataSource>;
|
|
45
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { HybridCache } from '@flusys/nestjs-shared/classes';
|
|
2
|
+
export declare class UtilsService {
|
|
3
|
+
constructor();
|
|
4
|
+
getCacheKey(entityName: string, params: any, entityId?: string, tenantId?: string): string;
|
|
5
|
+
trackCacheKey(cacheKey: string, entityName: string, cacheManager: HybridCache, entityId?: string, tenantId?: string): Promise<void>;
|
|
6
|
+
clearCache(entityName: string, cacheManager: HybridCache, entityId?: string, tenantId?: string): Promise<void>;
|
|
7
|
+
checkPhoneOrEmail(value: string): {
|
|
8
|
+
value: string | null;
|
|
9
|
+
type: 'phone' | 'email' | null;
|
|
10
|
+
};
|
|
11
|
+
transformToSlug(value: string, salt?: boolean): string;
|
|
12
|
+
getRandomInt(min: number, max: number): number;
|
|
13
|
+
generateRandomId(length: number): string;
|
|
14
|
+
getRandomOtpCode(): number;
|
|
15
|
+
extractColumnNameFromError(detail: string): {
|
|
16
|
+
columnName: string;
|
|
17
|
+
value: string;
|
|
18
|
+
};
|
|
19
|
+
getOtpEmailFormat(otp: number, userName?: string | null | undefined): string;
|
|
20
|
+
getResetPasswordEmailFormat(resetLink: string, userName?: string | null | undefined): string;
|
|
21
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@flusys/nestjs-shared",
|
|
3
|
+
"version": "0.1.0-alpha.1",
|
|
4
|
+
"description": "Common shared utilities for Flusys NestJS applications",
|
|
5
|
+
"main": "cjs/index.js",
|
|
6
|
+
"module": "fesm/index.js",
|
|
7
|
+
"types": "index.d.ts",
|
|
8
|
+
"sideEffects": false,
|
|
9
|
+
"keywords": [
|
|
10
|
+
"nestjs",
|
|
11
|
+
"common",
|
|
12
|
+
"utilities",
|
|
13
|
+
"decorators",
|
|
14
|
+
"guards",
|
|
15
|
+
"@flusys"
|
|
16
|
+
],
|
|
17
|
+
"license": "UNLICENSED",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./index.d.ts",
|
|
21
|
+
"import": "./fesm/index.js",
|
|
22
|
+
"require": "./cjs/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./classes": {
|
|
25
|
+
"types": "./classes/index.d.ts",
|
|
26
|
+
"import": "./fesm/classes-index.js",
|
|
27
|
+
"require": "./cjs/classes-index.js"
|
|
28
|
+
},
|
|
29
|
+
"./constants": {
|
|
30
|
+
"types": "./constants/index.d.ts",
|
|
31
|
+
"import": "./fesm/constants-index.js",
|
|
32
|
+
"require": "./cjs/constants-index.js"
|
|
33
|
+
},
|
|
34
|
+
"./decorators": {
|
|
35
|
+
"types": "./decorators/index.d.ts",
|
|
36
|
+
"import": "./fesm/decorators-index.js",
|
|
37
|
+
"require": "./cjs/decorators-index.js"
|
|
38
|
+
},
|
|
39
|
+
"./dtos": {
|
|
40
|
+
"types": "./dtos/index.d.ts",
|
|
41
|
+
"import": "./fesm/dtos-index.js",
|
|
42
|
+
"require": "./cjs/dtos-index.js"
|
|
43
|
+
},
|
|
44
|
+
"./entities": {
|
|
45
|
+
"types": "./entities/index.d.ts",
|
|
46
|
+
"import": "./fesm/entities-index.js",
|
|
47
|
+
"require": "./cjs/entities-index.js"
|
|
48
|
+
},
|
|
49
|
+
"./exceptions": {
|
|
50
|
+
"types": "./exceptions/index.d.ts",
|
|
51
|
+
"import": "./fesm/exceptions-index.js",
|
|
52
|
+
"require": "./cjs/exceptions-index.js"
|
|
53
|
+
},
|
|
54
|
+
"./guards": {
|
|
55
|
+
"types": "./guards/index.d.ts",
|
|
56
|
+
"import": "./fesm/guards-index.js",
|
|
57
|
+
"require": "./cjs/guards-index.js"
|
|
58
|
+
},
|
|
59
|
+
"./interceptors": {
|
|
60
|
+
"types": "./interceptors/index.d.ts",
|
|
61
|
+
"import": "./fesm/interceptors-index.js",
|
|
62
|
+
"require": "./cjs/interceptors-index.js"
|
|
63
|
+
},
|
|
64
|
+
"./interfaces": {
|
|
65
|
+
"types": "./interfaces/index.d.ts",
|
|
66
|
+
"import": "./fesm/interfaces-index.js",
|
|
67
|
+
"require": "./cjs/interfaces-index.js"
|
|
68
|
+
},
|
|
69
|
+
"./middlewares": {
|
|
70
|
+
"types": "./middlewares/index.d.ts",
|
|
71
|
+
"import": "./fesm/middlewares-index.js",
|
|
72
|
+
"require": "./cjs/middlewares-index.js"
|
|
73
|
+
},
|
|
74
|
+
"./modules": {
|
|
75
|
+
"types": "./modules/index.d.ts",
|
|
76
|
+
"import": "./fesm/modules-index.js",
|
|
77
|
+
"require": "./cjs/modules-index.js"
|
|
78
|
+
},
|
|
79
|
+
"./utils": {
|
|
80
|
+
"types": "./utils/index.d.ts",
|
|
81
|
+
"import": "./fesm/utils-index.js",
|
|
82
|
+
"require": "./cjs/utils-index.js"
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"peerDependencies": {
|
|
86
|
+
"@nestjs/common": "^10.0.0 || ^11.0.0",
|
|
87
|
+
"@nestjs/config": "^3.0.0 || ^4.0.0",
|
|
88
|
+
"@nestjs/core": "^10.0.0 || ^11.0.0",
|
|
89
|
+
"@nestjs/jwt": "^10.0.0 || ^11.0.0",
|
|
90
|
+
"@nestjs/passport": "^10.0.0 || ^11.0.0",
|
|
91
|
+
"@nestjs/swagger": "^7.0.0 || ^11.0.0",
|
|
92
|
+
"@nestjs/typeorm": "^10.0.0 || ^11.0.0",
|
|
93
|
+
"class-transformer": "^0.5.0",
|
|
94
|
+
"class-validator": "^0.14.0",
|
|
95
|
+
"typeorm": "^0.3.0"
|
|
96
|
+
},
|
|
97
|
+
"dependencies": {
|
|
98
|
+
"@flusys/nestjs-core": "0.1.0-alpha.1"
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Logger } from '@nestjs/common';
|
|
2
|
+
export declare class ErrorHandler {
|
|
3
|
+
static getErrorMessage(error: unknown): string;
|
|
4
|
+
static getErrorStack(error: unknown): string | undefined;
|
|
5
|
+
static createErrorContext(error: unknown, context?: {
|
|
6
|
+
operation?: string;
|
|
7
|
+
entity?: string;
|
|
8
|
+
userId?: string;
|
|
9
|
+
[key: string]: unknown;
|
|
10
|
+
}): {
|
|
11
|
+
error: {
|
|
12
|
+
message: string;
|
|
13
|
+
stack?: string;
|
|
14
|
+
name?: string;
|
|
15
|
+
};
|
|
16
|
+
context?: Record<string, unknown>;
|
|
17
|
+
};
|
|
18
|
+
static logError(logger: Logger, error: unknown, operation: string, context?: {
|
|
19
|
+
entity?: string;
|
|
20
|
+
userId?: string;
|
|
21
|
+
[key: string]: unknown;
|
|
22
|
+
}): void;
|
|
23
|
+
static rethrowError(error: unknown): never;
|
|
24
|
+
}
|
package/utils/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './error-handler.util';
|