lambda-toolkit 0.0.2-beta → 0.0.4-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/dist/index.mjs DELETED
@@ -1,1139 +0,0 @@
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
- /******/