@middy/util 2.5.3 → 3.0.0-alpha.2

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2017-2021 Luciano Mammino, will Farrell and the [Middy team](https://github.com/middyjs/middy/graphs/contributors)
3
+ Copyright (c) 2017-2022 Luciano Mammino, will Farrell and the [Middy team](https://github.com/middyjs/middy/graphs/contributors)
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -47,7 +47,7 @@ Everyone is very welcome to contribute to this repository. Feel free to [raise i
47
47
 
48
48
  ## License
49
49
 
50
- Licensed under [MIT License](LICENSE). Copyright (c) 2017-2021 Luciano Mammino, will Farrell, and the [Middy team](https://github.com/middyjs/middy/graphs/contributors).
50
+ Licensed under [MIT License](LICENSE). Copyright (c) 2017-2022 Luciano Mammino, will Farrell, and the [Middy team](https://github.com/middyjs/middy/graphs/contributors).
51
51
 
52
52
  <a href="https://app.fossa.io/projects/git%2Bgithub.com%2Fmiddyjs%2Fmiddy?ref=badge_large">
53
53
  <img src="https://app.fossa.io/api/projects/git%2Bgithub.com%2Fmiddyjs%2Fmiddy.svg?type=large" alt="FOSSA Status" style="max-width:100%;">
package/codes.js ADDED
@@ -0,0 +1,66 @@
1
+ export default {
2
+ 100: 'Continue',
3
+ 101: 'Switching Protocols',
4
+ 102: 'Processing',
5
+ 103: 'Early Hints',
6
+ 200: 'OK',
7
+ 201: 'Created',
8
+ 202: 'Accepted',
9
+ 203: 'Non-Authoritative Information',
10
+ 204: 'No Content',
11
+ 205: 'Reset Content',
12
+ 206: 'Partial Content',
13
+ 207: 'Multi-Status',
14
+ 208: 'Already Reported',
15
+ 226: 'IM Used',
16
+ 300: 'Multiple Choices',
17
+ 301: 'Moved Permanently',
18
+ 302: 'Found',
19
+ 303: 'See Other',
20
+ 304: 'Not Modified',
21
+ 305: 'Use Proxy',
22
+ 306: '(Unused)',
23
+ 307: 'Temporary Redirect',
24
+ 308: 'Permanent Redirect',
25
+ 400: 'Bad Request',
26
+ 401: 'Unauthorized',
27
+ 402: 'Payment Required',
28
+ 403: 'Forbidden',
29
+ 404: 'Not Found',
30
+ 405: 'Method Not Allowed',
31
+ 406: 'Not Acceptable',
32
+ 407: 'Proxy Authentication Required',
33
+ 408: 'Request Timeout',
34
+ 409: 'Conflict',
35
+ 410: 'Gone',
36
+ 411: 'Length Required',
37
+ 412: 'Precondition Failed',
38
+ 413: 'Payload Too Large',
39
+ 414: 'URI Too Long',
40
+ 415: 'Unsupported Media Type',
41
+ 416: 'Range Not Satisfiable',
42
+ 417: 'Expectation Failed',
43
+ 418: "I'm a teapot",
44
+ 421: 'Misdirected Request',
45
+ 422: 'Unprocessable Entity',
46
+ 423: 'Locked',
47
+ 424: 'Failed Dependency',
48
+ 425: 'Unordered Collection',
49
+ 426: 'Upgrade Required',
50
+ 428: 'Precondition Required',
51
+ 429: 'Too Many Requests',
52
+ 431: 'Request Header Fields Too Large',
53
+ 451: 'Unavailable For Legal Reasons',
54
+ 500: 'Internal Server Error',
55
+ 501: 'Not Implemented',
56
+ 502: 'Bad Gateway',
57
+ 503: 'Service Unavailable',
58
+ 504: 'Gateway Timeout',
59
+ 505: 'HTTP Version Not Supported',
60
+ 506: 'Variant Also Negotiates',
61
+ 507: 'Insufficient Storage',
62
+ 508: 'Loop Detected',
63
+ 509: 'Bandwidth Limit Exceeded',
64
+ 510: 'Not Extended',
65
+ 511: 'Network Authentication Required'
66
+ }
package/index.d.ts CHANGED
@@ -1,16 +1,14 @@
1
1
  import middy from '@middy/core'
2
- import { captureAWSClient } from 'aws-xray-sdk'
3
2
 
4
3
  interface Options<Client, ClientOptions> {
5
4
  AwsClient?: new() => Client
6
5
  awsClientOptions?: Partial<ClientOptions>
7
6
  awsClientAssumeRole?: string
8
- awsClientCapture?: typeof captureAWSClient
7
+ awsClientCapture?: (service: Client) => Client
9
8
  fetchData?: { [key: string]: string }
10
9
  disablePrefetch?: boolean
11
10
  cacheKey?: string
12
11
  cacheExpiry?: number
13
- setToEnv?: boolean
14
12
  setToContext?: boolean
15
13
  }
16
14
 
@@ -40,7 +38,7 @@ declare function clearCache (keys?: string | string[] | null): void
40
38
 
41
39
  declare function jsonSafeParse (string: string, reviver?: (key: string, value: any) => any): any
42
40
 
43
- declare function normalizeHttpResponse (response: any, fallbackResponse?: any): any
41
+ declare function normalizeHttpResponse (request: any, fallbackResponse?: any): any
44
42
 
45
43
  declare function createError (code: number, message: string, properties?: Record<string, any>): HttpError
46
44
 
package/index.js CHANGED
@@ -1,44 +1,29 @@
1
- "use strict";
2
-
3
- const {
4
- Agent
5
- } = require('https'); // const { NodeHttpHandler } = require('@aws-sdk/node-http-handler') // aws-sdk v3
6
-
7
-
8
- const awsClientDefaultOptions = {
9
- // AWS SDK v3
10
- // Docs: https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/enforcing-tls.html
11
-
12
- /* requestHandler: new NodeHttpHandler({
13
- httpsAgent: new Agent(
14
- {
15
- secureProtocol: 'TLSv1_2_method'
16
- }
17
- )
18
- }) */
19
- // Docs: https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/enforcing-tls.html
1
+ import { Agent } from 'https';
2
+ import statuses from './codes.js';
3
+ import { inherits } from 'util';
4
+ export const awsClientDefaultOptions = {
20
5
  httpOptions: {
21
6
  agent: new Agent({
22
7
  secureProtocol: 'TLSv1_2_method'
23
8
  })
24
9
  }
25
10
  };
26
-
27
- const createPrefetchClient = options => {
11
+ export const createPrefetchClient = options => {
28
12
  const awsClientOptions = { ...awsClientDefaultOptions,
29
13
  ...options.awsClientOptions
30
14
  };
31
- const client = new options.AwsClient(awsClientOptions); // AWS XRay
15
+ const client = new options.AwsClient(awsClientOptions);
32
16
 
33
- if (options.awsClientCapture) {
17
+ if (options.awsClientCapture && options.disablePrefetch) {
34
18
  return options.awsClientCapture(client);
19
+ } else if (options.awsClientCapture) {
20
+ console.warn('Unable to apply X-Ray outside of handler invocation scope.');
35
21
  }
36
22
 
37
23
  return client;
38
24
  };
39
-
40
- const createClient = async (options, request) => {
41
- let awsClientCredentials = {}; // Role Credentials
25
+ export const createClient = async (options, request) => {
26
+ let awsClientCredentials = {};
42
27
 
43
28
  if (options.awsClientAssumeRole) {
44
29
  if (!request) throw new Error('Request required when assuming role');
@@ -54,13 +39,10 @@ const createClient = async (options, request) => {
54
39
  awsClientOptions: awsClientCredentials
55
40
  });
56
41
  };
57
-
58
- const canPrefetch = options => {
59
- return !(options !== null && options !== void 0 && options.awsClientAssumeRole) && !(options !== null && options !== void 0 && options.disablePrefetch);
60
- }; // Internal Context
61
-
62
-
63
- const getInternal = async (variables, request) => {
42
+ export const canPrefetch = (options = {}) => {
43
+ return !options.awsClientAssumeRole && !options.disablePrefetch;
44
+ };
45
+ export const getInternal = async (variables, request) => {
64
46
  if (!variables || !request) return {};
65
47
  let keys = [];
66
48
  let values = [];
@@ -79,41 +61,37 @@ const getInternal = async (variables, request) => {
79
61
  const promises = [];
80
62
 
81
63
  for (const internalKey of values) {
82
- var _valuePromise;
83
-
84
- // 'internal.key.sub_value' -> { [key]: internal.key.sub_value }
85
64
  const pathOptionKey = internalKey.split('.');
86
65
  const rootOptionKey = pathOptionKey.shift();
87
66
  let valuePromise = request.internal[rootOptionKey];
88
67
 
89
- if (typeof ((_valuePromise = valuePromise) === null || _valuePromise === void 0 ? void 0 : _valuePromise.then) !== 'function') {
68
+ if (typeof valuePromise.then !== 'function') {
90
69
  valuePromise = Promise.resolve(valuePromise);
91
70
  }
92
71
 
93
72
  promises.push(valuePromise.then(value => pathOptionKey.reduce((p, c) => p === null || p === void 0 ? void 0 : p[c], value)));
94
- } // ensure promise has resolved by the time it's needed
95
- // If one of the promises throws it will bubble up to @middy/core
96
-
73
+ }
97
74
 
98
75
  values = await Promise.allSettled(promises);
99
- const errors = values.filter(res => res.status === 'rejected').map(res => res.reason.message);
100
- if (errors.length) throw new Error(JSON.stringify(errors));
76
+ const errors = values.filter(res => res.status === 'rejected').map(res => res.reason);
77
+
78
+ if (errors.length) {
79
+ const error = new Error('Failed to resolve internal values');
80
+ error.cause = errors;
81
+ throw error;
82
+ }
83
+
101
84
  return keys.reduce((obj, key, index) => ({ ...obj,
102
85
  [sanitizeKey(key)]: values[index].value
103
86
  }), {});
104
87
  };
105
-
106
88
  const sanitizeKeyPrefixLeadingNumber = /^([0-9])/;
107
89
  const sanitizeKeyRemoveDisallowedChar = /[^a-zA-Z0-9]+/g;
108
-
109
- const sanitizeKey = key => {
90
+ export const sanitizeKey = key => {
110
91
  return key.replace(sanitizeKeyPrefixLeadingNumber, '_$1').replace(sanitizeKeyRemoveDisallowedChar, '_');
111
- }; // fetch Cache
112
-
113
-
114
- const cache = {}; // key: { value:{fetchKey:Promise}, expiry }
115
-
116
- const processCache = (options, fetch = () => undefined, request) => {
92
+ };
93
+ const cache = {};
94
+ export const processCache = (options, fetch = () => undefined, request) => {
117
95
  const {
118
96
  cacheExpiry,
119
97
  cacheKey
@@ -121,7 +99,7 @@ const processCache = (options, fetch = () => undefined, request) => {
121
99
 
122
100
  if (cacheExpiry) {
123
101
  const cached = getCache(cacheKey);
124
- const unexpired = cached && (cacheExpiry < 0 || cached.expiry > Date.now());
102
+ const unexpired = cached.expiry && (cacheExpiry < 0 || cached.expiry > Date.now());
125
103
 
126
104
  if (unexpired && cached.modified) {
127
105
  const value = fetch(request, cached.value);
@@ -156,32 +134,26 @@ const processCache = (options, fetch = () => undefined, request) => {
156
134
  expiry
157
135
  };
158
136
  };
159
-
160
- const getCache = key => {
137
+ export const getCache = key => {
138
+ if (!cache[key]) return {};
161
139
  return cache[key];
162
- }; // Used to remove parts of a cache
163
-
164
-
165
- const modifyCache = (cacheKey, value) => {
140
+ };
141
+ export const modifyCache = (cacheKey, value) => {
166
142
  if (!cache[cacheKey]) return;
167
143
  cache[cacheKey] = { ...cache[cacheKey],
168
144
  value,
169
145
  modified: true
170
146
  };
171
147
  };
172
-
173
- const clearCache = (keys = null) => {
174
- var _keys;
175
-
176
- keys = (_keys = keys) !== null && _keys !== void 0 ? _keys : Object.keys(cache);
148
+ export const clearCache = (keys = null) => {
149
+ keys = keys ?? Object.keys(cache);
177
150
  if (!Array.isArray(keys)) keys = [keys];
178
151
 
179
152
  for (const cacheKey of keys) {
180
153
  cache[cacheKey] = undefined;
181
154
  }
182
155
  };
183
-
184
- const jsonSafeParse = (string, reviver) => {
156
+ export const jsonSafeParse = (string, reviver) => {
185
157
  if (typeof string !== 'string') return string;
186
158
  const firstChar = string[0];
187
159
  if (firstChar !== '{' && firstChar !== '[' && firstChar !== '"') return string;
@@ -192,52 +164,41 @@ const jsonSafeParse = (string, reviver) => {
192
164
 
193
165
  return string;
194
166
  };
167
+ export const normalizeHttpResponse = request => {
168
+ var _response, _response2, _response3, _response4;
195
169
 
196
- const normalizeHttpResponse = response => {
197
- var _response$headers, _response;
170
+ let {
171
+ response
172
+ } = request;
198
173
 
199
- // May require updating to catch other types
200
174
  if (response === undefined) {
201
175
  response = {};
202
- } else if (Array.isArray(response) || typeof response !== 'object' || response === null) {
176
+ } 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) {
203
177
  response = {
204
178
  body: response
205
179
  };
206
180
  }
207
181
 
208
- response.headers = (_response$headers = (_response = response) === null || _response === void 0 ? void 0 : _response.headers) !== null && _response$headers !== void 0 ? _response$headers : {};
182
+ (_response4 = response).headers ?? (_response4.headers = {});
183
+ request.response = response;
209
184
  return response;
210
- }; // smaller version of `http-errors`
211
-
212
-
213
- const statuses = require('./codes.json');
214
-
215
- const {
216
- inherits
217
- } = require('util');
218
-
185
+ };
219
186
  const createErrorRegexp = /[^a-zA-Z]/g;
220
-
221
- const createError = (code, message, properties = {}) => {
187
+ export const createError = (code, message, properties = {}) => {
222
188
  const name = statuses[code].replace(createErrorRegexp, '');
223
189
  const className = name.substr(-5) !== 'Error' ? name + 'Error' : name;
224
190
 
225
191
  function HttpError(message) {
226
- // create the error object
227
- const msg = message !== null && message !== void 0 ? message : statuses[code];
228
- const err = new Error(msg); // capture a stack trace to the construction point
229
-
230
- Error.captureStackTrace(err, HttpError); // adjust the [[Prototype]]
231
-
232
- Object.setPrototypeOf(err, HttpError.prototype); // redefine the error message
233
-
192
+ const msg = message ?? statuses[code];
193
+ const err = new Error(msg);
194
+ Error.captureStackTrace(err, HttpError);
195
+ Object.setPrototypeOf(err, HttpError.prototype);
234
196
  Object.defineProperty(err, 'message', {
235
197
  enumerable: true,
236
198
  configurable: true,
237
199
  value: msg,
238
200
  writable: true
239
- }); // redefine the error name
240
-
201
+ });
241
202
  Object.defineProperty(err, 'name', {
242
203
  enumerable: false,
243
204
  configurable: true,
@@ -258,8 +219,7 @@ const createError = (code, message, properties = {}) => {
258
219
  }, properties);
259
220
  return new HttpError(message);
260
221
  };
261
-
262
- module.exports = {
222
+ export default {
263
223
  createPrefetchClient,
264
224
  createClient,
265
225
  canPrefetch,
package/package.json CHANGED
@@ -1,20 +1,21 @@
1
1
  {
2
2
  "name": "@middy/util",
3
- "version": "2.5.3",
3
+ "version": "3.0.0-alpha.2",
4
4
  "description": "🛵 The stylish Node.js middleware engine for AWS Lambda (util package)",
5
- "type": "commonjs",
5
+ "type": "module",
6
6
  "engines": {
7
- "node": ">=12"
7
+ "node": ">=14"
8
8
  },
9
9
  "engineStrict": true,
10
10
  "publishConfig": {
11
11
  "access": "public"
12
12
  },
13
- "main": "index.js",
13
+ "exports": "./index.js",
14
14
  "types": "index.d.ts",
15
15
  "files": [
16
+ "index.js",
16
17
  "index.d.ts",
17
- "codes.json"
18
+ "codes.js"
18
19
  ],
19
20
  "scripts": {
20
21
  "test": "npm run test:unit",
@@ -44,12 +45,12 @@
44
45
  "url": "https://github.com/middyjs/middy/issues"
45
46
  },
46
47
  "devDependencies": {
47
- "@middy/core": "^2.5.3",
48
+ "@middy/core": "^3.0.0-alpha.2",
48
49
  "@types/aws-lambda": "^8.10.76",
49
- "@types/node": "^16.0.0",
50
+ "@types/node": "^17.0.0",
50
51
  "aws-sdk": "^2.939.0",
51
52
  "aws-xray-sdk": "^3.3.3"
52
53
  },
53
54
  "homepage": "https://github.com/middyjs/middy#readme",
54
- "gitHead": "690884d43b9cd632aeca9a5eba1612160b987cd4"
55
+ "gitHead": "de30419273ecbff08f367f47c7e320ec981cf145"
55
56
  }
package/codes.json DELETED
@@ -1,66 +0,0 @@
1
- {
2
- "100": "Continue",
3
- "101": "Switching Protocols",
4
- "102": "Processing",
5
- "103": "Early Hints",
6
- "200": "OK",
7
- "201": "Created",
8
- "202": "Accepted",
9
- "203": "Non-Authoritative Information",
10
- "204": "No Content",
11
- "205": "Reset Content",
12
- "206": "Partial Content",
13
- "207": "Multi-Status",
14
- "208": "Already Reported",
15
- "226": "IM Used",
16
- "300": "Multiple Choices",
17
- "301": "Moved Permanently",
18
- "302": "Found",
19
- "303": "See Other",
20
- "304": "Not Modified",
21
- "305": "Use Proxy",
22
- "306": "(Unused)",
23
- "307": "Temporary Redirect",
24
- "308": "Permanent Redirect",
25
- "400": "Bad Request",
26
- "401": "Unauthorized",
27
- "402": "Payment Required",
28
- "403": "Forbidden",
29
- "404": "Not Found",
30
- "405": "Method Not Allowed",
31
- "406": "Not Acceptable",
32
- "407": "Proxy Authentication Required",
33
- "408": "Request Timeout",
34
- "409": "Conflict",
35
- "410": "Gone",
36
- "411": "Length Required",
37
- "412": "Precondition Failed",
38
- "413": "Payload Too Large",
39
- "414": "URI Too Long",
40
- "415": "Unsupported Media Type",
41
- "416": "Range Not Satisfiable",
42
- "417": "Expectation Failed",
43
- "418": "I'm a teapot",
44
- "421": "Misdirected Request",
45
- "422": "Unprocessable Entity",
46
- "423": "Locked",
47
- "424": "Failed Dependency",
48
- "425": "Unordered Collection",
49
- "426": "Upgrade Required",
50
- "428": "Precondition Required",
51
- "429": "Too Many Requests",
52
- "431": "Request Header Fields Too Large",
53
- "451": "Unavailable For Legal Reasons",
54
- "500": "Internal Server Error",
55
- "501": "Not Implemented",
56
- "502": "Bad Gateway",
57
- "503": "Service Unavailable",
58
- "504": "Gateway Timeout",
59
- "505": "HTTP Version Not Supported",
60
- "506": "Variant Also Negotiates",
61
- "507": "Insufficient Storage",
62
- "508": "Loop Detected",
63
- "509": "Bandwidth Limit Exceeded",
64
- "510": "Not Extended",
65
- "511": "Network Authentication Required"
66
- }