@spytecgps/lambda-utils 2.3.5 → 2.3.7

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/dist/index.d.ts CHANGED
@@ -3,6 +3,5 @@ export * from './errors';
3
3
  export * from './validation';
4
4
  export * from './types';
5
5
  export * from './middleware';
6
- export * from './logger';
7
6
  export * from './utils';
8
7
  export * from './config';
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e=require("@spytecgps/sdk-logger"),r=require("dayjs"),t=require("dayjs/plugin/timezone"),s=require("dayjs/plugin/utc"),o=require("joi"),a=require("qs"),n=require("@middy/core"),i=require("@middy/http-error-handler"),l=require("@middy/http-response-serializer"),c=require("@middy/sqs-json-body-parser"),d=require("@middy/input-output-logger"),u=require("deepmerge");function p(e){var r=Object.create(null);return e&&Object.keys(e).forEach((function(t){if("default"!==t){var s=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,s.get?s:{enumerable:!0,get:function(){return e[t]}})}})),r.default=e,Object.freeze(r)}var g=p(o),m=p(a);r.extend(s),r.extend(t);const y=g.extend((e=>({type:"object",base:e.object(),messages:{"json.valid":"must be valid JSON"},coerce(e){try{return{value:JSON.parse(e)}}catch(e){return null}},validate:(e,r)=>e?{value:e}:{value:e,errors:r.error("json.valid")}}))),v=g.extend((e=>({type:"object",base:e.object(),coerce:e=>({value:m.parse(e)})}))),b=g.string().regex(/^\d{15,16}$/).message("Invalid IMEI"),x=g.string().regex(/^[0-9A-Za-z]{18,22}$/).message("Invalid ICCID"),h=g.extend((e=>({type:"imei",messages:"Invalid IMEI",base:e.string().regex(/^\d{15,16}$/)})),(e=>({type:"iccid",messages:"Invalid ICCID",base:e.string().regex(/^[0-9A-Za-z]{18,22}$/)})),(e=>({type:"urlEncodedObject",base:e.object(),coerce:e=>({value:m.parse(e)})})),(e=>({type:"jsonObject",base:e.object(),coerce(e){try{return{value:JSON.parse(e)}}catch(e){return null}},validate:(e,r)=>e?{value:e}:{value:e,errors:r.error("json.valid")}})),(e=>({type:"delimitedArray",base:e.array().default([]),coerce:e=>({value:e.split?e.split(","):e})})),(e=>({type:"queryStringParameters",messages:"Missing query parameters",base:e.object().required()})),(e=>({type:"date",base:e.date(),prepare(e,t){try{const t=r.tz(e,"UTC");if(t.isValid())return{value:t.toDate()}}catch(e){return t.error("any.invalid")}}})),(e=>({type:"jsonArray",base:e.array(),coerce(e){try{return{value:JSON.parse(e)}}catch(e){return{value:null}}},validate:(e,r)=>Array.isArray(e)?{value:e}:{value:e,errors:r.error("jsonArray.schema")}})),(e=>({type:"base64ThenUriEncodedObject",base:e.object(),coerce(e){try{const r=decodeURIComponent(Buffer.from(e,"base64").toString());return{value:JSON.parse(r)}}catch(e){return null}},validate:(e,r)=>e?{value:e}:{value:e,errors:r.error("json.valid")}})));class w extends Error{}class E extends w{code=400;statusCode=400;name="BadRequestError"}class f extends Error{code;statusCode}class C extends w{code=401;statusCode=401;name="UnauthorizedError"}const A=({scope:e,type:r}={})=>g.object({clientId:g.number(),resources:y.object({}),scope:e?g.string().pattern(new RegExp(`${e}`)).error((()=>new C(`missing scope ${e}`))):g.optional(),type:r?g.any().valid(r).error((()=>new C(`missing user type ${r}`))):g.optional(),enterprise:g.boolean().default(!1),maintenanceModule:g.boolean().default(!1),billingMethod:g.string().optional(),customerSegment:g.string().optional(),securityGroupTagId:g.number().optional().allow(null)}),q=g.object({authorizer:A()}),j=(e={})=>g.object({authorizer:A(e)}),O=(r,t,s)=>{if(!t)return e.logger.warn("skipping validation"),r;const{error:o,value:a}=t.validate(r,{allowUnknown:s?.allowUnknown||!0,errors:{label:"key",wrap:{label:!1}}});if(o)throw e.logger.error({error:o},"Validation error"),o.isJoi?new E(o.message):o;return a},R=h.object({requestContext:j()}),S={"Content-Type":"application/json","Access-Control-Allow-Origin":"*","Access-Control-Allow-Credentials":!0},I=(e,r,t)=>({success:e<400,message:r,result:t||void 0}),N=({statusCode:e=200,message:r="ok",data:t,headers:s={},rawResult:o=!1,stringifyBody:a=!0})=>{const n=o?t:I(e,r,t),i=a?n&&JSON.stringify(n):t;return{headers:{...S,...s},statusCode:e,body:i}};const _="_X_AMZN_TRACE_ID",T="x-correlation-",P=`${T}id`,M=`${T}trace-id`,z={before:async({event:r,context:t})=>{const s={awsRequestId:t.awsRequestId},o=r.requestContext?.requestId;o&&(s.apiRequestId=o),r.headers&&Object.keys(r.headers).forEach((e=>{e.toLowerCase().startsWith(T)&&(s[e]=r.headers[e])})),process.env[_]&&(s[M]=process.env[_]),s[P]||(s[P]=t.awsRequestId),e.logger.setHapnContext(s)}},H=d({omitPaths:["event.multiValueHeaders","event.multiValueQueryStringParameters"],logger:r=>{const t=r?.event?"event":"response";e.logger.info(r.event??r.response,t)}}),G={isWarmingUp:e=>"serverless-plugin-warmup"===e.source},$=(e={})=>{const r={...G,...e};return{before:e=>{if(r.isWarmingUp(e.event))return"warmup"}}},W=[$(),z,H],U=[l({serializers:[{regex:/^application\/xml$/,serializer:({body:e})=>`<message>${e}</message>`},{regex:/^application\/json$/,serializer:({body:e})=>JSON.stringify(e)},{regex:/^text\/plain$/,serializer:({body:e})=>e}],default:"application/json"}),{after:e=>{e.response=N(e.response)},onError:r=>{e.logger.error(r.error,"Request failed"),r.response=N({statusCode:r.error.code||500,message:r.error.message||"Error"})}}];const k=()=>"test"===process.env.NODE_ENV?"test":process.env.IS_OFFLINE&&"dev"===process.env.STAGE?"local":process.env.STAGE??process.env.NODE_ENV??"dev";Object.defineProperty(exports,"logger",{enumerable:!0,get:function(){return e.logger}}),Object.defineProperty(exports,"withRequest",{enumerable:!0,get:function(){return e.withRequest}}),exports.httpErrorHandler=i,exports.httpResponseSerializer=l,exports.sqsJsonBodyParser=c,exports.merge=u,exports.BadRequestError=E,exports.BaseError=f,exports.ConflictError=class extends w{code=409;statusCode=409;name="ConflictError"},exports.ForbiddenError=class extends w{code=403;statusCode=403;name="ForbiddenError"},exports.HttpError=w,exports.LambdaCache=class{collectionName;constructor(e){this.collectionName=e??`${process.env.AWS_LAMBDA_FUNCTION_NAME}-${process.env.AWS_LAMBDA_FUNCTION_VERSION}`,global.CACHE_STORAGE||(global.CACHE_STORAGE={}),global.CACHE_STORAGE[this.collectionName]||(global.CACHE_STORAGE[this.collectionName]=new Map)}set(e,r,t){const s=1e3*t+Date.now();global.CACHE_STORAGE[this.collectionName].set(e,{value:r,expire:s})}get(e){if(!e)throw new Error("key is required!");const r=global.CACHE_STORAGE[this.collectionName].get(e);return r?!r.expire||r.expire>Date.now()?r.value:this.remove(e):null}remove(e){global.CACHE_STORAGE[this.collectionName].get(e)&&global.CACHE_STORAGE[this.collectionName].delete(e)}},exports.NotFoundError=class extends w{code=404;statusCode=404;name="NotFoundError"},exports.SpytecJoi=h,exports.UnauthorizedError=C,exports.apiGatewayEventWrapper=async({event:r,context:t,schema:s,handler:o})=>{r&&t&&e.withRequest(r,t);try{const e=O(r,s),t=await o(e);return N(t)}catch(t){return e.logger.error({err:t,event:(a=r,{resource:a.resource,httpMethod:a.httpMethod,queryStringParameters:a.queryStringParameters,pathParameters:a.pathParameters,body:a.body})},"apiGatewayWrapper - caught error"),N({statusCode:t.code||500,message:t.message||"Error"})}var a},exports.apiGatewayMiddlewares=U,exports.apiGatewayMiddy=e=>n(e).use([...W,...U]),exports.baseMiddlewares=W,exports.buildProxyResult=N,exports.buildResponseBody=I,exports.defaultApiSchema=R,exports.getAuthorizerValidator=A,exports.getEnvKey=k,exports.getRequestContextValidator=j,exports.iccidSchema=x,exports.imeiSchema=b,exports.isDev=()=>"dev"===k(),exports.isLocal=()=>"local"===k(),exports.isProduction=()=>"prod"===k(),exports.isTest=()=>"test"===k(),exports.json=y,exports.middy=e=>n(e).use([...W]),exports.promiseWithCache=async(e,r,t,s)=>{let o=r.get(t);return o||(o=await e(),r.set(t,o,s)),o},exports.promiseWithTimeout=(e,r,t=new Error("Promise timed out"))=>{const s=new Promise(((e,s)=>{setTimeout((()=>{s(t)}),r)}));return Promise.race([e,s])},exports.requestContextValidator=q,exports.setupEnvConfig=e=>{const r=e.base,t=e[k()]??{};return u(r,t)},exports.sqsEventWrapper=async({event:r,context:t,schema:s,handler:o,singleHandler:a,mode:n="serial"})=>{r&&t&&e.withRequest(r,t);try{const e=O(r,s);await async function(e,r,t,s){if(!r&&!t)throw new Error("handler or singleHandler not defined");if(r)await r(e);else if(t){const r=e.Records;if("serial"===s)for(const e of r)await t(e);else"parallel"===s&&await Promise.all(r.map((e=>t(e))))}}(e,o,a,n)}catch(t){throw e.logger.error({err:t,event:(i=r,(i.Records||[]).map((e=>({messageId:e.messageId,body:e.body,messageAttributes:e.messageAttributes}))))},"sqsEventWrapper - caught error"),t}var i},exports.sqsEventWrapperWithReturn=async({event:r,context:t,schema:s,handler:o,singleHandler:a,mode:n="serial"})=>{r&&t&&e.withRequest(r,t);try{const e=O(r,s);return await(async(e,r,t,s)=>{if(!r&&!t)throw new Error("handler or singleHandler not defined");if(r)return await r(e);if(t){const r=e.Records;if("serial"===s){const e=[];for(const s of r){const r=await t(s);e.push(r)}return e}if("parallel"===s)return await Promise.all(r.map((e=>t(e))))}})(e,o,a,n)}catch(t){throw e.logger.error({err:t,event:(i=r,(i.Records||[]).map((e=>({messageId:e.messageId,body:e.body,messageAttributes:e.messageAttributes}))))},"sqsEventWrapper - caught error"),t}var i},exports.urlEncoded=v,exports.validateEvent=O,exports.validatorMiddleware=({schema:r,allowUnknown:t=!0})=>({before:s=>{const{error:o,value:a}=r.validate(s.event,{allowUnknown:t,errors:{label:"key",wrap:{label:!1}}});if(o)throw e.logger.error("Validation error",{error:o}),o.isJoi?new E(o.message):o;s.event=a}}),exports.warmupMiddleware=$;
1
+ "use strict";var e=require("@spytecgps/sdk-logger"),r=require("dayjs"),t=require("dayjs/plugin/timezone"),s=require("dayjs/plugin/utc"),o=require("joi"),a=require("qs"),n=require("@middy/core"),i=require("@middy/http-error-handler"),l=require("@middy/http-response-serializer"),d=require("@middy/sqs-json-body-parser"),c=require("deepmerge"),u=require("@middy/input-output-logger");function p(e){var r=Object.create(null);return e&&Object.keys(e).forEach((function(t){if("default"!==t){var s=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,s.get?s:{enumerable:!0,get:function(){return e[t]}})}})),r.default=e,Object.freeze(r)}var g=p(o),v=p(a);r.extend(s),r.extend(t);const m=g.extend((e=>({type:"object",base:e.object(),messages:{"json.valid":"must be valid JSON"},coerce(e){try{return{value:JSON.parse(e)}}catch(e){return null}},validate:(e,r)=>e?{value:e}:{value:e,errors:r.error("json.valid")}}))),x=g.extend((e=>({type:"object",base:e.object(),coerce:e=>({value:v.parse(e)})}))),y=g.string().regex(/^\d{15,16}$/).message("Invalid IMEI"),h=g.string().regex(/^[0-9A-Za-z]{18,22}$/).message("Invalid ICCID"),b=g.extend((e=>({type:"imei",messages:"Invalid IMEI",base:e.string().regex(/^\d{15,16}$/)})),(e=>({type:"iccid",messages:"Invalid ICCID",base:e.string().regex(/^[0-9A-Za-z]{18,22}$/)})),(e=>({type:"urlEncodedObject",base:e.object(),coerce:e=>({value:v.parse(e)})})),(e=>({type:"jsonObject",base:e.object(),coerce(e){try{return{value:JSON.parse(e)}}catch(e){return null}},validate:(e,r)=>e?{value:e}:{value:e,errors:r.error("json.valid")}})),(e=>({type:"delimitedArray",base:e.array().default([]),coerce:e=>({value:e.split?e.split(","):e})})),(e=>({type:"queryStringParameters",messages:"Missing query parameters",base:e.object().required()})),(e=>({type:"date",base:e.date(),prepare(e,t){try{const t=r.tz(e,"UTC");if(t.isValid())return{value:t.toDate()}}catch(e){return t.error("any.invalid")}}})),(e=>({type:"jsonArray",base:e.array(),coerce(e){try{return{value:JSON.parse(e)}}catch(e){return{value:null}}},validate:(e,r)=>Array.isArray(e)?{value:e}:{value:e,errors:r.error("jsonArray.schema")}})),(e=>({type:"base64ThenUriEncodedObject",base:e.object(),coerce(e){try{const r=decodeURIComponent(Buffer.from(e,"base64").toString());return{value:JSON.parse(r)}}catch(e){return null}},validate:(e,r)=>e?{value:e}:{value:e,errors:r.error("json.valid")}})));class E extends Error{}class w extends E{code=400;statusCode=400;name="BadRequestError"}class C extends Error{code;statusCode}class q extends E{code=401;statusCode=401;name="UnauthorizedError"}const f=({scope:e,type:r}={})=>g.object({clientId:g.number(),resources:m.object({}),scope:e?g.string().pattern(new RegExp(`${e}`)).error((()=>new q(`missing scope ${e}`))):g.optional(),type:r?g.any().valid(r).error((()=>new q(`missing user type ${r}`))):g.optional(),enterprise:g.boolean().default(!1),maintenanceModule:g.boolean().default(!1),billingMethod:g.string().optional(),customerSegment:g.string().optional(),securityGroupTagId:g.number().optional().allow(null)}),A=g.object({authorizer:f()}),j=(e={})=>g.object({authorizer:f(e)}),I=(r,t,s)=>{if(!t)return e.logger.warn("skipping validation"),r;const{error:o,value:a}=t.validate(r,{allowUnknown:s?.allowUnknown||!0,errors:{label:"key",wrap:{label:!1}}});if(o)throw e.logger.error({error:o},"Validation error"),o.isJoi?new w(o.message):o;return a},R=b.object({requestContext:j()}),O={"Content-Type":"application/json","Access-Control-Allow-Origin":"*","Access-Control-Allow-Credentials":!0},S=(e,r,t)=>({success:e<400,message:r,result:t||void 0}),N=({statusCode:e=200,message:r="ok",data:t,headers:s={},rawResult:o=!1,stringifyBody:a=!0})=>{const n=o?t:S(e,r,t),i=a?n&&JSON.stringify(n):t;return{headers:{...O,...s},statusCode:e,body:i}};const T=()=>"test"===process.env.NODE_ENV?"test":process.env.IS_OFFLINE&&"dev"===process.env.STAGE?"local":process.env.STAGE??process.env.NODE_ENV??"dev",_=()=>"local"===T(),M=()=>"test"===T(),P="_X_AMZN_TRACE_ID",z="x-correlation-",H=`${z}id`,G=`${z}trace-id`,$={before:async({event:r,context:t})=>{const s={awsRequestId:t.awsRequestId},o=r.requestContext?.requestId;o&&(s.apiRequestId=o),r.headers&&Object.keys(r.headers).forEach((e=>{e.toLowerCase().startsWith(z)&&(s[e]=r.headers[e])})),process.env[P]&&(s[G]=process.env[P]),s[H]||(s[H]=t.awsRequestId),e.logger.setHapnContext(s)}},W=u({omitPaths:["event.multiValueHeaders","event.multiValueQueryStringParameters","event.resource","event.httpMethod","event.headers","event.stageVariables","event.requestContext.resourceId","event.requestContext.resourcePath","event.requestContext.httpMethod","event.requestContext.extendedRequestId","event.requestContext.requestTime","event.requestContext.path","event.requestContext.accountId","event.requestContext.protocol","event.requestContext.stage","event.requestContext.domainPrefix","event.requestContext.requestTimeEpoch","event.requestContext.apiId","event.requestContext.domainName","event.requestContext.identity","event.isBase64Encoded","event.body","response.body","response.headers"],logger:r=>{const t=r?.event?"event":"response";e.logger.info(r.event??r.response,t)}}),U={isWarmingUp:e=>"serverless-plugin-warmup"===e.source},k=(e={})=>{const r={...U,...e};return{before:e=>{if(r.isWarmingUp(e.event))return"warmup"}}},D=[k(),$,_()||M()?void 0:W].filter(Boolean),V=[l({serializers:[{regex:/^application\/xml$/,serializer:({body:e})=>`<message>${e}</message>`},{regex:/^application\/json$/,serializer:({body:e})=>JSON.stringify(e)},{regex:/^text\/plain$/,serializer:({body:e})=>e}],default:"application/json"}),{after:e=>{e.response=N(e.response)},onError:r=>{e.logger.error(r.error,"Request failed"),r.response=N({statusCode:r.error.code||500,message:r.error.message||"Error"})}}];exports.httpErrorHandler=i,exports.httpResponseSerializer=l,exports.sqsJsonBodyParser=d,exports.merge=c,exports.BadRequestError=w,exports.BaseError=C,exports.ConflictError=class extends E{code=409;statusCode=409;name="ConflictError"},exports.ForbiddenError=class extends E{code=403;statusCode=403;name="ForbiddenError"},exports.HttpError=E,exports.LambdaCache=class{collectionName;constructor(e){this.collectionName=e??`${process.env.AWS_LAMBDA_FUNCTION_NAME}-${process.env.AWS_LAMBDA_FUNCTION_VERSION}`,global.CACHE_STORAGE||(global.CACHE_STORAGE={}),global.CACHE_STORAGE[this.collectionName]||(global.CACHE_STORAGE[this.collectionName]=new Map)}set(e,r,t){const s=1e3*t+Date.now();global.CACHE_STORAGE[this.collectionName].set(e,{value:r,expire:s})}get(e){if(!e)throw new Error("key is required!");const r=global.CACHE_STORAGE[this.collectionName].get(e);return r?!r.expire||r.expire>Date.now()?r.value:this.remove(e):null}remove(e){global.CACHE_STORAGE[this.collectionName].get(e)&&global.CACHE_STORAGE[this.collectionName].delete(e)}},exports.NotFoundError=class extends E{code=404;statusCode=404;name="NotFoundError"},exports.SpytecJoi=b,exports.UnauthorizedError=q,exports.apiGatewayEventWrapper=async({event:r,context:t,schema:s,handler:o})=>{r&&t&&e.withRequest(r,t);try{const e=I(r,s),t=await o(e);return N(t)}catch(t){return e.logger.error({err:t,event:(a=r,{resource:a.resource,httpMethod:a.httpMethod,queryStringParameters:a.queryStringParameters,pathParameters:a.pathParameters,body:a.body})},"apiGatewayWrapper - caught error"),N({statusCode:t.code||500,message:t.message||"Error"})}var a},exports.apiGatewayMiddlewares=V,exports.apiGatewayMiddy=e=>n(e).use([...D,...V]),exports.baseMiddlewares=D,exports.buildProxyResult=N,exports.buildResponseBody=S,exports.defaultApiSchema=R,exports.getAuthorizerValidator=f,exports.getEnvKey=T,exports.getRequestContextValidator=j,exports.iccidSchema=h,exports.imeiSchema=y,exports.isDev=()=>"dev"===T(),exports.isLocal=_,exports.isProduction=()=>"prod"===T(),exports.isTest=M,exports.json=m,exports.middy=e=>n(e).use([...D]),exports.promiseWithCache=async(e,r,t,s)=>{let o=r.get(t);return o||(o=await e(),r.set(t,o,s)),o},exports.promiseWithTimeout=(e,r,t=new Error("Promise timed out"))=>{const s=new Promise(((e,s)=>{setTimeout((()=>{s(t)}),r)}));return Promise.race([e,s])},exports.requestContextValidator=A,exports.setupEnvConfig=e=>{const r=e.base,t=e[T()]??{};return c(r,t)},exports.sqsEventWrapper=async({event:r,context:t,schema:s,handler:o,singleHandler:a,mode:n="serial"})=>{r&&t&&e.withRequest(r,t);try{const e=I(r,s);await async function(e,r,t,s){if(!r&&!t)throw new Error("handler or singleHandler not defined");if(r)await r(e);else if(t){const r=e.Records;if("serial"===s)for(const e of r)await t(e);else"parallel"===s&&await Promise.all(r.map((e=>t(e))))}}(e,o,a,n)}catch(t){throw e.logger.error({err:t,event:(i=r,(i.Records||[]).map((e=>({messageId:e.messageId,body:e.body,messageAttributes:e.messageAttributes}))))},"sqsEventWrapper - caught error"),t}var i},exports.sqsEventWrapperWithReturn=async({event:r,context:t,schema:s,handler:o,singleHandler:a,mode:n="serial"})=>{r&&t&&e.withRequest(r,t);try{const e=I(r,s);return await(async(e,r,t,s)=>{if(!r&&!t)throw new Error("handler or singleHandler not defined");if(r)return await r(e);if(t){const r=e.Records;if("serial"===s){const e=[];for(const s of r){const r=await t(s);e.push(r)}return e}if("parallel"===s)return await Promise.all(r.map((e=>t(e))))}})(e,o,a,n)}catch(t){throw e.logger.error({err:t,event:(i=r,(i.Records||[]).map((e=>({messageId:e.messageId,body:e.body,messageAttributes:e.messageAttributes}))))},"sqsEventWrapper - caught error"),t}var i},exports.urlEncoded=x,exports.validateEvent=I,exports.validatorMiddleware=({schema:r,allowUnknown:t=!0})=>({before:s=>{const{error:o,value:a}=r.validate(s.event,{allowUnknown:t,errors:{label:"key",wrap:{label:!1}}});if(o)throw e.logger.error("Validation error",{error:o}),o.isJoi?new w(o.message):o;s.event=a}}),exports.warmupMiddleware=k;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spytecgps/lambda-utils",
3
- "version": "2.3.5",
3
+ "version": "2.3.7",
4
4
  "description": "Lambda Utils",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -19,7 +19,7 @@
19
19
  },
20
20
  "repository": {
21
21
  "type": "git",
22
- "url": "git+https://github.com/spytecgps/lambda-utils"
22
+ "url": "git+https://github.com/spytecgps/lambda-utils.git"
23
23
  },
24
24
  "author": "@eliyahud",
25
25
  "license": "ISC",