@middy/util
Advanced tools
Comparing version 3.0.0-alpha.6 to 3.0.0-alpha.7
284
index.js
@@ -1,283 +0,3 @@ | ||
import { Agent } from 'https'; | ||
export const awsClientDefaultOptions = { | ||
httpOptions: { | ||
agent: new Agent({ | ||
secureProtocol: 'TLSv1_2_method' | ||
}) | ||
} | ||
}; | ||
export const createPrefetchClient = options => { | ||
const awsClientOptions = { ...awsClientDefaultOptions, | ||
...options.awsClientOptions | ||
}; | ||
const client = new options.AwsClient(awsClientOptions); | ||
import{Agent}from'https';var _response;export const awsClientDefaultOptions={httpOptions:{agent:new Agent({secureProtocol:'TLSv1_2_method'})}};export const createPrefetchClient=options=>{const awsClientOptions={...awsClientDefaultOptions,...options.awsClientOptions};const client=new options.AwsClient(awsClientOptions);if(options.awsClientCapture&&options.disablePrefetch){return options.awsClientCapture(client)}else if(options.awsClientCapture){console.warn('Unable to apply X-Ray outside of handler invocation scope.')}return client};export const createClient=async(options,request)=>{let awsClientCredentials={};if(options.awsClientAssumeRole){if(!request){throw new Error('Request required when assuming role')}awsClientCredentials=await getInternal({credentials:options.awsClientAssumeRole},request)}awsClientCredentials={...awsClientCredentials,...options.awsClientOptions};return createPrefetchClient({...options,awsClientOptions:awsClientCredentials})};export const canPrefetch=(options={})=>{return!options.awsClientAssumeRole&&!options.disablePrefetch};export const getInternal=async(variables,request)=>{if(!variables||!request)return{};let keys=[];let values=[];if(variables===true){keys=values=Object.keys(request.internal)}else if(typeof variables==='string'){keys=values=[variables]}else if(Array.isArray(variables)){keys=values=variables}else if(typeof variables==='object'){keys=Object.keys(variables);values=Object.values(variables)}const promises=[];for(const internalKey of values){const pathOptionKey=internalKey.split('.');const rootOptionKey=pathOptionKey.shift();let valuePromise=request.internal[rootOptionKey];if(!isPromise(valuePromise)){valuePromise=Promise.resolve(valuePromise)}promises.push(valuePromise.then(value=>pathOptionKey.reduce((p,c)=>p?.[c],value)))}values=await Promise.allSettled(promises);const errors=values.filter(res=>res.status==='rejected').map(res=>res.reason);if(errors.length){const error=new Error('Failed to resolve internal values');error.cause=errors;throw error}return keys.reduce((obj,key,index)=>({...obj,[sanitizeKey(key)]:values[index].value}),{})};const isPromise=promise=>typeof promise?.then==='function';const sanitizeKeyPrefixLeadingNumber=/^([0-9])/;const sanitizeKeyRemoveDisallowedChar=/[^a-zA-Z0-9]+/g;export const sanitizeKey=key=>{return key.replace(sanitizeKeyPrefixLeadingNumber,'_$1').replace(sanitizeKeyRemoveDisallowedChar,'_')};const cache={};export const processCache=(options,fetch=()=>undefined,request)=>{const{cacheExpiry,cacheKey}=options;if(cacheExpiry){const cached=getCache(cacheKey);const unexpired=cached.expiry&&(cacheExpiry<0||cached.expiry>Date.now());if(unexpired&&cached.modified){const value=fetch(request,cached.value);cache[cacheKey]={value:{...cached.value,...value},expiry:cached.expiry};return cache[cacheKey]}if(unexpired){return{...cached,cache:true}}}const value=fetch(request);const expiry=Date.now()+cacheExpiry;if(cacheExpiry){cache[cacheKey]={value,expiry}}return{value,expiry}};export const getCache=key=>{if(!cache[key])return{};return cache[key]};export const modifyCache=(cacheKey,value)=>{if(!cache[cacheKey])return;cache[cacheKey]={...cache[cacheKey],value,modified:true}};export const clearCache=(keys=null)=>{keys=keys??Object.keys(cache);if(!Array.isArray(keys))keys=[keys];for(const cacheKey of keys){cache[cacheKey]=undefined}};export const jsonSafeParse=(text,reviver)=>{if(typeof text!=='string')return text;const firstChar=text[0];if(firstChar!=='{'&&firstChar!=='['&&firstChar!=='"')return text;try{return JSON.parse(text,reviver)}catch(e){}return text};export const jsonSafeStringify=(value,replacer,space)=>{try{return JSON.stringify(value,replacer,space)}catch(e){}return value};export const normalizeHttpResponse=request=>{let{response}=request;if(response===undefined){response={}}else if(response?.statusCode===undefined&&response?.body===undefined&&response?.headers===undefined){response={body:response}}(_response=response).headers??(_response.headers={});request.response=response;return response};const createErrorRegexp=/[^a-zA-Z]/g;export class HttpError extends Error{constructor(code,message,options={}){if(message&& typeof message!=='string'){options=message;message=undefined}message??(message=httpErrorCodes[code]);super(message);this.cause=options.cause;const name=httpErrorCodes[code].replace(createErrorRegexp,'');this.name=name.substr(-5)!=='Error'?name+'Error':name;this.status=this.statusCode=code;this.expose=options.expose??code<500}}export const createError=(code,message,properties={})=>{return new HttpError(code,message,properties)};const httpErrorCodes={100:'Continue',101:'Switching Protocols',102:'Processing',103:'Early Hints',200:'OK',201:'Created',202:'Accepted',203:'Non-Authoritative Information',204:'No Content',205:'Reset Content',206:'Partial Content',207:'Multi-Status',208:'Already Reported',226:'IM Used',300:'Multiple Choices',301:'Moved Permanently',302:'Found',303:'See Other',304:'Not Modified',305:'Use Proxy',306:'(Unused)',307:'Temporary Redirect',308:'Permanent Redirect',400:'Bad Request',401:'Unauthorized',402:'Payment Required',403:'Forbidden',404:'Not Found',405:'Method Not Allowed',406:'Not Acceptable',407:'Proxy Authentication Required',408:'Request Timeout',409:'Conflict',410:'Gone',411:'Length Required',412:'Precondition Failed',413:'Payload Too Large',414:'URI Too Long',415:'Unsupported Media Type',416:'Range Not Satisfiable',417:'Expectation Failed',418:"I'm a teapot",421:'Misdirected Request',422:'Unprocessable Entity',423:'Locked',424:'Failed Dependency',425:'Unordered Collection',426:'Upgrade Required',428:'Precondition Required',429:'Too Many Requests',431:'Request Header Fields Too Large',451:'Unavailable For Legal Reasons',500:'Internal Server Error',501:'Not Implemented',502:'Bad Gateway',503:'Service Unavailable',504:'Gateway Timeout',505:'HTTP Version Not Supported',506:'Variant Also Negotiates',507:'Insufficient Storage',508:'Loop Detected',509:'Bandwidth Limit Exceeded',510:'Not Extended',511:'Network Authentication Required'} | ||
if (options.awsClientCapture && options.disablePrefetch) { | ||
return options.awsClientCapture(client); | ||
} else if (options.awsClientCapture) { | ||
console.warn('Unable to apply X-Ray outside of handler invocation scope.'); | ||
} | ||
return client; | ||
}; | ||
export const createClient = async (options, request) => { | ||
let awsClientCredentials = {}; | ||
if (options.awsClientAssumeRole) { | ||
if (!request) { | ||
throw new Error('Request required when assuming role'); | ||
} | ||
awsClientCredentials = await getInternal({ | ||
credentials: options.awsClientAssumeRole | ||
}, request); | ||
} | ||
awsClientCredentials = { ...awsClientCredentials, | ||
...options.awsClientOptions | ||
}; | ||
return createPrefetchClient({ ...options, | ||
awsClientOptions: awsClientCredentials | ||
}); | ||
}; | ||
export const canPrefetch = (options = {}) => { | ||
return !options.awsClientAssumeRole && !options.disablePrefetch; | ||
}; | ||
export const getInternal = async (variables, request) => { | ||
if (!variables || !request) return {}; | ||
let keys = []; | ||
let values = []; | ||
if (variables === true) { | ||
keys = values = Object.keys(request.internal); | ||
} else if (typeof variables === 'string') { | ||
keys = values = [variables]; | ||
} else if (Array.isArray(variables)) { | ||
keys = values = variables; | ||
} else if (typeof variables === 'object') { | ||
keys = Object.keys(variables); | ||
values = Object.values(variables); | ||
} | ||
const promises = []; | ||
for (const internalKey of values) { | ||
const pathOptionKey = internalKey.split('.'); | ||
const rootOptionKey = pathOptionKey.shift(); | ||
let valuePromise = request.internal[rootOptionKey]; | ||
if (!isPromise(valuePromise)) { | ||
valuePromise = Promise.resolve(valuePromise); | ||
} | ||
promises.push(valuePromise.then(value => pathOptionKey.reduce((p, c) => p === null || p === void 0 ? void 0 : p[c], value))); | ||
} | ||
values = await Promise.allSettled(promises); | ||
const errors = values.filter(res => res.status === 'rejected').map(res => res.reason); | ||
if (errors.length) { | ||
const error = new Error('Failed to resolve internal values'); | ||
error.cause = errors; | ||
throw error; | ||
} | ||
return keys.reduce((obj, key, index) => ({ ...obj, | ||
[sanitizeKey(key)]: values[index].value | ||
}), {}); | ||
}; | ||
const isPromise = promise => typeof (promise === null || promise === void 0 ? void 0 : promise.then) === 'function'; | ||
const sanitizeKeyPrefixLeadingNumber = /^([0-9])/; | ||
const sanitizeKeyRemoveDisallowedChar = /[^a-zA-Z0-9]+/g; | ||
export const sanitizeKey = key => { | ||
return key.replace(sanitizeKeyPrefixLeadingNumber, '_$1').replace(sanitizeKeyRemoveDisallowedChar, '_'); | ||
}; | ||
const cache = {}; | ||
export const processCache = (options, fetch = () => undefined, request) => { | ||
const { | ||
cacheExpiry, | ||
cacheKey | ||
} = options; | ||
if (cacheExpiry) { | ||
const cached = getCache(cacheKey); | ||
const unexpired = cached.expiry && (cacheExpiry < 0 || cached.expiry > Date.now()); | ||
if (unexpired && cached.modified) { | ||
const value = fetch(request, cached.value); | ||
cache[cacheKey] = { | ||
value: { ...cached.value, | ||
...value | ||
}, | ||
expiry: cached.expiry | ||
}; | ||
return cache[cacheKey]; | ||
} | ||
if (unexpired) { | ||
return { ...cached, | ||
cache: true | ||
}; | ||
} | ||
} | ||
const value = fetch(request); | ||
const expiry = Date.now() + cacheExpiry; | ||
if (cacheExpiry) { | ||
cache[cacheKey] = { | ||
value, | ||
expiry | ||
}; | ||
} | ||
return { | ||
value, | ||
expiry | ||
}; | ||
}; | ||
export const getCache = key => { | ||
if (!cache[key]) return {}; | ||
return cache[key]; | ||
}; | ||
export const modifyCache = (cacheKey, value) => { | ||
if (!cache[cacheKey]) return; | ||
cache[cacheKey] = { ...cache[cacheKey], | ||
value, | ||
modified: true | ||
}; | ||
}; | ||
export const clearCache = (keys = null) => { | ||
keys = keys ?? Object.keys(cache); | ||
if (!Array.isArray(keys)) keys = [keys]; | ||
for (const cacheKey of keys) { | ||
cache[cacheKey] = undefined; | ||
} | ||
}; | ||
export const jsonSafeParse = (text, reviver) => { | ||
if (typeof text !== 'string') return text; | ||
const firstChar = text[0]; | ||
if (firstChar !== '{' && firstChar !== '[' && firstChar !== '"') return text; | ||
try { | ||
return JSON.parse(text, reviver); | ||
} catch (e) {} | ||
return text; | ||
}; | ||
export const jsonSafeStringify = (value, replacer, space) => { | ||
try { | ||
return JSON.stringify(value, replacer, space); | ||
} catch (e) {} | ||
return value; | ||
}; | ||
export const normalizeHttpResponse = request => { | ||
var _response, _response2, _response3, _response4; | ||
let { | ||
response | ||
} = request; | ||
if (response === undefined) { | ||
response = {}; | ||
} else if (((_response = response) === null || _response === void 0 ? void 0 : _response.statusCode) === undefined && ((_response2 = response) === null || _response2 === void 0 ? void 0 : _response2.body) === undefined && ((_response3 = response) === null || _response3 === void 0 ? void 0 : _response3.headers) === undefined) { | ||
response = { | ||
body: response | ||
}; | ||
} | ||
(_response4 = response).headers ?? (_response4.headers = {}); | ||
request.response = response; | ||
return response; | ||
}; | ||
const createErrorRegexp = /[^a-zA-Z]/g; | ||
export class HttpError extends Error { | ||
constructor(code, message, options = {}) { | ||
if (message && typeof message !== 'string') { | ||
options = message; | ||
message = undefined; | ||
} | ||
message ?? (message = httpErrorCodes[code]); | ||
super(message); | ||
this.cause = options.cause; | ||
const name = httpErrorCodes[code].replace(createErrorRegexp, ''); | ||
this.name = name.substr(-5) !== 'Error' ? name + 'Error' : name; | ||
this.status = this.statusCode = code; | ||
this.expose = options.expose ?? code < 500; | ||
} | ||
} | ||
export const createError = (code, message, properties = {}) => { | ||
return new HttpError(code, message, properties); | ||
}; | ||
const httpErrorCodes = { | ||
100: 'Continue', | ||
101: 'Switching Protocols', | ||
102: 'Processing', | ||
103: 'Early Hints', | ||
200: 'OK', | ||
201: 'Created', | ||
202: 'Accepted', | ||
203: 'Non-Authoritative Information', | ||
204: 'No Content', | ||
205: 'Reset Content', | ||
206: 'Partial Content', | ||
207: 'Multi-Status', | ||
208: 'Already Reported', | ||
226: 'IM Used', | ||
300: 'Multiple Choices', | ||
301: 'Moved Permanently', | ||
302: 'Found', | ||
303: 'See Other', | ||
304: 'Not Modified', | ||
305: 'Use Proxy', | ||
306: '(Unused)', | ||
307: 'Temporary Redirect', | ||
308: 'Permanent Redirect', | ||
400: 'Bad Request', | ||
401: 'Unauthorized', | ||
402: 'Payment Required', | ||
403: 'Forbidden', | ||
404: 'Not Found', | ||
405: 'Method Not Allowed', | ||
406: 'Not Acceptable', | ||
407: 'Proxy Authentication Required', | ||
408: 'Request Timeout', | ||
409: 'Conflict', | ||
410: 'Gone', | ||
411: 'Length Required', | ||
412: 'Precondition Failed', | ||
413: 'Payload Too Large', | ||
414: 'URI Too Long', | ||
415: 'Unsupported Media Type', | ||
416: 'Range Not Satisfiable', | ||
417: 'Expectation Failed', | ||
418: "I'm a teapot", | ||
421: 'Misdirected Request', | ||
422: 'Unprocessable Entity', | ||
423: 'Locked', | ||
424: 'Failed Dependency', | ||
425: 'Unordered Collection', | ||
426: 'Upgrade Required', | ||
428: 'Precondition Required', | ||
429: 'Too Many Requests', | ||
431: 'Request Header Fields Too Large', | ||
451: 'Unavailable For Legal Reasons', | ||
500: 'Internal Server Error', | ||
501: 'Not Implemented', | ||
502: 'Bad Gateway', | ||
503: 'Service Unavailable', | ||
504: 'Gateway Timeout', | ||
505: 'HTTP Version Not Supported', | ||
506: 'Variant Also Negotiates', | ||
507: 'Insufficient Storage', | ||
508: 'Loop Detected', | ||
509: 'Bandwidth Limit Exceeded', | ||
510: 'Not Extended', | ||
511: 'Network Authentication Required' | ||
}; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@middy/util", | ||
"version": "3.0.0-alpha.6", | ||
"version": "3.0.0-alpha.7", | ||
"description": "🛵 The stylish Node.js middleware engine for AWS Lambda (util package)", | ||
@@ -49,3 +49,3 @@ "type": "module", | ||
"devDependencies": { | ||
"@middy/core": "^3.0.0-alpha.6", | ||
"@middy/core": "^3.0.0-alpha.7", | ||
"@types/aws-lambda": "^8.10.76", | ||
@@ -57,3 +57,3 @@ "@types/node": "^17.0.0", | ||
"homepage": "https://github.com/middyjs/middy#readme", | ||
"gitHead": "176660ed3e0716d6bfb635c77251b301e0e24720" | ||
"gitHead": "5cef39ebe49c201f97d71bb0680004de4b82cb91" | ||
} |
@@ -1,25 +0,35 @@ | ||
# Middy Util | ||
<div align="center"> | ||
<img alt="Middy logo" src="https://raw.githubusercontent.com/middyjs/middy/main/docs/img/middy-logo.png"/> | ||
</div> | ||
<div align="center"> | ||
<h1>Middy Utilities</h1> | ||
<img alt="Middy logo" src="https://raw.githubusercontent.com/middyjs/middy/main/docs/img/middy-logo.svg"/> | ||
<p><strong>Util component of the middy middleware, the stylish Node.js middleware engine for AWS Lambda</strong></p> | ||
</div> | ||
<div align="center"> | ||
<p> | ||
<a href="http://badge.fury.io/js/%40middy%2Futil"> | ||
<a href="https://www.npmjs.com/package/@middy/util?activeTab=versions"> | ||
<img src="https://badge.fury.io/js/%40middy%2Futil.svg" alt="npm version" style="max-width:100%;"> | ||
</a> | ||
<a href="https://packagephobia.com/result?p=@middy/util"> | ||
<img src="https://packagephobia.com/badge?p=@middy/util" alt="npm install size" style="max-width:100%;"> | ||
</a> | ||
<a href="https://github.com/middyjs/middy/actions"> | ||
<img src="https://github.com/middyjs/middy/workflows/Tests/badge.svg" alt="GitHub Actions test status badge" style="max-width:100%;"> | ||
</a> | ||
<br/> | ||
<a href="https://standardjs.com/"> | ||
<img src="https://img.shields.io/badge/code_style-standard-brightgreen.svg" alt="Standard Code Style" style="max-width:100%;"> | ||
</a> | ||
<a href="https://snyk.io/test/github/middyjs/middy"> | ||
<img src="https://snyk.io/test/github/middyjs/middy/badge.svg" alt="Known Vulnerabilities" data-canonical-src="https://snyk.io/test/github/middyjs/middy" style="max-width:100%;"> | ||
</a> | ||
<a href="https://standardjs.com/"> | ||
<img src="https://img.shields.io/badge/code_style-standard-brightgreen.svg" alt="Standard Code Style" style="max-width:100%;"> | ||
<a href="https://lgtm.com/projects/g/middyjs/middy/context:javascript"> | ||
<img src="https://img.shields.io/lgtm/grade/javascript/g/middyjs/middy.svg?logo=lgtm&logoWidth=18" alt="Language grade: JavaScript" style="max-width:100%;"> | ||
</a> | ||
<a href="https://bestpractices.coreinfrastructure.org/projects/5280"> | ||
<img src="https://bestpractices.coreinfrastructure.org/projects/5280/badge" alt="Core Infrastructure Initiative (CII) Best Practices" style="max-width:100%;"> | ||
</a> | ||
<br/> | ||
<a href="https://gitter.im/middyjs/Lobby"> | ||
<img src="https://badges.gitter.im/gitterHQ/gitter.svg" alt="Chat on Gitter" style="max-width:100%;"> | ||
<img src="https://badges.gitter.im/gitterHQ/gitter.svg" alt="Chat on Gitter" style="max-width:100%;"> | ||
</a> | ||
<a href="https://stackoverflow.com/questions/tagged/middy?sort=Newest&uqlId=35052"> | ||
<img src="https://img.shields.io/badge/StackOverflow-[middy]-yellow" alt="Ask questions on StackOverflow" style="max-width:100%;"> | ||
</a> | ||
</p> | ||
@@ -26,0 +36,0 @@ </div> |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
65
13269
54
4