lambda-toolkit 1.1.0 → 2.0.0-dev.0

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