@infineit-nestjs/services 1.0.21 → 1.0.23

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.
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.EntityActionService=void 0;const e=require("tslib"),r=require("@nestjs/common"),t=e.__importDefault(require("p-limit")),i=require("./logger.service"),s=require("./prisma.service");let n=class{constructor(e,r){this.prismaService=e,this.loggerService=r,this.batchSize=parseInt(process.env.BATCH_SIZE??"100",10),this.concurrencyLimit=parseInt(process.env.CONCURRENCY_LIMIT??"3",10)}async handleEntityActions(e,r,i,s){const n=this.capitalize(e),c=(0,t.default)(this.concurrencyLimit);try{const t=[];for(let e=0;e<r.length;e+=this.batchSize){const o=r.slice(e,e+this.batchSize);t.push(c((async()=>{this.loggerService.info(`Processing batch ${e/this.batchSize+1} for ${n}`);return await Promise.all(o.map((async(r,t)=>{const c=e+t;try{r[i.id]=i.value,"edit"===r.action&&(r.id=r[i.id_table_primary_key]);return{success:!0,id_return:(await this.executeQuery(r.action,n,"delete"===r.action?r[i.id_table_primary_key]:r,s[0][r.action])).id_return,data:r,index:c}}catch(e){return this.loggerService.error(`Error in batch operation for ${n}`,{error:e instanceof Error?e:new Error(String(e))}),{success:!1,error:e instanceof Error?e.message:String(e),data:r,index:c,retunrn_entity_name:i.id_return||"unknown_return_entity"}}})))})))}const o=(await Promise.all(t)).flat(),a=o.filter((e=>e.success)),u=o.filter((e=>!e.success));return{entity:e,message:`${n} operations completed.`,success:0===u.length,totalProcessed:r.length,totalFailed:u.length,totalSucceeded:a.length,failedOperations:u,succeededOperations:a}}catch(r){return this.loggerService.error(`Error during ${n} operations`,{error:r instanceof Error?r:new Error(String(r))}),{entity:e,message:"An unexpected error occurred during the operations.",success:!1}}}async processEntities(e){const r=e.filter((e=>!e.success)).reduce(((e,r)=>{const t=r.failedOperations.map((e=>({[e.retunrn_entity_name]:e.id_return,message:e.error,index:e.index})));return e.push({field:r.entity,errors:t}),e}),[]);return r.length>0?{success:!1,errorsByEntity:r}:{success:!0}}async executeQuery(e,r,t,i){try{const e=await this.prismaService.executeRawQuery(i,t);return{success:!0,id_return:e?.id||null}}catch(t){throw this.loggerService.error(`Error in ${e} operation for ${r}`,{error:t instanceof Error?t:new Error(String(t))}),new Error(`Error executing ${e} operation: ${r}`)}}capitalize(e){return e.charAt(0).toUpperCase()+e.slice(1)}};exports.EntityActionService=n,exports.EntityActionService=n=e.__decorate([(0,r.Injectable)(),e.__metadata("design:paramtypes",[s.PrismaService,i.LoggerService])],n);
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.EntityActionService=void 0;const e=require("tslib"),r=require("@nestjs/common"),t=e.__importDefault(require("p-limit")),i=require("./logger.service"),s=require("./prisma.service");let n=class{constructor(e,r){this.prismaService=e,this.loggerService=r,this.batchSize=parseInt(process.env.BATCH_SIZE??"100",10),this.concurrencyLimit=parseInt(process.env.CONCURRENCY_LIMIT??"3",10)}async handleEntityActions(e,r,i,s){const n=this.capitalize(e),c=(0,t.default)(this.concurrencyLimit);try{const t=[];for(let e=0;e<r.length;e+=this.batchSize){const o=r.slice(e,e+this.batchSize);t.push(c((async()=>{this.loggerService.info(`Processing batch ${e/this.batchSize+1} for ${n}`);return await Promise.all(o.map((async(r,t)=>{const c=e+t;try{r[i.id]=i.value,"edit"===r.action&&(r.id=r[i.id_table_primary_key]);return{success:!0,id_return:(await this.executeQuery(r.action,n,"delete"===r.action?r[i.id_table_primary_key]:r,s[0][r.action])).id_return,data:r,index:c}}catch(e){return this.loggerService.error(`Error in batch operation for ${n}`,{error:e instanceof Error?e:new Error(String(e))}),{success:!1,error:e instanceof Error?e.message:String(e),data:r,index:c,retunrn_entity_name:i.id_return||"unknown_return_entity"}}})))})))}const o=(await Promise.all(t)).flat(),a=o.filter((e=>e.success)),u=o.filter((e=>!e.success));return{entity:e,message:`${n} operations completed.`,success:0===u.length,totalProcessed:r.length,totalFailed:u.length,totalSucceeded:a.length,failedOperations:u,succeededOperations:a}}catch(r){return this.loggerService.error(`Error during ${n} operations`,{error:r instanceof Error?r:new Error(String(r))}),{entity:e,message:"An unexpected error occurred during the operations.",success:!1}}}async processEntities(e){const r=e.filter((e=>!e.success)).reduce(((e,r)=>{const t=r.failedOperations.map((e=>({[e.retunrn_entity_name]:e.id_return,message:e.error,index:e.index})));return e.push({field:r.entity,errors:t}),e}),[]);return r.length>0?{success:!1,errorsByEntity:r}:{success:!0}}async executeQuery(e,r,t,i){try{const e=await this.prismaService.executeRawQuery(i,t);return{success:!0,id_return:e?.id??e?.[0].id??null}}catch(t){throw this.loggerService.error(`Error in ${e} operation for ${r}`,{error:t instanceof Error?t:new Error(String(t))}),new Error(`Error executing ${e} operation: ${r}`)}}capitalize(e){return e.charAt(0).toUpperCase()+e.slice(1)}};exports.EntityActionService=n,exports.EntityActionService=n=e.__decorate([(0,r.Injectable)(),e.__metadata("design:paramtypes",[s.PrismaService,i.LoggerService])],n);
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.HttpServiceClient=void 0;const e=require("tslib"),r=require("@nestjs/common"),t=require("@nestjs/config"),s=e.__importDefault(require("axios")),i=e.__importDefault(require("axios-retry")),o=e.__importDefault(require("opossum")),c=require("prom-client"),a=require("./logger.service");let n=class{constructor(e,r){this.configService=e,this.loggerService=r,this.configureMetrics(),this.configureAxiosRetry(),this.configureCircuitBreaker()}configureMetrics(){this.requestCounter=new c.Counter({name:"service_client_requests_total",help:"Total number of requests made by the service client",labelNames:["service","method","status"]}),this.responseTimeHistogram=new c.Histogram({name:"service_client_response_time_seconds",help:"Response times of service client requests",labelNames:["service","method","status"],buckets:[.1,.5,1,2,5,10]})}configureAxiosRetry(){(0,i.default)(s.default,{retries:this.configService.getOrThrow("httpmicroservice.axios_retry_count"),retryDelay:e=>1e3*Math.pow(2,e),retryCondition:e=>i.default.isNetworkError(e)||!!e.response&&e.response.status>=500,onRetry:(e,r,t)=>{this.loggerService.warn(`Retry attempt #${e} for request to ${t.url}`,{sourceClass:this.constructor.name})}})}configureCircuitBreaker(){this.circuitBreaker=new o.default(this.callService.bind(this),{timeout:this.configService.getOrThrow("httpmicroservice.circuit_breaker_timeout"),errorThresholdPercentage:this.configService.getOrThrow("httpmicroservice.circuit_breaker_error_threshold"),resetTimeout:this.configService.getOrThrow("httpmicroservice.circuit_breaker_reset_timeout")}),this.circuitBreaker.fallback((e=>{this.loggerService.warn("Circuit breaker open. Fallback activated.",{sourceClass:this.constructor.name});return{message:"Service is currently unavailable. Please try again later.",error:e instanceof r.HttpException?e.getResponse():e.message}}))}async callService(e,r,t,i){const o={method:r,url:`${e}/${t}`,timeout:this.configService.getOrThrow("httpmicroservice.request_timeout")};"get"===r?o.params=i:o.data=i,this.requestCounter?.labels(e,r,"pending").inc();const c=Date.now();try{const i=await(0,s.default)(o),a=Date.now()-c;return this.responseTimeHistogram?.labels(e,r,"success").observe(a/1e3),this.requestCounter?.labels(e,r,"success").inc(),this.loggerService.info(`Successfully retrieved data from ${t} at ${e} in ${a}ms.`,{sourceClass:this.constructor.name}),i.data}catch(t){const s=Date.now()-c;throw this.responseTimeHistogram?.labels(e,r,"failure").observe(s/1e3),this.loggerService.error(`Error calling service at ${e}: ${t.message}`,{sourceClass:this.constructor.name}),this.handleServiceError(t)}}handleServiceError(e){if(e.response){const{status:t,data:s}=e.response;return new r.HttpException(s||"Service Error",t)}return e.request?new r.HttpException("Network Error",r.HttpStatus.SERVICE_UNAVAILABLE):new r.HttpException("Unexpected Error",r.HttpStatus.INTERNAL_SERVER_ERROR)}async getResource(e,t,s,i){const o=this.getServiceBaseURL(e);try{return await(this.circuitBreaker?.fire(o,t,s,i))}catch(t){const i=t;throw this.loggerService.error(`Error occurred while calling ${e} service at ${o}/${s}: ${i.message||i}`,{sourceClass:this.constructor.name}),new r.HttpException(`Service call to ${e} failed: ${i.message||"Service temporarily unavailable"}`,r.HttpStatus.SERVICE_UNAVAILABLE)}}getServiceBaseURL(e){const r=`httpmicroservice.${e}_microservice_url`,t=this.configService.getOrThrow(r);if(!t)throw new Error(`Service URL not found for service: ${e}. Please check your configuration.`);return t}async getMultipleResources(e,r,t,s){const i=e.map((e=>this.getResource(e,r,t,s)));return await Promise.all(i)}async getMultipleResourcesInBatch(e,t,s,i){let o=[];for(let c=0;c<e.length;c+=5){const a=e.slice(c,c+5);try{const e=a.map((e=>this.getResource(e,t,s,i))),r=await Promise.all(e);o=[...o,...r]}catch(e){throw this.loggerService.error("Error fetching data for batch",{sourceClass:this.constructor.name,error:e instanceof Error?e:new Error(String(e))}),new r.HttpException("Batch request failed",r.HttpStatus.INTERNAL_SERVER_ERROR)}}return o}};exports.HttpServiceClient=n,exports.HttpServiceClient=n=e.__decorate([(0,r.Injectable)(),e.__metadata("design:paramtypes",[t.ConfigService,a.LoggerService])],n);
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.HttpServiceClient=void 0;const e=require("tslib"),r=require("@nestjs/common"),t=require("@nestjs/config"),s=e.__importDefault(require("axios")),i=e.__importDefault(require("axios-retry")),o=e.__importDefault(require("opossum")),c=require("prom-client"),a=require("./logger.service");let n=class{constructor(e,r){this.configService=e,this.loggerService=r,this.configureMetrics(),this.configureAxiosRetry(),this.configureCircuitBreaker()}configureMetrics(){this.requestCounter=new c.Counter({name:"service_client_requests_total",help:"Total number of requests made by the service client",labelNames:["service","method","status"]}),this.responseTimeHistogram=new c.Histogram({name:"service_client_response_time_seconds",help:"Response times of service client requests",labelNames:["service","method","status"],buckets:[.1,.5,1,2,5,10]})}configureAxiosRetry(){(0,i.default)(s.default,{retries:this.configService.getOrThrow("httpmicroservice.axios_retry_count"),retryDelay:e=>1e3*Math.pow(2,e),retryCondition:e=>i.default.isNetworkError(e)||!!e.response&&e.response.status>=500,onRetry:(e,r,t)=>{this.loggerService.warn(`Retry attempt #${e} for request to ${t.url}`,{sourceClass:this.constructor.name})}})}configureCircuitBreaker(){this.circuitBreaker=new o.default(this.callService.bind(this),{timeout:this.configService.getOrThrow("httpmicroservice.circuit_breaker_timeout"),errorThresholdPercentage:this.configService.getOrThrow("httpmicroservice.circuit_breaker_error_threshold"),resetTimeout:this.configService.getOrThrow("httpmicroservice.circuit_breaker_reset_timeout")}),this.circuitBreaker.fallback((e=>{this.loggerService.warn("Circuit breaker open. Fallback activated.",{sourceClass:this.constructor.name});const t=e instanceof r.HttpException?e.getResponse():e.message;throw new r.ServiceUnavailableException({message:t,error:e.message})}))}async callService(e,r,t,i){const o={method:r,url:`${e}/${t}`,timeout:this.configService.getOrThrow("httpmicroservice.request_timeout")};"get"===r?o.params=i:o.data=i,this.requestCounter?.labels(e,r,"pending").inc();const c=Date.now();try{const i=await(0,s.default)(o),a=Date.now()-c;return this.responseTimeHistogram?.labels(e,r,"success").observe(a/1e3),this.requestCounter?.labels(e,r,"success").inc(),this.loggerService.info(`Successfully retrieved data from ${t} at ${e} in ${a}ms.`,{sourceClass:this.constructor.name}),i.data}catch(t){const s=Date.now()-c;throw this.responseTimeHistogram?.labels(e,r,"failure").observe(s/1e3),this.loggerService.error(`Error calling service at ${e}: ${t.message}`,{sourceClass:this.constructor.name}),this.handleServiceError(t)}}handleServiceError(e){if(e.response){const{status:t,data:s}=e.response;return new r.HttpException(s||"Service Error",t)}return e.request?new r.HttpException("Network Error",r.HttpStatus.SERVICE_UNAVAILABLE):new r.HttpException("Unexpected Error",r.HttpStatus.INTERNAL_SERVER_ERROR)}async getResource(e,t,s,i){const o=this.getServiceBaseURL(e);try{return await(this.circuitBreaker?.fire(o,t,s,i))}catch(t){const i=t;throw this.loggerService.error(`Error occurred while calling ${e} service at ${o}/${s}: ${i.message||i}`,{sourceClass:this.constructor.name}),new r.HttpException(`Service call to ${e} failed: ${i.message||"Service temporarily unavailable"}`,r.HttpStatus.SERVICE_UNAVAILABLE)}}getServiceBaseURL(e){const r=`httpmicroservice.${e}_microservice_url`,t=this.configService.getOrThrow(r);if(!t)throw new Error(`Service URL not found for service: ${e}. Please check your configuration.`);return t}async getMultipleResources(e,r,t,s){const i=e.map((e=>this.getResource(e,r,t,s)));return await Promise.all(i)}async getMultipleResourcesInBatch(e,t,s,i){let o=[];for(let c=0;c<e.length;c+=5){const a=e.slice(c,c+5);try{const e=a.map((e=>this.getResource(e,t,s,i))),r=await Promise.all(e);o=[...o,...r]}catch(e){throw this.loggerService.error("Error fetching data for batch",{sourceClass:this.constructor.name,error:e instanceof Error?e:new Error(String(e))}),new r.HttpException("Batch request failed",r.HttpStatus.INTERNAL_SERVER_ERROR)}}return o}};exports.HttpServiceClient=n,exports.HttpServiceClient=n=e.__decorate([(0,r.Injectable)(),e.__metadata("design:paramtypes",[t.ConfigService,a.LoggerService])],n);
@@ -1 +1 @@
1
- "use strict";var e;Object.defineProperty(exports,"__esModule",{value:!0}),exports.ResourceFetchService=void 0;const r=require("tslib"),t=require("@nestjs/common"),a=require("@infineit-nestjs/core/errors"),i=require("./data.transformer.service"),s=require("./http.client.service");let n=e=class{constructor(r,a){this.dataTransformerService=r,this.httpServiceClient=a,this.logger=new t.Logger(e.name)}async fetchResourcesDynamic(e){const r=e.map((e=>{const{resource:r,type:t,page:a=1,limit:i=10,version:s="v1",filters:n=[],sort:o=[],pagination:c="all"}=e,l=this.constructRelativePath({resource:r,type:t,page:a,limit:i,version:s,filters:n,sort:o,pagination:c});return this.fetchResources(r,l).then((e=>({[t]:e}))).catch((e=>(this.logger.error(`Error fetching resource ${t}: ${e.message}`),{[t]:{error:e.message}})))}));return(await Promise.all(r)).reduce(((e,r)=>Object.assign(e,r)),{})}async transformMultipleDataSets(e){const r=e.map((({name:e,data:r,fields:t})=>r?this.dataTransformerService.processData(r,t).then((r=>({[e]:r}))):Promise.resolve({[e]:{error:`${e} data is undefined`}})));return(await Promise.all(r)).reduce(((e,r)=>Object.assign(e,r)),{})}async getUniqueFieldValues(e,r){return r.reduce(((r,t)=>(r[t]=[...new Set(e.map((e=>e[t])))],r)),{})}async mergeData(e,r){return e.map((e=>r.reduce(((r,{field:t,data:a,field_name:i,removeField:s})=>{const n=this.getFieldValue(a,t,e[t],{[t]:e[t],name:`Default ${t.charAt(0).toUpperCase()+t.slice(1)}`});return r[i]=n,s&&delete r[t],r}),{...e})))}async generateQueryFunctions(e,r){return e.reduce(((e,{field:t,query:a})=>(e[t]=async e=>{const t=await r(a,e);return Array.isArray(t)?t:[t]},e)),{})}async applyDataTransformations(e,r,t,a){const i=await this.getUniqueFieldValues(e,r),s=await this.fetchAssociatedData(i,t),n=this.mapDataForTransformation(s,a);return this.mergeEnrichedData(e,n)}async fetchAssociatedData(e,r){const t={};return await Promise.all(Object.entries(r).map((async([r,i])=>{const s=e[r];if(!Array.isArray(s)||0===s.length)throw new a.MissingDataError(r);try{const e=await i(s.join(","));t[r]=Array.isArray(e)?e:[e]}catch(e){throw new Error(`Failed to fetch associated data for field: ${r}`,e)}}))),t}mapDataForTransformation(e,r){return r.map((({field:r,field_name:t,removeField:a})=>({field:r,data:e[r],field_name:t,removeField:a??!0})))}async mergeEnrichedData(e,r){const t=r.reduce(((e,{field:r,data:t,field_name:a})=>(e[a]=new Map(t.map((e=>[e[r],e]))),e)),{});return e.map((e=>{const a={...e};return r.forEach((({field:r,field_name:i,removeField:s})=>{const n=t[i],o=e[r],c=n?.get(o)||{[r]:o,name:`unknown-id-${o}`};a[i]=c,s&&delete a[r]})),a}))}constructRelativePath({resource:e,type:r,page:t,limit:a,version:i,filters:s,sort:n,pagination:o}){let c=`api/${i}/${r}`;const l=this.constructFilters(s),u=this.constructSort(n);return c+=`?pagination=${o}&page=${t}&limit=${a}`,l.length>0&&(c+=`&filters=[${l.join(",")}]`),u.length>0&&(c+=`&sort=[${u.join(",")}]`),this.logger.debug(`Constructed relative URL: ${c}`),c}constructFilters(e){return e.map((e=>`{"field":"${e.field}","operator":"${e.operator}","value":"${e.value}"}`))}constructSort(e){return e.map((e=>`{"field":"${e.field}","direction":"${e.direction}"}`))}fetchResources(e,r){return this.httpServiceClient.getResource(e,"get",r)}getFieldValue(e,r,t,a){return e.find((e=>e[r]===t))||a}};exports.ResourceFetchService=n,exports.ResourceFetchService=n=e=r.__decorate([(0,t.Injectable)(),r.__metadata("design:paramtypes",[i.DataTransformerService,s.HttpServiceClient])],n);
1
+ "use strict";var e;Object.defineProperty(exports,"__esModule",{value:!0}),exports.ResourceFetchService=void 0;const t=require("tslib"),r=require("@nestjs/common"),a=require("@infineit-nestjs/core/errors"),i=require("./data.transformer.service"),s=require("./http.client.service");let n=e=class{constructor(t,a){this.dataTransformerService=t,this.httpServiceClient=a,this.logger=new r.Logger(e.name)}async fetchResourcesDynamic(e){const t=e.map((e=>{const{resource:t,type:r,page:a=1,limit:i=10,version:s="v1",filters:n=[],sort:o=[],pagination:c="all"}=e,l=this.constructRelativePath({resource:t,type:r,page:a,limit:i,version:s,filters:n,sort:o,pagination:c});return this.fetchResources(t,l).then((e=>({[r]:e}))).catch((e=>{throw this.logger.error(`Error fetching resource ${r}: ${e.message}`),e}))}));return(await Promise.all(t)).reduce(((e,t)=>Object.assign(e,t)),{})}async transformMultipleDataSets(e){const t=e.map((({name:e,data:t,fields:r})=>t?this.dataTransformerService.processData(t,r).then((t=>({[e]:t}))):Promise.resolve({[e]:{error:`${e} data is undefined`}})));return(await Promise.all(t)).reduce(((e,t)=>Object.assign(e,t)),{})}async getUniqueFieldValues(e,t){return t.reduce(((t,r)=>(t[r]=[...new Set(e.map((e=>e[r])))],t)),{})}async mergeData(e,t){return e.map((e=>t.reduce(((t,{field:r,data:a,field_name:i,removeField:s})=>{const n=this.getFieldValue(a,r,e[r],{[r]:e[r],name:`Default ${r.charAt(0).toUpperCase()+r.slice(1)}`});return t[i]=n,s&&delete t[r],t}),{...e})))}async generateQueryFunctions(e,t){return e.reduce(((e,{field:r,query:a})=>(e[r]=async e=>{const r=await t(a,e);return Array.isArray(r)?r:[r]},e)),{})}async applyDataTransformations(e,t,r,a){const i=await this.getUniqueFieldValues(e,t),s=await this.fetchAssociatedData(i,r),n=this.mapDataForTransformation(s,a);return this.mergeEnrichedData(e,n)}async fetchAssociatedData(e,t){const r={};return await Promise.all(Object.entries(t).map((async([t,i])=>{const s=e[t];if(!Array.isArray(s)||0===s.length)throw new a.MissingDataError(t);try{const e=await i(s.join(","));r[t]=Array.isArray(e)?e:[e]}catch(e){throw new Error(`Failed to fetch associated data for field: ${t}`,e)}}))),r}mapDataForTransformation(e,t){return t.map((({field:t,field_name:r,removeField:a})=>({field:t,data:e[t],field_name:r,removeField:a??!0})))}async mergeEnrichedData(e,t){const r=t.reduce(((e,{field:t,data:r,field_name:a})=>(e[a]=new Map(r.map((e=>[e[t],e]))),e)),{});return e.map((e=>{const a={...e};return t.forEach((({field:t,field_name:i,removeField:s})=>{const n=r[i],o=e[t],c=n?.get(o)||{[t]:o,name:`unknown-id-${o}`};a[i]=c,s&&delete a[t]})),a}))}constructRelativePath({resource:e,type:t,page:r,limit:a,version:i,filters:s,sort:n,pagination:o}){let c=`api/${i}/${t}`;const l=this.constructFilters(s),u=this.constructSort(n);return c+=`?pagination=${o}&page=${r}&limit=${a}`,l.length>0&&(c+=`&filters=[${l.join(",")}]`),u.length>0&&(c+=`&sort=[${u.join(",")}]`),this.logger.debug(`Constructed relative URL: ${c}`),c}constructFilters(e){return e.map((e=>`{"field":"${e.field}","operator":"${e.operator}","value":"${e.value}"}`))}constructSort(e){return e.map((e=>`{"field":"${e.field}","direction":"${e.direction}"}`))}fetchResources(e,t){return this.httpServiceClient.getResource(e,"get",t)}getFieldValue(e,t,r,a){return e.find((e=>e[t]===r))||a}};exports.ResourceFetchService=n,exports.ResourceFetchService=n=e=t.__decorate([(0,r.Injectable)(),t.__metadata("design:paramtypes",[i.DataTransformerService,s.HttpServiceClient])],n);
@@ -1 +1 @@
1
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.EntityActionService=void 0;const e=require("tslib"),r=require("@nestjs/common"),t=e.__importDefault(require("p-limit")),i=require("./logger.service"),s=require("./prisma.service");let n=class{constructor(e,r){this.prismaService=e,this.loggerService=r,this.batchSize=parseInt(process.env.BATCH_SIZE??"100",10),this.concurrencyLimit=parseInt(process.env.CONCURRENCY_LIMIT??"3",10)}async handleEntityActions(e,r,i,s){const n=this.capitalize(e),c=(0,t.default)(this.concurrencyLimit);try{const t=[];for(let e=0;e<r.length;e+=this.batchSize){const o=r.slice(e,e+this.batchSize);t.push(c((async()=>{this.loggerService.info(`Processing batch ${e/this.batchSize+1} for ${n}`);return await Promise.all(o.map((async(r,t)=>{const c=e+t;try{r[i.id]=i.value,"edit"===r.action&&(r.id=r[i.id_table_primary_key]);return{success:!0,id_return:(await this.executeQuery(r.action,n,"delete"===r.action?r[i.id_table_primary_key]:r,s[0][r.action])).id_return,data:r,index:c}}catch(e){return this.loggerService.error(`Error in batch operation for ${n}`,{error:e instanceof Error?e:new Error(String(e))}),{success:!1,error:e instanceof Error?e.message:String(e),data:r,index:c,retunrn_entity_name:i.id_return||"unknown_return_entity"}}})))})))}const o=(await Promise.all(t)).flat(),a=o.filter((e=>e.success)),u=o.filter((e=>!e.success));return{entity:e,message:`${n} operations completed.`,success:0===u.length,totalProcessed:r.length,totalFailed:u.length,totalSucceeded:a.length,failedOperations:u,succeededOperations:a}}catch(r){return this.loggerService.error(`Error during ${n} operations`,{error:r instanceof Error?r:new Error(String(r))}),{entity:e,message:"An unexpected error occurred during the operations.",success:!1}}}async processEntities(e){const r=e.filter((e=>!e.success)).reduce(((e,r)=>{const t=r.failedOperations.map((e=>({[e.retunrn_entity_name]:e.id_return,message:e.error,index:e.index})));return e.push({field:r.entity,errors:t}),e}),[]);return r.length>0?{success:!1,errorsByEntity:r}:{success:!0}}async executeQuery(e,r,t,i){try{const e=await this.prismaService.executeRawQuery(i,t);return{success:!0,id_return:e?.id||null}}catch(t){throw this.loggerService.error(`Error in ${e} operation for ${r}`,{error:t instanceof Error?t:new Error(String(t))}),new Error(`Error executing ${e} operation: ${r}`)}}capitalize(e){return e.charAt(0).toUpperCase()+e.slice(1)}};exports.EntityActionService=n,exports.EntityActionService=n=e.__decorate([(0,r.Injectable)(),e.__metadata("design:paramtypes",[s.PrismaService,i.LoggerService])],n);
1
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.EntityActionService=void 0;const e=require("tslib"),r=require("@nestjs/common"),t=e.__importDefault(require("p-limit")),i=require("./logger.service"),s=require("./prisma.service");let n=class{constructor(e,r){this.prismaService=e,this.loggerService=r,this.batchSize=parseInt(process.env.BATCH_SIZE??"100",10),this.concurrencyLimit=parseInt(process.env.CONCURRENCY_LIMIT??"3",10)}async handleEntityActions(e,r,i,s){const n=this.capitalize(e),c=(0,t.default)(this.concurrencyLimit);try{const t=[];for(let e=0;e<r.length;e+=this.batchSize){const o=r.slice(e,e+this.batchSize);t.push(c((async()=>{this.loggerService.info(`Processing batch ${e/this.batchSize+1} for ${n}`);return await Promise.all(o.map((async(r,t)=>{const c=e+t;try{r[i.id]=i.value,"edit"===r.action&&(r.id=r[i.id_table_primary_key]);return{success:!0,id_return:(await this.executeQuery(r.action,n,"delete"===r.action?r[i.id_table_primary_key]:r,s[0][r.action])).id_return,data:r,index:c}}catch(e){return this.loggerService.error(`Error in batch operation for ${n}`,{error:e instanceof Error?e:new Error(String(e))}),{success:!1,error:e instanceof Error?e.message:String(e),data:r,index:c,retunrn_entity_name:i.id_return||"unknown_return_entity"}}})))})))}const o=(await Promise.all(t)).flat(),a=o.filter((e=>e.success)),u=o.filter((e=>!e.success));return{entity:e,message:`${n} operations completed.`,success:0===u.length,totalProcessed:r.length,totalFailed:u.length,totalSucceeded:a.length,failedOperations:u,succeededOperations:a}}catch(r){return this.loggerService.error(`Error during ${n} operations`,{error:r instanceof Error?r:new Error(String(r))}),{entity:e,message:"An unexpected error occurred during the operations.",success:!1}}}async processEntities(e){const r=e.filter((e=>!e.success)).reduce(((e,r)=>{const t=r.failedOperations.map((e=>({[e.retunrn_entity_name]:e.id_return,message:e.error,index:e.index})));return e.push({field:r.entity,errors:t}),e}),[]);return r.length>0?{success:!1,errorsByEntity:r}:{success:!0}}async executeQuery(e,r,t,i){try{const e=await this.prismaService.executeRawQuery(i,t);return{success:!0,id_return:e?.id??e?.[0].id??null}}catch(t){throw this.loggerService.error(`Error in ${e} operation for ${r}`,{error:t instanceof Error?t:new Error(String(t))}),new Error(`Error executing ${e} operation: ${r}`)}}capitalize(e){return e.charAt(0).toUpperCase()+e.slice(1)}};exports.EntityActionService=n,exports.EntityActionService=n=e.__decorate([(0,r.Injectable)(),e.__metadata("design:paramtypes",[s.PrismaService,i.LoggerService])],n);
@@ -1 +1 @@
1
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.HttpServiceClient=void 0;const e=require("tslib"),r=require("@nestjs/common"),t=require("@nestjs/config"),s=e.__importDefault(require("axios")),i=e.__importDefault(require("axios-retry")),o=e.__importDefault(require("opossum")),c=require("prom-client"),a=require("./logger.service");let n=class{constructor(e,r){this.configService=e,this.loggerService=r,this.configureMetrics(),this.configureAxiosRetry(),this.configureCircuitBreaker()}configureMetrics(){this.requestCounter=new c.Counter({name:"service_client_requests_total",help:"Total number of requests made by the service client",labelNames:["service","method","status"]}),this.responseTimeHistogram=new c.Histogram({name:"service_client_response_time_seconds",help:"Response times of service client requests",labelNames:["service","method","status"],buckets:[.1,.5,1,2,5,10]})}configureAxiosRetry(){(0,i.default)(s.default,{retries:this.configService.getOrThrow("httpmicroservice.axios_retry_count"),retryDelay:e=>1e3*Math.pow(2,e),retryCondition:e=>i.default.isNetworkError(e)||!!e.response&&e.response.status>=500,onRetry:(e,r,t)=>{this.loggerService.warn(`Retry attempt #${e} for request to ${t.url}`,{sourceClass:this.constructor.name})}})}configureCircuitBreaker(){this.circuitBreaker=new o.default(this.callService.bind(this),{timeout:this.configService.getOrThrow("httpmicroservice.circuit_breaker_timeout"),errorThresholdPercentage:this.configService.getOrThrow("httpmicroservice.circuit_breaker_error_threshold"),resetTimeout:this.configService.getOrThrow("httpmicroservice.circuit_breaker_reset_timeout")}),this.circuitBreaker.fallback((e=>{this.loggerService.warn("Circuit breaker open. Fallback activated.",{sourceClass:this.constructor.name});return{message:"Service is currently unavailable. Please try again later.",error:e instanceof r.HttpException?e.getResponse():e.message}}))}async callService(e,r,t,i){const o={method:r,url:`${e}/${t}`,timeout:this.configService.getOrThrow("httpmicroservice.request_timeout")};"get"===r?o.params=i:o.data=i,this.requestCounter?.labels(e,r,"pending").inc();const c=Date.now();try{const i=await(0,s.default)(o),a=Date.now()-c;return this.responseTimeHistogram?.labels(e,r,"success").observe(a/1e3),this.requestCounter?.labels(e,r,"success").inc(),this.loggerService.info(`Successfully retrieved data from ${t} at ${e} in ${a}ms.`,{sourceClass:this.constructor.name}),i.data}catch(t){const s=Date.now()-c;throw this.responseTimeHistogram?.labels(e,r,"failure").observe(s/1e3),this.loggerService.error(`Error calling service at ${e}: ${t.message}`,{sourceClass:this.constructor.name}),this.handleServiceError(t)}}handleServiceError(e){if(e.response){const{status:t,data:s}=e.response;return new r.HttpException(s||"Service Error",t)}return e.request?new r.HttpException("Network Error",r.HttpStatus.SERVICE_UNAVAILABLE):new r.HttpException("Unexpected Error",r.HttpStatus.INTERNAL_SERVER_ERROR)}async getResource(e,t,s,i){const o=this.getServiceBaseURL(e);try{return await(this.circuitBreaker?.fire(o,t,s,i))}catch(t){const i=t;throw this.loggerService.error(`Error occurred while calling ${e} service at ${o}/${s}: ${i.message||i}`,{sourceClass:this.constructor.name}),new r.HttpException(`Service call to ${e} failed: ${i.message||"Service temporarily unavailable"}`,r.HttpStatus.SERVICE_UNAVAILABLE)}}getServiceBaseURL(e){const r=`httpmicroservice.${e}_microservice_url`,t=this.configService.getOrThrow(r);if(!t)throw new Error(`Service URL not found for service: ${e}. Please check your configuration.`);return t}async getMultipleResources(e,r,t,s){const i=e.map((e=>this.getResource(e,r,t,s)));return await Promise.all(i)}async getMultipleResourcesInBatch(e,t,s,i){let o=[];for(let c=0;c<e.length;c+=5){const a=e.slice(c,c+5);try{const e=a.map((e=>this.getResource(e,t,s,i))),r=await Promise.all(e);o=[...o,...r]}catch(e){throw this.loggerService.error("Error fetching data for batch",{sourceClass:this.constructor.name,error:e instanceof Error?e:new Error(String(e))}),new r.HttpException("Batch request failed",r.HttpStatus.INTERNAL_SERVER_ERROR)}}return o}};exports.HttpServiceClient=n,exports.HttpServiceClient=n=e.__decorate([(0,r.Injectable)(),e.__metadata("design:paramtypes",[t.ConfigService,a.LoggerService])],n);
1
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.HttpServiceClient=void 0;const e=require("tslib"),r=require("@nestjs/common"),t=require("@nestjs/config"),s=e.__importDefault(require("axios")),i=e.__importDefault(require("axios-retry")),o=e.__importDefault(require("opossum")),c=require("prom-client"),a=require("./logger.service");let n=class{constructor(e,r){this.configService=e,this.loggerService=r,this.configureMetrics(),this.configureAxiosRetry(),this.configureCircuitBreaker()}configureMetrics(){this.requestCounter=new c.Counter({name:"service_client_requests_total",help:"Total number of requests made by the service client",labelNames:["service","method","status"]}),this.responseTimeHistogram=new c.Histogram({name:"service_client_response_time_seconds",help:"Response times of service client requests",labelNames:["service","method","status"],buckets:[.1,.5,1,2,5,10]})}configureAxiosRetry(){(0,i.default)(s.default,{retries:this.configService.getOrThrow("httpmicroservice.axios_retry_count"),retryDelay:e=>1e3*Math.pow(2,e),retryCondition:e=>i.default.isNetworkError(e)||!!e.response&&e.response.status>=500,onRetry:(e,r,t)=>{this.loggerService.warn(`Retry attempt #${e} for request to ${t.url}`,{sourceClass:this.constructor.name})}})}configureCircuitBreaker(){this.circuitBreaker=new o.default(this.callService.bind(this),{timeout:this.configService.getOrThrow("httpmicroservice.circuit_breaker_timeout"),errorThresholdPercentage:this.configService.getOrThrow("httpmicroservice.circuit_breaker_error_threshold"),resetTimeout:this.configService.getOrThrow("httpmicroservice.circuit_breaker_reset_timeout")}),this.circuitBreaker.fallback((e=>{this.loggerService.warn("Circuit breaker open. Fallback activated.",{sourceClass:this.constructor.name});const t=e instanceof r.HttpException?e.getResponse():e.message;throw new r.ServiceUnavailableException({message:t,error:e.message})}))}async callService(e,r,t,i){const o={method:r,url:`${e}/${t}`,timeout:this.configService.getOrThrow("httpmicroservice.request_timeout")};"get"===r?o.params=i:o.data=i,this.requestCounter?.labels(e,r,"pending").inc();const c=Date.now();try{const i=await(0,s.default)(o),a=Date.now()-c;return this.responseTimeHistogram?.labels(e,r,"success").observe(a/1e3),this.requestCounter?.labels(e,r,"success").inc(),this.loggerService.info(`Successfully retrieved data from ${t} at ${e} in ${a}ms.`,{sourceClass:this.constructor.name}),i.data}catch(t){const s=Date.now()-c;throw this.responseTimeHistogram?.labels(e,r,"failure").observe(s/1e3),this.loggerService.error(`Error calling service at ${e}: ${t.message}`,{sourceClass:this.constructor.name}),this.handleServiceError(t)}}handleServiceError(e){if(e.response){const{status:t,data:s}=e.response;return new r.HttpException(s||"Service Error",t)}return e.request?new r.HttpException("Network Error",r.HttpStatus.SERVICE_UNAVAILABLE):new r.HttpException("Unexpected Error",r.HttpStatus.INTERNAL_SERVER_ERROR)}async getResource(e,t,s,i){const o=this.getServiceBaseURL(e);try{return await(this.circuitBreaker?.fire(o,t,s,i))}catch(t){const i=t;throw this.loggerService.error(`Error occurred while calling ${e} service at ${o}/${s}: ${i.message||i}`,{sourceClass:this.constructor.name}),new r.HttpException(`Service call to ${e} failed: ${i.message||"Service temporarily unavailable"}`,r.HttpStatus.SERVICE_UNAVAILABLE)}}getServiceBaseURL(e){const r=`httpmicroservice.${e}_microservice_url`,t=this.configService.getOrThrow(r);if(!t)throw new Error(`Service URL not found for service: ${e}. Please check your configuration.`);return t}async getMultipleResources(e,r,t,s){const i=e.map((e=>this.getResource(e,r,t,s)));return await Promise.all(i)}async getMultipleResourcesInBatch(e,t,s,i){let o=[];for(let c=0;c<e.length;c+=5){const a=e.slice(c,c+5);try{const e=a.map((e=>this.getResource(e,t,s,i))),r=await Promise.all(e);o=[...o,...r]}catch(e){throw this.loggerService.error("Error fetching data for batch",{sourceClass:this.constructor.name,error:e instanceof Error?e:new Error(String(e))}),new r.HttpException("Batch request failed",r.HttpStatus.INTERNAL_SERVER_ERROR)}}return o}};exports.HttpServiceClient=n,exports.HttpServiceClient=n=e.__decorate([(0,r.Injectable)(),e.__metadata("design:paramtypes",[t.ConfigService,a.LoggerService])],n);
@@ -1 +1 @@
1
- var e;Object.defineProperty(exports,"__esModule",{value:!0}),exports.ResourceFetchService=void 0;const r=require("tslib"),t=require("@nestjs/common"),a=require("@infineit-nestjs/core/errors"),i=require("./data.transformer.service"),s=require("./http.client.service");let n=e=class{constructor(r,a){this.dataTransformerService=r,this.httpServiceClient=a,this.logger=new t.Logger(e.name)}async fetchResourcesDynamic(e){const r=e.map((e=>{const{resource:r,type:t,page:a=1,limit:i=10,version:s="v1",filters:n=[],sort:o=[],pagination:c="all"}=e,l=this.constructRelativePath({resource:r,type:t,page:a,limit:i,version:s,filters:n,sort:o,pagination:c});return this.fetchResources(r,l).then((e=>({[t]:e}))).catch((e=>(this.logger.error(`Error fetching resource ${t}: ${e.message}`),{[t]:{error:e.message}})))}));return(await Promise.all(r)).reduce(((e,r)=>Object.assign(e,r)),{})}async transformMultipleDataSets(e){const r=e.map((({name:e,data:r,fields:t})=>r?this.dataTransformerService.processData(r,t).then((r=>({[e]:r}))):Promise.resolve({[e]:{error:`${e} data is undefined`}})));return(await Promise.all(r)).reduce(((e,r)=>Object.assign(e,r)),{})}async getUniqueFieldValues(e,r){return r.reduce(((r,t)=>(r[t]=[...new Set(e.map((e=>e[t])))],r)),{})}async mergeData(e,r){return e.map((e=>r.reduce(((r,{field:t,data:a,field_name:i,removeField:s})=>{const n=this.getFieldValue(a,t,e[t],{[t]:e[t],name:`Default ${t.charAt(0).toUpperCase()+t.slice(1)}`});return r[i]=n,s&&delete r[t],r}),{...e})))}async generateQueryFunctions(e,r){return e.reduce(((e,{field:t,query:a})=>(e[t]=async e=>{const t=await r(a,e);return Array.isArray(t)?t:[t]},e)),{})}async applyDataTransformations(e,r,t,a){const i=await this.getUniqueFieldValues(e,r),s=await this.fetchAssociatedData(i,t),n=this.mapDataForTransformation(s,a);return this.mergeEnrichedData(e,n)}async fetchAssociatedData(e,r){const t={};return await Promise.all(Object.entries(r).map((async([r,i])=>{const s=e[r];if(!Array.isArray(s)||0===s.length)throw new a.MissingDataError(r);try{const e=await i(s.join(","));t[r]=Array.isArray(e)?e:[e]}catch(e){throw new Error(`Failed to fetch associated data for field: ${r}`,e)}}))),t}mapDataForTransformation(e,r){return r.map((({field:r,field_name:t,removeField:a})=>({field:r,data:e[r],field_name:t,removeField:a??!0})))}async mergeEnrichedData(e,r){const t=r.reduce(((e,{field:r,data:t,field_name:a})=>(e[a]=new Map(t.map((e=>[e[r],e]))),e)),{});return e.map((e=>{const a={...e};return r.forEach((({field:r,field_name:i,removeField:s})=>{const n=t[i],o=e[r],c=n?.get(o)||{[r]:o,name:`unknown-id-${o}`};a[i]=c,s&&delete a[r]})),a}))}constructRelativePath({resource:e,type:r,page:t,limit:a,version:i,filters:s,sort:n,pagination:o}){let c=`api/${i}/${r}`;const l=this.constructFilters(s),u=this.constructSort(n);return c+=`?pagination=${o}&page=${t}&limit=${a}`,l.length>0&&(c+=`&filters=[${l.join(",")}]`),u.length>0&&(c+=`&sort=[${u.join(",")}]`),this.logger.debug(`Constructed relative URL: ${c}`),c}constructFilters(e){return e.map((e=>`{"field":"${e.field}","operator":"${e.operator}","value":"${e.value}"}`))}constructSort(e){return e.map((e=>`{"field":"${e.field}","direction":"${e.direction}"}`))}fetchResources(e,r){return this.httpServiceClient.getResource(e,"get",r)}getFieldValue(e,r,t,a){return e.find((e=>e[r]===t))||a}};exports.ResourceFetchService=n,exports.ResourceFetchService=n=e=r.__decorate([(0,t.Injectable)(),r.__metadata("design:paramtypes",[i.DataTransformerService,s.HttpServiceClient])],n);
1
+ var e;Object.defineProperty(exports,"__esModule",{value:!0}),exports.ResourceFetchService=void 0;const t=require("tslib"),r=require("@nestjs/common"),a=require("@infineit-nestjs/core/errors"),i=require("./data.transformer.service"),s=require("./http.client.service");let n=e=class{constructor(t,a){this.dataTransformerService=t,this.httpServiceClient=a,this.logger=new r.Logger(e.name)}async fetchResourcesDynamic(e){const t=e.map((e=>{const{resource:t,type:r,page:a=1,limit:i=10,version:s="v1",filters:n=[],sort:o=[],pagination:c="all"}=e,l=this.constructRelativePath({resource:t,type:r,page:a,limit:i,version:s,filters:n,sort:o,pagination:c});return this.fetchResources(t,l).then((e=>({[r]:e}))).catch((e=>{throw this.logger.error(`Error fetching resource ${r}: ${e.message}`),e}))}));return(await Promise.all(t)).reduce(((e,t)=>Object.assign(e,t)),{})}async transformMultipleDataSets(e){const t=e.map((({name:e,data:t,fields:r})=>t?this.dataTransformerService.processData(t,r).then((t=>({[e]:t}))):Promise.resolve({[e]:{error:`${e} data is undefined`}})));return(await Promise.all(t)).reduce(((e,t)=>Object.assign(e,t)),{})}async getUniqueFieldValues(e,t){return t.reduce(((t,r)=>(t[r]=[...new Set(e.map((e=>e[r])))],t)),{})}async mergeData(e,t){return e.map((e=>t.reduce(((t,{field:r,data:a,field_name:i,removeField:s})=>{const n=this.getFieldValue(a,r,e[r],{[r]:e[r],name:`Default ${r.charAt(0).toUpperCase()+r.slice(1)}`});return t[i]=n,s&&delete t[r],t}),{...e})))}async generateQueryFunctions(e,t){return e.reduce(((e,{field:r,query:a})=>(e[r]=async e=>{const r=await t(a,e);return Array.isArray(r)?r:[r]},e)),{})}async applyDataTransformations(e,t,r,a){const i=await this.getUniqueFieldValues(e,t),s=await this.fetchAssociatedData(i,r),n=this.mapDataForTransformation(s,a);return this.mergeEnrichedData(e,n)}async fetchAssociatedData(e,t){const r={};return await Promise.all(Object.entries(t).map((async([t,i])=>{const s=e[t];if(!Array.isArray(s)||0===s.length)throw new a.MissingDataError(t);try{const e=await i(s.join(","));r[t]=Array.isArray(e)?e:[e]}catch(e){throw new Error(`Failed to fetch associated data for field: ${t}`,e)}}))),r}mapDataForTransformation(e,t){return t.map((({field:t,field_name:r,removeField:a})=>({field:t,data:e[t],field_name:r,removeField:a??!0})))}async mergeEnrichedData(e,t){const r=t.reduce(((e,{field:t,data:r,field_name:a})=>(e[a]=new Map(r.map((e=>[e[t],e]))),e)),{});return e.map((e=>{const a={...e};return t.forEach((({field:t,field_name:i,removeField:s})=>{const n=r[i],o=e[t],c=n?.get(o)||{[t]:o,name:`unknown-id-${o}`};a[i]=c,s&&delete a[t]})),a}))}constructRelativePath({resource:e,type:t,page:r,limit:a,version:i,filters:s,sort:n,pagination:o}){let c=`api/${i}/${t}`;const l=this.constructFilters(s),u=this.constructSort(n);return c+=`?pagination=${o}&page=${r}&limit=${a}`,l.length>0&&(c+=`&filters=[${l.join(",")}]`),u.length>0&&(c+=`&sort=[${u.join(",")}]`),this.logger.debug(`Constructed relative URL: ${c}`),c}constructFilters(e){return e.map((e=>`{"field":"${e.field}","operator":"${e.operator}","value":"${e.value}"}`))}constructSort(e){return e.map((e=>`{"field":"${e.field}","direction":"${e.direction}"}`))}fetchResources(e,t){return this.httpServiceClient.getResource(e,"get",t)}getFieldValue(e,t,r,a){return e.find((e=>e[t]===r))||a}};exports.ResourceFetchService=n,exports.ResourceFetchService=n=e=t.__decorate([(0,r.Injectable)(),t.__metadata("design:paramtypes",[i.DataTransformerService,s.HttpServiceClient])],n);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@infineit-nestjs/services",
3
- "version": "1.0.21",
3
+ "version": "1.0.23",
4
4
  "main": "./dist/cjs/index.js",
5
5
  "module": "./dist/es/index.mjs",
6
6
  "exports": {
@@ -37,9 +37,9 @@
37
37
  "dev": "concurrently -c blue,red -n tsc,rollup --kill-others \"tsc --watch -p . --preserveWatchOutput\" \"rollup --config --watch --no-watch.clearScreen\""
38
38
  },
39
39
  "dependencies": {
40
- "@infineit-nestjs/core": "1.0.12",
41
- "@infineit-nestjs/types": "1.0.5",
42
- "@infineit-nestjs/utils": "1.0.22",
40
+ "@infineit-nestjs/core": "1.0.14",
41
+ "@infineit-nestjs/types": "1.0.6",
42
+ "@infineit-nestjs/utils": "1.0.24",
43
43
  "@infineit/winston-logger": "^1.0.30",
44
44
  "@nestjs/axios": "^4.0.0",
45
45
  "@nestjs/microservices": "^11.1.2",
@@ -99,5 +99,5 @@
99
99
  "publishConfig": {
100
100
  "access": "public"
101
101
  },
102
- "gitHead": "4130b02564fd907e1b20cfdff876133d9f273509"
102
+ "gitHead": "8c13163bc583b9cb122a717ec86b45da1db88df3"
103
103
  }