lambda-toolkit 1.1.1 → 2.0.0-dev.1

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 ADDED
@@ -0,0 +1,2254 @@
1
+ import { AthenaClient as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_athena_fac0b5e3_AthenaClient__, GetQueryExecutionCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_athena_fac0b5e3_GetQueryExecutionCommand__, GetQueryResultsCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_athena_fac0b5e3_GetQueryResultsCommand__, StartQueryExecutionCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_athena_fac0b5e3_StartQueryExecutionCommand__ } from "@aws-sdk/client-athena";
2
+ import { createHash as __WEBPACK_EXTERNAL_MODULE_node_crypto_803ecaf5_createHash__, randomBytes as __WEBPACK_EXTERNAL_MODULE_node_crypto_803ecaf5_randomBytes__ } from "node:crypto";
3
+ import { CloudWatchLogsClient as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_cloudwatch_logs_2ca14d81_CloudWatchLogsClient__, GetQueryResultsCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_cloudwatch_logs_2ca14d81_GetQueryResultsCommand__, StartQueryCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_cloudwatch_logs_2ca14d81_StartQueryCommand__ } from "@aws-sdk/client-cloudwatch-logs";
4
+ import { DynamoDBClient as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_dynamodb_8ad5c6c3_DynamoDBClient__ } from "@aws-sdk/client-dynamodb";
5
+ import { BatchWriteCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_lib_dynamodb_4ad47c88_BatchWriteCommand__, DeleteCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_lib_dynamodb_4ad47c88_DeleteCommand__, DynamoDBDocumentClient as __WEBPACK_EXTERNAL_MODULE__aws_sdk_lib_dynamodb_4ad47c88_DynamoDBDocumentClient__, GetCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_lib_dynamodb_4ad47c88_GetCommand__, PutCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_lib_dynamodb_4ad47c88_PutCommand__, QueryCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_lib_dynamodb_4ad47c88_QueryCommand__, ScanCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_lib_dynamodb_4ad47c88_ScanCommand__, TransactWriteCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_lib_dynamodb_4ad47c88_TransactWriteCommand__, UpdateCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_lib_dynamodb_4ad47c88_UpdateCommand__ } from "@aws-sdk/lib-dynamodb";
6
+ import { InvokeCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_lambda_45e15e4c_InvokeCommand__, LambdaClient as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_lambda_45e15e4c_LambdaClient__ } from "@aws-sdk/client-lambda";
7
+ import { CopyObjectCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_s3_166f32a4_CopyObjectCommand__, GetObjectCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_s3_166f32a4_GetObjectCommand__, HeadObjectCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_s3_166f32a4_HeadObjectCommand__, PutObjectCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_s3_166f32a4_PutObjectCommand__, S3Client as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_s3_166f32a4_S3Client__ } from "@aws-sdk/client-s3";
8
+ import { getSignedUrl as __WEBPACK_EXTERNAL_MODULE__aws_sdk_s3_request_presigner_c7ff9288_getSignedUrl__ } from "@aws-sdk/s3-request-presigner";
9
+ import { DeleteSuppressedDestinationCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_sesv2_6677e3b1_DeleteSuppressedDestinationCommand__, SESv2Client as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_sesv2_6677e3b1_SESv2Client__, SendEmailCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_sesv2_6677e3b1_SendEmailCommand__ } from "@aws-sdk/client-sesv2";
10
+ import { PublishBatchCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_sns_aa88aa43_PublishBatchCommand__, PublishCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_sns_aa88aa43_PublishCommand__, SNSClient as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_sns_aa88aa43_SNSClient__ } from "@aws-sdk/client-sns";
11
+ import { DeleteMessageCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_sqs_1f0ecae0_DeleteMessageCommand__, SQSClient as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_sqs_1f0ecae0_SQSClient__, SendMessageBatchCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_sqs_1f0ecae0_SendMessageBatchCommand__, SendMessageCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_sqs_1f0ecae0_SendMessageCommand__ } from "@aws-sdk/client-sqs";
12
+ import { GetParameterCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_ssm_6758df31_GetParameterCommand__, SSMClient as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_ssm_6758df31_SSMClient__ } from "@aws-sdk/client-ssm";
13
+ import { QueryCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_timestream_query_1be755b6_QueryCommand__, ScalarType as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_timestream_query_1be755b6_ScalarType__, TimestreamQueryClient as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_timestream_query_1be755b6_TimestreamQueryClient__ } from "@aws-sdk/client-timestream-query";
14
+ import { Agent as __WEBPACK_EXTERNAL_MODULE_https_Agent__ } from "https";
15
+ import { TimestreamWriteClient as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_timestream_write_3c1b228d_TimestreamWriteClient__, WriteRecordsCommand as __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_timestream_write_3c1b228d_WriteRecordsCommand__ } from "@aws-sdk/client-timestream-write";
16
+ import { unzipSync as __WEBPACK_EXTERNAL_MODULE_node_zlib_38f1fbfb_unzipSync__ } from "node:zlib";
17
+ /******/ // The require scope
18
+ /******/ var __webpack_require__ = {};
19
+ /******/
20
+ /************************************************************************/
21
+ /******/ /* webpack/runtime/define property getters */
22
+ /******/ (() => {
23
+ /******/ // define getter functions for harmony exports
24
+ /******/ __webpack_require__.d = (exports, definition) => {
25
+ /******/ for(var key in definition) {
26
+ /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
27
+ /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
28
+ /******/ }
29
+ /******/ }
30
+ /******/ };
31
+ /******/ })();
32
+ /******/
33
+ /******/ /* webpack/runtime/hasOwnProperty shorthand */
34
+ /******/ (() => {
35
+ /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
36
+ /******/ })();
37
+ /******/
38
+ /******/ /* webpack/runtime/make namespace object */
39
+ /******/ (() => {
40
+ /******/ // define __esModule on exports
41
+ /******/ __webpack_require__.r = (exports) => {
42
+ /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
43
+ /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
44
+ /******/ }
45
+ /******/ Object.defineProperty(exports, '__esModule', { value: true });
46
+ /******/ };
47
+ /******/ })();
48
+ /******/
49
+ /************************************************************************/
50
+ var __webpack_exports__ = {};
51
+
52
+ // NAMESPACE OBJECT: ./src/array/index.js
53
+ var array_namespaceObject = {};
54
+ __webpack_require__.r(array_namespaceObject);
55
+ __webpack_require__.d(array_namespaceObject, {
56
+ joinUnique: () => (joinUnique),
57
+ joinUniqueCustom: () => (joinUniqueCustom),
58
+ splitBatches: () => (splitBatches)
59
+ });
60
+
61
+ // NAMESPACE OBJECT: ./src/aws/index.js
62
+ var aws_namespaceObject = {};
63
+ __webpack_require__.r(aws_namespaceObject);
64
+ __webpack_require__.d(aws_namespaceObject, {
65
+ athena: () => (athena),
66
+ cwLogs: () => (cwLogs),
67
+ dynamo: () => (dynamo),
68
+ lambda: () => (lambda),
69
+ s3: () => (s3),
70
+ ses: () => (ses),
71
+ sns: () => (sns),
72
+ sqs: () => (sqs),
73
+ ssm: () => (ssm),
74
+ timestreamQuery: () => (timestreamQuery),
75
+ timestreamWrite: () => (timestreamWrite)
76
+ });
77
+
78
+ // NAMESPACE OBJECT: ./src/epoch/index.js
79
+ var epoch_namespaceObject = {};
80
+ __webpack_require__.r(epoch_namespaceObject);
81
+ __webpack_require__.d(epoch_namespaceObject, {
82
+ days: () => (days),
83
+ hours: () => (hours),
84
+ minutes: () => (minutes),
85
+ months: () => (months),
86
+ msToS: () => (msToS),
87
+ round: () => (round),
88
+ seconds: () => (seconds)
89
+ });
90
+
91
+ // NAMESPACE OBJECT: ./src/math/index.js
92
+ var math_namespaceObject = {};
93
+ __webpack_require__.r(math_namespaceObject);
94
+ __webpack_require__.d(math_namespaceObject, {
95
+ calcMean: () => (calcMean),
96
+ calcMedian: () => (calcMedian),
97
+ calcMedianAbsDev: () => (calcMedianAbsDev),
98
+ calcStdDevPopulation: () => (calcStdDevPopulation),
99
+ calcStdDevSample: () => (calcStdDevSample),
100
+ calcZScore: () => (calcZScore),
101
+ roundGaussian: () => (roundGaussian),
102
+ roundStandard: () => (roundStandard)
103
+ });
104
+
105
+ // NAMESPACE OBJECT: ./src/object/index.js
106
+ var object_namespaceObject = {};
107
+ __webpack_require__.r(object_namespaceObject);
108
+ __webpack_require__.d(object_namespaceObject, {
109
+ camelize: () => (camelize_camelize),
110
+ filterProps: () => (filterProps),
111
+ removeEmptyArrays: () => (removeEmptyArrays),
112
+ snakelize: () => (snakelize_snakelize)
113
+ });
114
+
115
+ // NAMESPACE OBJECT: ./src/redis/index.js
116
+ var redis_namespaceObject = {};
117
+ __webpack_require__.r(redis_namespaceObject);
118
+ __webpack_require__.d(redis_namespaceObject, {
119
+ createClient: () => (createClient)
120
+ });
121
+
122
+ // NAMESPACE OBJECT: ./src/string/index.js
123
+ var string_namespaceObject = {};
124
+ __webpack_require__.r(string_namespaceObject);
125
+ __webpack_require__.d(string_namespaceObject, {
126
+ camelize: () => (camelize),
127
+ capitalizeWords: () => (capitalizeWords),
128
+ snakelize: () => (snakelize)
129
+ });
130
+
131
+ // NAMESPACE OBJECT: ./src/utils/index.js
132
+ var utils_namespaceObject = {};
133
+ __webpack_require__.r(utils_namespaceObject);
134
+ __webpack_require__.d(utils_namespaceObject, {
135
+ Timer: () => (Timer),
136
+ retryOnError: () => (retryOnError),
137
+ sleep: () => (sleep_sleep),
138
+ untarJsonGz: () => (untarJsonGz)
139
+ });
140
+
141
+ ;// ./src/lambda_api/text_enum.js
142
+ const Text = {
143
+ ERROR_500: 'Internal Server Error',
144
+ ERROR_405: 'Method Not Allowed',
145
+ INVALID_ERROR_TYPE: 'Argument "errorType" must be a constructor Function',
146
+ INVALID_FN: 'Argument "fn" must be of type function',
147
+ INVALID_METHOD: 'Argument "method" must be one of the default HTTP methods',
148
+ INVALID_STATUS_CODE: 'Argument "statusCode" must be valid HTTP Status Code',
149
+ INVALID_TRANSFORM_REQUEST: 'Argument "transformRequest" must be either "camelize", "snakelize", false or null',
150
+ INVALID_TRANSFORM_RESPONSE: 'Argument "transformResponse" must be either "camelize", "snakelize", false or null',
151
+ INVALID_MATCHER_ROUTE: 'Argument "route" must be either undefined or an string with length greater than 0',
152
+ INVALID_MATCHER_ROUTE_INCLUDES: 'Argument "routeIncludes" must be either undefined or an string with length greater than 0',
153
+ INVALID_MATCHER_ROUTE_NOT_INCLUDES: 'Argument "routeNotIncludes" must be either undefined or an string with length greater than 0',
154
+ INVALID_MATCHER_ROUTE_MATCH: 'Argument "routeMatch" must be either undefined or type RegExp',
155
+ INVALID_MATCHER_PATH: 'Argument "path" must be either undefined or an string with length greater than 0',
156
+ INVALID_MATCHER_PATH_INCLUDES: 'Argument "pathIncludes" must be either undefined or an string with length greater than 0',
157
+ INVALID_MATCHER_PATH_NOT_INCLUDES: 'Argument "pathNotIncludes" must be either undefined or an string with length greater than 0',
158
+ INVALID_MATCHER_PATH_MATCH: 'Argument "pathMatch" must be either undefined or type RegExp',
159
+ 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)'
160
+ };
161
+
162
+ ;// ./src/lambda_api/lambda_api_validation_error.js
163
+ class LambdaApiValidationError extends Error {};
164
+
165
+ ;// ./src/lambda_api/validator.js
166
+
167
+
168
+
169
+ const evaluate = ( condition, errorMessage ) => {
170
+ if ( !condition ) { throw new LambdaApiValidationError( errorMessage ); }
171
+ };
172
+
173
+ const isConstructor = v => {
174
+ try {
175
+ return !!Reflect.construct( new Proxy( v, {} ), [] );
176
+ } catch {
177
+ return false;
178
+ }
179
+ };
180
+
181
+ const Validator = {
182
+ errorType: v => evaluate( isConstructor( v ), Text.INVALID_ERROR_TYPE ),
183
+ function: v => evaluate( typeof v === 'function', Text.INVALID_FN ),
184
+ httpMethod: v => evaluate( [ 'DELETE', 'GET', 'HEAD', 'PATCH', 'POST', 'PUT' ].includes( v ), Text.INVALID_METHOD ),
185
+ matcherPath: v => evaluate( v === undefined || ( typeof v === 'string' && v.length > 0 ), Text.INVALID_MATCHER_PATH ),
186
+ matcherPathIncludes: v => evaluate( v === undefined || ( typeof v === 'string' && v.length > 0 ), Text.INVALID_MATCHER_PATH_INCLUDES ),
187
+ matcherPathMatch: v => evaluate( v === undefined || v?.constructor?.name === RegExp.name, Text.INVALID_MATCHER_PATH_MATCH ),
188
+ matcherPathNotIncludes: v => evaluate( v === undefined || ( typeof v === 'string' && v.length > 0 ), Text.INVALID_MATCHER_PATH_NOT_INCLUDES ),
189
+ matcherRoute: v => evaluate( v === undefined || ( typeof v === 'string' && v.length > 0 ), Text.INVALID_MATCHER_ROUTE ),
190
+ matcherRouteIncludes: v => evaluate( v === undefined || ( typeof v === 'string' && v.length > 0 ), Text.INVALID_MATCHER_ROUTE_INCLUDES ),
191
+ matcherRouteMatch: v => evaluate( v === undefined || v?.constructor?.name === RegExp.name, Text.INVALID_MATCHER_ROUTE_MATCH ),
192
+ matcherRouteNotIncludes: v => evaluate( v === undefined || ( typeof v === 'string' && v.length > 0 ), Text.INVALID_MATCHER_ROUTE_NOT_INCLUDES ),
193
+ statusCode: v => evaluate( typeof v === 'number' && /^[1-5]\d\d$/.test( String( v ) ), Text.INVALID_STATUS_CODE ),
194
+ transformRequest: v => evaluate( [ 'camelcase', 'snakecase', null, false ].includes( v ), Text.INVALID_TRANSFORM_REQUEST ),
195
+ transformResponse: v => evaluate( [ 'camelcase', 'snakecase', null, false ].includes( v ), Text.INVALID_TRANSFORM_RESPONSE )
196
+ };
197
+
198
+ ;// ./src/object/is_serializable.js
199
+ const isSerializable = obj =>
200
+ typeof obj === 'object' &&
201
+ obj !== null &&
202
+ !( obj instanceof String ) &&
203
+ !( obj instanceof Number ) &&
204
+ !( obj instanceof Boolean ) &&
205
+ !( obj instanceof Date );
206
+
207
+ ;// ./src/string/camelize.js
208
+ // Convert a string to camelCase
209
+ const camelize = ( input, { keepAllCaps = false } = {} ) =>
210
+ // Break the string into sequences to rebuild later
211
+ !input ? input : input.split( /\s/ )
212
+ // ALL_CAPS terms are ignored
213
+ .map( term => [ term, keepAllCaps && /^[A-Z_]+$/g.test( term ) ? term : term
214
+ // Matches the penultimate letter in a sequence of upper case followed by lower case and convert it to lower case
215
+ // Effectively creating a word break eg: BDay => bDay
216
+ .replace( /[A-Z](?=[A-Z][a-z])/g, c => `${c[0].toLowerCase()}` )
217
+ .replace( /([A-Z])([A-Z]+)/g, c => `${c[0]}${c.slice( 1 ).toLowerCase()}` ) // Sequences of upper case
218
+ .replace( /([-_]\w)/g, c => c[1].toUpperCase() ) // first letter after hyphen and underline
219
+ .replace( /^([A-Z])/g, c => c[0].toLowerCase() ) // first letter
220
+ ] )
221
+ // Rebuild the string replacing the converter terms keeping the original delimiters
222
+ .reduce( ( result, [ term, repl ] ) => result.replace( term, repl ), input );
223
+
224
+ ;// ./src/object/camelize.js
225
+
226
+
227
+
228
+ const change = ( obj, keepAllCaps ) =>
229
+ !isSerializable( obj ) ? obj : Object.entries( obj ).reduce( ( transformed, [ key, value ] ) => {
230
+ delete transformed[key];
231
+ transformed[camelize( key, { keepAllCaps } )] = typeof value === 'object' ? change( value, keepAllCaps ) : value;
232
+ return transformed;
233
+ }, Array.isArray( obj ) ? [] : {} );
234
+
235
+ const camelize_camelize = ( obj, { keepAllCaps = false } = {} ) => change( obj, keepAllCaps );
236
+
237
+ ;// ./src/string/snakelize.js
238
+ // convert a string to snake_case
239
+ const snakelize = ( input, { keepAllCaps = false } = {} ) =>
240
+ // Break the string into sequences to rebuild later
241
+ !input ? input : input.split( /\s/ )
242
+ // ALL_CAPS terms are ignored
243
+ .map( term => [ term, keepAllCaps && /^[A-Z_]+$/g.test( term ) ? term : term
244
+ .replace( /-/g, '_' ) // replaces hyphen
245
+ .replace( /([a-z\d])([A-Z])/g, '$1_$2' ) // add _ between lower and upper case letters
246
+ .replace( /([A-Z])([A-Z])(?=[a-z\d])/g, '$1_$2' ).toLowerCase() // add _ between uppercase char and next uppercase char follow by lowercase
247
+ ] )
248
+ // Rebuild the string replacing the converter terms keeping the original delimiters
249
+ .reduce( ( result, [ term, repl ] ) => result.replace( term, repl ), input );
250
+
251
+ ;// ./src/object/snakelize.js
252
+
253
+
254
+
255
+ const snakelize_change = ( obj, keepAllCaps ) =>
256
+ !isSerializable( obj ) ? obj : Object.entries( obj ).reduce( ( transformed, [ key, value ] ) => {
257
+ delete transformed[key];
258
+ transformed[snakelize( key, { keepAllCaps } )] = typeof value === 'object' ? snakelize_change( value, keepAllCaps ) : value;
259
+ return transformed;
260
+ }, Array.isArray( obj ) ? [] : {} );
261
+
262
+ const snakelize_snakelize = ( obj, { keepAllCaps = false } = {} ) => snakelize_change( obj, keepAllCaps );
263
+
264
+ ;// ./src/lambda_api/api_response.js
265
+
266
+
267
+ const charset = 'utf-8';
268
+
269
+ const transformFns = {
270
+ camelcase: camelize_camelize,
271
+ snakecase: snakelize_snakelize
272
+ };
273
+
274
+ class ApiResponse {
275
+ #headers = null;
276
+ #statusCode = null;
277
+ #transformFn = false;
278
+ #isBase64Encoded = false;
279
+ #body = '';
280
+
281
+ constructor( { headers = {}, transform } = {} ) {
282
+ this.#transformFn = transformFns[transform] ?? ( v => v );
283
+ this.#headers = Object.assign( {
284
+ 'Cache-Control': 'no-store',
285
+ 'Access-Control-Allow-Origin': '*'
286
+ }, headers );
287
+ }
288
+
289
+ setContent( statusCode, body, headers = {}, isBase64Encoded = false ) {
290
+ this.#statusCode = statusCode;
291
+ this.#isBase64Encoded = isBase64Encoded;
292
+ if ( body?.length === 0 || [ null, undefined ].includes( body ) ) {
293
+ this.#body = '';
294
+ } else if ( typeof body === 'object' ) {
295
+ this.#body = JSON.stringify( this.#transformFn( body ) );
296
+ this.#headers['Content-Type'] = `application/json; charset=${charset}`;
297
+ } else {
298
+ this.#body = String( body );
299
+ this.#headers['Content-Type'] = `text/plain; charset=${charset}`;
300
+ }
301
+ this.#headers['Content-Length'] = this.#body.length;
302
+ Object.assign( this.#headers, headers ?? {} );
303
+ return this;
304
+ }
305
+
306
+ toJSON() {
307
+ return {
308
+ isBase64Encoded: this.#isBase64Encoded,
309
+ statusCode: this.#statusCode,
310
+ body: this.#body,
311
+ headers: this.#headers
312
+ };
313
+ }
314
+ };
315
+
316
+ ;// ./src/lambda_api/event.js
317
+
318
+
319
+ const event_transformFns = {
320
+ camelcase: camelize_camelize,
321
+ snakecase: snakelize_snakelize
322
+ };
323
+
324
+ const parseJson = content => {
325
+ try {
326
+ return JSON.parse( content );
327
+ } catch {
328
+ return content;
329
+ }
330
+ };
331
+
332
+ class Event {
333
+ #transformFn;
334
+ authorizer;
335
+ body;
336
+ rawBody;
337
+ headers;
338
+ method;
339
+ params;
340
+ path;
341
+ queryString;
342
+ route;
343
+
344
+ context = {};
345
+
346
+ constructor( { transform = false } = {} ) {
347
+ this.#transformFn = event_transformFns[transform] ?? ( v => v );
348
+ }
349
+
350
+ parseFromAwsEvent( awsEvent ) {
351
+ this[`parseFromAwsEventV${awsEvent.version === '2.0' ? 2 : 1}`]( awsEvent );
352
+ }
353
+
354
+ parseFromAwsEventV1( awsEvent ) {
355
+ const {
356
+ body,
357
+ path,
358
+ resource,
359
+ httpMethod,
360
+ requestContext,
361
+ pathParameters,
362
+ headers,
363
+ multiValueHeaders,
364
+ queryStringParameters,
365
+ multiValueQueryStringParameters: multiValueQueryString,
366
+ isBase64Encoded
367
+ } = awsEvent;
368
+
369
+ const unifiedHeaders = {
370
+ ...headers,
371
+ ...Object.fromEntries( Object.entries( multiValueHeaders ?? {} ).map( ( [ k, v ] ) => [ k, Array.isArray( v ) ? v.join( ',' ) : k ] ) )
372
+ };
373
+
374
+ const unifiedQueryString = {
375
+ ...queryStringParameters,
376
+ ...Object.fromEntries( Object.entries( multiValueQueryString ?? {} ).map( ( [ k, v ] ) => [ k, Array.isArray( v ) ? v.join( ',' ) : k ] ) )
377
+ };
378
+
379
+ this.authorizer = requestContext?.authorizer;
380
+ this.rawBody = body ?? null;
381
+ this.body = body ? this.#transformFn( parseJson( body ) ) : null;
382
+ this.headers = unifiedHeaders ?? {};
383
+ this.method = httpMethod;
384
+ this.params = this.#transformFn( pathParameters ) ?? {};
385
+ this.path = path;
386
+ this.queryString = this.#transformFn( unifiedQueryString ) ?? {};
387
+ this.route = resource;
388
+ this.isBase64Encoded = isBase64Encoded ?? false;
389
+ }
390
+
391
+ parseFromAwsEventV2( awsEvent ) {
392
+ const {
393
+ body,
394
+ routeKey,
395
+ requestContext,
396
+ pathParameters,
397
+ headers,
398
+ queryStringParameters,
399
+ isBase64Encoded
400
+ } = awsEvent;
401
+
402
+ const { http: { method, path } } = requestContext;
403
+
404
+ this.authorizer = requestContext?.authorizer;
405
+ this.rawBody = body ?? null;
406
+ this.body = body ? this.#transformFn( parseJson( body ) ) : null;
407
+ this.headers = headers ?? {};
408
+ this.method = method;
409
+ this.params = this.#transformFn( pathParameters ) ?? {};
410
+ this.path = path;
411
+ this.queryString = this.#transformFn( queryStringParameters ) ?? {};
412
+ this.route = routeKey?.split( ' ' )[1].replace( /\/$/, '' );
413
+ this.isBase64Encoded = isBase64Encoded ?? false;
414
+ }
415
+ };
416
+
417
+ ;// ./src/lambda_api/handler.js
418
+
419
+
420
+ class Handler {
421
+ #method;
422
+ #fn;
423
+ #route;
424
+ #routeIncludes;
425
+ #routeNotIncludes;
426
+ #routeMatches;
427
+ #path;
428
+ #pathIncludes;
429
+ #pathNotIncludes;
430
+ #pathMatches;
431
+
432
+ constructor( { method, fn, ...matchers } ) {
433
+ Validator.httpMethod( method );
434
+ Validator.function( fn );
435
+ Validator.matcherRoute( matchers.route );
436
+ Validator.matcherRouteIncludes( matchers.routeIncludes );
437
+ Validator.matcherRouteNotIncludes( matchers.routeNotIncludes );
438
+ Validator.matcherRouteMatch( matchers.routeMatch );
439
+ Validator.matcherPath( matchers.path );
440
+ Validator.matcherPathIncludes( matchers.pathIncludes );
441
+ Validator.matcherPathNotIncludes( matchers.pathNotIncludes );
442
+ Validator.matcherPathMatch( matchers.pathMatch );
443
+
444
+ this.#method = method;
445
+ this.#fn = fn;
446
+ this.#route = matchers.route;
447
+ this.#routeIncludes = matchers.routeIncludes;
448
+ this.#routeNotIncludes = matchers.routeNotIncludes;
449
+ this.#routeMatches = matchers.routeMatches;
450
+ this.#path = matchers.path;
451
+ this.#pathIncludes = matchers.pathIncludes;
452
+ this.#pathNotIncludes = matchers.pathNotIncludes;
453
+ this.#pathMatches = matchers.pathMatches;
454
+ }
455
+
456
+ match( event ) {
457
+ if ( this.#method !== event.method ) {
458
+ return false;
459
+ }
460
+ if ( this.#route ) {
461
+ return this.#route === event.route;
462
+ }
463
+ if ( this.#path ) {
464
+ return this.#path === event.path;
465
+ }
466
+ if ( this.#routeIncludes && !event.route.includes( this.#routeIncludes ) ) {
467
+ return false;
468
+ }
469
+ if ( this.#routeNotIncludes && event.route.includes( this.#routeNotIncludes ) ) {
470
+ return false;
471
+ }
472
+ if ( this.#routeMatches && !this.#routeMatches.test( event.route ) ) {
473
+ return false;
474
+ }
475
+ if ( this.#pathIncludes && !event.path.includes( this.#pathIncludes ) ) {
476
+ return false;
477
+ }
478
+ if ( this.#pathNotIncludes && event.path.includes( this.#pathNotIncludes ) ) {
479
+ return false;
480
+ }
481
+ if ( this.#pathMatches && !this.#pathMatches.test( event.path ) ) {
482
+ return false;
483
+ }
484
+ return true;
485
+ }
486
+
487
+ get fn() { return this.#fn; }
488
+ };
489
+
490
+ ;// ./src/lambda_api/hook.js
491
+
492
+
493
+ class Hook {
494
+ #fn;
495
+
496
+ constructor( { fn } ) {
497
+ Validator.function( fn );
498
+ this.#fn = fn;
499
+ }
500
+
501
+ get fn() { return this.#fn; }
502
+ };
503
+
504
+ ;// ./src/lambda_api/user_response.js
505
+
506
+
507
+
508
+
509
+ class UserResponse {
510
+ constructor( args ) {
511
+ if ( args === undefined ) {
512
+ this.values = [ 204 ];
513
+ } else if ( typeof args === 'string' && args.length === 0 ) {
514
+ this.values = [ 204 ];
515
+
516
+ } else if ( typeof args === 'string' && args.length > 0 ) {
517
+ this.values = [ 200, args ];
518
+
519
+ } else if ( typeof args === 'number' ) {
520
+ Validator.statusCode( args );
521
+ this.values = [ args ];
522
+
523
+ } else if ( Array.isArray( args ) ) {
524
+ Validator.statusCode( args[0] );
525
+ this.values = args;
526
+
527
+ } else if ( args.statusCode ) {
528
+ Validator.statusCode( args.statusCode );
529
+ this.values = [ args.statusCode, args.body, args.headers, args.isBase64Encoded ];
530
+
531
+ } else if ( [ undefined, null ].includes( args ) ) {
532
+ this.values = [ 200 ];
533
+ } else {
534
+ throw new LambdaApiValidationError( Text.INVALID_USER_RESPONSE );
535
+ }
536
+ }
537
+ };
538
+
539
+ ;// ./src/lambda_api/lambda_api.js
540
+
541
+
542
+
543
+
544
+
545
+
546
+
547
+
548
+ class LambdaApi {
549
+ #apiResponse = null;
550
+ #handlers = [];
551
+ #errorResponses = [];
552
+ #beforeHooks = [];
553
+ #afterHooks = [];
554
+ #transformRequest = [];
555
+
556
+ /**
557
+ * Creates a new Lambda Api
558
+ *
559
+ * @param {Object} headers Any headers you want to be included in all responses
560
+ */
561
+ constructor( { headers = {}, transformRequest = false, transformResponse = false } = {} ) {
562
+ Validator.transformRequest( transformRequest );
563
+ Validator.transformResponse( transformResponse );
564
+
565
+ this.#transformRequest = transformRequest;
566
+ this.#apiResponse = new ApiResponse( { headers, transform: transformResponse } );
567
+ }
568
+
569
+ /**
570
+ * Register a function that will run before the matching route (only if matches)
571
+ *
572
+ * @param {Object} args
573
+ * @param {function} args.fn A function
574
+ */
575
+ addBeforeHook( { fn } = {} ) {
576
+ this.#beforeHooks.push( new Hook( { fn } ) );
577
+ }
578
+
579
+ /**
580
+ * Register a function that will run after the matching route (only if matches)
581
+ *
582
+ * @param {Object} args
583
+ * @param {function} args.fn A function
584
+ */
585
+ addAfterHook( { fn } = {} ) {
586
+ this.#afterHooks.push( new Hook( { fn } ) );
587
+ }
588
+
589
+ /**
590
+ * Register a handler for a given request method and optionally a path
591
+ *
592
+ * @param {Object} args
593
+ * @param {string} args.method The method to match this handler
594
+ * @param {function} args.fn The handler function
595
+ * @param {string} [args.route] A route to match this handler
596
+ * @param {string} [args.routeIncludes] A part of the route to match this handler
597
+ * @param {string} [args.routeNotIncludes] A part of the route to not match this handler
598
+ * @param {RegExp} [args.routeMatches] A RegExp to match the route
599
+ * @param {string} [args.path] A path to match this handler
600
+ * @param {string} [args.pathIncludes] A part of the path to match this handler
601
+ * @param {string} [args.pathNotIncludes] A part of the path to not match this handler
602
+ * @param {RegExp} [args.pathMatches] A RegExp to match the path
603
+ */
604
+ addHandler( { method, fn, ...matchers } = {} ) {
605
+ this.#handlers.push( new Handler( { method, fn, ...matchers } ) );
606
+ }
607
+
608
+ /**
609
+ * Register an automatic error code response for given error class (constructor name)
610
+ *
611
+ * @param {Object} args
612
+ * @param {string} args.code The HTTP status code to return
613
+ * @param {class} args.errorType The error class
614
+ * @param {string} [args.message=null] Optional message to return for the status code, if not present will default to Error.message
615
+ * @param {message} [args.errorType] And optional message to display
616
+ */
617
+ addErrorHandler( { errorType, code, message = null } = {} ) {
618
+ Validator.statusCode( code );
619
+ Validator.errorType( errorType );
620
+ this.#errorResponses.push( { errorType, code, message } );
621
+ }
622
+
623
+ /**
624
+ * Init the flow using a given AWS Lambda APIGateway event (v2 syntax)
625
+ *
626
+ * @param {Object} ApiGatewayPayload The raw API Gateway event
627
+ * @returns {Object} The http response with status, body and headers
628
+ */
629
+ async process( awsEvent ) {
630
+ const event = new Event( { transform: this.#transformRequest } );
631
+ event.parseFromAwsEvent( awsEvent );
632
+
633
+ if ( event.method === 'HEAD' ) {
634
+ return this.#apiResponse.setContent( 204 ).toJSON();
635
+ }
636
+
637
+ const handler = this.#handlers.find( h => h.match( event ) );
638
+ if ( !handler ) {
639
+ return this.#apiResponse.setContent( 405, Text.ERROR_405 ).toJSON();
640
+ }
641
+
642
+ const chain = [
643
+ ...this.#beforeHooks.map( b => b.fn ),
644
+ async ev => {
645
+ const result = await handler.fn( ev );
646
+ const response = new UserResponse( result );
647
+ this.#apiResponse.setContent( ...response.values ).toJSON();
648
+ },
649
+ ...this.#afterHooks.map( a => a.fn )
650
+ ];
651
+
652
+ try {
653
+ for ( const fn of chain ) {
654
+ await fn( event );
655
+ }
656
+ return this.#apiResponse.toJSON();
657
+
658
+ } catch ( error ) {
659
+ console.error( 'Lambda API Error', { error, event } );
660
+
661
+ const response = this.#errorResponses.find( e => error instanceof e.errorType );
662
+ if ( response ) {
663
+ return this.#apiResponse.setContent( response.code, response.message ?? error.message ).toJSON();
664
+ }
665
+ return this.#apiResponse.setContent( 500, Text.ERROR_500 ).toJSON();
666
+ }
667
+ }
668
+ };
669
+
670
+ ;// ./src/lambda_api/index.js
671
+
672
+
673
+
674
+
675
+ ;// ./src/array/join_unique.js
676
+ const joinUnique = ( ...args ) => [ ...new Set( args.filter( Array.isArray ).flat() ) ];
677
+
678
+ ;// ./src/array/join_unique_custom.js
679
+ const joinUniqueCustom = ( { key, items } ) => [
680
+ ...items.filter( Array.isArray ).flat().reduce( ( map, v ) => {
681
+ const k = key( v );
682
+ if ( !map.has( k ) ) {
683
+ map.set( k, v );
684
+ }
685
+ return map;
686
+ }, new Map() ).values()
687
+ ];
688
+
689
+ ;// ./src/array/split_batches.js
690
+ const splitBatches = ( items, size ) => items.reduce( ( arrs, item ) =>
691
+ ( arrs[0] && arrs[0].length < size ) ?
692
+ [ [ ...arrs[0], item ] ].concat( arrs.slice( 1 ) ) :
693
+ [ [ item ] ].concat( arrs )
694
+ , [] ).reverse();
695
+
696
+ ;// ./src/array/index.js
697
+
698
+
699
+
700
+
701
+
702
+
703
+ ;// external "@aws-sdk/client-athena"
704
+
705
+ ;// external "node:crypto"
706
+
707
+ ;// ./src/aws/core/cache_storage.js
708
+
709
+
710
+ const cacheSym = Symbol.for( 'cache' );
711
+
712
+ const hash = text => __WEBPACK_EXTERNAL_MODULE_node_crypto_803ecaf5_createHash__( 'md5' ).update( text ).digest( 'hex' );
713
+
714
+ const propOpts = {
715
+ enumerable: false,
716
+ configurable: false,
717
+ writable: false
718
+ };
719
+
720
+ const CacheStorage = {
721
+ set: ( key, value ) => {
722
+ const keySym = Symbol.for( hash( key ) );
723
+
724
+ if ( !global[cacheSym] ) {
725
+ Object.defineProperty( global, cacheSym, { ...propOpts, value: {} } );
726
+ }
727
+
728
+ Object.defineProperty( global[cacheSym], keySym, { ...propOpts, value } );
729
+ },
730
+ get: key => {
731
+ return global[cacheSym]?.[Symbol.for( hash( key ) )];
732
+ }
733
+ };
734
+
735
+ ;// ./src/aws/core/generic_client_provider.js
736
+
737
+
738
+ const genericClientProvider = ( constructor, args = [] ) => {
739
+ const cacheKey = `${constructor.name}(${args.map( arg => JSON.stringify( arg ) ).join( ',' )})`;
740
+ return CacheStorage.get( cacheKey ) ?? ( () => {
741
+ const client = Reflect.construct( constructor, args );
742
+ CacheStorage.set( cacheKey, client );
743
+ return client;
744
+ } )();
745
+ };
746
+
747
+ ;// ./src/aws/core/encoder.js
748
+ const Encoder = {
749
+ encode: k => {
750
+ if ( k === null || k === undefined ) { return k; }
751
+
752
+ return Buffer.from( JSON.stringify( k ) ).toString( 'base64' );
753
+ },
754
+ decode: k => {
755
+ if ( k === null || k === undefined ) { return k; }
756
+
757
+ const result = Buffer.from( k, 'base64' ).toString( 'utf8' );
758
+ try {
759
+ return JSON.parse( result );
760
+ } catch {
761
+ return result;
762
+ }
763
+ }
764
+ };
765
+
766
+ ;// ./src/aws/athena/lib/start_query.js
767
+
768
+
769
+
770
+ /**
771
+ * args : https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/athena/command/StartQueryExecutionCommand/
772
+ * A ClientRequestToken is created automatically
773
+ */
774
+ const startQuery = async ( { client, ...args } ) => {
775
+ const cmd = new __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_athena_fac0b5e3_StartQueryExecutionCommand__( {
776
+ ClientRequestToken: __WEBPACK_EXTERNAL_MODULE_node_crypto_803ecaf5_randomBytes__( 16 ).toString( 'hex' ),
777
+ ...args
778
+ } );
779
+ const { QueryExecutionId: queryId } = await client.send( cmd );
780
+ return queryId;
781
+ };
782
+
783
+ ;// ./src/aws/athena/lib/parse_value.js
784
+ /* eslint consistent-return: 0 */
785
+ const removeNullValues = ( o, isArray = Array.isArray( o ) ) =>
786
+ Object.entries( o ).reduce( ( newObj, [ k, v ] ) => {
787
+ if ( v === null && !isArray ) { return newObj; }
788
+ return Object.assign( newObj, { [k]: v?.constructor === Object ? removeNullValues( v ) : v } );
789
+ }, isArray ? [] : {} );
790
+
791
+ const parseValue = ( v, type ) => {
792
+ if ( [ null, undefined ].includes( v ) ) {
793
+ return undefined;
794
+ }
795
+ if ( v === '' && type !== 'varchar' ) {
796
+ return undefined;
797
+ }
798
+ if ( type === 'boolean' ) {
799
+ return v === 'true';
800
+ }
801
+ if ( [ 'float', 'decimal', 'double' ].includes( type ) ) {
802
+ return parseFloat( v );
803
+ }
804
+ if ( [ 'tinyint', 'smallint', 'int', 'bigint' ].includes( type ) ) {
805
+ return parseInt( v );
806
+ }
807
+ if ( 'timestamp' === type ) {
808
+ return new Date( v ).getTime();
809
+ }
810
+ if ( [ 'row', 'array' ].includes( type ) ) {
811
+ const obj = v.replace( /(?<=(?:{|,\s)[\w-_]+)=/g, '@@DELIMITER@@' ) // replaces delimiter = with @@DELIMITER@@
812
+ .replace( /(?<={|,\s)([\w_-]+)(?=@@DELIMITER@@)/g, '"$1"' ) // wrap object keys
813
+ .replace( /(?<=@@DELIMITER@@)((?:(?!,\s|}|\[|{).)+)/g, '"$1"' ) // wrap object values
814
+ .replace( /(?<=\[|,\s)((?:(?!,\s|{|\]|").)+)/g, '"$1"' ) // wrap array values
815
+ .replace( /"null"/g, 'null' ) // convert "null" to null
816
+ .replace( /@@DELIMITER@@/g, ':' ); // replaces @@DELIMITER@@ for :
817
+
818
+ return removeNullValues( JSON.parse( obj ) );
819
+ }
820
+ if ( 'json' === type ) {
821
+ return JSON.parse( v );
822
+ }
823
+ return v;
824
+ };
825
+
826
+ ;// ./src/aws/athena/lib/parse_results.js
827
+
828
+
829
+ const parseResults = resultSet => {
830
+ const columns = resultSet.ResultSetMetadata.ColumnInfo
831
+ .map( col => ( { name: col.Name, type: col.Type } ) );
832
+
833
+ // first data row contains the table field names
834
+ return resultSet.Rows.slice( 1 ).map( row => {
835
+ const values = row.Data.map( d => d.VarCharValue );
836
+ return columns.reduce( ( obj, p, i ) => Object.assign( obj, { [p.name]: parseValue( values[i], p.type ) } ), {} );
837
+ } );
838
+ };
839
+
840
+ ;// ./src/aws/athena/lib/polling_delay.js
841
+ const pollingDelay = 500;
842
+
843
+ ;// ./src/aws/athena/lib/get_results.js
844
+
845
+
846
+
847
+
848
+ const sleep = t => new Promise( r => setTimeout( () => r(), t ) );
849
+
850
+ const getQueryResults = async ( { client, queryExecutionId, maxResults, token } ) => {
851
+ const { NextToken: nextToken, ResultSet } = await client.send( new __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_athena_fac0b5e3_GetQueryResultsCommand__( {
852
+ ...{ QueryExecutionId: queryExecutionId },
853
+ ...( maxResults ? { MaxResults: maxResults } : {} ),
854
+ ...( token ? { NextToken: token } : {} )
855
+ } ) );
856
+
857
+ return { nextToken, items: parseResults( ResultSet ) };
858
+ };
859
+ const getQueryResultsRecursive = async ( { client, queryExecutionId, token } ) => {
860
+ const { nextToken, items } = await getQueryResults( { client, queryExecutionId, token } );
861
+
862
+ if ( nextToken ) {
863
+ return { items: items.concat( ( await getQueryResultsRecursive( { client, queryExecutionId, token: nextToken } ) ).items ) };
864
+ }
865
+ return { items };
866
+ };
867
+
868
+ /**
869
+ * https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/athena/command/GetQueryResultsCommand/
870
+ * { client, recursive, queryExecutionId, maxResults, paginationToken }
871
+ */
872
+ const getResults = async ( { client, recursive, queryExecutionId, token, maxResults } ) => {
873
+ const { QueryExecution: { Status: status } } = await client.send( new __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_athena_fac0b5e3_GetQueryExecutionCommand__( { QueryExecutionId: queryExecutionId } ) );
874
+
875
+ if ( status.State === 'FAILED' ) {
876
+ throw new Error( status.AthenaError?.ErrorMessage ?? status.StateChangeReason );
877
+ }
878
+
879
+ if ( status.State === 'SUCCEEDED' ) {
880
+ const fn = recursive ? getQueryResultsRecursive : getQueryResults;
881
+ return fn( { client, recursive, queryExecutionId, token, maxResults } );
882
+ }
883
+
884
+ // sleep an try again
885
+ await sleep( pollingDelay );
886
+ return getResults( { client, recursive, queryExecutionId, token, maxResults } );
887
+ };
888
+
889
+ ;// ./src/aws/athena/query.js
890
+
891
+
892
+
893
+
894
+ const getQueryExecutionId = async ( { client, nativeArgs, recursive, paginationToken } ) => {
895
+ if ( !recursive && paginationToken ) {
896
+ const { queryExecutionId, token } = Encoder.decode( paginationToken );
897
+ return { queryExecutionId, token };
898
+ }
899
+
900
+ const queryExecutionId = await startQuery( { client, ...nativeArgs } );
901
+ return { queryExecutionId };
902
+ };
903
+
904
+ /**
905
+ * @class Result
906
+ * @type {Object}
907
+ * @property {Object[]} items Each query result row, parsed to a camelized js object
908
+ * @property {String} paginationToken The next pagination token, if recursive = false ans there are more results for the query
909
+ */
910
+
911
+ /**
912
+ * Executes an Athena Query
913
+ * @param {*} client The native client
914
+ * @param {Object} nativeArgs The native args to start the Athena Query
915
+ * @param {Object=} options Query configuration
916
+ * @param {Boolean=} [options.recursive=false] If to recursive query all results or to return a paginationToken after each page
917
+ * @param {String=} options.paginationToken The pagination token received in the previous call to resume the query (only used when recursive = false)
918
+ * @param {Number=} options.maxResults The maximum number of results per page (only when using pagination token)
919
+ * @returns {Result} The query result
920
+ */
921
+ const query = async ( client, nativeArgs, options ) => {
922
+ const { recursive = false, paginationToken, maxResults } = options;
923
+
924
+ const { queryExecutionId, token } = await getQueryExecutionId( { client, nativeArgs, recursive, paginationToken } );
925
+
926
+ const { nextToken, items } = await getResults( { client, queryExecutionId, token, recursive, maxResults } );
927
+ return { paginationToken: nextToken ? Encoder.encode( { queryExecutionId, token: nextToken } ) : undefined, items };
928
+ };
929
+
930
+ ;// ./src/aws/core/create_instance.js
931
+ /**
932
+ * This is base object each AWS abstraction will provide
933
+ */
934
+ const createInstance = ( providerFn, methods ) => {
935
+ // This creates the "instance",
936
+ // so calling the method as a function returns a copy of its client instantiated with the given args
937
+ // every method called from it will use this instance
938
+ const factory = args => {
939
+ const client = providerFn( args );
940
+ // return self, so it is possible use the native client
941
+ methods.getClient = () => client;
942
+ return Object.entries( methods ).reduce( ( o, [ k, v ] ) => Object.assign( o, { [k]: v.bind( null, client ) } ), { } );
943
+ };
944
+
945
+ // This is the singleton part;
946
+ // First add the static method to the factory;
947
+ Object.entries( methods ).forEach( ( [ key, value ] ) => factory[key] = value );
948
+
949
+ // Then add the special method "getClient", so it is possible use the native client
950
+ factory.getClient = client => client;
951
+
952
+ // Finally makes the proxy which will allow each singleton method to use the client provider of the AWS service+
953
+ return new Proxy( factory, {
954
+ get( target, key ) {
955
+ const t = target[key];
956
+ return ( typeof t === 'function' ) ? t.bind( null, providerFn() ) : t;
957
+ }
958
+ } );
959
+ };
960
+
961
+ ;// ./src/aws/athena/index.js
962
+
963
+
964
+
965
+
966
+
967
+ const methods = {
968
+ query: query
969
+ };
970
+
971
+ const athena = createInstance( genericClientProvider.bind( null, __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_athena_fac0b5e3_AthenaClient__ ), methods );
972
+
973
+ ;// external "@aws-sdk/client-cloudwatch-logs"
974
+
975
+ ;// ./src/aws/cw_logs/query/start_query.js
976
+
977
+
978
+ const start_query_startQuery = async ( { client, nativeArgs, range } ) => {
979
+ const startTime = range?.from ? Math.trunc( range.from / 1000 ) : nativeArgs.startTime;
980
+ const endTime = range?.to ? Math.trunc( range.to / 1000 ) : nativeArgs.endTime;
981
+
982
+ const { queryId } = await client.send( new __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_cloudwatch_logs_2ca14d81_StartQueryCommand__( { ...nativeArgs, startTime, endTime } ) );
983
+ return queryId;
984
+ };
985
+
986
+ ;// ./src/aws/cw_logs/query/polling_delay.js
987
+ const polling_delay_pollingDelay = 500;
988
+
989
+ ;// ./src/utils/sleep.js
990
+ const sleep_sleep = t => new Promise( r => setTimeout( r, t ) );
991
+
992
+ ;// ./src/aws/cw_logs/query/get_results.js
993
+
994
+
995
+
996
+
997
+ const getResultsRecursive = async ( { client, command } ) => {
998
+ const { results, status } = await client.send( command );
999
+
1000
+ if ( [ 'Cancelled', 'Failed', 'Timeout', 'Unknown' ].includes( status ) ) {
1001
+ throw new Error( `Query status is "${status}"` );
1002
+ }
1003
+
1004
+ if ( status === 'Complete' ) {
1005
+ return results;
1006
+ }
1007
+
1008
+ // Running, Scheduled
1009
+ await sleep_sleep( polling_delay_pollingDelay );
1010
+ return getResultsRecursive( { client, command } );
1011
+ };
1012
+
1013
+ const get_results_getResults = async ( { client, queryId } ) => {
1014
+ const command = new __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_cloudwatch_logs_2ca14d81_GetQueryResultsCommand__( { queryId } );
1015
+ return getResultsRecursive( { client, command } );
1016
+ };
1017
+
1018
+ ;// ./src/aws/cw_logs/query/parse_value.js
1019
+ const parseInteger = value => {
1020
+ const number = parseInt( value, 10 );
1021
+ return number <= Number.MAX_SAFE_INTEGER && number >= Number.MIN_SAFE_INTEGER ? number : value;
1022
+ };
1023
+
1024
+ const parseFloatingPoint = value => {
1025
+ if ( value.replace( /[^\d]/g, '' ).length > 16 ) {
1026
+ return value;
1027
+ }
1028
+ const number = parseFloat( value, 10 );
1029
+ return number <= Number.MAX_SAFE_INTEGER && number >= Number.MIN_SAFE_INTEGER ? number : value;
1030
+ };
1031
+
1032
+ /* eslint-disable consistent-return */
1033
+ const parse_value_parseValue = value => {
1034
+ if ( [ null, undefined ].includes( value ) ) {
1035
+ return undefined;
1036
+ }
1037
+
1038
+ if ( /^\d{4}-\d\d-\d\d((T| )\d\d:\d\d:\d\d(.\d{3})?(Z|\+\d\d:?\d\d)?)?$/.test( value ) ) {
1039
+ return new Date( value );
1040
+ }
1041
+
1042
+ // integer
1043
+ if ( /^-?\d+$/.test( value ) ) {
1044
+ return parseInteger( value );
1045
+ }
1046
+
1047
+ // float
1048
+ if ( /^-?(\d+\.|\.\d+|\d+\.\d+)$/.test( value ) ) {
1049
+ return parseFloatingPoint( value );
1050
+ }
1051
+
1052
+ // boolean
1053
+ if ( /^true$/.test( value ) ) {
1054
+ return true;
1055
+ }
1056
+
1057
+ if ( /^false$/.test( value ) ) {
1058
+ return false;
1059
+ }
1060
+
1061
+ return value;
1062
+ };
1063
+
1064
+ ;// ./src/aws/cw_logs/query/parse_item.js
1065
+
1066
+
1067
+ const parseItem = item =>
1068
+ item.reduce( ( row, { field, value } ) =>
1069
+ Object.assign( row, {
1070
+ [field]: parse_value_parseValue( value )
1071
+ } ), {} );
1072
+
1073
+ ;// ./src/aws/cw_logs/query/parse_results.js
1074
+
1075
+
1076
+ const parse_results_parseResults = results => results.map( item => parseItem( item ) );
1077
+
1078
+ ;// ./src/aws/cw_logs/query/index.js
1079
+
1080
+
1081
+
1082
+
1083
+ /**
1084
+ * @class Result
1085
+ * @type {Object}
1086
+ * @property {Object[]} items Each query result row, parsed to a camelized js object
1087
+ * @property {Number} count Total number of results
1088
+ */
1089
+
1090
+ /**
1091
+ * Executes an Athena Query
1092
+ * @param {*} client The native client
1093
+ * @param {Object} nativeArgs The native args to start the Cloudwatch Query
1094
+ * @param {Object=} options Extra options for this command
1095
+ * @param {Object=} options.range Since the nativeArgs "startTime" and "endTime" are second based epochs, the "range" argument accepts milliseconds based epochs for convenience, thus overwriting the "nativeArgs"
1096
+ * @param {Number} options.range.from The beginning of the time range to query, overwrites "startTime"
1097
+ * @param {Number} options.range.to The end of the time range to query, overwrites "endTime"
1098
+ * @returns {Result} The query result
1099
+ */
1100
+ const query_query = async ( client, nativeArgs, { range = {} } = {} ) => {
1101
+ const queryId = await start_query_startQuery( { client, nativeArgs, range } );
1102
+ const results = await get_results_getResults( { client, queryId } );
1103
+ const items = parse_results_parseResults( results );
1104
+ return { items, count: items.length };
1105
+ };
1106
+
1107
+ ;// ./src/aws/cw_logs/index.js
1108
+
1109
+
1110
+
1111
+
1112
+
1113
+ const cw_logs_methods = {
1114
+ query: query_query
1115
+ };
1116
+
1117
+ const cwLogs = createInstance( genericClientProvider.bind( null, __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_cloudwatch_logs_2ca14d81_CloudWatchLogsClient__ ), cw_logs_methods );
1118
+
1119
+ ;// external "@aws-sdk/client-dynamodb"
1120
+
1121
+ ;// external "@aws-sdk/lib-dynamodb"
1122
+
1123
+ ;// ./src/aws/dynamo/document_client_provider.js
1124
+
1125
+
1126
+
1127
+
1128
+ const documentClientProvider = nativeArgs => {
1129
+ const translateConfig = {
1130
+ // Yes I copied those from the docs, read more here:
1131
+ // https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/modules/_aws_sdk_lib_dynamodb.html#dynamodbdocumentclientresolvedconfig-1
1132
+ marshallOptions: {
1133
+ // Whether to automatically convert empty strings, blobs, and sets to `null`.
1134
+ convertEmptyValues: true, // false, by default.
1135
+ // Whether to remove undefined values while marshalling.
1136
+ removeUndefinedValues: true, // false, by default.
1137
+ // Whether to convert typeof object to map attribute.
1138
+ convertClassInstanceToMap: true // false, by default.
1139
+ },
1140
+ unmarshallOptions: {
1141
+ // Whether to return numbers as a string instead of converting them to native JavaScript numbers.
1142
+ wrapNumbers: false // false, by default.
1143
+ }
1144
+ };
1145
+
1146
+ const key = `Dynamodb(${JSON.stringify( nativeArgs )}).DocumentClient`;
1147
+ return CacheStorage.get( key ) ?? ( () => {
1148
+ const client = new __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_dynamodb_8ad5c6c3_DynamoDBClient__( nativeArgs );
1149
+ const docClient = __WEBPACK_EXTERNAL_MODULE__aws_sdk_lib_dynamodb_4ad47c88_DynamoDBDocumentClient__.from( client, translateConfig );
1150
+
1151
+ CacheStorage.set( key, docClient );
1152
+ return docClient;
1153
+ } )();
1154
+ };
1155
+
1156
+ ;// ./src/aws/dynamo/get.js
1157
+
1158
+
1159
+ const parseArgs = args => {
1160
+ // native args mode
1161
+ if ( args[0] instanceof Object ) {
1162
+ return args[0];
1163
+ }
1164
+ // sugar mode
1165
+ return {
1166
+ TableName: args[0],
1167
+ Key: args[1]
1168
+ };
1169
+ };
1170
+
1171
+ const get = async ( client, ...args ) => {
1172
+ const response = await client.send( new __WEBPACK_EXTERNAL_MODULE__aws_sdk_lib_dynamodb_4ad47c88_GetCommand__( parseArgs( args ) ) );
1173
+ return response.Item;
1174
+ };
1175
+
1176
+ ;// ./src/aws/dynamo/put.js
1177
+
1178
+
1179
+ const put_parseArgs = args => {
1180
+ // native args mode
1181
+ if ( args[0] instanceof Object ) {
1182
+ return args[0];
1183
+ }
1184
+ // sugar mode
1185
+ return {
1186
+ TableName: args[0],
1187
+ Item: args[1],
1188
+ ReturnValues: 'NONE',
1189
+ ReturnConsumedCapacity: 'NONE'
1190
+ };
1191
+ };
1192
+
1193
+ /**
1194
+ *
1195
+ * @param {*} client
1196
+ * @param {...any} args The args. either one object with the native args or two string args, tableName and item.
1197
+ * @returns
1198
+ */
1199
+ const put = async ( client, ...args ) => {
1200
+ const nativeArgs = put_parseArgs( args );
1201
+ const response = await client.send( new __WEBPACK_EXTERNAL_MODULE__aws_sdk_lib_dynamodb_4ad47c88_PutCommand__( nativeArgs ) );
1202
+ return response.Attributes ?? nativeArgs.Item;
1203
+ };
1204
+
1205
+ ;// ./src/aws/dynamo/batch_write.js
1206
+
1207
+
1208
+
1209
+ const batchSize = 25;
1210
+
1211
+ const getMapper = method => method === 'put' ? v => ( { PutRequest: { Item: v } } ) : v => ( { DeleteRequest: { Key: v } } );
1212
+
1213
+ const process = async ( { client, method, table, batches } ) => {
1214
+ if ( batches.length === 0 ) { return true; }
1215
+
1216
+ const response = await client.send( new __WEBPACK_EXTERNAL_MODULE__aws_sdk_lib_dynamodb_4ad47c88_BatchWriteCommand__( { RequestItems: { [table]: batches[0] } } ) );
1217
+
1218
+ const unprocessed = response.UnprocessedItems?.[table];
1219
+ return process( {
1220
+ client, method, table,
1221
+ batches: unprocessed ? splitBatches( batches.slice( 1 ).flat().concat( unprocessed ), batchSize ) : batches.slice( 1 )
1222
+ } );
1223
+ };
1224
+
1225
+ const batchWrite = async ( client, method, table, items ) =>
1226
+ process( { client, method, table, batches: splitBatches( items.map( getMapper( method ) ), batchSize ) } );
1227
+
1228
+ ;// ./src/aws/dynamo/put_batch.js
1229
+
1230
+
1231
+ const putBatch = async ( client, ...args ) => batchWrite( client, 'put', ...args );
1232
+
1233
+ ;// ./src/aws/dynamo/select.js
1234
+
1235
+
1236
+
1237
+ const select_query = async ( { client, command, args, recursive, startKey, items = [], count = 0 } ) => {
1238
+ const response = await client.send( new command( {
1239
+ ...args,
1240
+ ...( startKey && { ExclusiveStartKey: startKey } )
1241
+ } ) );
1242
+
1243
+ const isCount = args.Select === 'COUNT';
1244
+ const hasLimit = Number.isFinite( args.Limit );
1245
+
1246
+ const result = {
1247
+ items: isCount ? null : items.concat( response.Items ),
1248
+ count: count + response.Count,
1249
+ startKey: response.LastEvaluatedKey
1250
+ };
1251
+
1252
+ if ( !recursive ) {
1253
+ return { items: result.items, count: result.count, ...( result.startKey && { nextToken: Encoder.encode( result.startKey ) } ) };
1254
+ }
1255
+
1256
+ if ( result.startKey && ( isCount || ( hasLimit && result.items.length < args.Limit ) || ( !isCount && !hasLimit ) ) ) {
1257
+ return select_query( { client, command, args, recursive, ...result } );
1258
+ }
1259
+
1260
+ if ( isCount ) {
1261
+ return { items: null, count: result.count };
1262
+ }
1263
+ const trimmedItems = result.items.slice( 0, args.Limit );
1264
+ return { items: trimmedItems, count: trimmedItems.length };
1265
+ };
1266
+
1267
+ const select_select = async ( client, method, args, options = { recursive: false, paginationToken: null } ) => {
1268
+ const command = method === 'scan' ? __WEBPACK_EXTERNAL_MODULE__aws_sdk_lib_dynamodb_4ad47c88_ScanCommand__ : __WEBPACK_EXTERNAL_MODULE__aws_sdk_lib_dynamodb_4ad47c88_QueryCommand__;
1269
+
1270
+ return select_query( { client, command, args, recursive: options.recursive, startKey: Encoder.decode( options.paginationToken ) } );
1271
+ };
1272
+
1273
+ ;// ./src/aws/dynamo/query.js
1274
+
1275
+
1276
+ const dynamo_query_query = async ( client, ...args ) => select_select( client, 'query', ...args );
1277
+
1278
+ ;// ./src/aws/dynamo/remove.js
1279
+
1280
+
1281
+ const remove = async ( client, tableName, key ) => {
1282
+ const { Attributes: item } = await client.send( new __WEBPACK_EXTERNAL_MODULE__aws_sdk_lib_dynamodb_4ad47c88_DeleteCommand__( {
1283
+ ReturnValues: 'ALL_OLD',
1284
+ TableName: tableName,
1285
+ Key: key
1286
+ } ) );
1287
+ return item;
1288
+ };
1289
+
1290
+ ;// ./src/aws/dynamo/remove_batch.js
1291
+
1292
+
1293
+ const removeBatch = async ( client, ...args ) => batchWrite( client, 'remove', ...args );
1294
+
1295
+ ;// ./src/aws/dynamo/scan.js
1296
+
1297
+
1298
+ const scan = async ( client, ...args ) => select_select( client, 'scan', ...args );
1299
+
1300
+ ;// ./src/aws/dynamo/smart_update.js
1301
+
1302
+
1303
+ const smartUpdate = async ( client, tableName, key, keyValues ) => {
1304
+ const { updates, removals, names, values } = Object.entries( keyValues ).reduce( ( args, [ k, value ], index ) => {
1305
+ const isRemoval = value === undefined;
1306
+
1307
+ const attrs = k.split( '.' ).map( ( attr, i ) => {
1308
+ const arrayPosition = attr.match( /\[(\d+)\]$/ )?.[1];
1309
+ return {
1310
+ key: `#${attr.replace( /\[\d+\]$|[^a-zA-Z0-9_]/g, '' )}${i}`,
1311
+ name: attr.replace( /\[\d+\]$/g, '' ),
1312
+ arrayPosition
1313
+ };
1314
+ } );
1315
+ const fullPath = attrs.map( attr => attr.key + ( attr.arrayPosition ? `[${attr.arrayPosition}]` : '' ) ).join( '.' );
1316
+ const valueId = `:v${index}`;
1317
+ const expAttrNames = attrs.reduce( ( obj, attr ) =>
1318
+ Object.assign( {}, obj, { [attr.key]: attr.name } )
1319
+ , {} );
1320
+
1321
+ Object.assign( args.names, expAttrNames );
1322
+
1323
+ if ( isRemoval ) {
1324
+ args.removals.push( fullPath );
1325
+ } else {
1326
+ args.updates.push( fullPath + ' = ' + valueId );
1327
+ Object.assign( args.values, { [valueId]: value } );
1328
+ }
1329
+
1330
+ return args;
1331
+ }, { removals: [], updates: [], names: {}, values: {} } );
1332
+
1333
+ const conditionalExpressions = [];
1334
+ for ( const k of Object.keys( key ) ) {
1335
+ Object.assign( names, { [`#key_${k}`]: k } );
1336
+ conditionalExpressions.push( `attribute_exists(#key_${k})` );
1337
+ }
1338
+
1339
+ if ( updates.length + removals.length === 0 ) { return null; }
1340
+
1341
+ const expressions = [];
1342
+ if ( updates.length ) {
1343
+ expressions.push( 'SET ' + updates.join( ', ' ) );
1344
+ } if ( removals.length ) {
1345
+ expressions.push( 'REMOVE ' + removals.join( ', ' ) );
1346
+ }
1347
+
1348
+ const statement = {
1349
+ TableName: tableName,
1350
+ ReturnValues: 'ALL_NEW',
1351
+ Key: key,
1352
+ ConditionExpression: conditionalExpressions.join( ' AND ' ),
1353
+ UpdateExpression: expressions.join( ' ' ),
1354
+ ExpressionAttributeNames: names
1355
+ };
1356
+ if ( Object.keys( values ).length > 0 ) {
1357
+ statement.ExpressionAttributeValues = values;
1358
+ }
1359
+
1360
+ try {
1361
+ const response = await client.send( new __WEBPACK_EXTERNAL_MODULE__aws_sdk_lib_dynamodb_4ad47c88_UpdateCommand__( statement ) );
1362
+ return response.Attributes;
1363
+ } catch ( error ) {
1364
+ if ( error.constructor.name === 'ConditionalCheckFailedException' ) {
1365
+ console.info( 'Fail to update a record that was not found.' );
1366
+ return null;
1367
+ }
1368
+ throw error;
1369
+ }
1370
+ };
1371
+
1372
+ ;// ./src/aws/dynamo/transact_write.js
1373
+
1374
+
1375
+ const transactWrite = async ( client, items ) => {
1376
+ const response = await client.send( new __WEBPACK_EXTERNAL_MODULE__aws_sdk_lib_dynamodb_4ad47c88_TransactWriteCommand__( { TransactItems: items } ) );
1377
+ return response;
1378
+ };
1379
+
1380
+ ;// ./src/aws/dynamo/update.js
1381
+
1382
+
1383
+ const update = async ( client, nativeArgs ) => {
1384
+ const args = Object.assign( { ReturnValues: 'ALL_NEW' }, nativeArgs );
1385
+ const response = await client.send( new __WEBPACK_EXTERNAL_MODULE__aws_sdk_lib_dynamodb_4ad47c88_UpdateCommand__( args ) );
1386
+ return response.Attributes;
1387
+ };
1388
+
1389
+ ;// ./src/aws/dynamo/index.js
1390
+
1391
+
1392
+
1393
+
1394
+
1395
+
1396
+
1397
+
1398
+
1399
+
1400
+
1401
+
1402
+
1403
+ const dynamo_methods = {
1404
+ get: get,
1405
+ put: put,
1406
+ putBatch: putBatch,
1407
+ query: dynamo_query_query,
1408
+ remove: remove,
1409
+ removeBatch: removeBatch,
1410
+ scan: scan,
1411
+ smartUpdate: smartUpdate,
1412
+ transactWrite: transactWrite,
1413
+ update: update
1414
+ };
1415
+
1416
+ const dynamo = createInstance( documentClientProvider, dynamo_methods );
1417
+
1418
+ ;// external "@aws-sdk/client-lambda"
1419
+
1420
+ ;// ./src/aws/lambda/lambda_error.js
1421
+ const parsePayload = payload => {
1422
+ try {
1423
+ return JSON.parse( Buffer.from( payload ).toString( 'utf-8' ) );
1424
+ } catch {
1425
+ return null;
1426
+ }
1427
+ };
1428
+
1429
+ class LambdaError extends Error {
1430
+ constructor( response ) {
1431
+ const { StatusCode: statusCode, Payload: rawPayload } = response;
1432
+ const payload = parsePayload( rawPayload );
1433
+ const lambdaErrorType = payload?.errorType ?? Error.name;
1434
+ const lambdaErrorMessage = payload?.errorMessage;
1435
+ if ( statusCode === 200 ) {
1436
+ super( `Invoked function threw "[${lambdaErrorType}]${lambdaErrorMessage ? ' ' + lambdaErrorMessage : ''}"` );
1437
+ } else {
1438
+ super( 'Error invoking the function' );
1439
+ }
1440
+ this.statusCode = statusCode;
1441
+ this.lambdaErrorType = lambdaErrorType;
1442
+ this.lambdaErrorMessage = lambdaErrorMessage;
1443
+ }
1444
+ };
1445
+
1446
+ ;// ./src/aws/lambda/invoke.js
1447
+
1448
+
1449
+
1450
+ const invoke = async ( client, name, payload = {}, type = 'RequestResponse' ) => {
1451
+ const response = await client.send( new __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_lambda_45e15e4c_InvokeCommand__( {
1452
+ FunctionName: name,
1453
+ InvocationType: type,
1454
+ Payload: Buffer.from( JSON.stringify( payload ) )
1455
+ } ) );
1456
+
1457
+ if ( response.FunctionError ) {
1458
+ throw new LambdaError( response );
1459
+ }
1460
+
1461
+ if ( type !== 'RequestResponse' ) { return true; }
1462
+
1463
+ try {
1464
+ return JSON.parse( Buffer.from( response.Payload ).toString() );
1465
+ } catch {
1466
+ return response.Payload;
1467
+ }
1468
+ };
1469
+
1470
+ ;// ./src/aws/lambda/index.js
1471
+
1472
+
1473
+
1474
+
1475
+
1476
+ const lambda_methods = {
1477
+ invoke: invoke
1478
+ };
1479
+
1480
+ const lambda = createInstance( genericClientProvider.bind( null, __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_lambda_45e15e4c_LambdaClient__ ), lambda_methods );
1481
+
1482
+ ;// external "@aws-sdk/client-s3"
1483
+
1484
+ ;// ./src/aws/s3/copy.js
1485
+
1486
+
1487
+ const copy = async ( client, bucket, key, source, nativeArgs ) => {
1488
+ const response = await client.send( new __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_s3_166f32a4_CopyObjectCommand__( {
1489
+ ...nativeArgs,
1490
+ Bucket: bucket,
1491
+ Key: key,
1492
+ CopySource: source
1493
+ } ) );
1494
+ return response;
1495
+ };
1496
+
1497
+ ;// ./src/aws/s3/download.js
1498
+
1499
+
1500
+ const download = async ( client, bucket, key, nativeArgs ) => {
1501
+ const response = await client.send( new __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_s3_166f32a4_GetObjectCommand__( {
1502
+ ...nativeArgs,
1503
+ Bucket: bucket,
1504
+ Key: key
1505
+ } ) );
1506
+ const stream = response.Body;
1507
+ return Buffer.concat( await stream.toArray() ).toString( 'utf-8' );
1508
+ };
1509
+
1510
+ ;// external "@aws-sdk/s3-request-presigner"
1511
+
1512
+ ;// ./src/aws/s3/get_signed_url.js
1513
+
1514
+
1515
+
1516
+ const getSignedUrl = async ( client, bucket, key, expiration ) => {
1517
+ const getObjectCmd = new __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_s3_166f32a4_GetObjectCommand__( { Bucket: bucket, Key: key } );
1518
+ const url = await __WEBPACK_EXTERNAL_MODULE__aws_sdk_s3_request_presigner_c7ff9288_getSignedUrl__( client, getObjectCmd, { expiresIn: expiration } );
1519
+ return url;
1520
+ };
1521
+
1522
+ ;// ./src/aws/s3/head.js
1523
+
1524
+
1525
+ const head = async ( client, bucket, key ) =>
1526
+ client.send( new __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_s3_166f32a4_HeadObjectCommand__( { Bucket: bucket, Key: key } ) );
1527
+
1528
+ ;// ./src/aws/s3/upload.js
1529
+
1530
+
1531
+ const upload = ( client, bucket, key, body, nativeArgs ) =>
1532
+ client.send( new __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_s3_166f32a4_PutObjectCommand__( {
1533
+ ...nativeArgs,
1534
+ Bucket: bucket,
1535
+ Key: key,
1536
+ Body: typeof body === 'string' || Buffer.isBuffer( body ) ? body : JSON.stringify( body )
1537
+ } ) );
1538
+
1539
+ ;// ./src/aws/s3/index.js
1540
+
1541
+
1542
+
1543
+
1544
+
1545
+
1546
+
1547
+
1548
+
1549
+ const s3_methods = {
1550
+ copy: copy,
1551
+ download: download,
1552
+ getSignedUrl: getSignedUrl,
1553
+ head: head,
1554
+ upload: upload
1555
+ };
1556
+
1557
+ const s3 = createInstance( genericClientProvider.bind( null, __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_s3_166f32a4_S3Client__ ), s3_methods );
1558
+
1559
+ ;// external "@aws-sdk/client-sesv2"
1560
+
1561
+ ;// ./src/aws/ses/delete_suppressed_destination.js
1562
+
1563
+
1564
+ const deleteSuppressedDestination = ( client, address ) => client.send( new __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_sesv2_6677e3b1_DeleteSuppressedDestinationCommand__( { EmailAddress: address } ) );
1565
+
1566
+ ;// ./src/aws/ses/send_email.js
1567
+
1568
+
1569
+ const sendEmail = ( client, { to = [], from, html, subject }, args ) =>
1570
+ client.send( new __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_sesv2_6677e3b1_SendEmailCommand__( {
1571
+ Destination: {
1572
+ ToAddresses: to
1573
+ },
1574
+ Content: {
1575
+ Simple: {
1576
+ Body: {
1577
+ Html: {
1578
+ Data: html,
1579
+ Charset: 'utf-8'
1580
+ }
1581
+ },
1582
+ Subject: {
1583
+ Data: subject
1584
+ }
1585
+ }
1586
+ },
1587
+ FromEmailAddress: from,
1588
+ ...args
1589
+ } ) );
1590
+
1591
+ ;// ./src/aws/ses/index.js
1592
+
1593
+
1594
+
1595
+
1596
+
1597
+
1598
+ const ses_methods = {
1599
+ deleteSuppressedDestination: deleteSuppressedDestination,
1600
+ sendEmail: sendEmail
1601
+ };
1602
+
1603
+ const ses = createInstance( genericClientProvider.bind( null, __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_sesv2_6677e3b1_SESv2Client__ ), ses_methods );
1604
+
1605
+ ;// external "@aws-sdk/client-sns"
1606
+
1607
+ ;// ./src/aws/sns/publish.js
1608
+
1609
+
1610
+ const publish = async ( client, topic, message, args = {} ) => {
1611
+ const response = await client.send( new __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_sns_aa88aa43_PublishCommand__( {
1612
+ ...args,
1613
+ TopicArn: topic,
1614
+ Message: typeof message === 'string' ? message : JSON.stringify( message )
1615
+ } ) );
1616
+ return response.MessageId;
1617
+ };
1618
+
1619
+ ;// ./src/aws/sns/publish_batch.js
1620
+
1621
+
1622
+ const publishBatch = async ( client, topic, messages ) => {
1623
+ if ( messages.length > 10 ) {
1624
+ throw new Error( 'SNS.publishBatch only accepts up to 10 messages.' );
1625
+ }
1626
+ const response = await client.send( new __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_sns_aa88aa43_PublishBatchCommand__( {
1627
+ TopicArn: topic,
1628
+ PublishBatchRequestEntries: messages.map( ( { body, id = null, nativeArgs }, index ) => ( {
1629
+ Id: id ?? `message_${index}`,
1630
+ Message: typeof body === 'string' ? body : JSON.stringify( body ),
1631
+ ...nativeArgs
1632
+ } ) )
1633
+ } ) );
1634
+
1635
+ if ( response.Failed?.length > 0 ) {
1636
+ const error = new Error( 'SNS.publishBatch Failed. See error details' );
1637
+ error.details = response.Failed;
1638
+ throw error;
1639
+ }
1640
+ return response;
1641
+ };
1642
+
1643
+ ;// ./src/aws/sns/index.js
1644
+
1645
+
1646
+
1647
+
1648
+
1649
+
1650
+ const sns_methods = {
1651
+ publish: publish,
1652
+ publishBatch: publishBatch
1653
+ };
1654
+
1655
+ const sns = createInstance( genericClientProvider.bind( null, __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_sns_aa88aa43_SNSClient__ ), sns_methods );
1656
+
1657
+ ;// external "@aws-sdk/client-sqs"
1658
+
1659
+ ;// ./src/aws/sqs/delete_message.js
1660
+
1661
+
1662
+ const deleteMessage = async ( client, queue, receiptHandle ) =>
1663
+ client.send( new __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_sqs_1f0ecae0_DeleteMessageCommand__( {
1664
+ QueueUrl: queue,
1665
+ ReceiptHandle: receiptHandle
1666
+ } ) );
1667
+
1668
+ ;// ./src/aws/sqs/sanitize_sqs.js
1669
+ /*
1670
+ References:
1671
+ - https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html
1672
+ - https://stackoverflow.com/questions/58809098/remove-invalid-characters-from-message-sent-to-aws-amazon-sqs
1673
+ */
1674
+ const sanitizeSqs = v => v?.replace( /[^\u0009\u000A\u000D\u0020-\uD7FF\uE000-\uFFFD\u{10000}-\u{10FFFF}]/ug, '' ) // eslint-disable-line
1675
+
1676
+ ;// ./src/aws/sqs/send_message.js
1677
+
1678
+
1679
+
1680
+ const sendMessage = async ( client, queue, body, args ) => {
1681
+ const response = await client.send( new __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_sqs_1f0ecae0_SendMessageCommand__( {
1682
+ ...args,
1683
+ MessageBody: sanitizeSqs( typeof body === 'string' ? body : JSON.stringify( body ) ),
1684
+ QueueUrl: queue
1685
+ } ) );
1686
+ return response.MessageId;
1687
+ };
1688
+
1689
+ ;// ./src/aws/sqs/send_message_batch.js
1690
+
1691
+
1692
+
1693
+ const sendMessageBatch = async ( client, queue, messages ) => {
1694
+ if ( messages.length > 10 ) {
1695
+ throw new Error( 'SQS.sendMessageBatch only accepts up to 10 messages.' );
1696
+ }
1697
+ const response = await client.send( new __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_sqs_1f0ecae0_SendMessageBatchCommand__( {
1698
+ QueueUrl: queue,
1699
+ Entries: messages.map( ( { body, id = null, nativeArgs }, index ) => ( {
1700
+ Id: id ?? `message_${index}`,
1701
+ MessageBody: sanitizeSqs( typeof body === 'string' ? body : JSON.stringify( body ) ),
1702
+ ...nativeArgs
1703
+ } ) )
1704
+ } ) );
1705
+
1706
+ if ( response.Failed?.length > 0 ) {
1707
+ const error = new Error( 'SQS.sendMessageBatch Failed. See error details' );
1708
+ error.details = response.Failed;
1709
+ throw error;
1710
+ }
1711
+ return response;
1712
+ };
1713
+
1714
+ ;// ./src/aws/sqs/index.js
1715
+
1716
+
1717
+
1718
+
1719
+
1720
+
1721
+
1722
+ const sqs_methods = {
1723
+ deleteMessage: deleteMessage,
1724
+ sendMessage: sendMessage,
1725
+ sendMessageBatch: sendMessageBatch
1726
+ };
1727
+
1728
+ const sqs = createInstance( genericClientProvider.bind( null, __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_sqs_1f0ecae0_SQSClient__ ), sqs_methods );
1729
+
1730
+ ;// external "@aws-sdk/client-ssm"
1731
+
1732
+ ;// ./src/aws/ssm/get.js
1733
+
1734
+
1735
+
1736
+ const get_get = async ( client, name ) => {
1737
+ const key = `SSM_${name}`;
1738
+ const cacheValue = CacheStorage.get( key );
1739
+ if ( cacheValue ) { return cacheValue; }
1740
+
1741
+ try {
1742
+ const response = await client.send( new __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_ssm_6758df31_GetParameterCommand__( { Name: name, WithDecryption: true } ) );
1743
+ const value = response?.Parameter?.Value;
1744
+ CacheStorage.set( key, value );
1745
+ return value;
1746
+ } catch ( error ) {
1747
+ if ( error.constructor.name === 'ParameterNotFound' ) {
1748
+ return null;
1749
+ }
1750
+ throw error;
1751
+ }
1752
+ };
1753
+
1754
+ ;// ./src/aws/ssm/index.js
1755
+
1756
+
1757
+
1758
+
1759
+
1760
+ const ssm_methods = { get: get_get };
1761
+
1762
+ const ssm = createInstance( genericClientProvider.bind( null, __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_ssm_6758df31_SSMClient__ ), ssm_methods );
1763
+
1764
+ ;// external "@aws-sdk/client-timestream-query"
1765
+
1766
+ ;// ./src/aws/timestream_query/parse_items.js
1767
+ // https://docs.aws.amazon.com/timestream/latest/developerguide/API_query_Type.html
1768
+ // https://docs.aws.amazon.com/timestream/latest/developerguide/supported-data-types.html
1769
+
1770
+
1771
+
1772
+ const parseBigInt = value => {
1773
+ const asInt = parseInt( value, 10 );
1774
+ return asInt <= Number.MAX_SAFE_INTEGER && asInt >= Number.MIN_SAFE_INTEGER ? asInt : value;
1775
+ };
1776
+
1777
+ const parseScalarValue = ( type, value ) => {
1778
+ switch ( type ) {
1779
+ case __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_timestream_query_1be755b6_ScalarType__.BOOLEAN:
1780
+ return value === 'true';
1781
+ case __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_timestream_query_1be755b6_ScalarType__.DOUBLE:
1782
+ return parseFloat( value );
1783
+ case __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_timestream_query_1be755b6_ScalarType__.TIMESTAMP:
1784
+ return new Date( `${value.replace( ' ', 'T' )}Z` );
1785
+ case __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_timestream_query_1be755b6_ScalarType__.INTEGER:
1786
+ return parseInt( value, 10 );
1787
+ case __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_timestream_query_1be755b6_ScalarType__.UNKNOWN: // is NULL
1788
+ return null;
1789
+ case __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_timestream_query_1be755b6_ScalarType__.BIGINT:
1790
+ return parseBigInt( value );
1791
+ case __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_timestream_query_1be755b6_ScalarType__.VARCHAR:
1792
+ case __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_timestream_query_1be755b6_ScalarType__.DATE:
1793
+ case __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_timestream_query_1be755b6_ScalarType__.TIME:
1794
+ case __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_timestream_query_1be755b6_ScalarType__.INTERVAL_DAY_TO_SECOND:
1795
+ case __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_timestream_query_1be755b6_ScalarType__.INTERVAL_YEAR_TO_MONTH:
1796
+ default:
1797
+ return value;
1798
+ }
1799
+ };
1800
+
1801
+ const parse_items_parseValue = ( typeInfo, datum ) => {
1802
+ // value might be null
1803
+ if ( datum['NullValue'] === true ) {
1804
+ return null;
1805
+ }
1806
+
1807
+ // or a time series
1808
+ if ( Object.hasOwn( typeInfo, 'TimeSeriesMeasureValueColumnInfo' ) ) {
1809
+ return datum.TimeSeriesValue.map( v => ( {
1810
+ time: new Date( v.Time ),
1811
+ value: parse_items_parseValue( typeInfo.TimeSeriesMeasureValueColumnInfo.Type, v.Value )
1812
+ } ) );
1813
+ }
1814
+
1815
+ // maybe an array
1816
+ if ( Object.hasOwn( typeInfo, 'ArrayColumnInfo' ) ) {
1817
+ return datum.ArrayValue.map( v => parse_items_parseValue( typeInfo.ArrayColumnInfo.Type, v ) );
1818
+ }
1819
+
1820
+ // or even a row
1821
+ if ( Object.hasOwn( typeInfo, 'RowColumnInfo' ) ) {
1822
+ const rowColumnInfo = typeInfo.RowColumnInfo;
1823
+ return datum.RowValue.Data.reduce( ( object, value, index ) => {
1824
+ const { Name: name, Type: typeInfo } = rowColumnInfo[index];
1825
+ return Object.assign( object, { [name]: parse_items_parseValue( typeInfo, value ) } );
1826
+ }, {} );
1827
+ }
1828
+
1829
+ // if none, it is scalar
1830
+ return parseScalarValue( typeInfo.ScalarType, datum['ScalarValue'] );
1831
+ };
1832
+
1833
+ const parseItems = response => {
1834
+ const { ColumnInfo: colInfo, Rows: rows } = response;
1835
+ return rows.map( row =>
1836
+ row.Data.reduce( ( entry, value, index ) => {
1837
+ const { Name: name, Type: typeInfo } = colInfo[index];
1838
+ return Object.assign( entry, { [name]: parse_items_parseValue( typeInfo, value ) } );
1839
+ }, { } )
1840
+ );
1841
+ };
1842
+
1843
+ ;// ./src/aws/timestream_query/query.js
1844
+
1845
+
1846
+
1847
+
1848
+ const sendQuery = async ( client, queryString, { prevItems = [], recursive, paginationToken, maxRows, rawResponse } ) => {
1849
+ const response = await client.send( new __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_timestream_query_1be755b6_QueryCommand__( { QueryString: queryString, NextToken: paginationToken, MaxRows: maxRows } ) );
1850
+ if ( !recursive && rawResponse ) {
1851
+ return response;
1852
+ }
1853
+
1854
+ const nextToken = response.NextToken;
1855
+ if ( nextToken && recursive ) {
1856
+ return sendQuery( client, queryString, { prevItems: parseItems( response ), recursive, paginationToken: nextToken, maxRows } );
1857
+ }
1858
+
1859
+ const items = prevItems.concat( parseItems( response ) );
1860
+ return { nextToken, count: items.length, items, queryStatus: camelize_camelize( response.QueryStatus ) };
1861
+ };
1862
+
1863
+ const timestream_query_query_query =
1864
+ async ( client, queryString, { recursive = false, paginationToken = undefined, maxRows = undefined, rawResponse = false } = {} ) =>
1865
+ sendQuery( client, queryString, { recursive, paginationToken, maxRows, rawResponse } );
1866
+
1867
+ ;// external "https"
1868
+
1869
+ ;// ./src/aws/timestream_query/index.js
1870
+
1871
+
1872
+
1873
+
1874
+
1875
+
1876
+ const timestream_query_methods = { query: timestream_query_query_query };
1877
+ const defaultArgs = {
1878
+ maxRetries: 10,
1879
+ httpOptions: { timeout: 60000, agent: new __WEBPACK_EXTERNAL_MODULE_https_Agent__( { maxSockets: 5000 } ) }
1880
+ };
1881
+
1882
+ const timestreamQuery =
1883
+ createInstance( args => genericClientProvider( __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_timestream_query_1be755b6_TimestreamQueryClient__, [ Object.assign( {}, defaultArgs, args ) ] ), timestream_query_methods );
1884
+
1885
+ ;// external "@aws-sdk/client-timestream-write"
1886
+
1887
+ ;// ./src/aws/timestream_write/write_records.js
1888
+
1889
+
1890
+ const writeRecords = async ( client, { database, table, records, ignoreRejections = false } ) => {
1891
+ try {
1892
+ const response = await client.send( new __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_timestream_write_3c1b228d_WriteRecordsCommand__( {
1893
+ DatabaseName: database,
1894
+ TableName: table,
1895
+ Records: records
1896
+ } ) );
1897
+ return { recordsIngested: response.RecordsIngested };
1898
+ } catch ( error ) {
1899
+ if ( ignoreRejections && error.name === 'RejectedRecordsException' ) {
1900
+ return { rejectedRecords: error.RejectedRecords };
1901
+ }
1902
+ throw error;
1903
+ }
1904
+ };
1905
+
1906
+ ;// ./src/aws/timestream_write/index.js
1907
+
1908
+
1909
+
1910
+
1911
+
1912
+
1913
+ const timestream_write_methods = { writeRecords: writeRecords };
1914
+ const timestream_write_defaultArgs = {
1915
+ maxRetries: 10,
1916
+ httpOptions: { timeout: 60000, agent: new __WEBPACK_EXTERNAL_MODULE_https_Agent__( { maxSockets: 5000 } ) }
1917
+ };
1918
+
1919
+ const timestreamWrite =
1920
+ createInstance( args => genericClientProvider( __WEBPACK_EXTERNAL_MODULE__aws_sdk_client_timestream_write_3c1b228d_TimestreamWriteClient__, [ Object.assign( {}, timestream_write_defaultArgs, args ) ] ), timestream_write_methods );
1921
+
1922
+ ;// ./src/aws/index.js
1923
+
1924
+
1925
+
1926
+
1927
+
1928
+
1929
+
1930
+
1931
+
1932
+
1933
+
1934
+
1935
+
1936
+
1937
+ ;// ./src/epoch/days.js
1938
+ const days = t => t * 24 * 60 * 60 * 1000;
1939
+
1940
+ ;// ./src/epoch/hours.js
1941
+ const hours = t => t * 60 * 60 * 1000;
1942
+
1943
+ ;// ./src/epoch/minutes.js
1944
+ const minutes = t => t * 60 * 1000;
1945
+
1946
+ ;// ./src/epoch/months.js
1947
+ const months = t => t * 30 * 24 * 60 * 60 * 1000;
1948
+
1949
+ ;// ./src/epoch/ms_to_s.js
1950
+ const msToS = v => Math.ceil( v / 1000 );
1951
+
1952
+ ;// ./src/epoch/round.js
1953
+ const round = ( time, interval ) => time - ( time % interval );
1954
+
1955
+ ;// ./src/epoch/seconds.js
1956
+ const seconds = t => t * 1000;
1957
+
1958
+ ;// ./src/epoch/index.js
1959
+
1960
+
1961
+
1962
+
1963
+
1964
+
1965
+
1966
+
1967
+
1968
+
1969
+ ;// ./src/math/calc_mean.js
1970
+ const calcMean = values => values.reduce( ( sum, value ) => sum + value, 0 ) / values.length;
1971
+
1972
+ ;// ./src/math/calc_median.js
1973
+ const calcMedian = values => {
1974
+ //Sort bug: https://www.tutorialrepublic.com/faq/how-to-sort-an-array-of-integers-correctly-in-javascript.php
1975
+ const sorted = values.slice().sort( ( a, b ) => a - b );
1976
+ const evenArray = values.length % 2 === 0;
1977
+ const midIndex = Math.floor( values.length / 2 );
1978
+ return evenArray ? ( sorted[midIndex - 1] + sorted[midIndex] ) / 2 : sorted[midIndex];
1979
+ };
1980
+
1981
+ ;// ./src/math/calc_median_abs_dev.js
1982
+
1983
+
1984
+ const calcMedianAbsDev = pop => {
1985
+ const center = calcMedian( pop );
1986
+ return calcMedian( pop.map( v => Math.abs( v - center ) ) );
1987
+ };
1988
+
1989
+ ;// ./src/math/calc_std_dev_population.js
1990
+
1991
+
1992
+ const calcStdDevPopulation = values => {
1993
+ const mean = calcMean( values );
1994
+ const squareDiffs = values.map( value => Math.pow( value - mean, 2 ) );
1995
+ const avgSquareDiff = calcMean( squareDiffs );
1996
+ return Math.sqrt( avgSquareDiff );
1997
+ };
1998
+
1999
+ ;// ./src/math/calc_std_dev_sample.js
2000
+
2001
+
2002
+ const calcStdDevSample = values => {
2003
+ if ( values.length < 2 ) { return NaN; }
2004
+
2005
+ const mean = calcMean( values );
2006
+ const squareDiffs = values.map( value => Math.pow( value - mean, 2 ) );
2007
+ const avgSquareDiff = squareDiffs.reduce( ( sum, v ) => sum + v, 0 ) / ( values.length - 1 );
2008
+ return Math.sqrt( avgSquareDiff );
2009
+ };
2010
+
2011
+ ;// ./src/math/calc_z_score.js
2012
+ const calcZScore = ( sample, mean, stdDev ) => stdDev === 0 ? NaN : ( sample - mean ) / stdDev;
2013
+
2014
+ ;// ./src/math/round_gaussian.js
2015
+ const roundGaussian = ( n, d = 2 ) => {
2016
+ if ( !isFinite( n ) || typeof n !== 'number' ) { return NaN; }
2017
+
2018
+ const m = Math.pow( 10, d );
2019
+ const num = +( n * m ).toFixed( 8 ); // Avoid rounding errors
2020
+ const i = Math.floor( num );
2021
+ const f = num - i;
2022
+ const e = 1e-8; // Allow for rounding errors in f
2023
+ const r = ( f > 0.5 - e && f < 0.5 + e ) ? // eslint-disable-line no-nested-ternary
2024
+ ( ( i % 2 === 0 ) ? i : i + 1 ) : Math.round( num );
2025
+ return r / m;
2026
+ };
2027
+
2028
+ ;// ./src/math/round_standard.js
2029
+ const roundStandard = ( n, d = 2 ) => Math.round( n * ( 10 ** d ) ) / ( 10 ** d );
2030
+
2031
+ ;// ./src/math/index.js
2032
+
2033
+
2034
+
2035
+
2036
+
2037
+
2038
+
2039
+
2040
+
2041
+
2042
+
2043
+ ;// ./src/object/filter_props.js
2044
+ const filterProps = ( obj, props ) => Object.fromEntries( Object.entries( obj ).filter( ( [ k ] ) => props.includes( k ) ) );
2045
+
2046
+ ;// ./src/object/remove_empty_arrays.js
2047
+ const removeEmptyArrays = o => Object.fromEntries( Object.entries( o ).filter( ( [ , v ] ) => !Array.isArray( v ) || v.length > 0 ) );
2048
+
2049
+ ;// ./src/object/index.js
2050
+
2051
+
2052
+
2053
+
2054
+
2055
+
2056
+
2057
+ ;// ./src/redis/create_client.js
2058
+ global.__redisInstances = {};
2059
+
2060
+ /**
2061
+ * Create a redis client instance
2062
+ *
2063
+ * @param {Object} args
2064
+ * @param {Object} args.redis Redis npm dependency
2065
+ * @param {String} args.address Redis DB address (either RW or RO)
2066
+ * @param {String} [args.protocol=rediss] Redis connection protocol
2067
+ * @param {String} [args.port=6379] Redis DB connection port
2068
+ * @returns redisClient A new redis client instance connected to the database
2069
+ */
2070
+ const createClient = async ( { redis, address, protocol = 'rediss', port = 6379 } ) => {
2071
+ if ( global.__redisInstances[address] ) {
2072
+ try {
2073
+ const r = await global.__redisInstances[address].ping();
2074
+ if ( r === 'PONG' ) {
2075
+ return global.__redisInstances[address];
2076
+ } else {
2077
+ delete global.__redisInstances[address];
2078
+ }
2079
+ } catch {
2080
+ delete global.__redisInstances[address];
2081
+ }
2082
+ }
2083
+
2084
+ const client = redis.createClient( { url: `${protocol}://${address}:${port}`, socket: { keepAlive: 15000 } } );
2085
+
2086
+ await client.connect();
2087
+
2088
+ global.__redisInstances[address] = client;
2089
+ return client;
2090
+ };
2091
+
2092
+ ;// ./src/redis/index.js
2093
+
2094
+
2095
+
2096
+
2097
+ ;// ./src/string/capitalize_words.js
2098
+ const capitalizeWords = input =>
2099
+ // Break the string into sequences to rebuild later
2100
+ !input ? input : input.split( /\s/ )
2101
+ // ALL_CAPS terms are ignored
2102
+ .map( term => [ term, term.charAt( 0 ).toUpperCase() + term.slice( 1 ).toLowerCase() ] )
2103
+ // Rebuild the string replacing the converter terms keeping the original delimiters
2104
+ .reduce( ( result, [ term, repl ] ) => result.replace( term, repl ), input );
2105
+
2106
+ ;// ./src/string/index.js
2107
+
2108
+
2109
+
2110
+
2111
+
2112
+
2113
+ ;// ./src/utils/retry_on_error.js
2114
+
2115
+
2116
+ const execWithRetry = async ( closure, { limit, delay, retryHook, execCount = 0 } ) => {
2117
+ if ( !( closure instanceof Function ) ) {
2118
+ throw new Error( 'Closure is not a function' );
2119
+ }
2120
+
2121
+ try {
2122
+ return await closure();
2123
+ } catch ( error ) {
2124
+ // exhausted
2125
+ if ( execCount === limit ) { throw error; }
2126
+
2127
+ // async retry hook to check if it should retry or give up and throw
2128
+ if ( retryHook instanceof Function ) {
2129
+ try {
2130
+ const retry = await retryHook( error, execCount );
2131
+ if ( retry === false ) { return false; }
2132
+
2133
+ // Hook errors break the flow
2134
+ } catch ( hookError ) {
2135
+ console.debug( hookError );
2136
+ throw hookError;
2137
+ }
2138
+ }
2139
+
2140
+ // if there is no hook back-off and retry
2141
+ if ( delay > 0 ) {
2142
+ await sleep_sleep( delay ** ( 1 + execCount ) );
2143
+ }
2144
+ return execWithRetry( closure, { limit, delay, retryHook, execCount: execCount + 1 } );
2145
+ }
2146
+ };
2147
+
2148
+ /**
2149
+ *
2150
+ * @param {Function} closure A self contained function that will be invoked
2151
+ * @param {Object} config
2152
+ * @param {Number} config.limit The max number of retries
2153
+ * @param {Number} config.delay The delay between each retry (it will be raised to the power of the number of retries, so it is exponential back-off)
2154
+ * @param {Function} config.retryHook A function to be called every time a retry is needed.
2155
+ * If this functions returns true, the retry flow continues until limit
2156
+ * If this functions returns false, the retry flow is aborted, returning false
2157
+ * If this functions throws an error, the retry flow is aborted with that error
2158
+ * @returns {Any} The closure result
2159
+ */
2160
+ const retryOnError = async ( closure, { limit = 0, delay = 0, retryHook = null } = {} ) =>
2161
+ execWithRetry( closure, { limit, delay, retryHook } );
2162
+
2163
+ ;// ./src/utils/timer.js
2164
+ class Timer {
2165
+ #startedAt;
2166
+ #stoppedAt = null;
2167
+ #running = false;
2168
+
2169
+ get elapsed() {
2170
+ if ( this.#running ) {
2171
+ return Date.now() - this.#startedAt;
2172
+ } else if ( !this.#startedAt ) {
2173
+ return 0;
2174
+ } else {
2175
+ return this.#stoppedAt - this.#startedAt;
2176
+ }
2177
+ }
2178
+
2179
+ get running() {
2180
+ return this.#running;
2181
+ }
2182
+
2183
+ start() {
2184
+ if ( !this.#running ) {
2185
+ this.#startedAt = Date.now();
2186
+ this.#running = true;
2187
+ }
2188
+ return this;
2189
+ }
2190
+
2191
+ restart() {
2192
+ this.#running = true;
2193
+ this.#startedAt = Date.now();
2194
+ return this;
2195
+ }
2196
+
2197
+ stop() {
2198
+ if ( this.#running ) {
2199
+ this.#running = false;
2200
+ this.#stoppedAt = Date.now();
2201
+ }
2202
+ return this.#stoppedAt - this.#startedAt;
2203
+ }
2204
+ };
2205
+
2206
+ ;// external "node:zlib"
2207
+
2208
+ ;// ./src/utils/untar_json_gz.js
2209
+
2210
+
2211
+ const firstIndexOf = ( c, ...vars ) => Math.min( ...vars.map( v => c.indexOf( v ) ).filter( n => n > -1 ) );
2212
+ const lastIndexOf = ( c, ...vars ) => Math.max( ...vars.map( v => c.lastIndexOf( v ) ) );
2213
+
2214
+ /**
2215
+ * Decompress JSON
2216
+ *
2217
+ * Reads a gzipped tarball (.tar.gz)
2218
+ * 1. Unzip it
2219
+ * 2. Convert all to utf-8
2220
+ * 3. Split files using the \0star separator
2221
+ * 4. Trim files until JSON markup start/end ({})
2222
+ * 5. JSON parse
2223
+ *
2224
+ * Enjoy this 100% native tarball decompression!
2225
+ */
2226
+ const untarJsonGz = raw =>
2227
+ __WEBPACK_EXTERNAL_MODULE_node_zlib_38f1fbfb_unzipSync__( raw )
2228
+ .toString( 'utf-8' )
2229
+ .split( '\0ustar' )
2230
+ .slice( 1 )
2231
+ .map( c =>
2232
+ JSON.parse( c.substring( firstIndexOf( c, '{', '[' ), lastIndexOf( c, '}', ']' ) + 1 ) )
2233
+ );
2234
+
2235
+ ;// ./src/utils/index.js
2236
+
2237
+
2238
+
2239
+
2240
+
2241
+
2242
+
2243
+ ;// ./src/index.mjs
2244
+
2245
+
2246
+
2247
+
2248
+
2249
+
2250
+
2251
+
2252
+
2253
+
2254
+ export { LambdaApi, array_namespaceObject as array, aws_namespaceObject as aws, epoch_namespaceObject as epoch, math_namespaceObject as math, object_namespaceObject as object, redis_namespaceObject as redis, string_namespaceObject as string, utils_namespaceObject as utils };