lambda-toolkit 0.0.2-beta
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/README.md +11 -0
- package/dist/index.cjs +1143 -0
- package/dist/index.mjs +1139 -0
- package/license +674 -0
- package/package.json +48 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,1139 @@
|
|
|
1
|
+
import { createRequire as __WEBPACK_EXTERNAL_createRequire } from "node:module";
|
|
2
|
+
/******/ var __webpack_modules__ = ({
|
|
3
|
+
|
|
4
|
+
/***/ 278:
|
|
5
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
6
|
+
|
|
7
|
+
const joinUnique = __webpack_require__( 836 );
|
|
8
|
+
const joinUniqueCustom = __webpack_require__( 536 );
|
|
9
|
+
const splitBatches = __webpack_require__( 821 );
|
|
10
|
+
|
|
11
|
+
module.exports = {
|
|
12
|
+
joinUnique,
|
|
13
|
+
joinUniqueCustom,
|
|
14
|
+
splitBatches
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
/***/ }),
|
|
19
|
+
|
|
20
|
+
/***/ 836:
|
|
21
|
+
/***/ ((module) => {
|
|
22
|
+
|
|
23
|
+
module.exports = ( ...args ) => [ ...new Set( args.filter( Array.isArray ).flat() ) ];
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
/***/ }),
|
|
27
|
+
|
|
28
|
+
/***/ 536:
|
|
29
|
+
/***/ ((module) => {
|
|
30
|
+
|
|
31
|
+
module.exports = ( { key, items } ) => [
|
|
32
|
+
...items.filter( Array.isArray ).flat().reduce( ( map, v ) => {
|
|
33
|
+
const k = key( v );
|
|
34
|
+
if ( !map.has( k ) ) {
|
|
35
|
+
map.set( k, v );
|
|
36
|
+
}
|
|
37
|
+
return map;
|
|
38
|
+
}, new Map() ).values()
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
/***/ }),
|
|
43
|
+
|
|
44
|
+
/***/ 821:
|
|
45
|
+
/***/ ((module) => {
|
|
46
|
+
|
|
47
|
+
module.exports = ( items, size ) => items.reduce( ( arrs, item ) =>
|
|
48
|
+
( arrs[0] && arrs[0].length < size ) ?
|
|
49
|
+
[ [ ...arrs[0], item ] ].concat( arrs.slice( 1 ) ) :
|
|
50
|
+
[ [ item ] ].concat( arrs )
|
|
51
|
+
, [] ).reverse();
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
/***/ }),
|
|
55
|
+
|
|
56
|
+
/***/ 263:
|
|
57
|
+
/***/ ((module) => {
|
|
58
|
+
|
|
59
|
+
module.exports = t => t * 24 * 60 * 60 * 1000;
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
/***/ }),
|
|
63
|
+
|
|
64
|
+
/***/ 961:
|
|
65
|
+
/***/ ((module) => {
|
|
66
|
+
|
|
67
|
+
module.exports = t => t * 60 * 60 * 1000;
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
/***/ }),
|
|
71
|
+
|
|
72
|
+
/***/ 830:
|
|
73
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
74
|
+
|
|
75
|
+
const days = __webpack_require__( 263 );
|
|
76
|
+
const hours = __webpack_require__( 961 );
|
|
77
|
+
const minutes = __webpack_require__( 635 );
|
|
78
|
+
const months = __webpack_require__( 500 );
|
|
79
|
+
const msToS = __webpack_require__( 416 );
|
|
80
|
+
const round = __webpack_require__( 990 );
|
|
81
|
+
const seconds = __webpack_require__( 51 );
|
|
82
|
+
|
|
83
|
+
module.exports = {
|
|
84
|
+
days,
|
|
85
|
+
hours,
|
|
86
|
+
minutes,
|
|
87
|
+
months,
|
|
88
|
+
msToS,
|
|
89
|
+
round,
|
|
90
|
+
seconds
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
/***/ }),
|
|
95
|
+
|
|
96
|
+
/***/ 635:
|
|
97
|
+
/***/ ((module) => {
|
|
98
|
+
|
|
99
|
+
module.exports = t => t * 60 * 1000;
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
/***/ }),
|
|
103
|
+
|
|
104
|
+
/***/ 500:
|
|
105
|
+
/***/ ((module) => {
|
|
106
|
+
|
|
107
|
+
module.exports = t => t * 30 * 24 * 60 * 60 * 1000;
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
/***/ }),
|
|
111
|
+
|
|
112
|
+
/***/ 416:
|
|
113
|
+
/***/ ((module) => {
|
|
114
|
+
|
|
115
|
+
module.exports = v => Math.ceil( v / 1000 );
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
/***/ }),
|
|
119
|
+
|
|
120
|
+
/***/ 990:
|
|
121
|
+
/***/ ((module) => {
|
|
122
|
+
|
|
123
|
+
module.exports = ( time, interval ) => time - ( time % interval );
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
/***/ }),
|
|
127
|
+
|
|
128
|
+
/***/ 51:
|
|
129
|
+
/***/ ((module) => {
|
|
130
|
+
|
|
131
|
+
module.exports = t => t * 1000;
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
/***/ }),
|
|
135
|
+
|
|
136
|
+
/***/ 44:
|
|
137
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
138
|
+
|
|
139
|
+
const { LambdaApi } = __webpack_require__( 705 );
|
|
140
|
+
const array = __webpack_require__( 278 );
|
|
141
|
+
const epoch = __webpack_require__( 830 );
|
|
142
|
+
const math = __webpack_require__( 943 );
|
|
143
|
+
const object = __webpack_require__( 762 );
|
|
144
|
+
const string = __webpack_require__( 268 );
|
|
145
|
+
const utils = __webpack_require__( 878 );
|
|
146
|
+
|
|
147
|
+
module.exports = {
|
|
148
|
+
array,
|
|
149
|
+
epoch,
|
|
150
|
+
LambdaApi,
|
|
151
|
+
math,
|
|
152
|
+
object,
|
|
153
|
+
string,
|
|
154
|
+
utils
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
/***/ }),
|
|
159
|
+
|
|
160
|
+
/***/ 119:
|
|
161
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
162
|
+
|
|
163
|
+
const { snakelize, camelize } = __webpack_require__( 762 );
|
|
164
|
+
const charset = 'utf-8';
|
|
165
|
+
|
|
166
|
+
const transformFns = {
|
|
167
|
+
camelcase: camelize,
|
|
168
|
+
snakecase: snakelize
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
module.exports = class ApiResponse {
|
|
172
|
+
#headers = null;
|
|
173
|
+
#statusCode = null;
|
|
174
|
+
#transformFn = false;
|
|
175
|
+
#body = '';
|
|
176
|
+
|
|
177
|
+
constructor( { headers = {}, transform } = {} ) {
|
|
178
|
+
this.#transformFn = transformFns[transform] ?? ( v => v );
|
|
179
|
+
this.#headers = Object.assign( {
|
|
180
|
+
'Cache-Control': 'no-store',
|
|
181
|
+
'Access-Control-Allow-Origin': '*'
|
|
182
|
+
}, headers );
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
setContent( statusCode, body, headers = {} ) {
|
|
186
|
+
this.#statusCode = statusCode;
|
|
187
|
+
if ( body?.length === 0 || [ null, undefined ].includes( body ) ) {
|
|
188
|
+
this.#body = '';
|
|
189
|
+
} else if ( typeof body === 'object' ) {
|
|
190
|
+
this.#body = JSON.stringify( this.#transformFn( body ) );
|
|
191
|
+
this.#headers['Content-Type'] = `application/json; charset=${charset}`;
|
|
192
|
+
} else {
|
|
193
|
+
this.#body = String( body );
|
|
194
|
+
this.#headers['Content-Type'] = `text/plain; charset=${charset}`;
|
|
195
|
+
}
|
|
196
|
+
this.#headers['Content-Length'] = this.#body.length;
|
|
197
|
+
Object.assign( this.#headers, headers ?? {} );
|
|
198
|
+
return this;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
toJSON() {
|
|
202
|
+
return {
|
|
203
|
+
statusCode: this.#statusCode,
|
|
204
|
+
body: this.#body,
|
|
205
|
+
headers: this.#headers
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
/***/ }),
|
|
212
|
+
|
|
213
|
+
/***/ 329:
|
|
214
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
215
|
+
|
|
216
|
+
const { camelize, snakelize } = __webpack_require__( 762 );
|
|
217
|
+
|
|
218
|
+
const transformFns = {
|
|
219
|
+
camelcase: camelize,
|
|
220
|
+
snakecase: snakelize
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
const parseJson = content => {
|
|
224
|
+
try {
|
|
225
|
+
return JSON.parse( content );
|
|
226
|
+
} catch {
|
|
227
|
+
return content;
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
module.exports = class Event {
|
|
232
|
+
#transformFn;
|
|
233
|
+
authorizer;
|
|
234
|
+
body;
|
|
235
|
+
headers;
|
|
236
|
+
method;
|
|
237
|
+
params;
|
|
238
|
+
path;
|
|
239
|
+
queryString;
|
|
240
|
+
route;
|
|
241
|
+
|
|
242
|
+
context = {};
|
|
243
|
+
|
|
244
|
+
constructor( { transform = false } = {} ) {
|
|
245
|
+
this.#transformFn = transformFns[transform] ?? ( v => v );
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
parseFromAwsEvent( awsEvent ) {
|
|
249
|
+
this[`parseFromAwsEventV${awsEvent.version !== '1.0' ? 2 : 1}`]( awsEvent );
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
parseFromAwsEventV1( awsEvent ) {
|
|
253
|
+
const {
|
|
254
|
+
body,
|
|
255
|
+
path,
|
|
256
|
+
resource,
|
|
257
|
+
httpMethod,
|
|
258
|
+
requestContext,
|
|
259
|
+
pathParameters,
|
|
260
|
+
headers,
|
|
261
|
+
multiValueHeaders,
|
|
262
|
+
queryStringParameters,
|
|
263
|
+
multiValueQueryStringParameters: multiValueQueryString
|
|
264
|
+
} = awsEvent;
|
|
265
|
+
|
|
266
|
+
const unifiedHeaders = {
|
|
267
|
+
headers,
|
|
268
|
+
...Object.fromEntries( Object.entries( multiValueHeaders ?? {} ).map( ( [ k, v ] ) => [ k, Array.isArray( v ) ? v.join( ',' ) : k ] ) )
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
const unifiedQueryString = {
|
|
272
|
+
queryStringParameters,
|
|
273
|
+
...Object.fromEntries( Object.entries( multiValueQueryString ?? {} ).map( ( [ k, v ] ) => [ k, Array.isArray( v ) ? v.join( ',' ) : k ] ) )
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
this.authorizer = requestContext?.authorizer;
|
|
277
|
+
this.body = body ? this.#transformFn( parseJson( body ) ) : null;
|
|
278
|
+
this.headers = unifiedHeaders ?? {};
|
|
279
|
+
this.method = httpMethod;
|
|
280
|
+
this.params = this.#transformFn( pathParameters ) ?? {};
|
|
281
|
+
this.path = path;
|
|
282
|
+
this.queryString = this.#transformFn( unifiedQueryString ) ?? {};
|
|
283
|
+
this.route = resource;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
parseFromAwsEventV2( awsEvent ) {
|
|
287
|
+
const {
|
|
288
|
+
body,
|
|
289
|
+
routeKey,
|
|
290
|
+
requestContext,
|
|
291
|
+
pathParameters,
|
|
292
|
+
headers,
|
|
293
|
+
queryStringParameters
|
|
294
|
+
} = awsEvent;
|
|
295
|
+
|
|
296
|
+
const { http: { method, path } } = requestContext;
|
|
297
|
+
|
|
298
|
+
this.authorizer = requestContext?.authorizer;
|
|
299
|
+
this.body = body ? this.#transformFn( parseJson( body ) ) : null;
|
|
300
|
+
this.headers = headers ?? {};
|
|
301
|
+
this.method = method;
|
|
302
|
+
this.params = this.#transformFn( pathParameters ) ?? {};
|
|
303
|
+
this.path = path;
|
|
304
|
+
this.queryString = this.#transformFn( queryStringParameters ) ?? {};
|
|
305
|
+
this.route = routeKey?.split( ' ' )[1].replace( /\/$/, '' );
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
/***/ }),
|
|
311
|
+
|
|
312
|
+
/***/ 109:
|
|
313
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
314
|
+
|
|
315
|
+
const validators = __webpack_require__( 994 );
|
|
316
|
+
|
|
317
|
+
module.exports = class Handler {
|
|
318
|
+
#method;
|
|
319
|
+
#fn;
|
|
320
|
+
#route;
|
|
321
|
+
#routeIncludes;
|
|
322
|
+
#routeNotIncludes;
|
|
323
|
+
#routeMatches;
|
|
324
|
+
#path;
|
|
325
|
+
#pathIncludes;
|
|
326
|
+
#pathNotIncludes;
|
|
327
|
+
#pathMatches;
|
|
328
|
+
|
|
329
|
+
constructor( { method, fn, ...matchers } ) {
|
|
330
|
+
validators.httpMethod( method );
|
|
331
|
+
validators.function( fn );
|
|
332
|
+
validators.matcherRoute( matchers.route );
|
|
333
|
+
validators.matcherRouteIncludes( matchers.routeIncludes );
|
|
334
|
+
validators.matcherRouteNotIncludes( matchers.routeNotIncludes );
|
|
335
|
+
validators.matcherRouteMatch( matchers.routeMatch );
|
|
336
|
+
validators.matcherPath( matchers.path );
|
|
337
|
+
validators.matcherPathIncludes( matchers.pathIncludes );
|
|
338
|
+
validators.matcherPathNotIncludes( matchers.pathNotIncludes );
|
|
339
|
+
validators.matcherPathMatch( matchers.pathMatch );
|
|
340
|
+
|
|
341
|
+
this.#method = method;
|
|
342
|
+
this.#fn = fn;
|
|
343
|
+
this.#route = matchers.route;
|
|
344
|
+
this.#routeIncludes = matchers.routeIncludes;
|
|
345
|
+
this.#routeNotIncludes = matchers.routeNotIncludes;
|
|
346
|
+
this.#routeMatches = matchers.routeMatches;
|
|
347
|
+
this.#path = matchers.path;
|
|
348
|
+
this.#pathIncludes = matchers.pathIncludes;
|
|
349
|
+
this.#pathNotIncludes = matchers.pathNotIncludes;
|
|
350
|
+
this.#pathMatches = matchers.pathMatches;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
match( event ) {
|
|
354
|
+
if ( this.#method !== event.method ) {
|
|
355
|
+
return false;
|
|
356
|
+
}
|
|
357
|
+
if ( this.#route ) {
|
|
358
|
+
return this.#route === event.route;
|
|
359
|
+
}
|
|
360
|
+
if ( this.#path ) {
|
|
361
|
+
return this.#path === event.path;
|
|
362
|
+
}
|
|
363
|
+
if ( this.#routeIncludes && !event.route.includes( this.#routeIncludes ) ) {
|
|
364
|
+
return false;
|
|
365
|
+
}
|
|
366
|
+
if ( this.#routeNotIncludes && event.route.includes( this.#routeNotIncludes ) ) {
|
|
367
|
+
return false;
|
|
368
|
+
}
|
|
369
|
+
if ( this.#routeMatches && !this.#routeMatches.test( event.route ) ) {
|
|
370
|
+
return false;
|
|
371
|
+
}
|
|
372
|
+
if ( this.#pathIncludes && !event.path.includes( this.#pathIncludes ) ) {
|
|
373
|
+
return false;
|
|
374
|
+
}
|
|
375
|
+
if ( this.#pathNotIncludes && event.path.includes( this.#pathNotIncludes ) ) {
|
|
376
|
+
return false;
|
|
377
|
+
}
|
|
378
|
+
if ( this.#pathMatches && !this.#pathMatches.test( event.path ) ) {
|
|
379
|
+
return false;
|
|
380
|
+
}
|
|
381
|
+
return true;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
get fn() { return this.#fn; }
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
/***/ }),
|
|
389
|
+
|
|
390
|
+
/***/ 798:
|
|
391
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
392
|
+
|
|
393
|
+
const validators = __webpack_require__( 994 );
|
|
394
|
+
|
|
395
|
+
module.exports = class Hook {
|
|
396
|
+
#fn;
|
|
397
|
+
|
|
398
|
+
constructor( { fn } ) {
|
|
399
|
+
validators.function( fn );
|
|
400
|
+
this.#fn = fn;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
get fn() { return this.#fn; }
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
/***/ }),
|
|
408
|
+
|
|
409
|
+
/***/ 705:
|
|
410
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
411
|
+
|
|
412
|
+
const LambdaApi = __webpack_require__( 321 );
|
|
413
|
+
|
|
414
|
+
module.exports = { LambdaApi };
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
/***/ }),
|
|
418
|
+
|
|
419
|
+
/***/ 321:
|
|
420
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
421
|
+
|
|
422
|
+
const validators = __webpack_require__( 994 );
|
|
423
|
+
const ApiResponse = __webpack_require__( 119 );
|
|
424
|
+
const Event = __webpack_require__( 329 );
|
|
425
|
+
const Handler = __webpack_require__( 109 );
|
|
426
|
+
const Hook = __webpack_require__( 798 );
|
|
427
|
+
const UserResponse = __webpack_require__( 282 );
|
|
428
|
+
const Text = __webpack_require__( 760 );
|
|
429
|
+
|
|
430
|
+
module.exports = class LambdaApi {
|
|
431
|
+
#apiResponse = null;
|
|
432
|
+
#handlers = [];
|
|
433
|
+
#errorResponses = [];
|
|
434
|
+
#beforeHooks = [];
|
|
435
|
+
#afterHooks = [];
|
|
436
|
+
#transformRequest = [];
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* Creates a new Lambda Api
|
|
440
|
+
*
|
|
441
|
+
* @param {Object} headers Any headers you want to be included in all responses
|
|
442
|
+
*/
|
|
443
|
+
constructor( { headers = {}, transformRequest = false, transformResponse = false } = {} ) {
|
|
444
|
+
validators.transformRequest( transformRequest );
|
|
445
|
+
validators.transformResponse( transformResponse );
|
|
446
|
+
|
|
447
|
+
this.#transformRequest = transformRequest;
|
|
448
|
+
this.#apiResponse = new ApiResponse( { headers, transform: transformResponse } );
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Register a function that will run before the matching route (only if matches)
|
|
453
|
+
*
|
|
454
|
+
* @param {Object} args
|
|
455
|
+
* @param {function} args.fn A function
|
|
456
|
+
*/
|
|
457
|
+
addBeforeHook( { fn } = {} ) {
|
|
458
|
+
this.#beforeHooks.push( new Hook( { fn } ) );
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Register a function that will run after the matching route (only if matches)
|
|
463
|
+
*
|
|
464
|
+
* @param {Object} args
|
|
465
|
+
* @param {function} args.fn A function
|
|
466
|
+
*/
|
|
467
|
+
addAfterHook( { fn } = {} ) {
|
|
468
|
+
this.#afterHooks.push( new Hook( { fn } ) );
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Register a handler for a given request method and optionally a path
|
|
473
|
+
*
|
|
474
|
+
* @param {Object} args
|
|
475
|
+
* @param {string} args.method The method to match this handler
|
|
476
|
+
* @param {function} args.fn The handler function
|
|
477
|
+
* @param {string} [args.route] A route to match this handler
|
|
478
|
+
* @param {string} [args.routeIncludes] A part of the route to match this handler
|
|
479
|
+
* @param {string} [args.routeNotIncludes] A part of the route to not match this handler
|
|
480
|
+
* @param {RegExp} [args.routeMatches] A RegExp to match the route
|
|
481
|
+
* @param {string} [args.path] A path to match this handler
|
|
482
|
+
* @param {string} [args.pathIncludes] A part of the path to match this handler
|
|
483
|
+
* @param {string} [args.pathNotIncludes] A part of the path to not match this handler
|
|
484
|
+
* @param {RegExp} [args.pathMatches] A RegExp to match the path
|
|
485
|
+
*/
|
|
486
|
+
addHandler( { method, fn, ...matchers } = {} ) {
|
|
487
|
+
this.#handlers.push( new Handler( { method, fn, ...matchers } ) );
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Register an automatic error code response for given error class (constructor name)
|
|
492
|
+
*
|
|
493
|
+
* @param {Object} args
|
|
494
|
+
* @param {string} args.code The HTTP status code to return
|
|
495
|
+
* @param {class} args.errorType The error class
|
|
496
|
+
* @param {string} [args.message=null] Optional message to return for the status code, if not present will default to Error.message
|
|
497
|
+
* @param {message} [args.errorType] And optional message to display
|
|
498
|
+
*/
|
|
499
|
+
addErrorHandler( { errorType, code, message = null } = {} ) {
|
|
500
|
+
validators.statusCode( code );
|
|
501
|
+
validators.errorType( errorType );
|
|
502
|
+
this.#errorResponses.push( { errorType, code, message } );
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* Init the flow using a given AWS Lambda APIGateway event (v2 syntax)
|
|
507
|
+
*
|
|
508
|
+
* @param {Object} ApiGatewayPayload The raw API Gateway event
|
|
509
|
+
* @returns {Object} The http response with status, body and headers
|
|
510
|
+
*/
|
|
511
|
+
async process( awsEvent ) {
|
|
512
|
+
const event = new Event( { transform: this.#transformRequest } );
|
|
513
|
+
event.parseFromAwsEvent( awsEvent );
|
|
514
|
+
|
|
515
|
+
if ( event.method === 'HEAD' ) {
|
|
516
|
+
return this.#apiResponse.setContent( 204 ).toJSON();
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
const handler = this.#handlers.find( h => h.match( event ) );
|
|
520
|
+
if ( !handler ) {
|
|
521
|
+
return this.#apiResponse.setContent( 405, Text.ERROR_405 ).toJSON();
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
const chain = [
|
|
525
|
+
...this.#beforeHooks.map( b => b.fn ),
|
|
526
|
+
async ev => {
|
|
527
|
+
const result = await handler.fn( ev );
|
|
528
|
+
const response = new UserResponse( result );
|
|
529
|
+
this.#apiResponse.setContent( ...response.values ).toJSON();
|
|
530
|
+
},
|
|
531
|
+
...this.#afterHooks.map( a => a.fn )
|
|
532
|
+
];
|
|
533
|
+
|
|
534
|
+
try {
|
|
535
|
+
for ( const fn of chain ) {
|
|
536
|
+
await fn( event );
|
|
537
|
+
}
|
|
538
|
+
return this.#apiResponse.toJSON();
|
|
539
|
+
|
|
540
|
+
} catch ( error ) {
|
|
541
|
+
console.error( 'Lambda API Error', { error, event } );
|
|
542
|
+
|
|
543
|
+
const response = this.#errorResponses.find( e => error instanceof e.errorType );
|
|
544
|
+
if ( response ) {
|
|
545
|
+
return this.#apiResponse.setContent( response.code, response.message ?? error.message ).toJSON();
|
|
546
|
+
}
|
|
547
|
+
return this.#apiResponse.setContent( 500, Text.ERROR_500 ).toJSON();
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
};
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
/***/ }),
|
|
554
|
+
|
|
555
|
+
/***/ 446:
|
|
556
|
+
/***/ ((module) => {
|
|
557
|
+
|
|
558
|
+
module.exports = class LambdaApiValidationError extends Error {};
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
/***/ }),
|
|
562
|
+
|
|
563
|
+
/***/ 760:
|
|
564
|
+
/***/ ((module) => {
|
|
565
|
+
|
|
566
|
+
module.exports = {
|
|
567
|
+
ERROR_500: 'Internal Server Error',
|
|
568
|
+
ERROR_405: 'Method Not Allowed',
|
|
569
|
+
INVALID_ERROR_TYPE: 'Argument "errorType" must be a constructor Function',
|
|
570
|
+
INVALID_FN: 'Argument "fn" must be of type function',
|
|
571
|
+
INVALID_METHOD: 'Argument "method" must be one of the default HTTP methods',
|
|
572
|
+
INVALID_STATUS_CODE: 'Argument "statusCode" must be valid HTTP Status Code',
|
|
573
|
+
INVALID_TRANSFORM_REQUEST: 'Argument "transformRequest" must be either "camelize", "snakelize", false or null',
|
|
574
|
+
INVALID_TRANSFORM_RESPONSE: 'Argument "transformResponse" must be either "camelize", "snakelize", false or null',
|
|
575
|
+
INVALID_MATCHER_ROUTE: 'Argument "route" must be either undefined or an string with length greater than 0',
|
|
576
|
+
INVALID_MATCHER_ROUTE_INCLUDES: 'Argument "routeIncludes" must be either undefined or an string with length greater than 0',
|
|
577
|
+
INVALID_MATCHER_ROUTE_NOT_INCLUDES: 'Argument "routeNotIncludes" must be either undefined or an string with length greater than 0',
|
|
578
|
+
INVALID_MATCHER_ROUTE_MATCH: 'Argument "routeMatch" must be either undefined or type RegExp',
|
|
579
|
+
INVALID_MATCHER_PATH: 'Argument "path" must be either undefined or an string with length greater than 0',
|
|
580
|
+
INVALID_MATCHER_PATH_INCLUDES: 'Argument "pathIncludes" must be either undefined or an string with length greater than 0',
|
|
581
|
+
INVALID_MATCHER_PATH_NOT_INCLUDES: 'Argument "pathNotIncludes" must be either undefined or an string with length greater than 0',
|
|
582
|
+
INVALID_MATCHER_PATH_MATCH: 'Argument "pathMatch" must be either undefined or type RegExp',
|
|
583
|
+
INVALID_USER_RESPONSE: 'Function return must be a number, a string, an array (where p=0 is a number) or an object (where .statusCode is a number)'
|
|
584
|
+
};
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
/***/ }),
|
|
588
|
+
|
|
589
|
+
/***/ 282:
|
|
590
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
591
|
+
|
|
592
|
+
const validators = __webpack_require__( 994 );
|
|
593
|
+
const LambdaApiValidationError = __webpack_require__( 446 );
|
|
594
|
+
const Text = __webpack_require__( 760 );
|
|
595
|
+
|
|
596
|
+
module.exports = class UserResponse {
|
|
597
|
+
constructor( args ) {
|
|
598
|
+
if ( args === undefined ) {
|
|
599
|
+
this.values = [ 204 ];
|
|
600
|
+
} else if ( typeof args === 'string' && args.length === 0 ) {
|
|
601
|
+
this.values = [ 204 ];
|
|
602
|
+
|
|
603
|
+
} else if ( typeof args === 'string' && args.length > 0 ) {
|
|
604
|
+
this.values = [ 200, args ];
|
|
605
|
+
|
|
606
|
+
} else if ( typeof args === 'number' ) {
|
|
607
|
+
validators.statusCode( args );
|
|
608
|
+
this.values = [ args ];
|
|
609
|
+
|
|
610
|
+
} else if ( Array.isArray( args ) ) {
|
|
611
|
+
validators.statusCode( args[0] );
|
|
612
|
+
this.values = args;
|
|
613
|
+
|
|
614
|
+
} else if ( args.statusCode ) {
|
|
615
|
+
validators.statusCode( args.statusCode );
|
|
616
|
+
this.values = [ args.statusCode, args.body, args.headers ];
|
|
617
|
+
|
|
618
|
+
} else if ( [ undefined, null ].includes( args ) ) {
|
|
619
|
+
this.values = [ 200 ];
|
|
620
|
+
} else {
|
|
621
|
+
throw new LambdaApiValidationError( Text.INVALID_USER_RESPONSE );
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
};
|
|
625
|
+
|
|
626
|
+
|
|
627
|
+
/***/ }),
|
|
628
|
+
|
|
629
|
+
/***/ 994:
|
|
630
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
631
|
+
|
|
632
|
+
const Text = __webpack_require__( 760 );
|
|
633
|
+
const LambdaApiValidationError = __webpack_require__( 446 );
|
|
634
|
+
|
|
635
|
+
const evaluate = ( condition, errorMessage ) => {
|
|
636
|
+
if ( !condition ) { throw new LambdaApiValidationError( errorMessage ); }
|
|
637
|
+
};
|
|
638
|
+
|
|
639
|
+
const isConstructor = v => {
|
|
640
|
+
try {
|
|
641
|
+
return !!Reflect.construct( new Proxy( v, {} ), [] );
|
|
642
|
+
} catch {
|
|
643
|
+
return false;
|
|
644
|
+
}
|
|
645
|
+
};
|
|
646
|
+
|
|
647
|
+
module.exports = {
|
|
648
|
+
errorType: v => evaluate( isConstructor( v ), Text.INVALID_ERROR_TYPE ),
|
|
649
|
+
function: v => evaluate( typeof v === 'function', Text.INVALID_FN ),
|
|
650
|
+
httpMethod: v => evaluate( [ 'DELETE', 'GET', 'HEAD', 'PATCH', 'POST', 'PUT' ].includes( v ), Text.INVALID_METHOD ),
|
|
651
|
+
matcherPath: v => evaluate( v === undefined || ( typeof v === 'string' && v.length > 0 ), Text.INVALID_MATCHER_PATH ),
|
|
652
|
+
matcherPathIncludes: v => evaluate( v === undefined || ( typeof v === 'string' && v.length > 0 ), Text.INVALID_MATCHER_PATH_INCLUDES ),
|
|
653
|
+
matcherPathMatch: v => evaluate( v === undefined || v?.constructor?.name === RegExp.name, Text.INVALID_MATCHER_PATH_MATCH ),
|
|
654
|
+
matcherPathNotIncludes: v => evaluate( v === undefined || ( typeof v === 'string' && v.length > 0 ), Text.INVALID_MATCHER_PATH_NOT_INCLUDES ),
|
|
655
|
+
matcherRoute: v => evaluate( v === undefined || ( typeof v === 'string' && v.length > 0 ), Text.INVALID_MATCHER_ROUTE ),
|
|
656
|
+
matcherRouteIncludes: v => evaluate( v === undefined || ( typeof v === 'string' && v.length > 0 ), Text.INVALID_MATCHER_ROUTE_INCLUDES ),
|
|
657
|
+
matcherRouteMatch: v => evaluate( v === undefined || v?.constructor?.name === RegExp.name, Text.INVALID_MATCHER_ROUTE_MATCH ),
|
|
658
|
+
matcherRouteNotIncludes: v => evaluate( v === undefined || ( typeof v === 'string' && v.length > 0 ), Text.INVALID_MATCHER_ROUTE_NOT_INCLUDES ),
|
|
659
|
+
statusCode: v => evaluate( typeof v === 'number' && /^[1-5]\d\d$/.test( String( v ) ), Text.INVALID_STATUS_CODE ),
|
|
660
|
+
transformRequest: v => evaluate( [ 'camelcase', 'snakecase', null, false ].includes( v ), Text.INVALID_TRANSFORM_REQUEST ),
|
|
661
|
+
transformResponse: v => evaluate( [ 'camelcase', 'snakecase', null, false ].includes( v ), Text.INVALID_TRANSFORM_RESPONSE )
|
|
662
|
+
};
|
|
663
|
+
|
|
664
|
+
|
|
665
|
+
/***/ }),
|
|
666
|
+
|
|
667
|
+
/***/ 124:
|
|
668
|
+
/***/ ((module) => {
|
|
669
|
+
|
|
670
|
+
module.exports = values => values.reduce( ( sum, value ) => sum + value, 0 ) / values.length;
|
|
671
|
+
|
|
672
|
+
|
|
673
|
+
/***/ }),
|
|
674
|
+
|
|
675
|
+
/***/ 187:
|
|
676
|
+
/***/ ((module) => {
|
|
677
|
+
|
|
678
|
+
module.exports = values => {
|
|
679
|
+
//Sort bug: https://www.tutorialrepublic.com/faq/how-to-sort-an-array-of-integers-correctly-in-javascript.php
|
|
680
|
+
const sorted = values.slice().sort( ( a, b ) => a - b );
|
|
681
|
+
const evenArray = values.length % 2 === 0;
|
|
682
|
+
const midIndex = Math.floor( values.length / 2 );
|
|
683
|
+
return evenArray ? ( sorted[midIndex - 1] + sorted[midIndex] ) / 2 : sorted[midIndex];
|
|
684
|
+
};
|
|
685
|
+
|
|
686
|
+
|
|
687
|
+
/***/ }),
|
|
688
|
+
|
|
689
|
+
/***/ 692:
|
|
690
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
691
|
+
|
|
692
|
+
const calcMedian = __webpack_require__( 187 );
|
|
693
|
+
|
|
694
|
+
module.exports = pop => {
|
|
695
|
+
const center = calcMedian( pop );
|
|
696
|
+
return calcMedian( pop.map( v => Math.abs( v - center ) ) );
|
|
697
|
+
};
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
/***/ }),
|
|
701
|
+
|
|
702
|
+
/***/ 736:
|
|
703
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
704
|
+
|
|
705
|
+
const calcMean = __webpack_require__( 124 );
|
|
706
|
+
|
|
707
|
+
module.exports = values => {
|
|
708
|
+
const mean = calcMean( values );
|
|
709
|
+
const squareDiffs = values.map( value => Math.pow( value - mean, 2 ) );
|
|
710
|
+
const avgSquareDiff = calcMean( squareDiffs );
|
|
711
|
+
return Math.sqrt( avgSquareDiff );
|
|
712
|
+
};
|
|
713
|
+
|
|
714
|
+
|
|
715
|
+
/***/ }),
|
|
716
|
+
|
|
717
|
+
/***/ 89:
|
|
718
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
719
|
+
|
|
720
|
+
const calcMean = __webpack_require__( 124 );
|
|
721
|
+
|
|
722
|
+
module.exports = values => {
|
|
723
|
+
if ( values.length < 2 ) { return NaN; }
|
|
724
|
+
|
|
725
|
+
const mean = calcMean( values );
|
|
726
|
+
const squareDiffs = values.map( value => Math.pow( value - mean, 2 ) );
|
|
727
|
+
const avgSquareDiff = squareDiffs.reduce( ( sum, v ) => sum + v, 0 ) / ( values.length - 1 );
|
|
728
|
+
return Math.sqrt( avgSquareDiff );
|
|
729
|
+
};
|
|
730
|
+
|
|
731
|
+
|
|
732
|
+
/***/ }),
|
|
733
|
+
|
|
734
|
+
/***/ 110:
|
|
735
|
+
/***/ ((module) => {
|
|
736
|
+
|
|
737
|
+
module.exports = ( sample, mean, stdDev ) => stdDev === 0 ? NaN : ( sample - mean ) / stdDev;
|
|
738
|
+
|
|
739
|
+
|
|
740
|
+
/***/ }),
|
|
741
|
+
|
|
742
|
+
/***/ 943:
|
|
743
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
744
|
+
|
|
745
|
+
const calcMean = __webpack_require__( 124 );
|
|
746
|
+
const calcMedian = __webpack_require__( 187 );
|
|
747
|
+
const calcMedianAbsDev = __webpack_require__( 692 );
|
|
748
|
+
const calcStdDevPopulation = __webpack_require__( 736 );
|
|
749
|
+
const calcStdDevSample = __webpack_require__( 89 );
|
|
750
|
+
const calcZScore = __webpack_require__( 110 );
|
|
751
|
+
const roundGaussian = __webpack_require__( 637 );
|
|
752
|
+
const roundStandard = __webpack_require__( 115 );
|
|
753
|
+
|
|
754
|
+
module.exports = {
|
|
755
|
+
calcMean,
|
|
756
|
+
calcMedian,
|
|
757
|
+
calcMedianAbsDev,
|
|
758
|
+
calcStdDevPopulation,
|
|
759
|
+
calcStdDevSample,
|
|
760
|
+
calcZScore,
|
|
761
|
+
roundGaussian,
|
|
762
|
+
roundStandard
|
|
763
|
+
};
|
|
764
|
+
|
|
765
|
+
|
|
766
|
+
/***/ }),
|
|
767
|
+
|
|
768
|
+
/***/ 637:
|
|
769
|
+
/***/ ((module) => {
|
|
770
|
+
|
|
771
|
+
module.exports = ( n, d = 2 ) => {
|
|
772
|
+
if ( !isFinite( n ) || typeof n !== 'number' ) { return NaN; }
|
|
773
|
+
|
|
774
|
+
const m = Math.pow( 10, d );
|
|
775
|
+
const num = +( n * m ).toFixed( 8 ); // Avoid rounding errors
|
|
776
|
+
const i = Math.floor( num );
|
|
777
|
+
const f = num - i;
|
|
778
|
+
const e = 1e-8; // Allow for rounding errors in f
|
|
779
|
+
const r = ( f > 0.5 - e && f < 0.5 + e ) ? // eslint-disable-line no-nested-ternary
|
|
780
|
+
( ( i % 2 === 0 ) ? i : i + 1 ) : Math.round( num );
|
|
781
|
+
return r / m;
|
|
782
|
+
};
|
|
783
|
+
|
|
784
|
+
|
|
785
|
+
/***/ }),
|
|
786
|
+
|
|
787
|
+
/***/ 115:
|
|
788
|
+
/***/ ((module) => {
|
|
789
|
+
|
|
790
|
+
module.exports = ( n, d = 2 ) => Math.round( n * ( 10 ** d ) ) / ( 10 ** d );
|
|
791
|
+
|
|
792
|
+
|
|
793
|
+
/***/ }),
|
|
794
|
+
|
|
795
|
+
/***/ 256:
|
|
796
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
797
|
+
|
|
798
|
+
const isSerializable = __webpack_require__( 864 );
|
|
799
|
+
const camelize = __webpack_require__( 914 );
|
|
800
|
+
|
|
801
|
+
const change = ( obj, keepAllCaps ) =>
|
|
802
|
+
!isSerializable( obj ) ? obj : Object.entries( obj ).reduce( ( transformed, [ key, value ] ) => {
|
|
803
|
+
delete transformed[key];
|
|
804
|
+
transformed[camelize( key, { keepAllCaps } )] = typeof value === 'object' ? change( value, keepAllCaps ) : value;
|
|
805
|
+
return transformed;
|
|
806
|
+
}, Array.isArray( obj ) ? [] : {} );
|
|
807
|
+
|
|
808
|
+
module.exports = ( obj, { keepAllCaps = false } = {} ) => change( obj, keepAllCaps );
|
|
809
|
+
|
|
810
|
+
|
|
811
|
+
/***/ }),
|
|
812
|
+
|
|
813
|
+
/***/ 451:
|
|
814
|
+
/***/ ((module) => {
|
|
815
|
+
|
|
816
|
+
module.exports = ( obj, props ) => Object.fromEntries( Object.entries( obj ).filter( ( [ k ] ) => props.includes( k ) ) );
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
/***/ }),
|
|
820
|
+
|
|
821
|
+
/***/ 762:
|
|
822
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
823
|
+
|
|
824
|
+
const camelize = __webpack_require__( 256 );
|
|
825
|
+
const filterProps = __webpack_require__( 451 );
|
|
826
|
+
const snakelize = __webpack_require__( 572 );
|
|
827
|
+
|
|
828
|
+
module.exports = {
|
|
829
|
+
camelize,
|
|
830
|
+
filterProps,
|
|
831
|
+
snakelize
|
|
832
|
+
};
|
|
833
|
+
|
|
834
|
+
|
|
835
|
+
/***/ }),
|
|
836
|
+
|
|
837
|
+
/***/ 864:
|
|
838
|
+
/***/ ((module) => {
|
|
839
|
+
|
|
840
|
+
module.exports = obj =>
|
|
841
|
+
typeof obj === 'object' &&
|
|
842
|
+
obj !== null &&
|
|
843
|
+
!( obj instanceof String ) &&
|
|
844
|
+
!( obj instanceof Number ) &&
|
|
845
|
+
!( obj instanceof Boolean ) &&
|
|
846
|
+
!( obj instanceof Date );
|
|
847
|
+
|
|
848
|
+
|
|
849
|
+
/***/ }),
|
|
850
|
+
|
|
851
|
+
/***/ 572:
|
|
852
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
853
|
+
|
|
854
|
+
const isSerializable = __webpack_require__( 864 );
|
|
855
|
+
const snakelize = __webpack_require__( 402 );
|
|
856
|
+
|
|
857
|
+
const change = ( obj, keepAllCaps ) =>
|
|
858
|
+
!isSerializable( obj ) ? obj : Object.entries( obj ).reduce( ( transformed, [ key, value ] ) => {
|
|
859
|
+
delete transformed[key];
|
|
860
|
+
transformed[snakelize( key, { keepAllCaps } )] = typeof value === 'object' ? change( value, keepAllCaps ) : value;
|
|
861
|
+
return transformed;
|
|
862
|
+
}, Array.isArray( obj ) ? [] : {} );
|
|
863
|
+
|
|
864
|
+
module.exports = ( obj, { keepAllCaps = false } = {} ) => change( obj, keepAllCaps );
|
|
865
|
+
|
|
866
|
+
|
|
867
|
+
/***/ }),
|
|
868
|
+
|
|
869
|
+
/***/ 914:
|
|
870
|
+
/***/ ((module) => {
|
|
871
|
+
|
|
872
|
+
// Convert a string to camelCase
|
|
873
|
+
module.exports = ( input, { keepAllCaps = false } = {} ) =>
|
|
874
|
+
// Break the string into sequences to rebuild later
|
|
875
|
+
!input ? input : input.split( /\s/ )
|
|
876
|
+
// ALL_CAPS terms are ignored
|
|
877
|
+
.map( term => [ term, keepAllCaps && /^[A-Z_]+$/g.test( term ) ? term : term
|
|
878
|
+
// Matches the penultimate letter in a sequence of upper case followed by lower case and convert it to lower case
|
|
879
|
+
// Effectively creating a word break eg: BDay => bDay
|
|
880
|
+
.replace( /[A-Z](?=[A-Z][a-z])/g, c => `${c[0].toLowerCase()}` )
|
|
881
|
+
.replace( /([A-Z])([A-Z]+)/g, c => `${c[0]}${c.slice( 1 ).toLowerCase()}` ) // Sequences of upper case
|
|
882
|
+
.replace( /([-_]\w)/g, c => c[1].toUpperCase() ) // first letter after hyphen and underline
|
|
883
|
+
.replace( /^([A-Z])/g, c => c[0].toLowerCase() ) // first letter
|
|
884
|
+
] )
|
|
885
|
+
// Rebuild the string replacing the converter terms keeping the original delimiters
|
|
886
|
+
.reduce( ( result, [ term, repl ] ) => result.replace( term, repl ), input );
|
|
887
|
+
|
|
888
|
+
|
|
889
|
+
/***/ }),
|
|
890
|
+
|
|
891
|
+
/***/ 258:
|
|
892
|
+
/***/ ((module) => {
|
|
893
|
+
|
|
894
|
+
module.exports = input =>
|
|
895
|
+
// Break the string into sequences to rebuild later
|
|
896
|
+
!input ? input : input.split( /\s/ )
|
|
897
|
+
// ALL_CAPS terms are ignored
|
|
898
|
+
.map( term => [ term, term.charAt( 0 ).toUpperCase() + term.slice( 1 ).toLowerCase() ] )
|
|
899
|
+
// Rebuild the string replacing the converter terms keeping the original delimiters
|
|
900
|
+
.reduce( ( result, [ term, repl ] ) => result.replace( term, repl ), input );
|
|
901
|
+
|
|
902
|
+
|
|
903
|
+
/***/ }),
|
|
904
|
+
|
|
905
|
+
/***/ 268:
|
|
906
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
907
|
+
|
|
908
|
+
const camelize = __webpack_require__( 914 );
|
|
909
|
+
const capitalizeWords = __webpack_require__( 258 );
|
|
910
|
+
const snakelize = __webpack_require__( 402 );
|
|
911
|
+
|
|
912
|
+
module.exports = {
|
|
913
|
+
camelize,
|
|
914
|
+
capitalizeWords,
|
|
915
|
+
snakelize
|
|
916
|
+
};
|
|
917
|
+
|
|
918
|
+
|
|
919
|
+
/***/ }),
|
|
920
|
+
|
|
921
|
+
/***/ 402:
|
|
922
|
+
/***/ ((module) => {
|
|
923
|
+
|
|
924
|
+
// convert a string to snake_case
|
|
925
|
+
module.exports = ( input, { keepAllCaps = false } = {} ) =>
|
|
926
|
+
// Break the string into sequences to rebuild later
|
|
927
|
+
!input ? input : input.split( /\s/ )
|
|
928
|
+
// ALL_CAPS terms are ignored
|
|
929
|
+
.map( term => [ term, keepAllCaps && /^[A-Z_]+$/g.test( term ) ? term : term
|
|
930
|
+
.replace( /-/g, '_' ) // replaces hyphen
|
|
931
|
+
.replace( /([a-z\d])([A-Z])/g, '$1_$2' ) // add _ between lower and upper case letters
|
|
932
|
+
.replace( /([A-Z])([A-Z])(?=[a-z\d])/g, '$1_$2' ).toLowerCase() // add _ between uppercase char and next uppercase char follow by lowercase
|
|
933
|
+
] )
|
|
934
|
+
// Rebuild the string replacing the converter terms keeping the original delimiters
|
|
935
|
+
.reduce( ( result, [ term, repl ] ) => result.replace( term, repl ), input );
|
|
936
|
+
|
|
937
|
+
|
|
938
|
+
/***/ }),
|
|
939
|
+
|
|
940
|
+
/***/ 878:
|
|
941
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
942
|
+
|
|
943
|
+
const retryOnError = __webpack_require__( 243 );
|
|
944
|
+
const sleep = __webpack_require__( 445 );
|
|
945
|
+
const Timer = __webpack_require__( 651 );
|
|
946
|
+
const untarJsonGz = __webpack_require__( 233 );
|
|
947
|
+
|
|
948
|
+
module.exports = {
|
|
949
|
+
retryOnError,
|
|
950
|
+
sleep,
|
|
951
|
+
Timer,
|
|
952
|
+
untarJsonGz
|
|
953
|
+
};
|
|
954
|
+
|
|
955
|
+
|
|
956
|
+
/***/ }),
|
|
957
|
+
|
|
958
|
+
/***/ 243:
|
|
959
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
960
|
+
|
|
961
|
+
const sleep = __webpack_require__( 445 );
|
|
962
|
+
|
|
963
|
+
const execWithRetry = async ( closure, { limit, delay, retryHook, execCount = 0 } ) => {
|
|
964
|
+
if ( !( closure instanceof Function ) ) {
|
|
965
|
+
throw new Error( 'Closure is not a function' );
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
try {
|
|
969
|
+
return await closure();
|
|
970
|
+
} catch ( error ) {
|
|
971
|
+
// exhausted
|
|
972
|
+
if ( execCount === limit ) { throw error; }
|
|
973
|
+
|
|
974
|
+
// async retry hook to check if it should retry or give up and throw
|
|
975
|
+
if ( retryHook instanceof Function ) {
|
|
976
|
+
try {
|
|
977
|
+
const retry = await retryHook( error, execCount );
|
|
978
|
+
if ( retry === false ) { return false; }
|
|
979
|
+
|
|
980
|
+
// Hook errors break the flow
|
|
981
|
+
} catch ( hookError ) {
|
|
982
|
+
console.debug( hookError );
|
|
983
|
+
throw hookError;
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
// if there is no hook back-off and retry
|
|
988
|
+
if ( delay > 0 ) {
|
|
989
|
+
await sleep( delay ** ( 1 + execCount ) );
|
|
990
|
+
}
|
|
991
|
+
return execWithRetry( closure, { limit, delay, retryHook, execCount: execCount + 1 } );
|
|
992
|
+
}
|
|
993
|
+
};
|
|
994
|
+
|
|
995
|
+
/**
|
|
996
|
+
*
|
|
997
|
+
* @param {Function} closure A self contained function that will be invoked
|
|
998
|
+
* @param {Object} config
|
|
999
|
+
* @param {Number} limit The max number of retries
|
|
1000
|
+
* @param {Number} delay The delay between each retry (it will be multiplied by the number of retries, so, it is linear back-off)
|
|
1001
|
+
* @param {Function} retryHook A function to be called every-time a retry is needed.
|
|
1002
|
+
* If this functions returns false, the retry error is raised
|
|
1003
|
+
* If this functions throws error, the thrown error is raised
|
|
1004
|
+
* @returns {Any} The closure result
|
|
1005
|
+
*/
|
|
1006
|
+
module.exports = async ( closure, { limit = 0, delay = 0, retryHook = null } = {} ) =>
|
|
1007
|
+
execWithRetry( closure, { limit, delay, retryHook } );
|
|
1008
|
+
|
|
1009
|
+
|
|
1010
|
+
/***/ }),
|
|
1011
|
+
|
|
1012
|
+
/***/ 445:
|
|
1013
|
+
/***/ ((module) => {
|
|
1014
|
+
|
|
1015
|
+
module.exports = t => new Promise( r => setTimeout( r, t ) );
|
|
1016
|
+
|
|
1017
|
+
|
|
1018
|
+
/***/ }),
|
|
1019
|
+
|
|
1020
|
+
/***/ 651:
|
|
1021
|
+
/***/ ((module) => {
|
|
1022
|
+
|
|
1023
|
+
module.exports = class Timer {
|
|
1024
|
+
#startedAt;
|
|
1025
|
+
#stoppedAt = null;
|
|
1026
|
+
#running = false;
|
|
1027
|
+
|
|
1028
|
+
get elapsed() {
|
|
1029
|
+
if ( this.#running ) {
|
|
1030
|
+
return Date.now() - this.#startedAt;
|
|
1031
|
+
} else if ( !this.#startedAt ) {
|
|
1032
|
+
return 0;
|
|
1033
|
+
} else {
|
|
1034
|
+
return this.#stoppedAt - this.#startedAt;
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
get running() {
|
|
1039
|
+
return this.#running;
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
start() {
|
|
1043
|
+
if ( !this.#running ) {
|
|
1044
|
+
this.#startedAt = Date.now();
|
|
1045
|
+
this.#running = true;
|
|
1046
|
+
}
|
|
1047
|
+
return this;
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
restart() {
|
|
1051
|
+
this.#running = true;
|
|
1052
|
+
this.#startedAt = Date.now();
|
|
1053
|
+
return this;
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
stop() {
|
|
1057
|
+
if ( this.#running ) {
|
|
1058
|
+
this.#running = false;
|
|
1059
|
+
this.#stoppedAt = Date.now();
|
|
1060
|
+
}
|
|
1061
|
+
return this.#stoppedAt - this.#startedAt;
|
|
1062
|
+
}
|
|
1063
|
+
};
|
|
1064
|
+
|
|
1065
|
+
|
|
1066
|
+
/***/ }),
|
|
1067
|
+
|
|
1068
|
+
/***/ 233:
|
|
1069
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
1070
|
+
|
|
1071
|
+
const { unzipSync } = __webpack_require__( 106 );
|
|
1072
|
+
|
|
1073
|
+
const firstIndexOf = ( c, ...vars ) => Math.min( ...vars.map( v => c.indexOf( v ) ).filter( n => n > -1 ) );
|
|
1074
|
+
const lastIndexOf = ( c, ...vars ) => Math.max( ...vars.map( v => c.lastIndexOf( v ) ) );
|
|
1075
|
+
|
|
1076
|
+
/**
|
|
1077
|
+
* Decompress JSON
|
|
1078
|
+
*
|
|
1079
|
+
* Reads a gzipped tarball (.tar.gz)
|
|
1080
|
+
* 1. Unzip it
|
|
1081
|
+
* 2. Convert all to utf-8
|
|
1082
|
+
* 3. Split files using the \0star separator
|
|
1083
|
+
* 4. Trim files until JSON markup start/end ({})
|
|
1084
|
+
* 5. JSON parse
|
|
1085
|
+
*
|
|
1086
|
+
* Enjoy this 100% native tarball decompression!
|
|
1087
|
+
*/
|
|
1088
|
+
module.exports = raw =>
|
|
1089
|
+
unzipSync( raw )
|
|
1090
|
+
.toString( 'utf-8' )
|
|
1091
|
+
.split( '\0ustar' )
|
|
1092
|
+
.slice( 1 )
|
|
1093
|
+
.map( c =>
|
|
1094
|
+
JSON.parse( c.substring( firstIndexOf( c, '{', '[' ), lastIndexOf( c, '}', ']' ) + 1 ) )
|
|
1095
|
+
);
|
|
1096
|
+
|
|
1097
|
+
|
|
1098
|
+
/***/ }),
|
|
1099
|
+
|
|
1100
|
+
/***/ 106:
|
|
1101
|
+
/***/ ((module) => {
|
|
1102
|
+
|
|
1103
|
+
module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("zlib");
|
|
1104
|
+
|
|
1105
|
+
/***/ })
|
|
1106
|
+
|
|
1107
|
+
/******/ });
|
|
1108
|
+
/************************************************************************/
|
|
1109
|
+
/******/ // The module cache
|
|
1110
|
+
/******/ var __webpack_module_cache__ = {};
|
|
1111
|
+
/******/
|
|
1112
|
+
/******/ // The require function
|
|
1113
|
+
/******/ function __webpack_require__(moduleId) {
|
|
1114
|
+
/******/ // Check if module is in cache
|
|
1115
|
+
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
|
1116
|
+
/******/ if (cachedModule !== undefined) {
|
|
1117
|
+
/******/ return cachedModule.exports;
|
|
1118
|
+
/******/ }
|
|
1119
|
+
/******/ // Create a new module (and put it into the cache)
|
|
1120
|
+
/******/ var module = __webpack_module_cache__[moduleId] = {
|
|
1121
|
+
/******/ // no module.id needed
|
|
1122
|
+
/******/ // no module.loaded needed
|
|
1123
|
+
/******/ exports: {}
|
|
1124
|
+
/******/ };
|
|
1125
|
+
/******/
|
|
1126
|
+
/******/ // Execute the module function
|
|
1127
|
+
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
1128
|
+
/******/
|
|
1129
|
+
/******/ // Return the exports of the module
|
|
1130
|
+
/******/ return module.exports;
|
|
1131
|
+
/******/ }
|
|
1132
|
+
/******/
|
|
1133
|
+
/************************************************************************/
|
|
1134
|
+
/******/
|
|
1135
|
+
/******/ // startup
|
|
1136
|
+
/******/ // Load entry module and return exports
|
|
1137
|
+
/******/ // This entry module is referenced by other modules so it can't be inlined
|
|
1138
|
+
/******/ var __webpack_exports__ = __webpack_require__(44);
|
|
1139
|
+
/******/
|