From eb69a08952aaf15936c0a3960b391b2680bdf02a Mon Sep 17 00:00:00 2001 From: oleiade Date: Mon, 25 Apr 2022 13:46:39 +0200 Subject: [PATCH 1/7] Implement S3Client.listObjects prefix parameter support --- build/aws.min.js | 2 +- build/aws.min.js.map | 2 +- build/s3.min.js | 2 +- build/s3.min.js.map | 2 +- src/internal/s3.ts | 15 +++++---------- 5 files changed, 9 insertions(+), 14 deletions(-) diff --git a/build/aws.min.js b/build/aws.min.js index 86a7537..70f7120 100644 --- a/build/aws.min.js +++ b/build/aws.min.js @@ -1,2 +1,2 @@ -(()=>{var e={877:(e,t,r)=>{var n=r(570),o=r(171),i=o;i.v1=n,i.v4=o,e.exports=i},327:e=>{for(var t=[],r=0;r<256;++r)t[r]=(r+256).toString(16).substr(1);e.exports=function(e,r){var n=r||0,o=t;return[o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]]].join("")}},217:e=>{var t="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof window.msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto);if(t){var r=new Uint8Array(16);e.exports=function(){return t(r),r}}else{var n=new Array(16);e.exports=function(){for(var e,t=0;t<16;t++)0==(3&t)&&(e=4294967296*Math.random()),n[t]=e>>>((3&t)<<3)&255;return n}}},570:(e,t,r)=>{var n,o,i=r(217),c=r(327),a=0,u=0;e.exports=function(e,t,r){var s=t&&r||0,f=t||[],l=(e=e||{}).node||n,p=void 0!==e.clockseq?e.clockseq:o;if(null==l||null==p){var h=i();null==l&&(l=n=[1|h[0],h[1],h[2],h[3],h[4],h[5]]),null==p&&(p=o=16383&(h[6]<<8|h[7]))}var y=void 0!==e.msecs?e.msecs:(new Date).getTime(),d=void 0!==e.nsecs?e.nsecs:u+1,b=y-a+(d-u)/1e4;if(b<0&&void 0===e.clockseq&&(p=p+1&16383),(b<0||y>a)&&void 0===e.nsecs&&(d=0),d>=1e4)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");a=y,u=d,o=p;var v=(1e4*(268435455&(y+=122192928e5))+d)%4294967296;f[s++]=v>>>24&255,f[s++]=v>>>16&255,f[s++]=v>>>8&255,f[s++]=255&v;var m=y/4294967296*1e4&268435455;f[s++]=m>>>8&255,f[s++]=255&m,f[s++]=m>>>24&15|16,f[s++]=m>>>16&255,f[s++]=p>>>8|128,f[s++]=255&p;for(var g=0;g<6;++g)f[s+g]=l[g];return t||c(f)}},171:(e,t,r)=>{var n=r(217),o=r(327);e.exports=function(e,t,r){var i=t&&r||0;"string"==typeof e&&(t="binary"===e?new Array(16):null,e=null);var c=(e=e||{}).random||(e.rng||n)();if(c[6]=15&c[6]|64,c[8]=63&c[8]|128,t)for(var a=0;a<16;++a)t[i+a]=c[a];return t||o(c)}}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var i=t[n]={exports:{}};return e[n](i,i.exports,r),i.exports}r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var n={};(()=>{"use strict";r.r(n),r.d(n,{AWSConfig:()=>V,InvalidAWSConfigError:()=>F,InvalidSignatureError:()=>R,S3Bucket:()=>ye,S3Client:()=>he,S3Object:()=>de,S3ServiceError:()=>be,Secret:()=>Ne,SecretsManagerClient:()=>De,SecretsManagerError:()=>qe,URIEncodingConfig:()=>D,signHeaders:()=>C});const e=require("k6/crypto");var t=r.n(e);const o=require("k6/html");function i(e){return i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i(e)}function c(e,t){for(var r=0;re.length)&&(t=e.length);for(var r=0,n=new Array(t);r="A"&&r<="Z"||r>="a"&&r<="z"||function(e){return e>="0"&&e<="9"}(e)||"-._~".includes(e)?e:" "==e?"%20":"/"==e&&t?"/":"%"+e.charCodeAt(0).toString(16).toUpperCase();var r})).join("")}var D=w((function e(t,r){O(this,e),b(this,"double",void 0),b(this,"path",void 0),this.double=t,this.path=r}));function N(e){return new Date(e).toISOString().replace(/[:\-]|\.\d{3}/g,"")}function q(e){return N(e).substring(0,8)}function I(e){return I="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},I(e)}function M(e,t){if(t&&("object"===I(t)||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e)}function z(e){var t="function"==typeof Map?new Map:void 0;return z=function(e){if(null===e||(r=e,-1===Function.toString.call(r).indexOf("[native code]")))return e;var r;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return H(e,arguments,B(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),U(n,e)},z(e)}function H(e,t,r){return H=L()?Reflect.construct:function(e,t,r){var n=[null];n.push.apply(n,t);var o=new(Function.bind.apply(e,n));return r&&U(o,r.prototype),o},H.apply(null,arguments)}function L(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}function U(e,t){return U=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},U(e,t)}function B(e){return B=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},B(e)}function X(e,t){for(var r=0;r=1400&&r<=1499){var o=n.Message||n.message||n.__type;if("InvalidSignatureException"===n.__type)throw new R(o,n.__type);throw new qe(o,n.__type,e)}if(1500===r)throw new qe("An error occured on the server side","InternalServiceError",e)}}}]),r}(Q),Ne=function(){function e(t,r,n,o,i,c){var a=arguments.length>6&&void 0!==arguments[6]?arguments[6]:[];Oe(this,e),xe(this,"name",void 0),xe(this,"arn",void 0),xe(this,"secret",void 0),xe(this,"createdDate",void 0),xe(this,"lastAccessedDate",void 0),xe(this,"lastChangedDate",void 0),xe(this,"tags",void 0),this.name=t,this.arn=r,this.secret=n,this.createdDate=o,this.lastAccessedDate=i,this.lastChangedDate=c,this.tags=a}return Se(e,null,[{key:"fromJSON",value:function(t){return new e(t.Name,t.ARN,t.SecretString,t.CreatedDate,t.LastAccessedDate,t.LastChangedDate,t.Tags)}}]),e}(),qe=function(e){Ce(r,e);var t=Ee(r);function r(e,n,o){var i;return Oe(this,r),xe(Te(i=t.call(this,e,n)),"operation",void 0),i.name="SecretsManagerServiceError",i.operation=o,i}return Se(r)}(y)})();var o=exports;for(var i in n)o[i]=n[i];n.__esModule&&Object.defineProperty(o,"__esModule",{value:!0})})(); +(()=>{var e={877:(e,t,r)=>{var n=r(570),o=r(171),i=o;i.v1=n,i.v4=o,e.exports=i},327:e=>{for(var t=[],r=0;r<256;++r)t[r]=(r+256).toString(16).substr(1);e.exports=function(e,r){var n=r||0,o=t;return[o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]]].join("")}},217:e=>{var t="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof window.msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto);if(t){var r=new Uint8Array(16);e.exports=function(){return t(r),r}}else{var n=new Array(16);e.exports=function(){for(var e,t=0;t<16;t++)0==(3&t)&&(e=4294967296*Math.random()),n[t]=e>>>((3&t)<<3)&255;return n}}},570:(e,t,r)=>{var n,o,i=r(217),c=r(327),a=0,u=0;e.exports=function(e,t,r){var s=t&&r||0,f=t||[],l=(e=e||{}).node||n,p=void 0!==e.clockseq?e.clockseq:o;if(null==l||null==p){var h=i();null==l&&(l=n=[1|h[0],h[1],h[2],h[3],h[4],h[5]]),null==p&&(p=o=16383&(h[6]<<8|h[7]))}var y=void 0!==e.msecs?e.msecs:(new Date).getTime(),d=void 0!==e.nsecs?e.nsecs:u+1,b=y-a+(d-u)/1e4;if(b<0&&void 0===e.clockseq&&(p=p+1&16383),(b<0||y>a)&&void 0===e.nsecs&&(d=0),d>=1e4)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");a=y,u=d,o=p;var v=(1e4*(268435455&(y+=122192928e5))+d)%4294967296;f[s++]=v>>>24&255,f[s++]=v>>>16&255,f[s++]=v>>>8&255,f[s++]=255&v;var m=y/4294967296*1e4&268435455;f[s++]=m>>>8&255,f[s++]=255&m,f[s++]=m>>>24&15|16,f[s++]=m>>>16&255,f[s++]=p>>>8|128,f[s++]=255&p;for(var g=0;g<6;++g)f[s+g]=l[g];return t||c(f)}},171:(e,t,r)=>{var n=r(217),o=r(327);e.exports=function(e,t,r){var i=t&&r||0;"string"==typeof e&&(t="binary"===e?new Array(16):null,e=null);var c=(e=e||{}).random||(e.rng||n)();if(c[6]=15&c[6]|64,c[8]=63&c[8]|128,t)for(var a=0;a<16;++a)t[i+a]=c[a];return t||o(c)}}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var i=t[n]={exports:{}};return e[n](i,i.exports,r),i.exports}r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var n={};(()=>{"use strict";r.r(n),r.d(n,{AWSConfig:()=>V,InvalidAWSConfigError:()=>F,InvalidSignatureError:()=>R,S3Bucket:()=>ye,S3Client:()=>he,S3Object:()=>de,S3ServiceError:()=>be,Secret:()=>Ne,SecretsManagerClient:()=>De,SecretsManagerError:()=>qe,URIEncodingConfig:()=>D,signHeaders:()=>C});const e=require("k6/crypto");var t=r.n(e);const o=require("k6/html");function i(e){return i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i(e)}function c(e,t){for(var r=0;re.length)&&(t=e.length);for(var r=0,n=new Array(t);r="A"&&r<="Z"||r>="a"&&r<="z"||function(e){return e>="0"&&e<="9"}(e)||"-._~".includes(e)?e:" "==e?"%20":"/"==e&&t?"/":"%"+e.charCodeAt(0).toString(16).toUpperCase();var r})).join("")}var D=w((function e(t,r){O(this,e),b(this,"double",void 0),b(this,"path",void 0),this.double=t,this.path=r}));function N(e){return new Date(e).toISOString().replace(/[:\-]|\.\d{3}/g,"")}function q(e){return N(e).substring(0,8)}function I(e){return I="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},I(e)}function M(e,t){if(t&&("object"===I(t)||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e)}function z(e){var t="function"==typeof Map?new Map:void 0;return z=function(e){if(null===e||(r=e,-1===Function.toString.call(r).indexOf("[native code]")))return e;var r;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return H(e,arguments,B(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),U(n,e)},z(e)}function H(e,t,r){return H=L()?Reflect.construct:function(e,t,r){var n=[null];n.push.apply(n,t);var o=new(Function.bind.apply(e,n));return r&&U(o,r.prototype),o},H.apply(null,arguments)}function L(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}function U(e,t){return U=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},U(e,t)}function B(e){return B=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},B(e)}function X(e,t){for(var r=0;r=1400&&r<=1499){var o=n.Message||n.message||n.__type;if("InvalidSignatureException"===n.__type)throw new R(o,n.__type);throw new qe(o,n.__type,e)}if(1500===r)throw new qe("An error occured on the server side","InternalServiceError",e)}}}]),r}(Q),Ne=function(){function e(t,r,n,o,i,c){var a=arguments.length>6&&void 0!==arguments[6]?arguments[6]:[];Oe(this,e),ke(this,"name",void 0),ke(this,"arn",void 0),ke(this,"secret",void 0),ke(this,"createdDate",void 0),ke(this,"lastAccessedDate",void 0),ke(this,"lastChangedDate",void 0),ke(this,"tags",void 0),this.name=t,this.arn=r,this.secret=n,this.createdDate=o,this.lastAccessedDate=i,this.lastChangedDate=c,this.tags=a}return Se(e,null,[{key:"fromJSON",value:function(t){return new e(t.Name,t.ARN,t.SecretString,t.CreatedDate,t.LastAccessedDate,t.LastChangedDate,t.Tags)}}]),e}(),qe=function(e){Ce(r,e);var t=Ee(r);function r(e,n,o){var i;return Oe(this,r),ke(Te(i=t.call(this,e,n)),"operation",void 0),i.name="SecretsManagerServiceError",i.operation=o,i}return Se(r)}(y)})();var o=exports;for(var i in n)o[i]=n[i];n.__esModule&&Object.defineProperty(o,"__esModule",{value:!0})})(); //# sourceMappingURL=aws.min.js.map \ No newline at end of file diff --git a/build/aws.min.js.map b/build/aws.min.js.map index c5b491c..9646b7a 100644 --- a/build/aws.min.js.map +++ b/build/aws.min.js.map @@ -1 +1 @@ -{"version":3,"file":"aws.min.js","mappings":"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","sources":["webpack://k6-jslib-aws/./node_modules/uuid/index.js","webpack://k6-jslib-aws/./node_modules/uuid/lib/bytesToUuid.js","webpack://k6-jslib-aws/./node_modules/uuid/lib/rng-browser.js","webpack://k6-jslib-aws/./node_modules/uuid/v1.js","webpack://k6-jslib-aws/./node_modules/uuid/v4.js","webpack://k6-jslib-aws/webpack/bootstrap","webpack://k6-jslib-aws/webpack/runtime/compat get default export","webpack://k6-jslib-aws/webpack/runtime/define property getters","webpack://k6-jslib-aws/webpack/runtime/hasOwnProperty shorthand","webpack://k6-jslib-aws/webpack/runtime/make namespace object","webpack://k6-jslib-aws/external commonjs \"k6/crypto\"","webpack://k6-jslib-aws/external commonjs \"k6/html\"","webpack://k6-jslib-aws/./src/internal/error.ts","webpack://k6-jslib-aws/./src/internal/signature.ts","webpack://k6-jslib-aws/./src/internal/config.ts","webpack://k6-jslib-aws/external commonjs \"k6/http\"","webpack://k6-jslib-aws/./src/internal/client.ts","webpack://k6-jslib-aws/./src/internal/s3.ts","webpack://k6-jslib-aws/./src/internal/secrets-manager.ts"],"sourcesContent":["var v1 = require('./v1');\nvar v4 = require('./v4');\n\nvar uuid = v4;\nuuid.v1 = v1;\nuuid.v4 = v4;\n\nmodule.exports = uuid;\n","/**\n * Convert array of 16 byte values to UUID string format of the form:\n * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n */\nvar byteToHex = [];\nfor (var i = 0; i < 256; ++i) {\n byteToHex[i] = (i + 0x100).toString(16).substr(1);\n}\n\nfunction bytesToUuid(buf, offset) {\n var i = offset || 0;\n var bth = byteToHex;\n // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4\n return ([\n bth[buf[i++]], bth[buf[i++]],\n bth[buf[i++]], bth[buf[i++]], '-',\n bth[buf[i++]], bth[buf[i++]], '-',\n bth[buf[i++]], bth[buf[i++]], '-',\n bth[buf[i++]], bth[buf[i++]], '-',\n bth[buf[i++]], bth[buf[i++]],\n bth[buf[i++]], bth[buf[i++]],\n bth[buf[i++]], bth[buf[i++]]\n ]).join('');\n}\n\nmodule.exports = bytesToUuid;\n","// Unique ID creation requires a high quality random # generator. In the\n// browser this is a little complicated due to unknown quality of Math.random()\n// and inconsistent support for the `crypto` API. We do the best we can via\n// feature-detection\n\n// getRandomValues needs to be invoked in a context where \"this\" is a Crypto\n// implementation. Also, find the complete implementation of crypto on IE11.\nvar getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||\n (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));\n\nif (getRandomValues) {\n // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto\n var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef\n\n module.exports = function whatwgRNG() {\n getRandomValues(rnds8);\n return rnds8;\n };\n} else {\n // Math.random()-based (RNG)\n //\n // If all else fails, use Math.random(). It's fast, but is of unspecified\n // quality.\n var rnds = new Array(16);\n\n module.exports = function mathRNG() {\n for (var i = 0, r; i < 16; i++) {\n if ((i & 0x03) === 0) r = Math.random() * 0x100000000;\n rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;\n }\n\n return rnds;\n };\n}\n","var rng = require('./lib/rng');\nvar bytesToUuid = require('./lib/bytesToUuid');\n\n// **`v1()` - Generate time-based UUID**\n//\n// Inspired by https://github.com/LiosK/UUID.js\n// and http://docs.python.org/library/uuid.html\n\nvar _nodeId;\nvar _clockseq;\n\n// Previous uuid creation time\nvar _lastMSecs = 0;\nvar _lastNSecs = 0;\n\n// See https://github.com/uuidjs/uuid for API details\nfunction v1(options, buf, offset) {\n var i = buf && offset || 0;\n var b = buf || [];\n\n options = options || {};\n var node = options.node || _nodeId;\n var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq;\n\n // node and clockseq need to be initialized to random values if they're not\n // specified. We do this lazily to minimize issues related to insufficient\n // system entropy. See #189\n if (node == null || clockseq == null) {\n var seedBytes = rng();\n if (node == null) {\n // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)\n node = _nodeId = [\n seedBytes[0] | 0x01,\n seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]\n ];\n }\n if (clockseq == null) {\n // Per 4.2.2, randomize (14 bit) clockseq\n clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;\n }\n }\n\n // UUID timestamps are 100 nano-second units since the Gregorian epoch,\n // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so\n // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'\n // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.\n var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime();\n\n // Per 4.2.1.2, use count of uuid's generated during the current clock\n // cycle to simulate higher resolution clock\n var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1;\n\n // Time since last uuid creation (in msecs)\n var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;\n\n // Per 4.2.1.2, Bump clockseq on clock regression\n if (dt < 0 && options.clockseq === undefined) {\n clockseq = clockseq + 1 & 0x3fff;\n }\n\n // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new\n // time interval\n if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {\n nsecs = 0;\n }\n\n // Per 4.2.1.2 Throw error if too many uuids are requested\n if (nsecs >= 10000) {\n throw new Error('uuid.v1(): Can\\'t create more than 10M uuids/sec');\n }\n\n _lastMSecs = msecs;\n _lastNSecs = nsecs;\n _clockseq = clockseq;\n\n // Per 4.1.4 - Convert from unix epoch to Gregorian epoch\n msecs += 12219292800000;\n\n // `time_low`\n var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;\n b[i++] = tl >>> 24 & 0xff;\n b[i++] = tl >>> 16 & 0xff;\n b[i++] = tl >>> 8 & 0xff;\n b[i++] = tl & 0xff;\n\n // `time_mid`\n var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;\n b[i++] = tmh >>> 8 & 0xff;\n b[i++] = tmh & 0xff;\n\n // `time_high_and_version`\n b[i++] = tmh >>> 24 & 0xf | 0x10; // include version\n b[i++] = tmh >>> 16 & 0xff;\n\n // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)\n b[i++] = clockseq >>> 8 | 0x80;\n\n // `clock_seq_low`\n b[i++] = clockseq & 0xff;\n\n // `node`\n for (var n = 0; n < 6; ++n) {\n b[i + n] = node[n];\n }\n\n return buf ? buf : bytesToUuid(b);\n}\n\nmodule.exports = v1;\n","var rng = require('./lib/rng');\nvar bytesToUuid = require('./lib/bytesToUuid');\n\nfunction v4(options, buf, offset) {\n var i = buf && offset || 0;\n\n if (typeof(options) == 'string') {\n buf = options === 'binary' ? new Array(16) : null;\n options = null;\n }\n options = options || {};\n\n var rnds = options.random || (options.rng || rng)();\n\n // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n rnds[6] = (rnds[6] & 0x0f) | 0x40;\n rnds[8] = (rnds[8] & 0x3f) | 0x80;\n\n // Copy bytes to buffer, if provided\n if (buf) {\n for (var ii = 0; ii < 16; ++ii) {\n buf[i + ii] = rnds[ii];\n }\n }\n\n return buf || bytesToUuid(rnds);\n}\n\nmodule.exports = v4;\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/crypto\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/html\");","import { parseHTML } from 'k6/html'\n\n/**\n * Base class to derive errors from\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class AWSError extends Error {\n code: string\n\n /**\n * Create an AWSError\n *\n * @param {string} message - A longer human readable error message.\n * @param {string} code - A unique short code representing the error that was emitted\n */\n constructor(message: string, code: string) {\n super(message)\n this.name = 'AWSError'\n this.code = code\n }\n\n /**\n * Parse an AWSError from an XML document\n *\n * @param {string} xmlDocument - Serialized XML document to parse the error from\n */\n static parseXML(xmlDocument: string): AWSError {\n const doc = parseHTML(xmlDocument)\n return new AWSError(doc.find('Message').text(), doc.find('Code').text())\n }\n}\n","import crypto, { hmac, sha256 } from 'k6/crypto'\nimport { HTTPMethod, HTTPHeaders } from './http'\nimport { AWSConfig } from './config'\nimport { AWSError } from './error'\n\n/**\n * Includes AWS v4 signing information to the provided HTTP headers object.\n *\n * This function will compute the `Authorization` header signature for the\n * provided request components, and add it to `header`. It will do so by following\n * the procedure detailled AWS' API docs: https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html\n *\n * The resulting `Authorization` header value is computed for the provided\n * headers object. Thus, any modification of the headers past a call to `signHeaders`\n * would effectively invalidate their signature, and the function should be\n * called again to recompute it.\n *\n * @param {object} headers - HTTP headers request to sign.\n * @param {number} requestTimestamp - Timestamp of the request\n * @param {string} method - HTTP method used\n * @param {string} path - HTTP request URL's path\n * @param {string} queryString - HTTP request URL's querystring\n * @param {string | ArrayBuffer} body - HTTP request's payload\n * @param {AWSConfig} - AWS configuration\n * @param {string} service - AWS service name\n * @param {URIEncodingConfig} - URI encoding configuration\n */\nexport function signHeaders(\n headers: HTTPHeaders,\n requestTimestamp: number,\n method: HTTPMethod,\n path: string,\n queryString: string,\n body: string | ArrayBuffer,\n awsConfig: AWSConfig,\n service: string,\n URIencodingConfig: URIEncodingConfig\n): HTTPHeaders {\n const derivedSigningKey = deriveSigningKey(\n awsConfig.secretAccessKey,\n requestTimestamp,\n awsConfig.region,\n service\n )\n\n const canonicalRequest = createCanonicalRequest(\n method,\n path,\n queryString,\n headers,\n body,\n URIencodingConfig\n )\n\n const stringToSign = createStringToSign(\n requestTimestamp,\n awsConfig.region,\n service,\n sha256(canonicalRequest, 'hex')\n )\n\n const credentialScope = createCredentialScope(requestTimestamp, awsConfig.region, service)\n const signedHeaders = createSignedHeaders(headers)\n const signature = calculateSignature(derivedSigningKey, stringToSign)\n const authorizationHeader = `${HashingAlgorithm} Credential=${awsConfig.accessKeyID}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`\n\n headers['Authorization'] = authorizationHeader\n\n return headers\n}\n\n/**\n * Error indicating an Invalid signature has been sent to AWS services\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class InvalidSignatureError extends AWSError {\n /**\n * Constructs an InvalidSignatureError\n *\n * @param {string} message - human readable error message\n */\n constructor(message: string, code: string) {\n super(message, code)\n this.name = 'InvalidSignatureError'\n }\n}\n\n/**\n * Calculte the signature for AWS signature version 4\n *\n * @param {string} derivedSigningKey - dervied signing key as computed by `deriveSigningKey`\n * @param {string} stringToSign - String to sign as computed by `createStringToSign`\n * @return {string}\n */\nexport function calculateSignature(derivedSigningKey: ArrayBuffer, stringToSign: string): string {\n return hmac('sha256', derivedSigningKey, stringToSign, 'hex')\n}\n/**\n * Derives the signing key for authenticating requests signed with\n * the Signature version 4 authentication protocol.\n *\n * deriveSigningKey produces a signing key by creating a series of\n * hash-based message authentication codes (HMACs) represented in\n * a binary format.\n *\n * The derived signing key is specific to the date it's made at, as well as\n * the service and region it targets.\n *\n * @param {string} secretAccessKey - the AWS secret access key to derive the signing key for\n * @param {number} time - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service. MUST be UTF-8 encoded.\n * @return {string}\n */\nexport function deriveSigningKey(\n secretAccessKey: string,\n time: number,\n region: string,\n service: string\n): ArrayBuffer {\n const kSecret = secretAccessKey\n const date = toDate(time)\n\n // FIXME: hmac takes ArrayBuffer as input, but returns bytes (number[]).\n // How does one convert from one to the other?\n const kDate: any = hmac('sha256', 'AWS4' + kSecret, date, 'binary')\n const kRegion: any = hmac('sha256', kDate, region, 'binary')\n const kService: any = hmac('sha256', kRegion, service, 'binary')\n const kSigning: any = hmac('sha256', kService, 'aws4_request', 'binary')\n\n return kSigning\n}\n\n// Hashing Algorithm to use in the signature process\nexport const HashingAlgorithm = 'AWS4-HMAC-SHA256'\n\n/**\n * Certain services, such as S3, allow for unsigned payloads. If\n * producing a signed canonical request for such service, pass\n * the `UnsignedPayload` constant value as the payload parameter.\n */\nexport const UnsignedPayload = 'UNSIGNED-PAYLOAD'\n\n/**\n * Create the \"string to sign\" part of the signature Version 4 protocol.\n *\n * The \"string to sign\" includes meta information about your request and\n * about the canonical request that you created with `createCanonicalRequest`.\n * It is used hand in hand with the signing key to create the request signature.\n *\n * @param {number} requestTimestamp - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service name. MUST be UTF-8 encoded.\n * @param {string} hashedCanonicalRequest - canonical request as produced by calling the createCanonicalRequest function,\n * hashed using the SHA256 algorithm (encoded in hexadecimal format).\n * @return {string}\n */\nexport function createStringToSign(\n requestTimestamp: number,\n region: string,\n service: string,\n hashedCanonicalRequest: string\n): string {\n // the request date specified in ISO8601 format: YYYYMMDD'T'HHMMSS'Z'\n const requestDateTime = toTime(requestTimestamp)\n\n // The credential scope value, consisting of the date in YYYYMMDD format,\n // the targeted region, the targeted service, and a termination string.\n // Note that the region and service MUST be UTF-8 encoded.\n const credentialScope = createCredentialScope(requestTimestamp, region, service)\n\n const stringToSign = [\n // Algorithm\n HashingAlgorithm,\n\n // RequestDateTime\n requestDateTime,\n\n // CredentialScope\n credentialScope,\n\n // HashedCanonicalRequest\n hashedCanonicalRequest,\n ].join('\\n')\n\n return stringToSign\n}\n\n/**\n *\n * Helper function creating a credential scope string to use in the signature\n * version 4 process. A credential scope consists of the date of the request\n * in YYYYMMDD format, the targeted region, the targeted service, and a\n * termination string.\n *\n * Note that the region and service MUST be UTF-8 encoded.\n *\n * @param {number} requestTimestamp - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service name. MUST be UTF-8 encoded.\n * @return {string}\n */\nexport function createCredentialScope(\n requestTimestamp: number,\n region: string,\n service: string\n): string {\n return [toDate(requestTimestamp), region, service, 'aws4_request'].join('/')\n}\n\n/**\n * Create a string that includes information from your request\n * in a AWS signature v4 standardized (canonical) format.\n *\n * @param {string} method - the HTTP request method\n * @param {string} uri - URI-encoded version of the absolute path component of the URI\n * @param {string} query - request's query string\n * @param {Object} headers - all the HTTP headers that you wish to include with the signed request\n * @param {string | ArrayBuffer} payload - payload to include as the body of the request\n * @param {URIEncodingConfig} URIencodingConfig- URI encoding configuration\n * @return {string}\n */\nexport function createCanonicalRequest(\n method: HTTPMethod,\n uri: string,\n query: string,\n headers: HTTPHeaders,\n payload: string | ArrayBuffer,\n URIencodingConfig: URIEncodingConfig\n): string {\n const httpRequestMethod = method.toUpperCase()\n const canonicalURI = createCanonicalURI(uri, URIencodingConfig)\n const canonicalQueryString = createCanonicalQueryString(query)\n const canonicalHeaders = createCanonicalHeaders(headers)\n const signedHeaders = createSignedHeaders(headers)\n const requestPayload = createCanonicalPayload(payload)\n\n const canonicalRequest = [\n httpRequestMethod,\n canonicalURI,\n canonicalQueryString,\n canonicalHeaders,\n signedHeaders,\n requestPayload,\n ].join('\\n')\n\n return canonicalRequest\n}\n\n/**\n * Creates the (canonical) URI-encoded version of the\n * absolute path component of the URI: everything in the URI\n * from the HTTP host to the question mark character (\"?\")\n * that begins the query string parameters (if any).\n *\n * @param {string} uri - URI to canonize\n * @param {URIEncodingConfig} - URI encoding configuration\n * @return {string} - canonical URL\n */\nexport function createCanonicalURI(uri: string, URIencodingConfig: URIEncodingConfig): string {\n if (uri == '/') {\n return uri\n }\n\n let canonicalURI = uri\n if (uri[uri.length - 1] == '/' && canonicalURI[canonicalURI.length - 1] != '/') {\n canonicalURI += '/'\n }\n\n canonicalURI = URIEncode(canonicalURI, URIencodingConfig.path)\n\n return URIencodingConfig.double ? URIEncode(canonicalURI, URIencodingConfig.path) : canonicalURI\n}\n\n// FIXME: does it work as expected?\n/**\n * Creates the canonical form of the request's query\n * string. If the request does not include a query string,\n * provide an empty string.\n *\n * @param {String | Object} qs - query string to canonize\n * @return {string}\n */\nexport function createCanonicalQueryString(qs: string): string {\n if (qs === '') {\n return ''\n }\n\n // const intermediary: { [key: string]: string } = parseQueryString(qs)\n\n // return Object.keys(intermediary)\n // .sort()\n // .map((key: string) => {\n // // const values: string[] = Array.isArray(intermediary[key])\n // // ? intermediary[key]\n // // : [intermediary[key]]\n // const values = intermediary[key]\n\n // return values\n // .sort()\n // .map((val: string) => encodeURIComponent(key) + '=' + encodeURIComponent(val))\n // .join('&')\n // })\n // .join('&')\n\n return parseQueryString(qs)\n .map(([key, value]: [string, string]): string => {\n return encodeURIComponent(key) + '=' + encodeURIComponent(value)\n })\n .join('&')\n}\n/**\n * Create the canonical form of the request's headers.\n * Canonical headers consist of all the HTTP headers you\n * are including with the signed request.\n *\n * Note that:\n * * for HTTP/1.1 requests, the headers should at least\n * contain the `host` header.\n * * for HTTP/2, the `:authority` header must be used instead\n * of `host`.\n *\n * @param {Object} headers\n * @return {string}\n */\nexport function createCanonicalHeaders(headers: HTTPHeaders) {\n if (headers.constructor !== Object || Object.entries(headers).length === 0) {\n return ''\n }\n\n const canonicalHeaders = Object.entries(headers)\n .map(([name, values]) => {\n const canonicalName = name.toLowerCase().trim()\n const normalizedValues = Array.isArray(values) ? values : [values]\n\n // Note that we do not need to sort values\n const canonicalValues = normalizedValues\n .map((v) => {\n // convert sequential spaces to a single space\n return v.replace(/\\s+/g, ' ').replace(/^\\s+|\\s+$/g, '')\n })\n .join(',') // standard for multiple values in a HTTP header\n\n return canonicalName + ':' + canonicalValues + '\\n'\n })\n .sort()\n .join('')\n\n return canonicalHeaders\n}\n\n/**\n * Create the canonical request's signed headers.\n *\n * The signed headers part of the request contains the\n * list of headers included in the request's signing process.\n *\n * Note that:\n * * for HTTP/1.1 requests, the `host` header must be included.\n * * for HTTP/2 requests, the `:authority` header must be included instead\n * of host.\n * * if used, the `x-amz-date` header must be included.\n *\n * @param {Object} headers\n * @return {string}\n * @throws {TypeError} - on headers not being an Object, or being empty.\n */\nexport function createSignedHeaders(headers: { [key: string]: string }) {\n if (headers.constructor !== Object) {\n throw new TypeError('headers should be an object')\n }\n\n if (Object.entries(headers).length === 0) {\n throw 'headers should at least contain either the Host (HTTP 1.1) or :authority (HTTP 2) parameter'\n }\n\n // To create the signed headers list, convert\n // all header names to lowercase, sort them by\n // character code, and use a semicolon to separate\n // the header names.\n const result = Object.keys(headers)\n .map((name) => name.toLowerCase().trim())\n .sort()\n .join(';')\n\n return result\n}\n\n/**\n * Create the canonical form of the request's payload.\n *\n * The canonical payload consists in a lowercased, hex encoded,\n * SHA256 hash of the requests body/payload.\n *\n * Certain services, such as S3, allow for unsigned payload. If\n * producing a signed canonical request for such service, pass\n * the `UnsignedPayload` constant value as the payload parameter.\n *\n * @param {String | ArrayBuffer} payload\n * @return {string}\n */\nexport function createCanonicalPayload(payload: string | ArrayBuffer) {\n if (payload === UnsignedPayload) {\n return payload\n }\n\n // Note that if the paylaod is null, we convert it\n // to an empty string.\n // TODO: Should switching to empty string if null impact headers?\n return crypto.sha256(payload || '', 'hex').toLowerCase()\n}\n\n/**\n * URIEncodes encodes every bytes of a URI to be URL-safe.\n *\n * This implementation is specific to AWS; who intended to make it as\n * close as possible to the underlying RFC 3946. It:\n * * URI encode every byte except the unreserved characters: 'A'-'Z', 'a'-'z', '0'-'9',\n * '-', '.', '_', and '~'.\n * * considers the space character as a reserved character and must URI encodes\n * encodes it as \"%20\" (and not as \"+\").\n * * URI encodes every byte by prefixing with '%' the two-digit hexadecimal value of the byte.\n * * If the `path` argument is set, forward slashes are not encoded, to fit with\n * S3 requirements.\n *\n * N.B: this implementation differs with ES6' mainly in that it does\n * encode the \"'\" character.\n *\n * Based on AWS implementation: https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-core/src/main/java/com/amazonaws/util/SdkHttpUtils.java#L66\n * Encoding specs: https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html\n *\n * @param {string} uri - uri to encode\n * @param {boolean} path - slash characters should be encoded everywhere,\n * but in paths, set to false when encoding a path\n * @return {string} the URI encoded result\n */\nexport function URIEncode(uri: string, path: boolean): string {\n if (uri == '') {\n return uri\n }\n\n return uri\n .split('') // to be able to map over a string, because... javascript...\n .map((letter: string) => {\n if (isAlpha(letter) || isNumeric(letter) || '-._~'.includes(letter)) {\n return letter\n }\n\n // Space should be explicitly encoded to as %20.\n if (letter == ' ') {\n return '%20'\n }\n\n // If the URI is a path, the forward slash shouldn't\n // be encoded.\n if (letter == '/' && path) {\n return '/'\n }\n\n return '%' + letter.charCodeAt(0).toString(16).toUpperCase()\n })\n .join('')\n}\n\n/**\n * Class holding URI encoding configuration\n */\nexport class URIEncodingConfig {\n double: boolean\n path: boolean\n\n /**\n *\n * @param {boolean} double - should the URI be double encoded?\n * @param {boolean} path - is the URI a path? If so, its forward\n * slashes won't be URIencoded.\n */\n constructor(double: boolean, path: boolean) {\n this.double = double\n this.path = path\n }\n}\n\n/**\n * Compute the request time value as specified by the ISO8601\n * format: YYYYMMDD'T'HHMMSS'Z'\n *\n * @param {number} timestamp\n * @return {string}\n */\nexport function toTime(timestamp: number): string {\n return new Date(timestamp).toISOString().replace(/[:\\-]|\\.\\d{3}/g, '')\n}\n/**\n * Computethe request date value in the format: YYYMMDD\n *\n * @param {number} timestamp\n * @return {string}\n */\nexport function toDate(timestamp: number): string {\n return toTime(timestamp).substring(0, 8)\n}\n\n// FIXME: does it work as expected?\n/**\n * Parse a HTTP request URL's querystring into an object\n * containing its `key=value` pairs.\n *\n * @param {string} qs\n * @return {object}\n */\nexport function parseQueryString(qs: string): Array<[string, string]> {\n if (qs.length === 0) {\n return []\n }\n\n return qs\n .split('&')\n .filter((e) => e)\n .map((v: string): [string, string] => {\n const parts = v.split('=', 2) as [string, string]\n return [decodeURIComponent(parts[0]), decodeURIComponent(parts[1])]\n })\n .sort((a: [string, string], b: [string, string]) => {\n return a[0].localeCompare(b[0])\n })\n}\n\nfunction isAlpha(c: string): boolean {\n return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')\n}\n\nfunction isNumeric(c: string): boolean {\n return c >= '0' && c <= '9'\n}\n\n// FIXME: finish implementation when needed\n// See the following for more details:\n// * https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html\n// * https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html\n// export function signQueryString(\n// queryString,\n// requestTimestamp,\n// accessKeyID,\n// secretAccessKey,\n// region,\n// service,\n// ttl, // in seconds\n// headers,\n// doubleURIEncoding = true\n// ) {\n// const credential = [accessKeyID, toDate(requestTimestamp), region, service].join('/')\n//\n// const canonicalRequest = createCanonicalRequest(\n// method,\n// path,\n// queryString,\n// headers,\n// body,\n// doubleURIEncoding\n// )\n//\n// const derivedSigningKey = deriveSigningKey(secretAccessKey, requestTimestamp, region, service)\n//\n// const stringToSign = createStringToSign(\n// requestTimestamp,\n// region,\n// service,\n// sha256(canonicalRequest, 'hex')\n// )\n//\n// const signedHeaders = createSignedHeaders(headers)\n// const signature = calculateSignature(derivedSigningKey, stringToSign)\n//\n// return [\n// `X-Amz-Algorithm=${HashingAlgorithm}`,\n// `X-Amz-Credential=${crediental}`,\n// `X-Amz-Date=${toTime(requestTimestamp)}`,\n// `X-Amz-Expires=${ttl}`,\n// `X-Amz-SignedHeaders=${signedHeaders}`,\n// `X-Amz-Signature=${signature}`,\n//`X-Amz-Security-Token=`, // TODO: optional\n// ].join('&')\n// }\n","/** Class holding an AWS connection information */\nexport class AWSConfig {\n region: string\n accessKeyID: string\n secretAccessKey: string\n\n /**\n * Create an AWSConfig.\n *\n * @param {string} region - the AWS region to connect to, as listed: https://docs.aws.amazon.com/general/latest/gr/rande.html\n * @param {string} accessKeyID - Your user's AWS access key id credential\n * @param {string} secretAccessKey - Your user's AWS secret access key credential\n * @throws {InvalidArgumentException}\n */\n constructor(region: string, accessKeyID: string, secretAccessKey: string) {\n if (typeof region !== 'string' || region === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS region; reason: should be a non empty string'\n )\n }\n\n if (typeof accessKeyID !== 'string' || accessKeyID === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS access key ID; reason: should be a non empty string'\n )\n }\n\n if (typeof secretAccessKey !== 'string' || secretAccessKey === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS secret access key; reason: should be a non empty string'\n )\n }\n\n this.region = region\n this.accessKeyID = accessKeyID\n this.secretAccessKey = secretAccessKey\n }\n}\n\n/** Class representing an invalid AWS configuration */\nexport class InvalidAWSConfigError extends Error {\n constructor(message: string) {\n super(message)\n }\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/http\");","import { HTTPMethod, HTTPHeaders } from './http'\nimport { AWSConfig } from './config'\nimport { signHeaders, URIEncodingConfig, toTime } from './signature'\n\n/**\n * Class allowing to build requests targeting AWS APIs\n *\n * This class is meant to be used as a base class for specific\n * services clients. See S3Client or SecretsManagerClient for\n * usage examples.\n */\nexport class AWSClient {\n awsConfig: AWSConfig\n serviceName: string\n URIencodingConfig: URIEncodingConfig\n\n /**\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n * @param {string} serviceName - name of the service to target.\n * @param {URIEncodingConfig} URIencodingConfig - configures how requests URIs should be encoded.\n */\n constructor(awsConfig: AWSConfig, serviceName: string, URIencodingConfig: URIEncodingConfig) {\n this.awsConfig = awsConfig\n this.serviceName = serviceName\n this.URIencodingConfig = URIencodingConfig\n }\n\n buildRequest(\n method: HTTPMethod,\n host: string,\n path: string,\n queryString: string,\n body: string | ArrayBuffer,\n headers: HTTPHeaders\n ): AWSRequest {\n const requestTimestamp: number = Date.now()\n const date: string = toTime(requestTimestamp)\n\n headers['Host'] = host\n headers['X-Amz-Date'] = date\n\n headers = signHeaders(\n // headers\n headers,\n\n // requestTimestamp\n requestTimestamp,\n\n // method\n method,\n\n // path\n path,\n\n // querystring\n queryString,\n\n // body\n body,\n\n // AWS configuration\n this.awsConfig,\n\n // AwS target service name\n this.serviceName,\n\n // doubleEncoding: S3 does single-encoding of the uri component\n // pathURIEncoding: S3 manipulates object keys, and forward slashes\n // shouldn't be URI encoded\n this.URIencodingConfig\n )\n\n // '?' should not be part of the querystring when we sign the headers\n path = path !== '' ? path : '/'\n let url = `https://${host}${path}`\n if (queryString !== '') {\n url += `?${queryString}`\n }\n\n return { url: url, headers: headers }\n }\n}\n\n/**\n * Type alias representing the result of an AWSClient.buildRequest call\n */\nexport interface AWSRequest {\n url: string\n headers: HTTPHeaders\n}\n","import { bytes } from 'k6'\nimport http from 'k6/http'\nimport { parseHTML } from 'k6/html'\nimport { sha256 } from 'k6/crypto'\n\nimport { InvalidSignatureError, URIEncodingConfig } from './signature'\nimport { AWSClient, AWSRequest } from './client'\nimport { AWSError } from './error'\nimport { AWSConfig } from './config'\n\n/** Class allowing to interact with Amazon AWS's S3 service */\nexport class S3Client extends AWSClient {\n /**\n * Create a S3Client\n *\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n */\n constructor(awsConfig: AWSConfig) {\n const URIencodingConfig = new URIEncodingConfig(false, true)\n super(awsConfig, 's3', URIencodingConfig)\n }\n\n /**\n * Returns a list of all buckets owned by the authenticated sender of the request.\n * To use this operation, you must have the s3:ListAllMyBuckets permission.\n *\n * @return {Array.} buckets - An array of objects describing S3 buckets\n * with the following fields: name, and creationDate.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n listBuckets(): Array {\n // Prepare request\n const method = 'GET'\n const host = `${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(method, host, '/', '', body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n let buckets: Array = []\n\n const doc = parseHTML(res.body as string)\n\n doc.find('Buckets')\n .children()\n .each((_, bucketDefinition) => {\n let bucket = {}\n\n bucketDefinition.children().forEach((child) => {\n switch (child.nodeName()) {\n case 'name':\n Object.assign(bucket, { name: child.textContent() })\n break\n case 'creationdate':\n Object.assign(bucket, {\n creationDate: Date.parse(child.textContent()),\n })\n }\n })\n\n buckets.push(bucket as S3Bucket)\n })\n\n return buckets\n }\n\n /**\n * Returns some or all (up to 1,000) of the objects in a bucket.\n *\n * @param {string} bucketName - Bucket name to list.\n * @param {string?} prefix='' - Limits the response to keys that begin with the specified prefix.\n * @return {Array.} - returns an array of objects describing S3 objects\n * with the following fields: key, lastModified, etag, size and storageClass.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n listObjects(bucketName: string, prefix?: string): Array {\n // Prepare request\n const method = 'GET'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n '/',\n 'list-type=2',\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n let objects: Array = []\n\n // Extract the objects definition from\n // the XML response\n parseHTML(res.body as string)\n .find('Contents')\n .each((_, objectDefinition) => {\n let obj = {}\n\n objectDefinition.children().forEach((child) => {\n switch (child.nodeName()) {\n case 'key':\n Object.assign(obj, { key: child.textContent() })\n break\n case 'lastmodified':\n // const parsed = Date.parse(\n // child.textContent(),\n // 'YYYY-MM-ddTHH:mm:ss.sssZ'\n // )\n Object.assign(obj, { lastModified: Date.parse(child.textContent()) })\n break\n case 'etag':\n Object.assign(obj, { etag: child.textContent() })\n break\n case 'size':\n Object.assign(obj, { size: parseInt(child.textContent()) })\n break\n case 'storageclass':\n Object.assign(obj, { storageClass: child.textContent() })\n }\n })\n\n objects.push(obj as S3Object)\n })\n\n return objects\n }\n /**\n * Retrieves an Object from Amazon S3.\n *\n * To use getObject, you must have `READ` access to the object.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to get.\n * @return {S3Object} - returns the content of the fetched S3 Object.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n getObject(bucketName: string, objectKey: string): S3Object {\n // Prepare request\n const method = 'GET'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(method, host, path, '', body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n return new S3Object(\n objectKey,\n Date.parse(res.headers['Last-Modified']),\n res.headers['ETag'],\n parseInt(res.headers['Content-Length']),\n undefined, // GetObject response doesn't contain the storage class\n res.body\n )\n }\n /**\n * Adds an object to a bucket.\n *\n * You must have WRITE permissions on a bucket to add an object to it.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to put.\n * @param {string | ArrayBuffer} data - the content of the S3 Object to upload.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n putObject(bucketName: string, objectKey: string, data: string | ArrayBuffer) {\n // Prepare request\n const method = 'PUT'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const queryString = ''\n const body = data\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n path,\n queryString,\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n }\n\n /**\n * Removes the null version (if there is one) of an object and inserts a delete marker,\n * which becomes the latest version of the object.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to delete.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n deleteObject(bucketName: string, objectKey: string): void {\n // Prepare request\n const method = 'DELETE'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const queryString = ''\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n path,\n queryString,\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n }\n\n // FIXME: remove dependency to `error_message`\n // FIXME: just pass it the response?\n _handle_error(error_code: number, error_message: string, error_body: string) {\n if (error_message == '' || error_code === 0) {\n return\n }\n\n // FIXME: should be error_code === 1301 instead\n // See: https://github.com/grafana/k6/issues/2474\n // See: https://github.com/golang/go/issues/49281\n if (error_message && error_message.startsWith('301')) {\n // Bucket not found\n throw new S3ServiceError('Resource not found', 'ResourceNotFound', 'getObject')\n }\n\n const awsError = AWSError.parseXML(error_body)\n switch (awsError.code) {\n case 'AuthorizationHeaderMalformed':\n throw new InvalidSignatureError(awsError.message, awsError.code)\n default:\n throw new S3ServiceError(awsError.message, awsError.code, 'listObjects')\n }\n }\n}\n\n// TODO: use interface instead?\n/** Class representing a S3 Bucket */\nexport class S3Bucket {\n name: string\n creationDate: Date\n\n /**\n * Create an S3 Bucket\n *\n * @param {string} name - S3 bucket's name\n * @param {Date} creationDate - S3 bucket's creation date\n */\n constructor(name: string, creationDate: Date) {\n this.name = name\n this.creationDate = creationDate\n }\n}\n\n// TODO: use interface instead?\n/** Class representing an S3 Object */\nexport class S3Object {\n key: string\n lastModified: number\n etag: string\n size: number\n storageClass: StorageClass\n data?: string | bytes | null\n\n /**\n * Create an S3 Object\n *\n * @param {string} key - S3 object's key\n * @param {Date} lastModified - S3 object last modification date\n * @param {string} etag - S3 object's etag\n * @param {number} size - S3 object's size\n * @param {StorageClass} storageClass - S3 object's storage class\n * @param {string | bytes | null} data=null - S3 Object's data\n */\n constructor(\n key: string,\n lastModified: number,\n etag: string,\n size: number,\n storageClass: StorageClass,\n data?: string | bytes | null\n ) {\n this.key = key\n this.lastModified = lastModified\n this.etag = etag\n this.size = size\n this.storageClass = storageClass\n this.data = data\n }\n}\n\n/**\n * Error indicating a S3 operation failed\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class S3ServiceError extends AWSError {\n operation: string\n\n /**\n * Constructs a S3ServiceError\n *\n * @param {string} message - human readable error message\n * @param {string} code - A unique short code representing the error that was emitted\n * @param {string} operation - Name of the failed Operation\n */\n constructor(message: string, code: string, operation: string) {\n super(message, code)\n this.name = 'S3ServiceError'\n this.operation = operation\n }\n}\n\n/**\n * Describes the class of storage used to store a S3 object.\n */\ntype StorageClass =\n | 'STANDARD'\n | 'REDUCED_REDUNDANCY'\n | 'GLACIER'\n | 'STANDARD_IA'\n | 'INTELLIGENT_TIERING'\n | 'DEEP_ARCHIVE'\n | 'OUTPOSTS'\n | 'GLACIER_IR'\n | undefined\n","import { JSONArray, JSONObject } from 'k6'\nimport http, { RefinedResponse, ResponseType } from 'k6/http'\n\nimport { AWSClient, AWSRequest } from './client'\nimport { AWSError } from './error'\nimport { AWSConfig } from './config'\nimport { InvalidSignatureError, URIEncodingConfig } from './signature'\nimport { v4 as uuidv4 } from 'uuid'\nimport { HTTPMethod, HTTPHeaders } from './http'\n\n/**\n * Class allowing to interact with Amazon AWS's SecretsManager service\n */\nexport class SecretsManagerClient extends AWSClient {\n method: HTTPMethod\n commonHeaders: HTTPHeaders\n\n /**\n * Create a SecretsManagerClient\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n */\n constructor(awsConfig: AWSConfig) {\n const URIencodingConfig = new URIEncodingConfig(true, false)\n super(awsConfig, 'secretsmanager', URIencodingConfig)\n\n // this.serviceName = 'secretsmanager'\n\n // All interactions with the Secrets Manager service\n // are made via the GET or POST method.\n this.method = 'POST'\n\n this.commonHeaders = {\n 'Accept-Encoding': 'identity',\n 'Content-Type': 'application/x-amz-json-1.1',\n }\n }\n\n /**\n * Returns a list of all secrets owned by the authenticated sender of the request.\n * To use this operation, you must have the secretsmanager:ListSecrets permission.\n *\n * @return {Array.} secrets - An array of objects describing Secret Manager's secrets\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n listSecrets(): Array {\n const body = JSON.stringify({})\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.ListSecrets`,\n }\n )\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('ListSecrets', res)\n const json: JSONArray = res.json('SecretList') as JSONArray\n\n return json.map((s) => Secret.fromJSON(s as JSONObject))\n }\n\n /**\n * Retrieves a secret from Amazon Sercets Manager\n *\n * @param {string} secretID - The ARN or name of the secret to retrieve.\n * @returns {Secret} - returns the content of the fetched Secret object.\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n getSecret(secretID: string): Secret | undefined {\n const body = JSON.stringify({ SecretId: secretID })\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.GetSecretValue`,\n }\n )\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('GetSecretValue', res)\n\n return Secret.fromJSON(res.json() as JSONObject)\n }\n\n /**\n * Creates a new secret\n *\n * Note that this method only supports string-based values at the moment.\n *\n * @param {string} name - The name of the new secret.\n * The secret name can contain ASCII letters, numbers, and the following characters: /_+=.@\n * @param {string} secretString - The text data to encrypt and store in this new version of the secret.\n * @param {string} description - The description of the secret.\n * @param {string} versionID=null - Version of the secret. This value helps ensure idempotency.\n * As a default, if no versionID is provided, one will be created for you using the UUID v4\n * algorithm.\n * @param {Array.} tags=[] - A list of tags to attach to the secret. Each tag is a key and\n * value pair of strings in a JSON text string. Note that tag key names are case sensitive.\n * @returns {Secret} - returns the created secret\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n createSecret(\n name: string,\n secretString: string,\n description: string,\n versionID?: string,\n tags?: Array\n ): Secret {\n versionID = versionID || uuidv4()\n\n const body = JSON.stringify({\n Name: name,\n Description: description,\n SecretString: secretString,\n ClientRequestToken: versionID,\n Tags: tags,\n })\n\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.CreateSecret`,\n }\n )\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n // headers['X-Amz-Target'] = `${this.serviceName}.CreateSecret`\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('CreateSecret', res)\n\n return Secret.fromJSON(res.json() as JSONObject)\n }\n /**\n * Update a secret's value.\n *\n * Note that this method only support string-based values at the moment.\n *\n * @param {string} secretID - The ARN or name of the secret to update.\n * @param {string} secretString - The text data to encrypt and store in this new version of the secret.\n * @param {} versionID=null - A unique identifier for the new version of the secret. This value helps ensure idempotency.\n * As a default, if no versionID is provided, one will be created for you using the UUID v4\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n putSecretValue(secretID: string, secretString: string, versionID?: string): Secret {\n versionID = versionID || uuidv4()\n\n const body = JSON.stringify({\n SecretId: secretID,\n SecretString: secretString,\n ClientRequestToken: versionID,\n })\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.PutSecretValue`,\n }\n )\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('PutSecretValue', res)\n\n return Secret.fromJSON(res.json() as JSONObject)\n }\n\n /**\n * Deletes a secret and all of its versions.\n *\n * You can specify a recovery window during which you can restore the secret.\n * The minimum recovery window is 7 days. The default recovery window is 30 days.\n *\n * @param {string} secretID - The ARN or name of the secret to delete.\n * @param {number} recoveryWindow - The number of days from 7 to 30 that Secrets Manager\n * waits before permanently deleting the secret.\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n deleteSecret(\n secretID: string,\n { recoveryWindow = 30, noRecovery = false }: { recoveryWindow: number; noRecovery: boolean }\n ) {\n const payload: { [key: string]: string | boolean | number } = {\n SecretId: secretID,\n }\n\n // noRecovery and recoveryWindow are exclusive parameters\n if (noRecovery === true) {\n payload['ForceDeleteWithoutRecovery'] = true\n } else {\n payload['RecoveryWindowInDays'] = recoveryWindow\n }\n\n const body = JSON.stringify(payload)\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.DeleteSecret`,\n }\n )\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('DeleteSecret', res)\n }\n\n get host() {\n return `${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n }\n\n // TODO: operation should be an enum\n _handle_error(operation: string, response: RefinedResponse) {\n const errorCode = response.error_code\n if (errorCode === 0) {\n return\n }\n\n const error = response.json() as JSONObject\n if (errorCode >= 1400 && errorCode <= 1499) {\n // In the event of certain errors, the message is not set.\n // Also, note the inconsistency in casing...\n const errorMessage: string =\n (error.Message as string) || (error.message as string) || (error.__type as string)\n\n // Handle specifically the case of an invalid signature\n if (error.__type === 'InvalidSignatureException') {\n throw new InvalidSignatureError(errorMessage, error.__type)\n }\n\n // Otherwise throw a standard service error\n throw new SecretsManagerError(errorMessage, error.__type as string, operation)\n }\n\n if (errorCode === 1500) {\n throw new SecretsManagerError(\n 'An error occured on the server side',\n 'InternalServiceError',\n operation\n )\n }\n }\n}\n\n// TODO: create a Tags type\n\n/**\n * Class representing a Secret Manager's secret\n */\nexport class Secret {\n name: string\n arn: string\n secret: string\n createdDate: number\n lastAccessedDate: number\n lastChangedDate: number\n tags: Array<{ [key: string]: string }>\n\n /**\n * Constructs a Secret Manager's Secret\n *\n * @param {string} name - The friendly name of the secret.\n * @param {string} arn - The ARN of the secret.\n * @param {number} createdDate - The date and time that this version of the secret was created.\n * @param {number} lastAccessedDate - The last date that this secret was accessed. This value is\n * truncated to midnight of the date and therefore shows only the date, not the time.\n * @param {number} lastChangedDate - The last date and time that this secret was modified in any way.\n * @param {Array.} tags - The list of user-defined tags associated with the secret.\n */\n constructor(\n name: string,\n arn: string,\n secretString: string,\n createdDate: number,\n lastAccessedDate: number,\n lastChangedDate: number,\n tags: Array<{ [key: string]: string }> = []\n ) {\n this.name = name\n this.arn = arn\n this.secret = secretString\n this.createdDate = createdDate\n this.lastAccessedDate = lastAccessedDate\n this.lastChangedDate = lastChangedDate\n this.tags = tags\n }\n\n /**\n * Parses and constructs a Secret Manager's Secret from the content\n * of a JSON response returned by the AWS service\n *\n * @param {Object} json - JSON object as returned and parsed from\n * the AWS service's API call.\n * @returns {Secret}\n */\n static fromJSON(json: JSONObject) {\n return new Secret(\n json.Name as string,\n json.ARN as string,\n json.SecretString as string,\n json.CreatedDate as number,\n json.LastAccessedDate as number,\n json.LastChangedDate as number,\n json.Tags as Array<{ [key: string]: string }>\n )\n }\n}\n\nexport class SecretsManagerError extends AWSError {\n operation: string\n\n /**\n * Constructs a SecretsManagerError\n *\n * @param {string} message - human readable error message\n * @param {string} code - A unique short code representing the error that was emitted\n * @param {string} operation - Name of the failed Operation\n */\n constructor(message: string, code: string, operation: string) {\n super(message, code)\n this.name = 'SecretsManagerServiceError'\n this.operation = operation\n }\n}\n"],"names":["v1","v4","uuid","module","exports","byteToHex","i","toString","substr","buf","offset","bth","join","getRandomValues","crypto","bind","window","msCrypto","rnds8","Uint8Array","rnds","Array","r","Math","random","_nodeId","_clockseq","rng","bytesToUuid","_lastMSecs","_lastNSecs","options","b","node","clockseq","undefined","seedBytes","msecs","Date","getTime","nsecs","dt","Error","tl","tmh","n","ii","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","__webpack_modules__","getter","__esModule","d","a","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","require","AWSError","message","code","name","xmlDocument","doc","parseHTML","find","text","signHeaders","headers","requestTimestamp","method","path","queryString","body","awsConfig","service","URIencodingConfig","derivedSigningKey","secretAccessKey","time","region","kSecret","date","toDate","kDate","hmac","kRegion","kService","deriveSigningKey","canonicalRequest","uri","query","payload","httpRequestMethod","toUpperCase","canonicalURI","length","URIEncode","createCanonicalURI","canonicalQueryString","qs","split","filter","e","map","v","parts","decodeURIComponent","sort","localeCompare","parseQueryString","encodeURIComponent","createCanonicalQueryString","canonicalHeaders","constructor","entries","values","toLowerCase","trim","isArray","replace","createCanonicalHeaders","signedHeaders","createSignedHeaders","requestPayload","UnsignedPayload","createCanonicalPayload","createCanonicalRequest","stringToSign","hashedCanonicalRequest","requestDateTime","toTime","credentialScope","createCredentialScope","HashingAlgorithm","createStringToSign","sha256","signature","calculateSignature","authorizationHeader","accessKeyID","InvalidSignatureError","TypeError","keys","letter","c","isNumeric","includes","charCodeAt","URIEncodingConfig","double","this","timestamp","toISOString","substring","AWSConfig","InvalidAWSConfigError","AWSClient","serviceName","host","now","url","S3Client","signedRequest","res","http","_handle_error","error_code","error","buckets","children","each","_","bucketDefinition","bucket","forEach","child","nodeName","assign","textContent","creationDate","parse","push","bucketName","prefix","objects","objectDefinition","lastModified","etag","size","parseInt","storageClass","objectKey","S3Object","data","error_message","error_body","startsWith","S3ServiceError","awsError","parseXML","S3Bucket","operation","SecretsManagerClient","commonHeaders","JSON","stringify","json","s","Secret","fromJSON","secretID","SecretId","secretString","description","versionID","tags","uuidv4","Name","Description","SecretString","ClientRequestToken","Tags","recoveryWindow","noRecovery","response","errorCode","errorMessage","Message","__type","SecretsManagerError","arn","createdDate","lastAccessedDate","lastChangedDate","secret","ARN","CreatedDate","LastAccessedDate","LastChangedDate"],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"aws.min.js","mappings":"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","sources":["webpack://k6-jslib-aws/./node_modules/uuid/index.js","webpack://k6-jslib-aws/./node_modules/uuid/lib/bytesToUuid.js","webpack://k6-jslib-aws/./node_modules/uuid/lib/rng-browser.js","webpack://k6-jslib-aws/./node_modules/uuid/v1.js","webpack://k6-jslib-aws/./node_modules/uuid/v4.js","webpack://k6-jslib-aws/webpack/bootstrap","webpack://k6-jslib-aws/webpack/runtime/compat get default export","webpack://k6-jslib-aws/webpack/runtime/define property getters","webpack://k6-jslib-aws/webpack/runtime/hasOwnProperty shorthand","webpack://k6-jslib-aws/webpack/runtime/make namespace object","webpack://k6-jslib-aws/external commonjs \"k6/crypto\"","webpack://k6-jslib-aws/external commonjs \"k6/html\"","webpack://k6-jslib-aws/./src/internal/error.ts","webpack://k6-jslib-aws/./src/internal/signature.ts","webpack://k6-jslib-aws/./src/internal/config.ts","webpack://k6-jslib-aws/external commonjs \"k6/http\"","webpack://k6-jslib-aws/./src/internal/client.ts","webpack://k6-jslib-aws/./src/internal/s3.ts","webpack://k6-jslib-aws/./src/internal/secrets-manager.ts"],"sourcesContent":["var v1 = require('./v1');\nvar v4 = require('./v4');\n\nvar uuid = v4;\nuuid.v1 = v1;\nuuid.v4 = v4;\n\nmodule.exports = uuid;\n","/**\n * Convert array of 16 byte values to UUID string format of the form:\n * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n */\nvar byteToHex = [];\nfor (var i = 0; i < 256; ++i) {\n byteToHex[i] = (i + 0x100).toString(16).substr(1);\n}\n\nfunction bytesToUuid(buf, offset) {\n var i = offset || 0;\n var bth = byteToHex;\n // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4\n return ([\n bth[buf[i++]], bth[buf[i++]],\n bth[buf[i++]], bth[buf[i++]], '-',\n bth[buf[i++]], bth[buf[i++]], '-',\n bth[buf[i++]], bth[buf[i++]], '-',\n bth[buf[i++]], bth[buf[i++]], '-',\n bth[buf[i++]], bth[buf[i++]],\n bth[buf[i++]], bth[buf[i++]],\n bth[buf[i++]], bth[buf[i++]]\n ]).join('');\n}\n\nmodule.exports = bytesToUuid;\n","// Unique ID creation requires a high quality random # generator. In the\n// browser this is a little complicated due to unknown quality of Math.random()\n// and inconsistent support for the `crypto` API. We do the best we can via\n// feature-detection\n\n// getRandomValues needs to be invoked in a context where \"this\" is a Crypto\n// implementation. Also, find the complete implementation of crypto on IE11.\nvar getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||\n (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));\n\nif (getRandomValues) {\n // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto\n var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef\n\n module.exports = function whatwgRNG() {\n getRandomValues(rnds8);\n return rnds8;\n };\n} else {\n // Math.random()-based (RNG)\n //\n // If all else fails, use Math.random(). It's fast, but is of unspecified\n // quality.\n var rnds = new Array(16);\n\n module.exports = function mathRNG() {\n for (var i = 0, r; i < 16; i++) {\n if ((i & 0x03) === 0) r = Math.random() * 0x100000000;\n rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;\n }\n\n return rnds;\n };\n}\n","var rng = require('./lib/rng');\nvar bytesToUuid = require('./lib/bytesToUuid');\n\n// **`v1()` - Generate time-based UUID**\n//\n// Inspired by https://github.com/LiosK/UUID.js\n// and http://docs.python.org/library/uuid.html\n\nvar _nodeId;\nvar _clockseq;\n\n// Previous uuid creation time\nvar _lastMSecs = 0;\nvar _lastNSecs = 0;\n\n// See https://github.com/uuidjs/uuid for API details\nfunction v1(options, buf, offset) {\n var i = buf && offset || 0;\n var b = buf || [];\n\n options = options || {};\n var node = options.node || _nodeId;\n var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq;\n\n // node and clockseq need to be initialized to random values if they're not\n // specified. We do this lazily to minimize issues related to insufficient\n // system entropy. See #189\n if (node == null || clockseq == null) {\n var seedBytes = rng();\n if (node == null) {\n // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)\n node = _nodeId = [\n seedBytes[0] | 0x01,\n seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]\n ];\n }\n if (clockseq == null) {\n // Per 4.2.2, randomize (14 bit) clockseq\n clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;\n }\n }\n\n // UUID timestamps are 100 nano-second units since the Gregorian epoch,\n // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so\n // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'\n // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.\n var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime();\n\n // Per 4.2.1.2, use count of uuid's generated during the current clock\n // cycle to simulate higher resolution clock\n var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1;\n\n // Time since last uuid creation (in msecs)\n var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;\n\n // Per 4.2.1.2, Bump clockseq on clock regression\n if (dt < 0 && options.clockseq === undefined) {\n clockseq = clockseq + 1 & 0x3fff;\n }\n\n // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new\n // time interval\n if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {\n nsecs = 0;\n }\n\n // Per 4.2.1.2 Throw error if too many uuids are requested\n if (nsecs >= 10000) {\n throw new Error('uuid.v1(): Can\\'t create more than 10M uuids/sec');\n }\n\n _lastMSecs = msecs;\n _lastNSecs = nsecs;\n _clockseq = clockseq;\n\n // Per 4.1.4 - Convert from unix epoch to Gregorian epoch\n msecs += 12219292800000;\n\n // `time_low`\n var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;\n b[i++] = tl >>> 24 & 0xff;\n b[i++] = tl >>> 16 & 0xff;\n b[i++] = tl >>> 8 & 0xff;\n b[i++] = tl & 0xff;\n\n // `time_mid`\n var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;\n b[i++] = tmh >>> 8 & 0xff;\n b[i++] = tmh & 0xff;\n\n // `time_high_and_version`\n b[i++] = tmh >>> 24 & 0xf | 0x10; // include version\n b[i++] = tmh >>> 16 & 0xff;\n\n // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)\n b[i++] = clockseq >>> 8 | 0x80;\n\n // `clock_seq_low`\n b[i++] = clockseq & 0xff;\n\n // `node`\n for (var n = 0; n < 6; ++n) {\n b[i + n] = node[n];\n }\n\n return buf ? buf : bytesToUuid(b);\n}\n\nmodule.exports = v1;\n","var rng = require('./lib/rng');\nvar bytesToUuid = require('./lib/bytesToUuid');\n\nfunction v4(options, buf, offset) {\n var i = buf && offset || 0;\n\n if (typeof(options) == 'string') {\n buf = options === 'binary' ? new Array(16) : null;\n options = null;\n }\n options = options || {};\n\n var rnds = options.random || (options.rng || rng)();\n\n // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n rnds[6] = (rnds[6] & 0x0f) | 0x40;\n rnds[8] = (rnds[8] & 0x3f) | 0x80;\n\n // Copy bytes to buffer, if provided\n if (buf) {\n for (var ii = 0; ii < 16; ++ii) {\n buf[i + ii] = rnds[ii];\n }\n }\n\n return buf || bytesToUuid(rnds);\n}\n\nmodule.exports = v4;\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/crypto\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/html\");","import { parseHTML } from 'k6/html'\n\n/**\n * Base class to derive errors from\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class AWSError extends Error {\n code: string\n\n /**\n * Create an AWSError\n *\n * @param {string} message - A longer human readable error message.\n * @param {string} code - A unique short code representing the error that was emitted\n */\n constructor(message: string, code: string) {\n super(message)\n this.name = 'AWSError'\n this.code = code\n }\n\n /**\n * Parse an AWSError from an XML document\n *\n * @param {string} xmlDocument - Serialized XML document to parse the error from\n */\n static parseXML(xmlDocument: string): AWSError {\n const doc = parseHTML(xmlDocument)\n return new AWSError(doc.find('Message').text(), doc.find('Code').text())\n }\n}\n","import crypto, { hmac, sha256 } from 'k6/crypto'\nimport { HTTPMethod, HTTPHeaders } from './http'\nimport { AWSConfig } from './config'\nimport { AWSError } from './error'\n\n/**\n * Includes AWS v4 signing information to the provided HTTP headers object.\n *\n * This function will compute the `Authorization` header signature for the\n * provided request components, and add it to `header`. It will do so by following\n * the procedure detailled AWS' API docs: https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html\n *\n * The resulting `Authorization` header value is computed for the provided\n * headers object. Thus, any modification of the headers past a call to `signHeaders`\n * would effectively invalidate their signature, and the function should be\n * called again to recompute it.\n *\n * @param {object} headers - HTTP headers request to sign.\n * @param {number} requestTimestamp - Timestamp of the request\n * @param {string} method - HTTP method used\n * @param {string} path - HTTP request URL's path\n * @param {string} queryString - HTTP request URL's querystring\n * @param {string | ArrayBuffer} body - HTTP request's payload\n * @param {AWSConfig} - AWS configuration\n * @param {string} service - AWS service name\n * @param {URIEncodingConfig} - URI encoding configuration\n */\nexport function signHeaders(\n headers: HTTPHeaders,\n requestTimestamp: number,\n method: HTTPMethod,\n path: string,\n queryString: string,\n body: string | ArrayBuffer,\n awsConfig: AWSConfig,\n service: string,\n URIencodingConfig: URIEncodingConfig\n): HTTPHeaders {\n const derivedSigningKey = deriveSigningKey(\n awsConfig.secretAccessKey,\n requestTimestamp,\n awsConfig.region,\n service\n )\n\n const canonicalRequest = createCanonicalRequest(\n method,\n path,\n queryString,\n headers,\n body,\n URIencodingConfig\n )\n\n const stringToSign = createStringToSign(\n requestTimestamp,\n awsConfig.region,\n service,\n sha256(canonicalRequest, 'hex')\n )\n\n const credentialScope = createCredentialScope(requestTimestamp, awsConfig.region, service)\n const signedHeaders = createSignedHeaders(headers)\n const signature = calculateSignature(derivedSigningKey, stringToSign)\n const authorizationHeader = `${HashingAlgorithm} Credential=${awsConfig.accessKeyID}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`\n\n headers['Authorization'] = authorizationHeader\n\n return headers\n}\n\n/**\n * Error indicating an Invalid signature has been sent to AWS services\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class InvalidSignatureError extends AWSError {\n /**\n * Constructs an InvalidSignatureError\n *\n * @param {string} message - human readable error message\n */\n constructor(message: string, code: string) {\n super(message, code)\n this.name = 'InvalidSignatureError'\n }\n}\n\n/**\n * Calculte the signature for AWS signature version 4\n *\n * @param {string} derivedSigningKey - dervied signing key as computed by `deriveSigningKey`\n * @param {string} stringToSign - String to sign as computed by `createStringToSign`\n * @return {string}\n */\nexport function calculateSignature(derivedSigningKey: ArrayBuffer, stringToSign: string): string {\n return hmac('sha256', derivedSigningKey, stringToSign, 'hex')\n}\n/**\n * Derives the signing key for authenticating requests signed with\n * the Signature version 4 authentication protocol.\n *\n * deriveSigningKey produces a signing key by creating a series of\n * hash-based message authentication codes (HMACs) represented in\n * a binary format.\n *\n * The derived signing key is specific to the date it's made at, as well as\n * the service and region it targets.\n *\n * @param {string} secretAccessKey - the AWS secret access key to derive the signing key for\n * @param {number} time - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service. MUST be UTF-8 encoded.\n * @return {string}\n */\nexport function deriveSigningKey(\n secretAccessKey: string,\n time: number,\n region: string,\n service: string\n): ArrayBuffer {\n const kSecret = secretAccessKey\n const date = toDate(time)\n\n // FIXME: hmac takes ArrayBuffer as input, but returns bytes (number[]).\n // How does one convert from one to the other?\n const kDate: any = hmac('sha256', 'AWS4' + kSecret, date, 'binary')\n const kRegion: any = hmac('sha256', kDate, region, 'binary')\n const kService: any = hmac('sha256', kRegion, service, 'binary')\n const kSigning: any = hmac('sha256', kService, 'aws4_request', 'binary')\n\n return kSigning\n}\n\n// Hashing Algorithm to use in the signature process\nexport const HashingAlgorithm = 'AWS4-HMAC-SHA256'\n\n/**\n * Certain services, such as S3, allow for unsigned payloads. If\n * producing a signed canonical request for such service, pass\n * the `UnsignedPayload` constant value as the payload parameter.\n */\nexport const UnsignedPayload = 'UNSIGNED-PAYLOAD'\n\n/**\n * Create the \"string to sign\" part of the signature Version 4 protocol.\n *\n * The \"string to sign\" includes meta information about your request and\n * about the canonical request that you created with `createCanonicalRequest`.\n * It is used hand in hand with the signing key to create the request signature.\n *\n * @param {number} requestTimestamp - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service name. MUST be UTF-8 encoded.\n * @param {string} hashedCanonicalRequest - canonical request as produced by calling the createCanonicalRequest function,\n * hashed using the SHA256 algorithm (encoded in hexadecimal format).\n * @return {string}\n */\nexport function createStringToSign(\n requestTimestamp: number,\n region: string,\n service: string,\n hashedCanonicalRequest: string\n): string {\n // the request date specified in ISO8601 format: YYYYMMDD'T'HHMMSS'Z'\n const requestDateTime = toTime(requestTimestamp)\n\n // The credential scope value, consisting of the date in YYYYMMDD format,\n // the targeted region, the targeted service, and a termination string.\n // Note that the region and service MUST be UTF-8 encoded.\n const credentialScope = createCredentialScope(requestTimestamp, region, service)\n\n const stringToSign = [\n // Algorithm\n HashingAlgorithm,\n\n // RequestDateTime\n requestDateTime,\n\n // CredentialScope\n credentialScope,\n\n // HashedCanonicalRequest\n hashedCanonicalRequest,\n ].join('\\n')\n\n return stringToSign\n}\n\n/**\n *\n * Helper function creating a credential scope string to use in the signature\n * version 4 process. A credential scope consists of the date of the request\n * in YYYYMMDD format, the targeted region, the targeted service, and a\n * termination string.\n *\n * Note that the region and service MUST be UTF-8 encoded.\n *\n * @param {number} requestTimestamp - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service name. MUST be UTF-8 encoded.\n * @return {string}\n */\nexport function createCredentialScope(\n requestTimestamp: number,\n region: string,\n service: string\n): string {\n return [toDate(requestTimestamp), region, service, 'aws4_request'].join('/')\n}\n\n/**\n * Create a string that includes information from your request\n * in a AWS signature v4 standardized (canonical) format.\n *\n * @param {string} method - the HTTP request method\n * @param {string} uri - URI-encoded version of the absolute path component of the URI\n * @param {string} query - request's query string\n * @param {Object} headers - all the HTTP headers that you wish to include with the signed request\n * @param {string | ArrayBuffer} payload - payload to include as the body of the request\n * @param {URIEncodingConfig} URIencodingConfig- URI encoding configuration\n * @return {string}\n */\nexport function createCanonicalRequest(\n method: HTTPMethod,\n uri: string,\n query: string,\n headers: HTTPHeaders,\n payload: string | ArrayBuffer,\n URIencodingConfig: URIEncodingConfig\n): string {\n const httpRequestMethod = method.toUpperCase()\n const canonicalURI = createCanonicalURI(uri, URIencodingConfig)\n const canonicalQueryString = createCanonicalQueryString(query)\n const canonicalHeaders = createCanonicalHeaders(headers)\n const signedHeaders = createSignedHeaders(headers)\n const requestPayload = createCanonicalPayload(payload)\n\n const canonicalRequest = [\n httpRequestMethod,\n canonicalURI,\n canonicalQueryString,\n canonicalHeaders,\n signedHeaders,\n requestPayload,\n ].join('\\n')\n\n return canonicalRequest\n}\n\n/**\n * Creates the (canonical) URI-encoded version of the\n * absolute path component of the URI: everything in the URI\n * from the HTTP host to the question mark character (\"?\")\n * that begins the query string parameters (if any).\n *\n * @param {string} uri - URI to canonize\n * @param {URIEncodingConfig} - URI encoding configuration\n * @return {string} - canonical URL\n */\nexport function createCanonicalURI(uri: string, URIencodingConfig: URIEncodingConfig): string {\n if (uri == '/') {\n return uri\n }\n\n let canonicalURI = uri\n if (uri[uri.length - 1] == '/' && canonicalURI[canonicalURI.length - 1] != '/') {\n canonicalURI += '/'\n }\n\n canonicalURI = URIEncode(canonicalURI, URIencodingConfig.path)\n\n return URIencodingConfig.double ? URIEncode(canonicalURI, URIencodingConfig.path) : canonicalURI\n}\n\n// FIXME: does it work as expected?\n/**\n * Creates the canonical form of the request's query\n * string. If the request does not include a query string,\n * provide an empty string.\n *\n * @param {String | Object} qs - query string to canonize\n * @return {string}\n */\nexport function createCanonicalQueryString(qs: string): string {\n if (qs === '') {\n return ''\n }\n\n // const intermediary: { [key: string]: string } = parseQueryString(qs)\n\n // return Object.keys(intermediary)\n // .sort()\n // .map((key: string) => {\n // // const values: string[] = Array.isArray(intermediary[key])\n // // ? intermediary[key]\n // // : [intermediary[key]]\n // const values = intermediary[key]\n\n // return values\n // .sort()\n // .map((val: string) => encodeURIComponent(key) + '=' + encodeURIComponent(val))\n // .join('&')\n // })\n // .join('&')\n\n return parseQueryString(qs)\n .map(([key, value]: [string, string]): string => {\n return encodeURIComponent(key) + '=' + encodeURIComponent(value)\n })\n .join('&')\n}\n/**\n * Create the canonical form of the request's headers.\n * Canonical headers consist of all the HTTP headers you\n * are including with the signed request.\n *\n * Note that:\n * * for HTTP/1.1 requests, the headers should at least\n * contain the `host` header.\n * * for HTTP/2, the `:authority` header must be used instead\n * of `host`.\n *\n * @param {Object} headers\n * @return {string}\n */\nexport function createCanonicalHeaders(headers: HTTPHeaders) {\n if (headers.constructor !== Object || Object.entries(headers).length === 0) {\n return ''\n }\n\n const canonicalHeaders = Object.entries(headers)\n .map(([name, values]) => {\n const canonicalName = name.toLowerCase().trim()\n const normalizedValues = Array.isArray(values) ? values : [values]\n\n // Note that we do not need to sort values\n const canonicalValues = normalizedValues\n .map((v) => {\n // convert sequential spaces to a single space\n return v.replace(/\\s+/g, ' ').replace(/^\\s+|\\s+$/g, '')\n })\n .join(',') // standard for multiple values in a HTTP header\n\n return canonicalName + ':' + canonicalValues + '\\n'\n })\n .sort()\n .join('')\n\n return canonicalHeaders\n}\n\n/**\n * Create the canonical request's signed headers.\n *\n * The signed headers part of the request contains the\n * list of headers included in the request's signing process.\n *\n * Note that:\n * * for HTTP/1.1 requests, the `host` header must be included.\n * * for HTTP/2 requests, the `:authority` header must be included instead\n * of host.\n * * if used, the `x-amz-date` header must be included.\n *\n * @param {Object} headers\n * @return {string}\n * @throws {TypeError} - on headers not being an Object, or being empty.\n */\nexport function createSignedHeaders(headers: { [key: string]: string }) {\n if (headers.constructor !== Object) {\n throw new TypeError('headers should be an object')\n }\n\n if (Object.entries(headers).length === 0) {\n throw 'headers should at least contain either the Host (HTTP 1.1) or :authority (HTTP 2) parameter'\n }\n\n // To create the signed headers list, convert\n // all header names to lowercase, sort them by\n // character code, and use a semicolon to separate\n // the header names.\n const result = Object.keys(headers)\n .map((name) => name.toLowerCase().trim())\n .sort()\n .join(';')\n\n return result\n}\n\n/**\n * Create the canonical form of the request's payload.\n *\n * The canonical payload consists in a lowercased, hex encoded,\n * SHA256 hash of the requests body/payload.\n *\n * Certain services, such as S3, allow for unsigned payload. If\n * producing a signed canonical request for such service, pass\n * the `UnsignedPayload` constant value as the payload parameter.\n *\n * @param {String | ArrayBuffer} payload\n * @return {string}\n */\nexport function createCanonicalPayload(payload: string | ArrayBuffer) {\n if (payload === UnsignedPayload) {\n return payload\n }\n\n // Note that if the paylaod is null, we convert it\n // to an empty string.\n // TODO: Should switching to empty string if null impact headers?\n return crypto.sha256(payload || '', 'hex').toLowerCase()\n}\n\n/**\n * URIEncodes encodes every bytes of a URI to be URL-safe.\n *\n * This implementation is specific to AWS; who intended to make it as\n * close as possible to the underlying RFC 3946. It:\n * * URI encode every byte except the unreserved characters: 'A'-'Z', 'a'-'z', '0'-'9',\n * '-', '.', '_', and '~'.\n * * considers the space character as a reserved character and must URI encodes\n * encodes it as \"%20\" (and not as \"+\").\n * * URI encodes every byte by prefixing with '%' the two-digit hexadecimal value of the byte.\n * * If the `path` argument is set, forward slashes are not encoded, to fit with\n * S3 requirements.\n *\n * N.B: this implementation differs with ES6' mainly in that it does\n * encode the \"'\" character.\n *\n * Based on AWS implementation: https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-core/src/main/java/com/amazonaws/util/SdkHttpUtils.java#L66\n * Encoding specs: https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html\n *\n * @param {string} uri - uri to encode\n * @param {boolean} path - slash characters should be encoded everywhere,\n * but in paths, set to false when encoding a path\n * @return {string} the URI encoded result\n */\nexport function URIEncode(uri: string, path: boolean): string {\n if (uri == '') {\n return uri\n }\n\n return uri\n .split('') // to be able to map over a string, because... javascript...\n .map((letter: string) => {\n if (isAlpha(letter) || isNumeric(letter) || '-._~'.includes(letter)) {\n return letter\n }\n\n // Space should be explicitly encoded to as %20.\n if (letter == ' ') {\n return '%20'\n }\n\n // If the URI is a path, the forward slash shouldn't\n // be encoded.\n if (letter == '/' && path) {\n return '/'\n }\n\n return '%' + letter.charCodeAt(0).toString(16).toUpperCase()\n })\n .join('')\n}\n\n/**\n * Class holding URI encoding configuration\n */\nexport class URIEncodingConfig {\n double: boolean\n path: boolean\n\n /**\n *\n * @param {boolean} double - should the URI be double encoded?\n * @param {boolean} path - is the URI a path? If so, its forward\n * slashes won't be URIencoded.\n */\n constructor(double: boolean, path: boolean) {\n this.double = double\n this.path = path\n }\n}\n\n/**\n * Compute the request time value as specified by the ISO8601\n * format: YYYYMMDD'T'HHMMSS'Z'\n *\n * @param {number} timestamp\n * @return {string}\n */\nexport function toTime(timestamp: number): string {\n return new Date(timestamp).toISOString().replace(/[:\\-]|\\.\\d{3}/g, '')\n}\n/**\n * Computethe request date value in the format: YYYMMDD\n *\n * @param {number} timestamp\n * @return {string}\n */\nexport function toDate(timestamp: number): string {\n return toTime(timestamp).substring(0, 8)\n}\n\n// FIXME: does it work as expected?\n/**\n * Parse a HTTP request URL's querystring into an object\n * containing its `key=value` pairs.\n *\n * @param {string} qs\n * @return {object}\n */\nexport function parseQueryString(qs: string): Array<[string, string]> {\n if (qs.length === 0) {\n return []\n }\n\n return qs\n .split('&')\n .filter((e) => e)\n .map((v: string): [string, string] => {\n const parts = v.split('=', 2) as [string, string]\n return [decodeURIComponent(parts[0]), decodeURIComponent(parts[1])]\n })\n .sort((a: [string, string], b: [string, string]) => {\n return a[0].localeCompare(b[0])\n })\n}\n\nfunction isAlpha(c: string): boolean {\n return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')\n}\n\nfunction isNumeric(c: string): boolean {\n return c >= '0' && c <= '9'\n}\n\n// FIXME: finish implementation when needed\n// See the following for more details:\n// * https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html\n// * https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html\n// export function signQueryString(\n// queryString,\n// requestTimestamp,\n// accessKeyID,\n// secretAccessKey,\n// region,\n// service,\n// ttl, // in seconds\n// headers,\n// doubleURIEncoding = true\n// ) {\n// const credential = [accessKeyID, toDate(requestTimestamp), region, service].join('/')\n//\n// const canonicalRequest = createCanonicalRequest(\n// method,\n// path,\n// queryString,\n// headers,\n// body,\n// doubleURIEncoding\n// )\n//\n// const derivedSigningKey = deriveSigningKey(secretAccessKey, requestTimestamp, region, service)\n//\n// const stringToSign = createStringToSign(\n// requestTimestamp,\n// region,\n// service,\n// sha256(canonicalRequest, 'hex')\n// )\n//\n// const signedHeaders = createSignedHeaders(headers)\n// const signature = calculateSignature(derivedSigningKey, stringToSign)\n//\n// return [\n// `X-Amz-Algorithm=${HashingAlgorithm}`,\n// `X-Amz-Credential=${crediental}`,\n// `X-Amz-Date=${toTime(requestTimestamp)}`,\n// `X-Amz-Expires=${ttl}`,\n// `X-Amz-SignedHeaders=${signedHeaders}`,\n// `X-Amz-Signature=${signature}`,\n//`X-Amz-Security-Token=`, // TODO: optional\n// ].join('&')\n// }\n","/** Class holding an AWS connection information */\nexport class AWSConfig {\n region: string\n accessKeyID: string\n secretAccessKey: string\n\n /**\n * Create an AWSConfig.\n *\n * @param {string} region - the AWS region to connect to, as listed: https://docs.aws.amazon.com/general/latest/gr/rande.html\n * @param {string} accessKeyID - Your user's AWS access key id credential\n * @param {string} secretAccessKey - Your user's AWS secret access key credential\n * @throws {InvalidArgumentException}\n */\n constructor(region: string, accessKeyID: string, secretAccessKey: string) {\n if (typeof region !== 'string' || region === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS region; reason: should be a non empty string'\n )\n }\n\n if (typeof accessKeyID !== 'string' || accessKeyID === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS access key ID; reason: should be a non empty string'\n )\n }\n\n if (typeof secretAccessKey !== 'string' || secretAccessKey === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS secret access key; reason: should be a non empty string'\n )\n }\n\n this.region = region\n this.accessKeyID = accessKeyID\n this.secretAccessKey = secretAccessKey\n }\n}\n\n/** Class representing an invalid AWS configuration */\nexport class InvalidAWSConfigError extends Error {\n constructor(message: string) {\n super(message)\n }\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/http\");","import { HTTPMethod, HTTPHeaders } from './http'\nimport { AWSConfig } from './config'\nimport { signHeaders, URIEncodingConfig, toTime } from './signature'\n\n/**\n * Class allowing to build requests targeting AWS APIs\n *\n * This class is meant to be used as a base class for specific\n * services clients. See S3Client or SecretsManagerClient for\n * usage examples.\n */\nexport class AWSClient {\n awsConfig: AWSConfig\n serviceName: string\n URIencodingConfig: URIEncodingConfig\n\n /**\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n * @param {string} serviceName - name of the service to target.\n * @param {URIEncodingConfig} URIencodingConfig - configures how requests URIs should be encoded.\n */\n constructor(awsConfig: AWSConfig, serviceName: string, URIencodingConfig: URIEncodingConfig) {\n this.awsConfig = awsConfig\n this.serviceName = serviceName\n this.URIencodingConfig = URIencodingConfig\n }\n\n buildRequest(\n method: HTTPMethod,\n host: string,\n path: string,\n queryString: string,\n body: string | ArrayBuffer,\n headers: HTTPHeaders\n ): AWSRequest {\n const requestTimestamp: number = Date.now()\n const date: string = toTime(requestTimestamp)\n\n headers['Host'] = host\n headers['X-Amz-Date'] = date\n\n headers = signHeaders(\n // headers\n headers,\n\n // requestTimestamp\n requestTimestamp,\n\n // method\n method,\n\n // path\n path,\n\n // querystring\n queryString,\n\n // body\n body,\n\n // AWS configuration\n this.awsConfig,\n\n // AwS target service name\n this.serviceName,\n\n // doubleEncoding: S3 does single-encoding of the uri component\n // pathURIEncoding: S3 manipulates object keys, and forward slashes\n // shouldn't be URI encoded\n this.URIencodingConfig\n )\n\n // '?' should not be part of the querystring when we sign the headers\n path = path !== '' ? path : '/'\n let url = `https://${host}${path}`\n if (queryString !== '') {\n url += `?${queryString}`\n }\n\n return { url: url, headers: headers }\n }\n}\n\n/**\n * Type alias representing the result of an AWSClient.buildRequest call\n */\nexport interface AWSRequest {\n url: string\n headers: HTTPHeaders\n}\n","import { bytes } from 'k6'\nimport http from 'k6/http'\nimport { parseHTML } from 'k6/html'\nimport { sha256 } from 'k6/crypto'\n\nimport { InvalidSignatureError, URIEncodingConfig } from './signature'\nimport { AWSClient, AWSRequest } from './client'\nimport { AWSError } from './error'\nimport { AWSConfig } from './config'\n\n/** Class allowing to interact with Amazon AWS's S3 service */\nexport class S3Client extends AWSClient {\n /**\n * Create a S3Client\n *\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n */\n constructor(awsConfig: AWSConfig) {\n const URIencodingConfig = new URIEncodingConfig(false, true)\n super(awsConfig, 's3', URIencodingConfig)\n }\n\n /**\n * Returns a list of all buckets owned by the authenticated sender of the request.\n * To use this operation, you must have the s3:ListAllMyBuckets permission.\n *\n * @return {Array.} buckets - An array of objects describing S3 buckets\n * with the following fields: name, and creationDate.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n listBuckets(): Array {\n // Prepare request\n const method = 'GET'\n const host = `${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(method, host, '/', '', body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n let buckets: Array = []\n\n const doc = parseHTML(res.body as string)\n\n doc.find('Buckets')\n .children()\n .each((_, bucketDefinition) => {\n let bucket = {}\n\n bucketDefinition.children().forEach((child) => {\n switch (child.nodeName()) {\n case 'name':\n Object.assign(bucket, { name: child.textContent() })\n break\n case 'creationdate':\n Object.assign(bucket, {\n creationDate: Date.parse(child.textContent()),\n })\n }\n })\n\n buckets.push(bucket as S3Bucket)\n })\n\n return buckets\n }\n\n /**\n * Returns some or all (up to 1,000) of the objects in a bucket.\n *\n * @param {string} bucketName - Bucket name to list.\n * @param {string?} prefix='' - Limits the response to keys that begin with the specified prefix.\n * @return {Array.} - returns an array of objects describing S3 objects\n * with the following fields: key, lastModified, etag, size and storageClass.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n listObjects(bucketName: string, prefix?: string): Array {\n // Prepare request\n const method = 'GET'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const body = ''\n const querystring = `list-type=2&prefix=${prefix}`\n const signedRequest: AWSRequest = super.buildRequest(method, host, '/', querystring, body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n Prefix: prefix ?? '',\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n let objects: Array = []\n\n // Extract the objects definition from\n // the XML response\n parseHTML(res.body as string)\n .find('Contents')\n .each((_, objectDefinition) => {\n let obj = {}\n\n objectDefinition.children().forEach((child) => {\n switch (child.nodeName()) {\n case 'key':\n Object.assign(obj, { key: child.textContent() })\n break\n case 'lastmodified':\n Object.assign(obj, { lastModified: Date.parse(child.textContent()) })\n break\n case 'etag':\n Object.assign(obj, { etag: child.textContent() })\n break\n case 'size':\n Object.assign(obj, { size: parseInt(child.textContent()) })\n break\n case 'storageclass':\n Object.assign(obj, { storageClass: child.textContent() })\n }\n })\n\n objects.push(obj as S3Object)\n })\n\n return objects\n }\n /**\n * Retrieves an Object from Amazon S3.\n *\n * To use getObject, you must have `READ` access to the object.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to get.\n * @return {S3Object} - returns the content of the fetched S3 Object.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n getObject(bucketName: string, objectKey: string): S3Object {\n // Prepare request\n const method = 'GET'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(method, host, path, '', body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n return new S3Object(\n objectKey,\n Date.parse(res.headers['Last-Modified']),\n res.headers['ETag'],\n parseInt(res.headers['Content-Length']),\n undefined, // FIXME: GetObject response doesn't contain the storage class\n res.body\n )\n }\n /**\n * Adds an object to a bucket.\n *\n * You must have WRITE permissions on a bucket to add an object to it.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to put.\n * @param {string | ArrayBuffer} data - the content of the S3 Object to upload.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n putObject(bucketName: string, objectKey: string, data: string | ArrayBuffer) {\n // Prepare request\n const method = 'PUT'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const queryString = ''\n const body = data\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n path,\n queryString,\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n }\n\n /**\n * Removes the null version (if there is one) of an object and inserts a delete marker,\n * which becomes the latest version of the object.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to delete.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n deleteObject(bucketName: string, objectKey: string): void {\n // Prepare request\n const method = 'DELETE'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const queryString = ''\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n path,\n queryString,\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n }\n\n // FIXME: remove dependency to `error_message`\n // FIXME: just pass it the response?\n _handle_error(error_code: number, error_message: string, error_body: string) {\n if (error_message == '' || error_code === 0) {\n return\n }\n\n // FIXME: should be error_code === 1301 instead\n // See: https://github.com/grafana/k6/issues/2474\n // See: https://github.com/golang/go/issues/49281\n if (error_message && error_message.startsWith('301')) {\n // Bucket not found\n throw new S3ServiceError('Resource not found', 'ResourceNotFound', 'getObject')\n }\n\n const awsError = AWSError.parseXML(error_body)\n switch (awsError.code) {\n case 'AuthorizationHeaderMalformed':\n throw new InvalidSignatureError(awsError.message, awsError.code)\n default:\n throw new S3ServiceError(awsError.message, awsError.code, 'listObjects')\n }\n }\n}\n\n// TODO: use interface instead?\n/** Class representing a S3 Bucket */\nexport class S3Bucket {\n name: string\n creationDate: Date\n\n /**\n * Create an S3 Bucket\n *\n * @param {string} name - S3 bucket's name\n * @param {Date} creationDate - S3 bucket's creation date\n */\n constructor(name: string, creationDate: Date) {\n this.name = name\n this.creationDate = creationDate\n }\n}\n\n// TODO: use interface instead?\n/** Class representing an S3 Object */\nexport class S3Object {\n key: string\n lastModified: number\n etag: string\n size: number\n storageClass: StorageClass\n data?: string | bytes | null\n\n /**\n * Create an S3 Object\n *\n * @param {string} key - S3 object's key\n * @param {Date} lastModified - S3 object last modification date\n * @param {string} etag - S3 object's etag\n * @param {number} size - S3 object's size\n * @param {StorageClass} storageClass - S3 object's storage class\n * @param {string | bytes | null} data=null - S3 Object's data\n */\n constructor(\n key: string,\n lastModified: number,\n etag: string,\n size: number,\n storageClass: StorageClass,\n data?: string | bytes | null\n ) {\n this.key = key\n this.lastModified = lastModified\n this.etag = etag\n this.size = size\n this.storageClass = storageClass\n this.data = data\n }\n}\n\n/**\n * Error indicating a S3 operation failed\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class S3ServiceError extends AWSError {\n operation: string\n\n /**\n * Constructs a S3ServiceError\n *\n * @param {string} message - human readable error message\n * @param {string} code - A unique short code representing the error that was emitted\n * @param {string} operation - Name of the failed Operation\n */\n constructor(message: string, code: string, operation: string) {\n super(message, code)\n this.name = 'S3ServiceError'\n this.operation = operation\n }\n}\n\n/**\n * Describes the class of storage used to store a S3 object.\n */\ntype StorageClass =\n | 'STANDARD'\n | 'REDUCED_REDUNDANCY'\n | 'GLACIER'\n | 'STANDARD_IA'\n | 'INTELLIGENT_TIERING'\n | 'DEEP_ARCHIVE'\n | 'OUTPOSTS'\n | 'GLACIER_IR'\n | undefined\n","import { JSONArray, JSONObject } from 'k6'\nimport http, { RefinedResponse, ResponseType } from 'k6/http'\n\nimport { AWSClient, AWSRequest } from './client'\nimport { AWSError } from './error'\nimport { AWSConfig } from './config'\nimport { InvalidSignatureError, URIEncodingConfig } from './signature'\nimport { v4 as uuidv4 } from 'uuid'\nimport { HTTPMethod, HTTPHeaders } from './http'\n\n/**\n * Class allowing to interact with Amazon AWS's SecretsManager service\n */\nexport class SecretsManagerClient extends AWSClient {\n method: HTTPMethod\n commonHeaders: HTTPHeaders\n\n /**\n * Create a SecretsManagerClient\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n */\n constructor(awsConfig: AWSConfig) {\n const URIencodingConfig = new URIEncodingConfig(true, false)\n super(awsConfig, 'secretsmanager', URIencodingConfig)\n\n // this.serviceName = 'secretsmanager'\n\n // All interactions with the Secrets Manager service\n // are made via the GET or POST method.\n this.method = 'POST'\n\n this.commonHeaders = {\n 'Accept-Encoding': 'identity',\n 'Content-Type': 'application/x-amz-json-1.1',\n }\n }\n\n /**\n * Returns a list of all secrets owned by the authenticated sender of the request.\n * To use this operation, you must have the secretsmanager:ListSecrets permission.\n *\n * @return {Array.} secrets - An array of objects describing Secret Manager's secrets\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n listSecrets(): Array {\n const body = JSON.stringify({})\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.ListSecrets`,\n }\n )\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('ListSecrets', res)\n const json: JSONArray = res.json('SecretList') as JSONArray\n\n return json.map((s) => Secret.fromJSON(s as JSONObject))\n }\n\n /**\n * Retrieves a secret from Amazon Sercets Manager\n *\n * @param {string} secretID - The ARN or name of the secret to retrieve.\n * @returns {Secret} - returns the content of the fetched Secret object.\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n getSecret(secretID: string): Secret | undefined {\n const body = JSON.stringify({ SecretId: secretID })\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.GetSecretValue`,\n }\n )\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('GetSecretValue', res)\n\n return Secret.fromJSON(res.json() as JSONObject)\n }\n\n /**\n * Creates a new secret\n *\n * Note that this method only supports string-based values at the moment.\n *\n * @param {string} name - The name of the new secret.\n * The secret name can contain ASCII letters, numbers, and the following characters: /_+=.@\n * @param {string} secretString - The text data to encrypt and store in this new version of the secret.\n * @param {string} description - The description of the secret.\n * @param {string} versionID=null - Version of the secret. This value helps ensure idempotency.\n * As a default, if no versionID is provided, one will be created for you using the UUID v4\n * algorithm.\n * @param {Array.} tags=[] - A list of tags to attach to the secret. Each tag is a key and\n * value pair of strings in a JSON text string. Note that tag key names are case sensitive.\n * @returns {Secret} - returns the created secret\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n createSecret(\n name: string,\n secretString: string,\n description: string,\n versionID?: string,\n tags?: Array\n ): Secret {\n versionID = versionID || uuidv4()\n\n const body = JSON.stringify({\n Name: name,\n Description: description,\n SecretString: secretString,\n ClientRequestToken: versionID,\n Tags: tags,\n })\n\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.CreateSecret`,\n }\n )\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n // headers['X-Amz-Target'] = `${this.serviceName}.CreateSecret`\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('CreateSecret', res)\n\n return Secret.fromJSON(res.json() as JSONObject)\n }\n /**\n * Update a secret's value.\n *\n * Note that this method only support string-based values at the moment.\n *\n * @param {string} secretID - The ARN or name of the secret to update.\n * @param {string} secretString - The text data to encrypt and store in this new version of the secret.\n * @param {} versionID=null - A unique identifier for the new version of the secret. This value helps ensure idempotency.\n * As a default, if no versionID is provided, one will be created for you using the UUID v4\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n putSecretValue(secretID: string, secretString: string, versionID?: string): Secret {\n versionID = versionID || uuidv4()\n\n const body = JSON.stringify({\n SecretId: secretID,\n SecretString: secretString,\n ClientRequestToken: versionID,\n })\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.PutSecretValue`,\n }\n )\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('PutSecretValue', res)\n\n return Secret.fromJSON(res.json() as JSONObject)\n }\n\n /**\n * Deletes a secret and all of its versions.\n *\n * You can specify a recovery window during which you can restore the secret.\n * The minimum recovery window is 7 days. The default recovery window is 30 days.\n *\n * @param {string} secretID - The ARN or name of the secret to delete.\n * @param {number} recoveryWindow - The number of days from 7 to 30 that Secrets Manager\n * waits before permanently deleting the secret.\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n deleteSecret(\n secretID: string,\n { recoveryWindow = 30, noRecovery = false }: { recoveryWindow: number; noRecovery: boolean }\n ) {\n const payload: { [key: string]: string | boolean | number } = {\n SecretId: secretID,\n }\n\n // noRecovery and recoveryWindow are exclusive parameters\n if (noRecovery === true) {\n payload['ForceDeleteWithoutRecovery'] = true\n } else {\n payload['RecoveryWindowInDays'] = recoveryWindow\n }\n\n const body = JSON.stringify(payload)\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.DeleteSecret`,\n }\n )\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('DeleteSecret', res)\n }\n\n get host() {\n return `${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n }\n\n // TODO: operation should be an enum\n _handle_error(operation: string, response: RefinedResponse) {\n const errorCode = response.error_code\n if (errorCode === 0) {\n return\n }\n\n const error = response.json() as JSONObject\n if (errorCode >= 1400 && errorCode <= 1499) {\n // In the event of certain errors, the message is not set.\n // Also, note the inconsistency in casing...\n const errorMessage: string =\n (error.Message as string) || (error.message as string) || (error.__type as string)\n\n // Handle specifically the case of an invalid signature\n if (error.__type === 'InvalidSignatureException') {\n throw new InvalidSignatureError(errorMessage, error.__type)\n }\n\n // Otherwise throw a standard service error\n throw new SecretsManagerError(errorMessage, error.__type as string, operation)\n }\n\n if (errorCode === 1500) {\n throw new SecretsManagerError(\n 'An error occured on the server side',\n 'InternalServiceError',\n operation\n )\n }\n }\n}\n\n// TODO: create a Tags type\n\n/**\n * Class representing a Secret Manager's secret\n */\nexport class Secret {\n name: string\n arn: string\n secret: string\n createdDate: number\n lastAccessedDate: number\n lastChangedDate: number\n tags: Array<{ [key: string]: string }>\n\n /**\n * Constructs a Secret Manager's Secret\n *\n * @param {string} name - The friendly name of the secret.\n * @param {string} arn - The ARN of the secret.\n * @param {number} createdDate - The date and time that this version of the secret was created.\n * @param {number} lastAccessedDate - The last date that this secret was accessed. This value is\n * truncated to midnight of the date and therefore shows only the date, not the time.\n * @param {number} lastChangedDate - The last date and time that this secret was modified in any way.\n * @param {Array.} tags - The list of user-defined tags associated with the secret.\n */\n constructor(\n name: string,\n arn: string,\n secretString: string,\n createdDate: number,\n lastAccessedDate: number,\n lastChangedDate: number,\n tags: Array<{ [key: string]: string }> = []\n ) {\n this.name = name\n this.arn = arn\n this.secret = secretString\n this.createdDate = createdDate\n this.lastAccessedDate = lastAccessedDate\n this.lastChangedDate = lastChangedDate\n this.tags = tags\n }\n\n /**\n * Parses and constructs a Secret Manager's Secret from the content\n * of a JSON response returned by the AWS service\n *\n * @param {Object} json - JSON object as returned and parsed from\n * the AWS service's API call.\n * @returns {Secret}\n */\n static fromJSON(json: JSONObject) {\n return new Secret(\n json.Name as string,\n json.ARN as string,\n json.SecretString as string,\n json.CreatedDate as number,\n json.LastAccessedDate as number,\n json.LastChangedDate as number,\n json.Tags as Array<{ [key: string]: string }>\n )\n }\n}\n\nexport class SecretsManagerError extends AWSError {\n operation: string\n\n /**\n * Constructs a SecretsManagerError\n *\n * @param {string} message - human readable error message\n * @param {string} code - A unique short code representing the error that was emitted\n * @param {string} operation - Name of the failed Operation\n */\n constructor(message: string, code: string, operation: string) {\n super(message, code)\n this.name = 'SecretsManagerServiceError'\n this.operation = operation\n }\n}\n"],"names":["v1","v4","uuid","module","exports","byteToHex","i","toString","substr","buf","offset","bth","join","getRandomValues","crypto","bind","window","msCrypto","rnds8","Uint8Array","rnds","Array","r","Math","random","_nodeId","_clockseq","rng","bytesToUuid","_lastMSecs","_lastNSecs","options","b","node","clockseq","undefined","seedBytes","msecs","Date","getTime","nsecs","dt","Error","tl","tmh","n","ii","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","__webpack_modules__","getter","__esModule","d","a","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","require","AWSError","message","code","name","xmlDocument","doc","parseHTML","find","text","signHeaders","headers","requestTimestamp","method","path","queryString","body","awsConfig","service","URIencodingConfig","derivedSigningKey","secretAccessKey","time","region","kSecret","date","toDate","kDate","hmac","kRegion","kService","deriveSigningKey","canonicalRequest","uri","query","payload","httpRequestMethod","toUpperCase","canonicalURI","length","URIEncode","createCanonicalURI","canonicalQueryString","qs","split","filter","e","map","v","parts","decodeURIComponent","sort","localeCompare","parseQueryString","encodeURIComponent","createCanonicalQueryString","canonicalHeaders","constructor","entries","values","toLowerCase","trim","isArray","replace","createCanonicalHeaders","signedHeaders","createSignedHeaders","requestPayload","UnsignedPayload","createCanonicalPayload","createCanonicalRequest","stringToSign","hashedCanonicalRequest","requestDateTime","toTime","credentialScope","createCredentialScope","HashingAlgorithm","createStringToSign","sha256","signature","calculateSignature","authorizationHeader","accessKeyID","InvalidSignatureError","TypeError","keys","letter","c","isNumeric","includes","charCodeAt","URIEncodingConfig","double","this","timestamp","toISOString","substring","AWSConfig","InvalidAWSConfigError","AWSClient","serviceName","host","now","url","S3Client","signedRequest","res","http","_handle_error","error_code","error","buckets","children","each","_","bucketDefinition","bucket","forEach","child","nodeName","assign","textContent","creationDate","parse","push","bucketName","prefix","querystring","Prefix","objects","objectDefinition","lastModified","etag","size","parseInt","storageClass","objectKey","S3Object","data","error_message","error_body","startsWith","S3ServiceError","awsError","parseXML","S3Bucket","operation","SecretsManagerClient","commonHeaders","JSON","stringify","json","s","Secret","fromJSON","secretID","SecretId","secretString","description","versionID","tags","uuidv4","Name","Description","SecretString","ClientRequestToken","Tags","recoveryWindow","noRecovery","response","errorCode","errorMessage","Message","__type","SecretsManagerError","arn","createdDate","lastAccessedDate","lastChangedDate","secret","ARN","CreatedDate","LastAccessedDate","LastChangedDate"],"sourceRoot":""} \ No newline at end of file diff --git a/build/s3.min.js b/build/s3.min.js index 0032a8b..2778ae3 100644 --- a/build/s3.min.js +++ b/build/s3.min.js @@ -1,2 +1,2 @@ -(()=>{"use strict";var e={n:t=>{var r=t&&t.__esModule?()=>t.default:()=>t;return e.d(r,{a:r}),r},d:(t,r)=>{for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{AWSConfig:()=>F,InvalidAWSConfigError:()=>$,InvalidSignatureError:()=>R,S3Bucket:()=>ye,S3Client:()=>pe,S3Object:()=>he,S3ServiceError:()=>be,URIEncodingConfig:()=>I});const r=require("k6/crypto");var n=e.n(r);const o=require("k6/html");function i(e){return i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i(e)}function c(e,t){for(var r=0;re.length)&&(t=e.length);for(var r=0,n=new Array(t);r="A"&&r<="Z"||r>="a"&&r<="z"||function(e){return e>="0"&&e<="9"}(e)||"-._~".includes(e)?e:" "==e?"%20":"/"==e&&t?"/":"%"+e.charCodeAt(0).toString(16).toUpperCase();var r})).join("")}var I=w((function e(t,r){O(this,e),d(this,"double",void 0),d(this,"path",void 0),this.double=t,this.path=r}));function M(e){return new Date(e).toISOString().replace(/[:\-]|\.\d{3}/g,"")}function D(e){return M(e).substring(0,8)}function z(e){return z="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},z(e)}function q(e,t){if(t&&("object"===z(t)||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e)}function H(e){var t="function"==typeof Map?new Map:void 0;return H=function(e){if(null===e||(r=e,-1===Function.toString.call(r).indexOf("[native code]")))return e;var r;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return U(e,arguments,B(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),L(n,e)},H(e)}function U(e,t,r){return U=N()?Reflect.construct:function(e,t,r){var n=[null];n.push.apply(n,t);var o=new(Function.bind.apply(e,n));return r&&L(o,r.prototype),o},U.apply(null,arguments)}function N(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}function L(e,t){return L=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},L(e,t)}function B(e){return B=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},B(e)}function W(e,t){for(var r=0;r{"use strict";var e={n:t=>{var r=t&&t.__esModule?()=>t.default:()=>t;return e.d(r,{a:r}),r},d:(t,r)=>{for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{AWSConfig:()=>F,InvalidAWSConfigError:()=>$,InvalidSignatureError:()=>R,S3Bucket:()=>ye,S3Client:()=>pe,S3Object:()=>he,S3ServiceError:()=>be,URIEncodingConfig:()=>I});const r=require("k6/crypto");var n=e.n(r);const o=require("k6/html");function i(e){return i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i(e)}function c(e,t){for(var r=0;re.length)&&(t=e.length);for(var r=0,n=new Array(t);r="A"&&r<="Z"||r>="a"&&r<="z"||function(e){return e>="0"&&e<="9"}(e)||"-._~".includes(e)?e:" "==e?"%20":"/"==e&&t?"/":"%"+e.charCodeAt(0).toString(16).toUpperCase();var r})).join("")}var I=w((function e(t,r){O(this,e),d(this,"double",void 0),d(this,"path",void 0),this.double=t,this.path=r}));function M(e){return new Date(e).toISOString().replace(/[:\-]|\.\d{3}/g,"")}function D(e){return M(e).substring(0,8)}function z(e){return z="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},z(e)}function q(e,t){if(t&&("object"===z(t)||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e)}function H(e){var t="function"==typeof Map?new Map:void 0;return H=function(e){if(null===e||(r=e,-1===Function.toString.call(r).indexOf("[native code]")))return e;var r;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return U(e,arguments,B(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),L(n,e)},H(e)}function U(e,t,r){return U=N()?Reflect.construct:function(e,t,r){var n=[null];n.push.apply(n,t);var o=new(Function.bind.apply(e,n));return r&&L(o,r.prototype),o},U.apply(null,arguments)}function N(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}function L(e,t){return L=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},L(e,t)}function B(e){return B=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},B(e)}function W(e,t){for(var r=0;r {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/crypto\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/html\");","import { parseHTML } from 'k6/html'\n\n/**\n * Base class to derive errors from\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class AWSError extends Error {\n code: string\n\n /**\n * Create an AWSError\n *\n * @param {string} message - A longer human readable error message.\n * @param {string} code - A unique short code representing the error that was emitted\n */\n constructor(message: string, code: string) {\n super(message)\n this.name = 'AWSError'\n this.code = code\n }\n\n /**\n * Parse an AWSError from an XML document\n *\n * @param {string} xmlDocument - Serialized XML document to parse the error from\n */\n static parseXML(xmlDocument: string): AWSError {\n const doc = parseHTML(xmlDocument)\n return new AWSError(doc.find('Message').text(), doc.find('Code').text())\n }\n}\n","import crypto, { hmac, sha256 } from 'k6/crypto'\nimport { HTTPMethod, HTTPHeaders } from './http'\nimport { AWSConfig } from './config'\nimport { AWSError } from './error'\n\n/**\n * Includes AWS v4 signing information to the provided HTTP headers object.\n *\n * This function will compute the `Authorization` header signature for the\n * provided request components, and add it to `header`. It will do so by following\n * the procedure detailled AWS' API docs: https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html\n *\n * The resulting `Authorization` header value is computed for the provided\n * headers object. Thus, any modification of the headers past a call to `signHeaders`\n * would effectively invalidate their signature, and the function should be\n * called again to recompute it.\n *\n * @param {object} headers - HTTP headers request to sign.\n * @param {number} requestTimestamp - Timestamp of the request\n * @param {string} method - HTTP method used\n * @param {string} path - HTTP request URL's path\n * @param {string} queryString - HTTP request URL's querystring\n * @param {string | ArrayBuffer} body - HTTP request's payload\n * @param {AWSConfig} - AWS configuration\n * @param {string} service - AWS service name\n * @param {URIEncodingConfig} - URI encoding configuration\n */\nexport function signHeaders(\n headers: HTTPHeaders,\n requestTimestamp: number,\n method: HTTPMethod,\n path: string,\n queryString: string,\n body: string | ArrayBuffer,\n awsConfig: AWSConfig,\n service: string,\n URIencodingConfig: URIEncodingConfig\n): HTTPHeaders {\n const derivedSigningKey = deriveSigningKey(\n awsConfig.secretAccessKey,\n requestTimestamp,\n awsConfig.region,\n service\n )\n\n const canonicalRequest = createCanonicalRequest(\n method,\n path,\n queryString,\n headers,\n body,\n URIencodingConfig\n )\n\n const stringToSign = createStringToSign(\n requestTimestamp,\n awsConfig.region,\n service,\n sha256(canonicalRequest, 'hex')\n )\n\n const credentialScope = createCredentialScope(requestTimestamp, awsConfig.region, service)\n const signedHeaders = createSignedHeaders(headers)\n const signature = calculateSignature(derivedSigningKey, stringToSign)\n const authorizationHeader = `${HashingAlgorithm} Credential=${awsConfig.accessKeyID}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`\n\n headers['Authorization'] = authorizationHeader\n\n return headers\n}\n\n/**\n * Error indicating an Invalid signature has been sent to AWS services\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class InvalidSignatureError extends AWSError {\n /**\n * Constructs an InvalidSignatureError\n *\n * @param {string} message - human readable error message\n */\n constructor(message: string, code: string) {\n super(message, code)\n this.name = 'InvalidSignatureError'\n }\n}\n\n/**\n * Calculte the signature for AWS signature version 4\n *\n * @param {string} derivedSigningKey - dervied signing key as computed by `deriveSigningKey`\n * @param {string} stringToSign - String to sign as computed by `createStringToSign`\n * @return {string}\n */\nexport function calculateSignature(derivedSigningKey: ArrayBuffer, stringToSign: string): string {\n return hmac('sha256', derivedSigningKey, stringToSign, 'hex')\n}\n/**\n * Derives the signing key for authenticating requests signed with\n * the Signature version 4 authentication protocol.\n *\n * deriveSigningKey produces a signing key by creating a series of\n * hash-based message authentication codes (HMACs) represented in\n * a binary format.\n *\n * The derived signing key is specific to the date it's made at, as well as\n * the service and region it targets.\n *\n * @param {string} secretAccessKey - the AWS secret access key to derive the signing key for\n * @param {number} time - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service. MUST be UTF-8 encoded.\n * @return {string}\n */\nexport function deriveSigningKey(\n secretAccessKey: string,\n time: number,\n region: string,\n service: string\n): ArrayBuffer {\n const kSecret = secretAccessKey\n const date = toDate(time)\n\n // FIXME: hmac takes ArrayBuffer as input, but returns bytes (number[]).\n // How does one convert from one to the other?\n const kDate: any = hmac('sha256', 'AWS4' + kSecret, date, 'binary')\n const kRegion: any = hmac('sha256', kDate, region, 'binary')\n const kService: any = hmac('sha256', kRegion, service, 'binary')\n const kSigning: any = hmac('sha256', kService, 'aws4_request', 'binary')\n\n return kSigning\n}\n\n// Hashing Algorithm to use in the signature process\nexport const HashingAlgorithm = 'AWS4-HMAC-SHA256'\n\n/**\n * Certain services, such as S3, allow for unsigned payloads. If\n * producing a signed canonical request for such service, pass\n * the `UnsignedPayload` constant value as the payload parameter.\n */\nexport const UnsignedPayload = 'UNSIGNED-PAYLOAD'\n\n/**\n * Create the \"string to sign\" part of the signature Version 4 protocol.\n *\n * The \"string to sign\" includes meta information about your request and\n * about the canonical request that you created with `createCanonicalRequest`.\n * It is used hand in hand with the signing key to create the request signature.\n *\n * @param {number} requestTimestamp - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service name. MUST be UTF-8 encoded.\n * @param {string} hashedCanonicalRequest - canonical request as produced by calling the createCanonicalRequest function,\n * hashed using the SHA256 algorithm (encoded in hexadecimal format).\n * @return {string}\n */\nexport function createStringToSign(\n requestTimestamp: number,\n region: string,\n service: string,\n hashedCanonicalRequest: string\n): string {\n // the request date specified in ISO8601 format: YYYYMMDD'T'HHMMSS'Z'\n const requestDateTime = toTime(requestTimestamp)\n\n // The credential scope value, consisting of the date in YYYYMMDD format,\n // the targeted region, the targeted service, and a termination string.\n // Note that the region and service MUST be UTF-8 encoded.\n const credentialScope = createCredentialScope(requestTimestamp, region, service)\n\n const stringToSign = [\n // Algorithm\n HashingAlgorithm,\n\n // RequestDateTime\n requestDateTime,\n\n // CredentialScope\n credentialScope,\n\n // HashedCanonicalRequest\n hashedCanonicalRequest,\n ].join('\\n')\n\n return stringToSign\n}\n\n/**\n *\n * Helper function creating a credential scope string to use in the signature\n * version 4 process. A credential scope consists of the date of the request\n * in YYYYMMDD format, the targeted region, the targeted service, and a\n * termination string.\n *\n * Note that the region and service MUST be UTF-8 encoded.\n *\n * @param {number} requestTimestamp - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service name. MUST be UTF-8 encoded.\n * @return {string}\n */\nexport function createCredentialScope(\n requestTimestamp: number,\n region: string,\n service: string\n): string {\n return [toDate(requestTimestamp), region, service, 'aws4_request'].join('/')\n}\n\n/**\n * Create a string that includes information from your request\n * in a AWS signature v4 standardized (canonical) format.\n *\n * @param {string} method - the HTTP request method\n * @param {string} uri - URI-encoded version of the absolute path component of the URI\n * @param {string} query - request's query string\n * @param {Object} headers - all the HTTP headers that you wish to include with the signed request\n * @param {string | ArrayBuffer} payload - payload to include as the body of the request\n * @param {URIEncodingConfig} URIencodingConfig- URI encoding configuration\n * @return {string}\n */\nexport function createCanonicalRequest(\n method: HTTPMethod,\n uri: string,\n query: string,\n headers: HTTPHeaders,\n payload: string | ArrayBuffer,\n URIencodingConfig: URIEncodingConfig\n): string {\n const httpRequestMethod = method.toUpperCase()\n const canonicalURI = createCanonicalURI(uri, URIencodingConfig)\n const canonicalQueryString = createCanonicalQueryString(query)\n const canonicalHeaders = createCanonicalHeaders(headers)\n const signedHeaders = createSignedHeaders(headers)\n const requestPayload = createCanonicalPayload(payload)\n\n const canonicalRequest = [\n httpRequestMethod,\n canonicalURI,\n canonicalQueryString,\n canonicalHeaders,\n signedHeaders,\n requestPayload,\n ].join('\\n')\n\n return canonicalRequest\n}\n\n/**\n * Creates the (canonical) URI-encoded version of the\n * absolute path component of the URI: everything in the URI\n * from the HTTP host to the question mark character (\"?\")\n * that begins the query string parameters (if any).\n *\n * @param {string} uri - URI to canonize\n * @param {URIEncodingConfig} - URI encoding configuration\n * @return {string} - canonical URL\n */\nexport function createCanonicalURI(uri: string, URIencodingConfig: URIEncodingConfig): string {\n if (uri == '/') {\n return uri\n }\n\n let canonicalURI = uri\n if (uri[uri.length - 1] == '/' && canonicalURI[canonicalURI.length - 1] != '/') {\n canonicalURI += '/'\n }\n\n canonicalURI = URIEncode(canonicalURI, URIencodingConfig.path)\n\n return URIencodingConfig.double ? URIEncode(canonicalURI, URIencodingConfig.path) : canonicalURI\n}\n\n// FIXME: does it work as expected?\n/**\n * Creates the canonical form of the request's query\n * string. If the request does not include a query string,\n * provide an empty string.\n *\n * @param {String | Object} qs - query string to canonize\n * @return {string}\n */\nexport function createCanonicalQueryString(qs: string): string {\n if (qs === '') {\n return ''\n }\n\n // const intermediary: { [key: string]: string } = parseQueryString(qs)\n\n // return Object.keys(intermediary)\n // .sort()\n // .map((key: string) => {\n // // const values: string[] = Array.isArray(intermediary[key])\n // // ? intermediary[key]\n // // : [intermediary[key]]\n // const values = intermediary[key]\n\n // return values\n // .sort()\n // .map((val: string) => encodeURIComponent(key) + '=' + encodeURIComponent(val))\n // .join('&')\n // })\n // .join('&')\n\n return parseQueryString(qs)\n .map(([key, value]: [string, string]): string => {\n return encodeURIComponent(key) + '=' + encodeURIComponent(value)\n })\n .join('&')\n}\n/**\n * Create the canonical form of the request's headers.\n * Canonical headers consist of all the HTTP headers you\n * are including with the signed request.\n *\n * Note that:\n * * for HTTP/1.1 requests, the headers should at least\n * contain the `host` header.\n * * for HTTP/2, the `:authority` header must be used instead\n * of `host`.\n *\n * @param {Object} headers\n * @return {string}\n */\nexport function createCanonicalHeaders(headers: HTTPHeaders) {\n if (headers.constructor !== Object || Object.entries(headers).length === 0) {\n return ''\n }\n\n const canonicalHeaders = Object.entries(headers)\n .map(([name, values]) => {\n const canonicalName = name.toLowerCase().trim()\n const normalizedValues = Array.isArray(values) ? values : [values]\n\n // Note that we do not need to sort values\n const canonicalValues = normalizedValues\n .map((v) => {\n // convert sequential spaces to a single space\n return v.replace(/\\s+/g, ' ').replace(/^\\s+|\\s+$/g, '')\n })\n .join(',') // standard for multiple values in a HTTP header\n\n return canonicalName + ':' + canonicalValues + '\\n'\n })\n .sort()\n .join('')\n\n return canonicalHeaders\n}\n\n/**\n * Create the canonical request's signed headers.\n *\n * The signed headers part of the request contains the\n * list of headers included in the request's signing process.\n *\n * Note that:\n * * for HTTP/1.1 requests, the `host` header must be included.\n * * for HTTP/2 requests, the `:authority` header must be included instead\n * of host.\n * * if used, the `x-amz-date` header must be included.\n *\n * @param {Object} headers\n * @return {string}\n * @throws {TypeError} - on headers not being an Object, or being empty.\n */\nexport function createSignedHeaders(headers: { [key: string]: string }) {\n if (headers.constructor !== Object) {\n throw new TypeError('headers should be an object')\n }\n\n if (Object.entries(headers).length === 0) {\n throw 'headers should at least contain either the Host (HTTP 1.1) or :authority (HTTP 2) parameter'\n }\n\n // To create the signed headers list, convert\n // all header names to lowercase, sort them by\n // character code, and use a semicolon to separate\n // the header names.\n const result = Object.keys(headers)\n .map((name) => name.toLowerCase().trim())\n .sort()\n .join(';')\n\n return result\n}\n\n/**\n * Create the canonical form of the request's payload.\n *\n * The canonical payload consists in a lowercased, hex encoded,\n * SHA256 hash of the requests body/payload.\n *\n * Certain services, such as S3, allow for unsigned payload. If\n * producing a signed canonical request for such service, pass\n * the `UnsignedPayload` constant value as the payload parameter.\n *\n * @param {String | ArrayBuffer} payload\n * @return {string}\n */\nexport function createCanonicalPayload(payload: string | ArrayBuffer) {\n if (payload === UnsignedPayload) {\n return payload\n }\n\n // Note that if the paylaod is null, we convert it\n // to an empty string.\n // TODO: Should switching to empty string if null impact headers?\n return crypto.sha256(payload || '', 'hex').toLowerCase()\n}\n\n/**\n * URIEncodes encodes every bytes of a URI to be URL-safe.\n *\n * This implementation is specific to AWS; who intended to make it as\n * close as possible to the underlying RFC 3946. It:\n * * URI encode every byte except the unreserved characters: 'A'-'Z', 'a'-'z', '0'-'9',\n * '-', '.', '_', and '~'.\n * * considers the space character as a reserved character and must URI encodes\n * encodes it as \"%20\" (and not as \"+\").\n * * URI encodes every byte by prefixing with '%' the two-digit hexadecimal value of the byte.\n * * If the `path` argument is set, forward slashes are not encoded, to fit with\n * S3 requirements.\n *\n * N.B: this implementation differs with ES6' mainly in that it does\n * encode the \"'\" character.\n *\n * Based on AWS implementation: https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-core/src/main/java/com/amazonaws/util/SdkHttpUtils.java#L66\n * Encoding specs: https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html\n *\n * @param {string} uri - uri to encode\n * @param {boolean} path - slash characters should be encoded everywhere,\n * but in paths, set to false when encoding a path\n * @return {string} the URI encoded result\n */\nexport function URIEncode(uri: string, path: boolean): string {\n if (uri == '') {\n return uri\n }\n\n return uri\n .split('') // to be able to map over a string, because... javascript...\n .map((letter: string) => {\n if (isAlpha(letter) || isNumeric(letter) || '-._~'.includes(letter)) {\n return letter\n }\n\n // Space should be explicitly encoded to as %20.\n if (letter == ' ') {\n return '%20'\n }\n\n // If the URI is a path, the forward slash shouldn't\n // be encoded.\n if (letter == '/' && path) {\n return '/'\n }\n\n return '%' + letter.charCodeAt(0).toString(16).toUpperCase()\n })\n .join('')\n}\n\n/**\n * Class holding URI encoding configuration\n */\nexport class URIEncodingConfig {\n double: boolean\n path: boolean\n\n /**\n *\n * @param {boolean} double - should the URI be double encoded?\n * @param {boolean} path - is the URI a path? If so, its forward\n * slashes won't be URIencoded.\n */\n constructor(double: boolean, path: boolean) {\n this.double = double\n this.path = path\n }\n}\n\n/**\n * Compute the request time value as specified by the ISO8601\n * format: YYYYMMDD'T'HHMMSS'Z'\n *\n * @param {number} timestamp\n * @return {string}\n */\nexport function toTime(timestamp: number): string {\n return new Date(timestamp).toISOString().replace(/[:\\-]|\\.\\d{3}/g, '')\n}\n/**\n * Computethe request date value in the format: YYYMMDD\n *\n * @param {number} timestamp\n * @return {string}\n */\nexport function toDate(timestamp: number): string {\n return toTime(timestamp).substring(0, 8)\n}\n\n// FIXME: does it work as expected?\n/**\n * Parse a HTTP request URL's querystring into an object\n * containing its `key=value` pairs.\n *\n * @param {string} qs\n * @return {object}\n */\nexport function parseQueryString(qs: string): Array<[string, string]> {\n if (qs.length === 0) {\n return []\n }\n\n return qs\n .split('&')\n .filter((e) => e)\n .map((v: string): [string, string] => {\n const parts = v.split('=', 2) as [string, string]\n return [decodeURIComponent(parts[0]), decodeURIComponent(parts[1])]\n })\n .sort((a: [string, string], b: [string, string]) => {\n return a[0].localeCompare(b[0])\n })\n}\n\nfunction isAlpha(c: string): boolean {\n return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')\n}\n\nfunction isNumeric(c: string): boolean {\n return c >= '0' && c <= '9'\n}\n\n// FIXME: finish implementation when needed\n// See the following for more details:\n// * https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html\n// * https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html\n// export function signQueryString(\n// queryString,\n// requestTimestamp,\n// accessKeyID,\n// secretAccessKey,\n// region,\n// service,\n// ttl, // in seconds\n// headers,\n// doubleURIEncoding = true\n// ) {\n// const credential = [accessKeyID, toDate(requestTimestamp), region, service].join('/')\n//\n// const canonicalRequest = createCanonicalRequest(\n// method,\n// path,\n// queryString,\n// headers,\n// body,\n// doubleURIEncoding\n// )\n//\n// const derivedSigningKey = deriveSigningKey(secretAccessKey, requestTimestamp, region, service)\n//\n// const stringToSign = createStringToSign(\n// requestTimestamp,\n// region,\n// service,\n// sha256(canonicalRequest, 'hex')\n// )\n//\n// const signedHeaders = createSignedHeaders(headers)\n// const signature = calculateSignature(derivedSigningKey, stringToSign)\n//\n// return [\n// `X-Amz-Algorithm=${HashingAlgorithm}`,\n// `X-Amz-Credential=${crediental}`,\n// `X-Amz-Date=${toTime(requestTimestamp)}`,\n// `X-Amz-Expires=${ttl}`,\n// `X-Amz-SignedHeaders=${signedHeaders}`,\n// `X-Amz-Signature=${signature}`,\n//`X-Amz-Security-Token=`, // TODO: optional\n// ].join('&')\n// }\n","/** Class holding an AWS connection information */\nexport class AWSConfig {\n region: string\n accessKeyID: string\n secretAccessKey: string\n\n /**\n * Create an AWSConfig.\n *\n * @param {string} region - the AWS region to connect to, as listed: https://docs.aws.amazon.com/general/latest/gr/rande.html\n * @param {string} accessKeyID - Your user's AWS access key id credential\n * @param {string} secretAccessKey - Your user's AWS secret access key credential\n * @throws {InvalidArgumentException}\n */\n constructor(region: string, accessKeyID: string, secretAccessKey: string) {\n if (typeof region !== 'string' || region === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS region; reason: should be a non empty string'\n )\n }\n\n if (typeof accessKeyID !== 'string' || accessKeyID === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS access key ID; reason: should be a non empty string'\n )\n }\n\n if (typeof secretAccessKey !== 'string' || secretAccessKey === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS secret access key; reason: should be a non empty string'\n )\n }\n\n this.region = region\n this.accessKeyID = accessKeyID\n this.secretAccessKey = secretAccessKey\n }\n}\n\n/** Class representing an invalid AWS configuration */\nexport class InvalidAWSConfigError extends Error {\n constructor(message: string) {\n super(message)\n }\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/http\");","import { bytes } from 'k6'\nimport http from 'k6/http'\nimport { parseHTML } from 'k6/html'\nimport { sha256 } from 'k6/crypto'\n\nimport { InvalidSignatureError, URIEncodingConfig } from './signature'\nimport { AWSClient, AWSRequest } from './client'\nimport { AWSError } from './error'\nimport { AWSConfig } from './config'\n\n/** Class allowing to interact with Amazon AWS's S3 service */\nexport class S3Client extends AWSClient {\n /**\n * Create a S3Client\n *\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n */\n constructor(awsConfig: AWSConfig) {\n const URIencodingConfig = new URIEncodingConfig(false, true)\n super(awsConfig, 's3', URIencodingConfig)\n }\n\n /**\n * Returns a list of all buckets owned by the authenticated sender of the request.\n * To use this operation, you must have the s3:ListAllMyBuckets permission.\n *\n * @return {Array.} buckets - An array of objects describing S3 buckets\n * with the following fields: name, and creationDate.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n listBuckets(): Array {\n // Prepare request\n const method = 'GET'\n const host = `${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(method, host, '/', '', body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n let buckets: Array = []\n\n const doc = parseHTML(res.body as string)\n\n doc.find('Buckets')\n .children()\n .each((_, bucketDefinition) => {\n let bucket = {}\n\n bucketDefinition.children().forEach((child) => {\n switch (child.nodeName()) {\n case 'name':\n Object.assign(bucket, { name: child.textContent() })\n break\n case 'creationdate':\n Object.assign(bucket, {\n creationDate: Date.parse(child.textContent()),\n })\n }\n })\n\n buckets.push(bucket as S3Bucket)\n })\n\n return buckets\n }\n\n /**\n * Returns some or all (up to 1,000) of the objects in a bucket.\n *\n * @param {string} bucketName - Bucket name to list.\n * @param {string?} prefix='' - Limits the response to keys that begin with the specified prefix.\n * @return {Array.} - returns an array of objects describing S3 objects\n * with the following fields: key, lastModified, etag, size and storageClass.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n listObjects(bucketName: string, prefix?: string): Array {\n // Prepare request\n const method = 'GET'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n '/',\n 'list-type=2',\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n let objects: Array = []\n\n // Extract the objects definition from\n // the XML response\n parseHTML(res.body as string)\n .find('Contents')\n .each((_, objectDefinition) => {\n let obj = {}\n\n objectDefinition.children().forEach((child) => {\n switch (child.nodeName()) {\n case 'key':\n Object.assign(obj, { key: child.textContent() })\n break\n case 'lastmodified':\n // const parsed = Date.parse(\n // child.textContent(),\n // 'YYYY-MM-ddTHH:mm:ss.sssZ'\n // )\n Object.assign(obj, { lastModified: Date.parse(child.textContent()) })\n break\n case 'etag':\n Object.assign(obj, { etag: child.textContent() })\n break\n case 'size':\n Object.assign(obj, { size: parseInt(child.textContent()) })\n break\n case 'storageclass':\n Object.assign(obj, { storageClass: child.textContent() })\n }\n })\n\n objects.push(obj as S3Object)\n })\n\n return objects\n }\n /**\n * Retrieves an Object from Amazon S3.\n *\n * To use getObject, you must have `READ` access to the object.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to get.\n * @return {S3Object} - returns the content of the fetched S3 Object.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n getObject(bucketName: string, objectKey: string): S3Object {\n // Prepare request\n const method = 'GET'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(method, host, path, '', body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n return new S3Object(\n objectKey,\n Date.parse(res.headers['Last-Modified']),\n res.headers['ETag'],\n parseInt(res.headers['Content-Length']),\n undefined, // GetObject response doesn't contain the storage class\n res.body\n )\n }\n /**\n * Adds an object to a bucket.\n *\n * You must have WRITE permissions on a bucket to add an object to it.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to put.\n * @param {string | ArrayBuffer} data - the content of the S3 Object to upload.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n putObject(bucketName: string, objectKey: string, data: string | ArrayBuffer) {\n // Prepare request\n const method = 'PUT'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const queryString = ''\n const body = data\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n path,\n queryString,\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n }\n\n /**\n * Removes the null version (if there is one) of an object and inserts a delete marker,\n * which becomes the latest version of the object.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to delete.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n deleteObject(bucketName: string, objectKey: string): void {\n // Prepare request\n const method = 'DELETE'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const queryString = ''\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n path,\n queryString,\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n }\n\n // FIXME: remove dependency to `error_message`\n // FIXME: just pass it the response?\n _handle_error(error_code: number, error_message: string, error_body: string) {\n if (error_message == '' || error_code === 0) {\n return\n }\n\n // FIXME: should be error_code === 1301 instead\n // See: https://github.com/grafana/k6/issues/2474\n // See: https://github.com/golang/go/issues/49281\n if (error_message && error_message.startsWith('301')) {\n // Bucket not found\n throw new S3ServiceError('Resource not found', 'ResourceNotFound', 'getObject')\n }\n\n const awsError = AWSError.parseXML(error_body)\n switch (awsError.code) {\n case 'AuthorizationHeaderMalformed':\n throw new InvalidSignatureError(awsError.message, awsError.code)\n default:\n throw new S3ServiceError(awsError.message, awsError.code, 'listObjects')\n }\n }\n}\n\n// TODO: use interface instead?\n/** Class representing a S3 Bucket */\nexport class S3Bucket {\n name: string\n creationDate: Date\n\n /**\n * Create an S3 Bucket\n *\n * @param {string} name - S3 bucket's name\n * @param {Date} creationDate - S3 bucket's creation date\n */\n constructor(name: string, creationDate: Date) {\n this.name = name\n this.creationDate = creationDate\n }\n}\n\n// TODO: use interface instead?\n/** Class representing an S3 Object */\nexport class S3Object {\n key: string\n lastModified: number\n etag: string\n size: number\n storageClass: StorageClass\n data?: string | bytes | null\n\n /**\n * Create an S3 Object\n *\n * @param {string} key - S3 object's key\n * @param {Date} lastModified - S3 object last modification date\n * @param {string} etag - S3 object's etag\n * @param {number} size - S3 object's size\n * @param {StorageClass} storageClass - S3 object's storage class\n * @param {string | bytes | null} data=null - S3 Object's data\n */\n constructor(\n key: string,\n lastModified: number,\n etag: string,\n size: number,\n storageClass: StorageClass,\n data?: string | bytes | null\n ) {\n this.key = key\n this.lastModified = lastModified\n this.etag = etag\n this.size = size\n this.storageClass = storageClass\n this.data = data\n }\n}\n\n/**\n * Error indicating a S3 operation failed\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class S3ServiceError extends AWSError {\n operation: string\n\n /**\n * Constructs a S3ServiceError\n *\n * @param {string} message - human readable error message\n * @param {string} code - A unique short code representing the error that was emitted\n * @param {string} operation - Name of the failed Operation\n */\n constructor(message: string, code: string, operation: string) {\n super(message, code)\n this.name = 'S3ServiceError'\n this.operation = operation\n }\n}\n\n/**\n * Describes the class of storage used to store a S3 object.\n */\ntype StorageClass =\n | 'STANDARD'\n | 'REDUCED_REDUNDANCY'\n | 'GLACIER'\n | 'STANDARD_IA'\n | 'INTELLIGENT_TIERING'\n | 'DEEP_ARCHIVE'\n | 'OUTPOSTS'\n | 'GLACIER_IR'\n | undefined\n","import { HTTPMethod, HTTPHeaders } from './http'\nimport { AWSConfig } from './config'\nimport { signHeaders, URIEncodingConfig, toTime } from './signature'\n\n/**\n * Class allowing to build requests targeting AWS APIs\n *\n * This class is meant to be used as a base class for specific\n * services clients. See S3Client or SecretsManagerClient for\n * usage examples.\n */\nexport class AWSClient {\n awsConfig: AWSConfig\n serviceName: string\n URIencodingConfig: URIEncodingConfig\n\n /**\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n * @param {string} serviceName - name of the service to target.\n * @param {URIEncodingConfig} URIencodingConfig - configures how requests URIs should be encoded.\n */\n constructor(awsConfig: AWSConfig, serviceName: string, URIencodingConfig: URIEncodingConfig) {\n this.awsConfig = awsConfig\n this.serviceName = serviceName\n this.URIencodingConfig = URIencodingConfig\n }\n\n buildRequest(\n method: HTTPMethod,\n host: string,\n path: string,\n queryString: string,\n body: string | ArrayBuffer,\n headers: HTTPHeaders\n ): AWSRequest {\n const requestTimestamp: number = Date.now()\n const date: string = toTime(requestTimestamp)\n\n headers['Host'] = host\n headers['X-Amz-Date'] = date\n\n headers = signHeaders(\n // headers\n headers,\n\n // requestTimestamp\n requestTimestamp,\n\n // method\n method,\n\n // path\n path,\n\n // querystring\n queryString,\n\n // body\n body,\n\n // AWS configuration\n this.awsConfig,\n\n // AwS target service name\n this.serviceName,\n\n // doubleEncoding: S3 does single-encoding of the uri component\n // pathURIEncoding: S3 manipulates object keys, and forward slashes\n // shouldn't be URI encoded\n this.URIencodingConfig\n )\n\n // '?' should not be part of the querystring when we sign the headers\n path = path !== '' ? path : '/'\n let url = `https://${host}${path}`\n if (queryString !== '') {\n url += `?${queryString}`\n }\n\n return { url: url, headers: headers }\n }\n}\n\n/**\n * Type alias representing the result of an AWSClient.buildRequest call\n */\nexport interface AWSRequest {\n url: string\n headers: HTTPHeaders\n}\n"],"names":["__webpack_require__","module","getter","__esModule","d","a","exports","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","require","AWSError","message","code","name","xmlDocument","doc","parseHTML","find","text","Error","signHeaders","headers","requestTimestamp","method","path","queryString","body","awsConfig","service","URIencodingConfig","derivedSigningKey","secretAccessKey","time","region","kSecret","date","toDate","kDate","hmac","kRegion","kService","deriveSigningKey","canonicalRequest","uri","query","payload","httpRequestMethod","toUpperCase","canonicalURI","length","URIEncode","createCanonicalURI","canonicalQueryString","qs","split","filter","e","map","v","parts","decodeURIComponent","sort","b","localeCompare","parseQueryString","encodeURIComponent","join","createCanonicalQueryString","canonicalHeaders","constructor","entries","values","toLowerCase","trim","Array","isArray","replace","createCanonicalHeaders","signedHeaders","createSignedHeaders","requestPayload","UnsignedPayload","crypto","createCanonicalPayload","createCanonicalRequest","stringToSign","hashedCanonicalRequest","requestDateTime","toTime","credentialScope","createCredentialScope","HashingAlgorithm","createStringToSign","sha256","signature","calculateSignature","authorizationHeader","accessKeyID","InvalidSignatureError","TypeError","keys","letter","c","isNumeric","includes","charCodeAt","toString","URIEncodingConfig","double","this","timestamp","Date","toISOString","substring","AWSConfig","InvalidAWSConfigError","S3Client","host","serviceName","signedRequest","res","http","url","_handle_error","error_code","error","buckets","children","each","_","bucketDefinition","bucket","forEach","child","nodeName","assign","textContent","creationDate","parse","push","bucketName","prefix","objects","objectDefinition","lastModified","etag","size","parseInt","storageClass","objectKey","S3Object","undefined","data","error_message","error_body","startsWith","S3ServiceError","awsError","parseXML","now","S3Bucket","operation"],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"s3.min.js","mappings":"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","sources":["webpack://k6-jslib-aws/webpack/bootstrap","webpack://k6-jslib-aws/webpack/runtime/compat get default export","webpack://k6-jslib-aws/webpack/runtime/define property getters","webpack://k6-jslib-aws/webpack/runtime/hasOwnProperty shorthand","webpack://k6-jslib-aws/webpack/runtime/make namespace object","webpack://k6-jslib-aws/external commonjs \"k6/crypto\"","webpack://k6-jslib-aws/external commonjs \"k6/html\"","webpack://k6-jslib-aws/./src/internal/error.ts","webpack://k6-jslib-aws/./src/internal/signature.ts","webpack://k6-jslib-aws/./src/internal/config.ts","webpack://k6-jslib-aws/external commonjs \"k6/http\"","webpack://k6-jslib-aws/./src/internal/s3.ts","webpack://k6-jslib-aws/./src/internal/client.ts"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/crypto\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/html\");","import { parseHTML } from 'k6/html'\n\n/**\n * Base class to derive errors from\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class AWSError extends Error {\n code: string\n\n /**\n * Create an AWSError\n *\n * @param {string} message - A longer human readable error message.\n * @param {string} code - A unique short code representing the error that was emitted\n */\n constructor(message: string, code: string) {\n super(message)\n this.name = 'AWSError'\n this.code = code\n }\n\n /**\n * Parse an AWSError from an XML document\n *\n * @param {string} xmlDocument - Serialized XML document to parse the error from\n */\n static parseXML(xmlDocument: string): AWSError {\n const doc = parseHTML(xmlDocument)\n return new AWSError(doc.find('Message').text(), doc.find('Code').text())\n }\n}\n","import crypto, { hmac, sha256 } from 'k6/crypto'\nimport { HTTPMethod, HTTPHeaders } from './http'\nimport { AWSConfig } from './config'\nimport { AWSError } from './error'\n\n/**\n * Includes AWS v4 signing information to the provided HTTP headers object.\n *\n * This function will compute the `Authorization` header signature for the\n * provided request components, and add it to `header`. It will do so by following\n * the procedure detailled AWS' API docs: https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html\n *\n * The resulting `Authorization` header value is computed for the provided\n * headers object. Thus, any modification of the headers past a call to `signHeaders`\n * would effectively invalidate their signature, and the function should be\n * called again to recompute it.\n *\n * @param {object} headers - HTTP headers request to sign.\n * @param {number} requestTimestamp - Timestamp of the request\n * @param {string} method - HTTP method used\n * @param {string} path - HTTP request URL's path\n * @param {string} queryString - HTTP request URL's querystring\n * @param {string | ArrayBuffer} body - HTTP request's payload\n * @param {AWSConfig} - AWS configuration\n * @param {string} service - AWS service name\n * @param {URIEncodingConfig} - URI encoding configuration\n */\nexport function signHeaders(\n headers: HTTPHeaders,\n requestTimestamp: number,\n method: HTTPMethod,\n path: string,\n queryString: string,\n body: string | ArrayBuffer,\n awsConfig: AWSConfig,\n service: string,\n URIencodingConfig: URIEncodingConfig\n): HTTPHeaders {\n const derivedSigningKey = deriveSigningKey(\n awsConfig.secretAccessKey,\n requestTimestamp,\n awsConfig.region,\n service\n )\n\n const canonicalRequest = createCanonicalRequest(\n method,\n path,\n queryString,\n headers,\n body,\n URIencodingConfig\n )\n\n const stringToSign = createStringToSign(\n requestTimestamp,\n awsConfig.region,\n service,\n sha256(canonicalRequest, 'hex')\n )\n\n const credentialScope = createCredentialScope(requestTimestamp, awsConfig.region, service)\n const signedHeaders = createSignedHeaders(headers)\n const signature = calculateSignature(derivedSigningKey, stringToSign)\n const authorizationHeader = `${HashingAlgorithm} Credential=${awsConfig.accessKeyID}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`\n\n headers['Authorization'] = authorizationHeader\n\n return headers\n}\n\n/**\n * Error indicating an Invalid signature has been sent to AWS services\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class InvalidSignatureError extends AWSError {\n /**\n * Constructs an InvalidSignatureError\n *\n * @param {string} message - human readable error message\n */\n constructor(message: string, code: string) {\n super(message, code)\n this.name = 'InvalidSignatureError'\n }\n}\n\n/**\n * Calculte the signature for AWS signature version 4\n *\n * @param {string} derivedSigningKey - dervied signing key as computed by `deriveSigningKey`\n * @param {string} stringToSign - String to sign as computed by `createStringToSign`\n * @return {string}\n */\nexport function calculateSignature(derivedSigningKey: ArrayBuffer, stringToSign: string): string {\n return hmac('sha256', derivedSigningKey, stringToSign, 'hex')\n}\n/**\n * Derives the signing key for authenticating requests signed with\n * the Signature version 4 authentication protocol.\n *\n * deriveSigningKey produces a signing key by creating a series of\n * hash-based message authentication codes (HMACs) represented in\n * a binary format.\n *\n * The derived signing key is specific to the date it's made at, as well as\n * the service and region it targets.\n *\n * @param {string} secretAccessKey - the AWS secret access key to derive the signing key for\n * @param {number} time - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service. MUST be UTF-8 encoded.\n * @return {string}\n */\nexport function deriveSigningKey(\n secretAccessKey: string,\n time: number,\n region: string,\n service: string\n): ArrayBuffer {\n const kSecret = secretAccessKey\n const date = toDate(time)\n\n // FIXME: hmac takes ArrayBuffer as input, but returns bytes (number[]).\n // How does one convert from one to the other?\n const kDate: any = hmac('sha256', 'AWS4' + kSecret, date, 'binary')\n const kRegion: any = hmac('sha256', kDate, region, 'binary')\n const kService: any = hmac('sha256', kRegion, service, 'binary')\n const kSigning: any = hmac('sha256', kService, 'aws4_request', 'binary')\n\n return kSigning\n}\n\n// Hashing Algorithm to use in the signature process\nexport const HashingAlgorithm = 'AWS4-HMAC-SHA256'\n\n/**\n * Certain services, such as S3, allow for unsigned payloads. If\n * producing a signed canonical request for such service, pass\n * the `UnsignedPayload` constant value as the payload parameter.\n */\nexport const UnsignedPayload = 'UNSIGNED-PAYLOAD'\n\n/**\n * Create the \"string to sign\" part of the signature Version 4 protocol.\n *\n * The \"string to sign\" includes meta information about your request and\n * about the canonical request that you created with `createCanonicalRequest`.\n * It is used hand in hand with the signing key to create the request signature.\n *\n * @param {number} requestTimestamp - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service name. MUST be UTF-8 encoded.\n * @param {string} hashedCanonicalRequest - canonical request as produced by calling the createCanonicalRequest function,\n * hashed using the SHA256 algorithm (encoded in hexadecimal format).\n * @return {string}\n */\nexport function createStringToSign(\n requestTimestamp: number,\n region: string,\n service: string,\n hashedCanonicalRequest: string\n): string {\n // the request date specified in ISO8601 format: YYYYMMDD'T'HHMMSS'Z'\n const requestDateTime = toTime(requestTimestamp)\n\n // The credential scope value, consisting of the date in YYYYMMDD format,\n // the targeted region, the targeted service, and a termination string.\n // Note that the region and service MUST be UTF-8 encoded.\n const credentialScope = createCredentialScope(requestTimestamp, region, service)\n\n const stringToSign = [\n // Algorithm\n HashingAlgorithm,\n\n // RequestDateTime\n requestDateTime,\n\n // CredentialScope\n credentialScope,\n\n // HashedCanonicalRequest\n hashedCanonicalRequest,\n ].join('\\n')\n\n return stringToSign\n}\n\n/**\n *\n * Helper function creating a credential scope string to use in the signature\n * version 4 process. A credential scope consists of the date of the request\n * in YYYYMMDD format, the targeted region, the targeted service, and a\n * termination string.\n *\n * Note that the region and service MUST be UTF-8 encoded.\n *\n * @param {number} requestTimestamp - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service name. MUST be UTF-8 encoded.\n * @return {string}\n */\nexport function createCredentialScope(\n requestTimestamp: number,\n region: string,\n service: string\n): string {\n return [toDate(requestTimestamp), region, service, 'aws4_request'].join('/')\n}\n\n/**\n * Create a string that includes information from your request\n * in a AWS signature v4 standardized (canonical) format.\n *\n * @param {string} method - the HTTP request method\n * @param {string} uri - URI-encoded version of the absolute path component of the URI\n * @param {string} query - request's query string\n * @param {Object} headers - all the HTTP headers that you wish to include with the signed request\n * @param {string | ArrayBuffer} payload - payload to include as the body of the request\n * @param {URIEncodingConfig} URIencodingConfig- URI encoding configuration\n * @return {string}\n */\nexport function createCanonicalRequest(\n method: HTTPMethod,\n uri: string,\n query: string,\n headers: HTTPHeaders,\n payload: string | ArrayBuffer,\n URIencodingConfig: URIEncodingConfig\n): string {\n const httpRequestMethod = method.toUpperCase()\n const canonicalURI = createCanonicalURI(uri, URIencodingConfig)\n const canonicalQueryString = createCanonicalQueryString(query)\n const canonicalHeaders = createCanonicalHeaders(headers)\n const signedHeaders = createSignedHeaders(headers)\n const requestPayload = createCanonicalPayload(payload)\n\n const canonicalRequest = [\n httpRequestMethod,\n canonicalURI,\n canonicalQueryString,\n canonicalHeaders,\n signedHeaders,\n requestPayload,\n ].join('\\n')\n\n return canonicalRequest\n}\n\n/**\n * Creates the (canonical) URI-encoded version of the\n * absolute path component of the URI: everything in the URI\n * from the HTTP host to the question mark character (\"?\")\n * that begins the query string parameters (if any).\n *\n * @param {string} uri - URI to canonize\n * @param {URIEncodingConfig} - URI encoding configuration\n * @return {string} - canonical URL\n */\nexport function createCanonicalURI(uri: string, URIencodingConfig: URIEncodingConfig): string {\n if (uri == '/') {\n return uri\n }\n\n let canonicalURI = uri\n if (uri[uri.length - 1] == '/' && canonicalURI[canonicalURI.length - 1] != '/') {\n canonicalURI += '/'\n }\n\n canonicalURI = URIEncode(canonicalURI, URIencodingConfig.path)\n\n return URIencodingConfig.double ? URIEncode(canonicalURI, URIencodingConfig.path) : canonicalURI\n}\n\n// FIXME: does it work as expected?\n/**\n * Creates the canonical form of the request's query\n * string. If the request does not include a query string,\n * provide an empty string.\n *\n * @param {String | Object} qs - query string to canonize\n * @return {string}\n */\nexport function createCanonicalQueryString(qs: string): string {\n if (qs === '') {\n return ''\n }\n\n // const intermediary: { [key: string]: string } = parseQueryString(qs)\n\n // return Object.keys(intermediary)\n // .sort()\n // .map((key: string) => {\n // // const values: string[] = Array.isArray(intermediary[key])\n // // ? intermediary[key]\n // // : [intermediary[key]]\n // const values = intermediary[key]\n\n // return values\n // .sort()\n // .map((val: string) => encodeURIComponent(key) + '=' + encodeURIComponent(val))\n // .join('&')\n // })\n // .join('&')\n\n return parseQueryString(qs)\n .map(([key, value]: [string, string]): string => {\n return encodeURIComponent(key) + '=' + encodeURIComponent(value)\n })\n .join('&')\n}\n/**\n * Create the canonical form of the request's headers.\n * Canonical headers consist of all the HTTP headers you\n * are including with the signed request.\n *\n * Note that:\n * * for HTTP/1.1 requests, the headers should at least\n * contain the `host` header.\n * * for HTTP/2, the `:authority` header must be used instead\n * of `host`.\n *\n * @param {Object} headers\n * @return {string}\n */\nexport function createCanonicalHeaders(headers: HTTPHeaders) {\n if (headers.constructor !== Object || Object.entries(headers).length === 0) {\n return ''\n }\n\n const canonicalHeaders = Object.entries(headers)\n .map(([name, values]) => {\n const canonicalName = name.toLowerCase().trim()\n const normalizedValues = Array.isArray(values) ? values : [values]\n\n // Note that we do not need to sort values\n const canonicalValues = normalizedValues\n .map((v) => {\n // convert sequential spaces to a single space\n return v.replace(/\\s+/g, ' ').replace(/^\\s+|\\s+$/g, '')\n })\n .join(',') // standard for multiple values in a HTTP header\n\n return canonicalName + ':' + canonicalValues + '\\n'\n })\n .sort()\n .join('')\n\n return canonicalHeaders\n}\n\n/**\n * Create the canonical request's signed headers.\n *\n * The signed headers part of the request contains the\n * list of headers included in the request's signing process.\n *\n * Note that:\n * * for HTTP/1.1 requests, the `host` header must be included.\n * * for HTTP/2 requests, the `:authority` header must be included instead\n * of host.\n * * if used, the `x-amz-date` header must be included.\n *\n * @param {Object} headers\n * @return {string}\n * @throws {TypeError} - on headers not being an Object, or being empty.\n */\nexport function createSignedHeaders(headers: { [key: string]: string }) {\n if (headers.constructor !== Object) {\n throw new TypeError('headers should be an object')\n }\n\n if (Object.entries(headers).length === 0) {\n throw 'headers should at least contain either the Host (HTTP 1.1) or :authority (HTTP 2) parameter'\n }\n\n // To create the signed headers list, convert\n // all header names to lowercase, sort them by\n // character code, and use a semicolon to separate\n // the header names.\n const result = Object.keys(headers)\n .map((name) => name.toLowerCase().trim())\n .sort()\n .join(';')\n\n return result\n}\n\n/**\n * Create the canonical form of the request's payload.\n *\n * The canonical payload consists in a lowercased, hex encoded,\n * SHA256 hash of the requests body/payload.\n *\n * Certain services, such as S3, allow for unsigned payload. If\n * producing a signed canonical request for such service, pass\n * the `UnsignedPayload` constant value as the payload parameter.\n *\n * @param {String | ArrayBuffer} payload\n * @return {string}\n */\nexport function createCanonicalPayload(payload: string | ArrayBuffer) {\n if (payload === UnsignedPayload) {\n return payload\n }\n\n // Note that if the paylaod is null, we convert it\n // to an empty string.\n // TODO: Should switching to empty string if null impact headers?\n return crypto.sha256(payload || '', 'hex').toLowerCase()\n}\n\n/**\n * URIEncodes encodes every bytes of a URI to be URL-safe.\n *\n * This implementation is specific to AWS; who intended to make it as\n * close as possible to the underlying RFC 3946. It:\n * * URI encode every byte except the unreserved characters: 'A'-'Z', 'a'-'z', '0'-'9',\n * '-', '.', '_', and '~'.\n * * considers the space character as a reserved character and must URI encodes\n * encodes it as \"%20\" (and not as \"+\").\n * * URI encodes every byte by prefixing with '%' the two-digit hexadecimal value of the byte.\n * * If the `path` argument is set, forward slashes are not encoded, to fit with\n * S3 requirements.\n *\n * N.B: this implementation differs with ES6' mainly in that it does\n * encode the \"'\" character.\n *\n * Based on AWS implementation: https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-core/src/main/java/com/amazonaws/util/SdkHttpUtils.java#L66\n * Encoding specs: https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html\n *\n * @param {string} uri - uri to encode\n * @param {boolean} path - slash characters should be encoded everywhere,\n * but in paths, set to false when encoding a path\n * @return {string} the URI encoded result\n */\nexport function URIEncode(uri: string, path: boolean): string {\n if (uri == '') {\n return uri\n }\n\n return uri\n .split('') // to be able to map over a string, because... javascript...\n .map((letter: string) => {\n if (isAlpha(letter) || isNumeric(letter) || '-._~'.includes(letter)) {\n return letter\n }\n\n // Space should be explicitly encoded to as %20.\n if (letter == ' ') {\n return '%20'\n }\n\n // If the URI is a path, the forward slash shouldn't\n // be encoded.\n if (letter == '/' && path) {\n return '/'\n }\n\n return '%' + letter.charCodeAt(0).toString(16).toUpperCase()\n })\n .join('')\n}\n\n/**\n * Class holding URI encoding configuration\n */\nexport class URIEncodingConfig {\n double: boolean\n path: boolean\n\n /**\n *\n * @param {boolean} double - should the URI be double encoded?\n * @param {boolean} path - is the URI a path? If so, its forward\n * slashes won't be URIencoded.\n */\n constructor(double: boolean, path: boolean) {\n this.double = double\n this.path = path\n }\n}\n\n/**\n * Compute the request time value as specified by the ISO8601\n * format: YYYYMMDD'T'HHMMSS'Z'\n *\n * @param {number} timestamp\n * @return {string}\n */\nexport function toTime(timestamp: number): string {\n return new Date(timestamp).toISOString().replace(/[:\\-]|\\.\\d{3}/g, '')\n}\n/**\n * Computethe request date value in the format: YYYMMDD\n *\n * @param {number} timestamp\n * @return {string}\n */\nexport function toDate(timestamp: number): string {\n return toTime(timestamp).substring(0, 8)\n}\n\n// FIXME: does it work as expected?\n/**\n * Parse a HTTP request URL's querystring into an object\n * containing its `key=value` pairs.\n *\n * @param {string} qs\n * @return {object}\n */\nexport function parseQueryString(qs: string): Array<[string, string]> {\n if (qs.length === 0) {\n return []\n }\n\n return qs\n .split('&')\n .filter((e) => e)\n .map((v: string): [string, string] => {\n const parts = v.split('=', 2) as [string, string]\n return [decodeURIComponent(parts[0]), decodeURIComponent(parts[1])]\n })\n .sort((a: [string, string], b: [string, string]) => {\n return a[0].localeCompare(b[0])\n })\n}\n\nfunction isAlpha(c: string): boolean {\n return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')\n}\n\nfunction isNumeric(c: string): boolean {\n return c >= '0' && c <= '9'\n}\n\n// FIXME: finish implementation when needed\n// See the following for more details:\n// * https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html\n// * https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html\n// export function signQueryString(\n// queryString,\n// requestTimestamp,\n// accessKeyID,\n// secretAccessKey,\n// region,\n// service,\n// ttl, // in seconds\n// headers,\n// doubleURIEncoding = true\n// ) {\n// const credential = [accessKeyID, toDate(requestTimestamp), region, service].join('/')\n//\n// const canonicalRequest = createCanonicalRequest(\n// method,\n// path,\n// queryString,\n// headers,\n// body,\n// doubleURIEncoding\n// )\n//\n// const derivedSigningKey = deriveSigningKey(secretAccessKey, requestTimestamp, region, service)\n//\n// const stringToSign = createStringToSign(\n// requestTimestamp,\n// region,\n// service,\n// sha256(canonicalRequest, 'hex')\n// )\n//\n// const signedHeaders = createSignedHeaders(headers)\n// const signature = calculateSignature(derivedSigningKey, stringToSign)\n//\n// return [\n// `X-Amz-Algorithm=${HashingAlgorithm}`,\n// `X-Amz-Credential=${crediental}`,\n// `X-Amz-Date=${toTime(requestTimestamp)}`,\n// `X-Amz-Expires=${ttl}`,\n// `X-Amz-SignedHeaders=${signedHeaders}`,\n// `X-Amz-Signature=${signature}`,\n//`X-Amz-Security-Token=`, // TODO: optional\n// ].join('&')\n// }\n","/** Class holding an AWS connection information */\nexport class AWSConfig {\n region: string\n accessKeyID: string\n secretAccessKey: string\n\n /**\n * Create an AWSConfig.\n *\n * @param {string} region - the AWS region to connect to, as listed: https://docs.aws.amazon.com/general/latest/gr/rande.html\n * @param {string} accessKeyID - Your user's AWS access key id credential\n * @param {string} secretAccessKey - Your user's AWS secret access key credential\n * @throws {InvalidArgumentException}\n */\n constructor(region: string, accessKeyID: string, secretAccessKey: string) {\n if (typeof region !== 'string' || region === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS region; reason: should be a non empty string'\n )\n }\n\n if (typeof accessKeyID !== 'string' || accessKeyID === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS access key ID; reason: should be a non empty string'\n )\n }\n\n if (typeof secretAccessKey !== 'string' || secretAccessKey === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS secret access key; reason: should be a non empty string'\n )\n }\n\n this.region = region\n this.accessKeyID = accessKeyID\n this.secretAccessKey = secretAccessKey\n }\n}\n\n/** Class representing an invalid AWS configuration */\nexport class InvalidAWSConfigError extends Error {\n constructor(message: string) {\n super(message)\n }\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/http\");","import { bytes } from 'k6'\nimport http from 'k6/http'\nimport { parseHTML } from 'k6/html'\nimport { sha256 } from 'k6/crypto'\n\nimport { InvalidSignatureError, URIEncodingConfig } from './signature'\nimport { AWSClient, AWSRequest } from './client'\nimport { AWSError } from './error'\nimport { AWSConfig } from './config'\n\n/** Class allowing to interact with Amazon AWS's S3 service */\nexport class S3Client extends AWSClient {\n /**\n * Create a S3Client\n *\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n */\n constructor(awsConfig: AWSConfig) {\n const URIencodingConfig = new URIEncodingConfig(false, true)\n super(awsConfig, 's3', URIencodingConfig)\n }\n\n /**\n * Returns a list of all buckets owned by the authenticated sender of the request.\n * To use this operation, you must have the s3:ListAllMyBuckets permission.\n *\n * @return {Array.} buckets - An array of objects describing S3 buckets\n * with the following fields: name, and creationDate.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n listBuckets(): Array {\n // Prepare request\n const method = 'GET'\n const host = `${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(method, host, '/', '', body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n let buckets: Array = []\n\n const doc = parseHTML(res.body as string)\n\n doc.find('Buckets')\n .children()\n .each((_, bucketDefinition) => {\n let bucket = {}\n\n bucketDefinition.children().forEach((child) => {\n switch (child.nodeName()) {\n case 'name':\n Object.assign(bucket, { name: child.textContent() })\n break\n case 'creationdate':\n Object.assign(bucket, {\n creationDate: Date.parse(child.textContent()),\n })\n }\n })\n\n buckets.push(bucket as S3Bucket)\n })\n\n return buckets\n }\n\n /**\n * Returns some or all (up to 1,000) of the objects in a bucket.\n *\n * @param {string} bucketName - Bucket name to list.\n * @param {string?} prefix='' - Limits the response to keys that begin with the specified prefix.\n * @return {Array.} - returns an array of objects describing S3 objects\n * with the following fields: key, lastModified, etag, size and storageClass.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n listObjects(bucketName: string, prefix?: string): Array {\n // Prepare request\n const method = 'GET'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const body = ''\n const querystring = `list-type=2&prefix=${prefix}`\n const signedRequest: AWSRequest = super.buildRequest(method, host, '/', querystring, body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n Prefix: prefix ?? '',\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n let objects: Array = []\n\n // Extract the objects definition from\n // the XML response\n parseHTML(res.body as string)\n .find('Contents')\n .each((_, objectDefinition) => {\n let obj = {}\n\n objectDefinition.children().forEach((child) => {\n switch (child.nodeName()) {\n case 'key':\n Object.assign(obj, { key: child.textContent() })\n break\n case 'lastmodified':\n Object.assign(obj, { lastModified: Date.parse(child.textContent()) })\n break\n case 'etag':\n Object.assign(obj, { etag: child.textContent() })\n break\n case 'size':\n Object.assign(obj, { size: parseInt(child.textContent()) })\n break\n case 'storageclass':\n Object.assign(obj, { storageClass: child.textContent() })\n }\n })\n\n objects.push(obj as S3Object)\n })\n\n return objects\n }\n /**\n * Retrieves an Object from Amazon S3.\n *\n * To use getObject, you must have `READ` access to the object.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to get.\n * @return {S3Object} - returns the content of the fetched S3 Object.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n getObject(bucketName: string, objectKey: string): S3Object {\n // Prepare request\n const method = 'GET'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(method, host, path, '', body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n return new S3Object(\n objectKey,\n Date.parse(res.headers['Last-Modified']),\n res.headers['ETag'],\n parseInt(res.headers['Content-Length']),\n undefined, // FIXME: GetObject response doesn't contain the storage class\n res.body\n )\n }\n /**\n * Adds an object to a bucket.\n *\n * You must have WRITE permissions on a bucket to add an object to it.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to put.\n * @param {string | ArrayBuffer} data - the content of the S3 Object to upload.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n putObject(bucketName: string, objectKey: string, data: string | ArrayBuffer) {\n // Prepare request\n const method = 'PUT'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const queryString = ''\n const body = data\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n path,\n queryString,\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n }\n\n /**\n * Removes the null version (if there is one) of an object and inserts a delete marker,\n * which becomes the latest version of the object.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to delete.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n deleteObject(bucketName: string, objectKey: string): void {\n // Prepare request\n const method = 'DELETE'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const queryString = ''\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n path,\n queryString,\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n }\n\n // FIXME: remove dependency to `error_message`\n // FIXME: just pass it the response?\n _handle_error(error_code: number, error_message: string, error_body: string) {\n if (error_message == '' || error_code === 0) {\n return\n }\n\n // FIXME: should be error_code === 1301 instead\n // See: https://github.com/grafana/k6/issues/2474\n // See: https://github.com/golang/go/issues/49281\n if (error_message && error_message.startsWith('301')) {\n // Bucket not found\n throw new S3ServiceError('Resource not found', 'ResourceNotFound', 'getObject')\n }\n\n const awsError = AWSError.parseXML(error_body)\n switch (awsError.code) {\n case 'AuthorizationHeaderMalformed':\n throw new InvalidSignatureError(awsError.message, awsError.code)\n default:\n throw new S3ServiceError(awsError.message, awsError.code, 'listObjects')\n }\n }\n}\n\n// TODO: use interface instead?\n/** Class representing a S3 Bucket */\nexport class S3Bucket {\n name: string\n creationDate: Date\n\n /**\n * Create an S3 Bucket\n *\n * @param {string} name - S3 bucket's name\n * @param {Date} creationDate - S3 bucket's creation date\n */\n constructor(name: string, creationDate: Date) {\n this.name = name\n this.creationDate = creationDate\n }\n}\n\n// TODO: use interface instead?\n/** Class representing an S3 Object */\nexport class S3Object {\n key: string\n lastModified: number\n etag: string\n size: number\n storageClass: StorageClass\n data?: string | bytes | null\n\n /**\n * Create an S3 Object\n *\n * @param {string} key - S3 object's key\n * @param {Date} lastModified - S3 object last modification date\n * @param {string} etag - S3 object's etag\n * @param {number} size - S3 object's size\n * @param {StorageClass} storageClass - S3 object's storage class\n * @param {string | bytes | null} data=null - S3 Object's data\n */\n constructor(\n key: string,\n lastModified: number,\n etag: string,\n size: number,\n storageClass: StorageClass,\n data?: string | bytes | null\n ) {\n this.key = key\n this.lastModified = lastModified\n this.etag = etag\n this.size = size\n this.storageClass = storageClass\n this.data = data\n }\n}\n\n/**\n * Error indicating a S3 operation failed\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class S3ServiceError extends AWSError {\n operation: string\n\n /**\n * Constructs a S3ServiceError\n *\n * @param {string} message - human readable error message\n * @param {string} code - A unique short code representing the error that was emitted\n * @param {string} operation - Name of the failed Operation\n */\n constructor(message: string, code: string, operation: string) {\n super(message, code)\n this.name = 'S3ServiceError'\n this.operation = operation\n }\n}\n\n/**\n * Describes the class of storage used to store a S3 object.\n */\ntype StorageClass =\n | 'STANDARD'\n | 'REDUCED_REDUNDANCY'\n | 'GLACIER'\n | 'STANDARD_IA'\n | 'INTELLIGENT_TIERING'\n | 'DEEP_ARCHIVE'\n | 'OUTPOSTS'\n | 'GLACIER_IR'\n | undefined\n","import { HTTPMethod, HTTPHeaders } from './http'\nimport { AWSConfig } from './config'\nimport { signHeaders, URIEncodingConfig, toTime } from './signature'\n\n/**\n * Class allowing to build requests targeting AWS APIs\n *\n * This class is meant to be used as a base class for specific\n * services clients. See S3Client or SecretsManagerClient for\n * usage examples.\n */\nexport class AWSClient {\n awsConfig: AWSConfig\n serviceName: string\n URIencodingConfig: URIEncodingConfig\n\n /**\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n * @param {string} serviceName - name of the service to target.\n * @param {URIEncodingConfig} URIencodingConfig - configures how requests URIs should be encoded.\n */\n constructor(awsConfig: AWSConfig, serviceName: string, URIencodingConfig: URIEncodingConfig) {\n this.awsConfig = awsConfig\n this.serviceName = serviceName\n this.URIencodingConfig = URIencodingConfig\n }\n\n buildRequest(\n method: HTTPMethod,\n host: string,\n path: string,\n queryString: string,\n body: string | ArrayBuffer,\n headers: HTTPHeaders\n ): AWSRequest {\n const requestTimestamp: number = Date.now()\n const date: string = toTime(requestTimestamp)\n\n headers['Host'] = host\n headers['X-Amz-Date'] = date\n\n headers = signHeaders(\n // headers\n headers,\n\n // requestTimestamp\n requestTimestamp,\n\n // method\n method,\n\n // path\n path,\n\n // querystring\n queryString,\n\n // body\n body,\n\n // AWS configuration\n this.awsConfig,\n\n // AwS target service name\n this.serviceName,\n\n // doubleEncoding: S3 does single-encoding of the uri component\n // pathURIEncoding: S3 manipulates object keys, and forward slashes\n // shouldn't be URI encoded\n this.URIencodingConfig\n )\n\n // '?' should not be part of the querystring when we sign the headers\n path = path !== '' ? path : '/'\n let url = `https://${host}${path}`\n if (queryString !== '') {\n url += `?${queryString}`\n }\n\n return { url: url, headers: headers }\n }\n}\n\n/**\n * Type alias representing the result of an AWSClient.buildRequest call\n */\nexport interface AWSRequest {\n url: string\n headers: HTTPHeaders\n}\n"],"names":["__webpack_require__","module","getter","__esModule","d","a","exports","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","require","AWSError","message","code","name","xmlDocument","doc","parseHTML","find","text","Error","signHeaders","headers","requestTimestamp","method","path","queryString","body","awsConfig","service","URIencodingConfig","derivedSigningKey","secretAccessKey","time","region","kSecret","date","toDate","kDate","hmac","kRegion","kService","deriveSigningKey","canonicalRequest","uri","query","payload","httpRequestMethod","toUpperCase","canonicalURI","length","URIEncode","createCanonicalURI","canonicalQueryString","qs","split","filter","e","map","v","parts","decodeURIComponent","sort","b","localeCompare","parseQueryString","encodeURIComponent","join","createCanonicalQueryString","canonicalHeaders","constructor","entries","values","toLowerCase","trim","Array","isArray","replace","createCanonicalHeaders","signedHeaders","createSignedHeaders","requestPayload","UnsignedPayload","crypto","createCanonicalPayload","createCanonicalRequest","stringToSign","hashedCanonicalRequest","requestDateTime","toTime","credentialScope","createCredentialScope","HashingAlgorithm","createStringToSign","sha256","signature","calculateSignature","authorizationHeader","accessKeyID","InvalidSignatureError","TypeError","keys","letter","c","isNumeric","includes","charCodeAt","toString","URIEncodingConfig","double","this","timestamp","Date","toISOString","substring","AWSConfig","InvalidAWSConfigError","S3Client","host","serviceName","signedRequest","res","http","url","_handle_error","error_code","error","buckets","children","each","_","bucketDefinition","bucket","forEach","child","nodeName","assign","textContent","creationDate","parse","push","bucketName","prefix","querystring","Prefix","objects","objectDefinition","lastModified","etag","size","parseInt","storageClass","objectKey","S3Object","undefined","data","error_message","error_body","startsWith","S3ServiceError","awsError","parseXML","now","S3Bucket","operation"],"sourceRoot":""} \ No newline at end of file diff --git a/src/internal/s3.ts b/src/internal/s3.ts index 7ad6ed7..a0c0353 100644 --- a/src/internal/s3.ts +++ b/src/internal/s3.ts @@ -85,16 +85,11 @@ export class S3Client extends AWSClient { const method = 'GET' const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com` const body = '' - const signedRequest: AWSRequest = super.buildRequest( - method, - host, - '/', - 'list-type=2', - body, - { - 'X-Amz-Content-SHA256': sha256(body, 'hex'), - } - ) + const querystring = `list-type=2&prefix=${prefix}` + const signedRequest: AWSRequest = super.buildRequest(method, host, '/', querystring, body, { + 'X-Amz-Content-SHA256': sha256(body, 'hex'), + Prefix: prefix ?? '', + }) const res = http.request(method, signedRequest.url, body, { headers: signedRequest.headers, From 33238e643e44bc817eb90accbafb5106b003d9e7 Mon Sep 17 00:00:00 2001 From: oleiade Date: Mon, 25 Apr 2022 13:54:54 +0200 Subject: [PATCH 2/7] Ensure S3Client.getObject sets the Object's storage class --- build/aws.min.js | 2 +- build/aws.min.js.map | 2 +- build/s3.min.js | 2 +- build/s3.min.js.map | 2 +- src/internal/s3.ts | 6 +++++- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/build/aws.min.js b/build/aws.min.js index 70f7120..4dbf015 100644 --- a/build/aws.min.js +++ b/build/aws.min.js @@ -1,2 +1,2 @@ -(()=>{var e={877:(e,t,r)=>{var n=r(570),o=r(171),i=o;i.v1=n,i.v4=o,e.exports=i},327:e=>{for(var t=[],r=0;r<256;++r)t[r]=(r+256).toString(16).substr(1);e.exports=function(e,r){var n=r||0,o=t;return[o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]]].join("")}},217:e=>{var t="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof window.msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto);if(t){var r=new Uint8Array(16);e.exports=function(){return t(r),r}}else{var n=new Array(16);e.exports=function(){for(var e,t=0;t<16;t++)0==(3&t)&&(e=4294967296*Math.random()),n[t]=e>>>((3&t)<<3)&255;return n}}},570:(e,t,r)=>{var n,o,i=r(217),c=r(327),a=0,u=0;e.exports=function(e,t,r){var s=t&&r||0,f=t||[],l=(e=e||{}).node||n,p=void 0!==e.clockseq?e.clockseq:o;if(null==l||null==p){var h=i();null==l&&(l=n=[1|h[0],h[1],h[2],h[3],h[4],h[5]]),null==p&&(p=o=16383&(h[6]<<8|h[7]))}var y=void 0!==e.msecs?e.msecs:(new Date).getTime(),d=void 0!==e.nsecs?e.nsecs:u+1,b=y-a+(d-u)/1e4;if(b<0&&void 0===e.clockseq&&(p=p+1&16383),(b<0||y>a)&&void 0===e.nsecs&&(d=0),d>=1e4)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");a=y,u=d,o=p;var v=(1e4*(268435455&(y+=122192928e5))+d)%4294967296;f[s++]=v>>>24&255,f[s++]=v>>>16&255,f[s++]=v>>>8&255,f[s++]=255&v;var m=y/4294967296*1e4&268435455;f[s++]=m>>>8&255,f[s++]=255&m,f[s++]=m>>>24&15|16,f[s++]=m>>>16&255,f[s++]=p>>>8|128,f[s++]=255&p;for(var g=0;g<6;++g)f[s+g]=l[g];return t||c(f)}},171:(e,t,r)=>{var n=r(217),o=r(327);e.exports=function(e,t,r){var i=t&&r||0;"string"==typeof e&&(t="binary"===e?new Array(16):null,e=null);var c=(e=e||{}).random||(e.rng||n)();if(c[6]=15&c[6]|64,c[8]=63&c[8]|128,t)for(var a=0;a<16;++a)t[i+a]=c[a];return t||o(c)}}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var i=t[n]={exports:{}};return e[n](i,i.exports,r),i.exports}r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var n={};(()=>{"use strict";r.r(n),r.d(n,{AWSConfig:()=>V,InvalidAWSConfigError:()=>F,InvalidSignatureError:()=>R,S3Bucket:()=>ye,S3Client:()=>he,S3Object:()=>de,S3ServiceError:()=>be,Secret:()=>Ne,SecretsManagerClient:()=>De,SecretsManagerError:()=>qe,URIEncodingConfig:()=>D,signHeaders:()=>C});const e=require("k6/crypto");var t=r.n(e);const o=require("k6/html");function i(e){return i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i(e)}function c(e,t){for(var r=0;re.length)&&(t=e.length);for(var r=0,n=new Array(t);r="A"&&r<="Z"||r>="a"&&r<="z"||function(e){return e>="0"&&e<="9"}(e)||"-._~".includes(e)?e:" "==e?"%20":"/"==e&&t?"/":"%"+e.charCodeAt(0).toString(16).toUpperCase();var r})).join("")}var D=w((function e(t,r){O(this,e),b(this,"double",void 0),b(this,"path",void 0),this.double=t,this.path=r}));function N(e){return new Date(e).toISOString().replace(/[:\-]|\.\d{3}/g,"")}function q(e){return N(e).substring(0,8)}function I(e){return I="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},I(e)}function M(e,t){if(t&&("object"===I(t)||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e)}function z(e){var t="function"==typeof Map?new Map:void 0;return z=function(e){if(null===e||(r=e,-1===Function.toString.call(r).indexOf("[native code]")))return e;var r;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return H(e,arguments,B(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),U(n,e)},z(e)}function H(e,t,r){return H=L()?Reflect.construct:function(e,t,r){var n=[null];n.push.apply(n,t);var o=new(Function.bind.apply(e,n));return r&&U(o,r.prototype),o},H.apply(null,arguments)}function L(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}function U(e,t){return U=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},U(e,t)}function B(e){return B=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},B(e)}function X(e,t){for(var r=0;r=1400&&r<=1499){var o=n.Message||n.message||n.__type;if("InvalidSignatureException"===n.__type)throw new R(o,n.__type);throw new qe(o,n.__type,e)}if(1500===r)throw new qe("An error occured on the server side","InternalServiceError",e)}}}]),r}(Q),Ne=function(){function e(t,r,n,o,i,c){var a=arguments.length>6&&void 0!==arguments[6]?arguments[6]:[];Oe(this,e),ke(this,"name",void 0),ke(this,"arn",void 0),ke(this,"secret",void 0),ke(this,"createdDate",void 0),ke(this,"lastAccessedDate",void 0),ke(this,"lastChangedDate",void 0),ke(this,"tags",void 0),this.name=t,this.arn=r,this.secret=n,this.createdDate=o,this.lastAccessedDate=i,this.lastChangedDate=c,this.tags=a}return Se(e,null,[{key:"fromJSON",value:function(t){return new e(t.Name,t.ARN,t.SecretString,t.CreatedDate,t.LastAccessedDate,t.LastChangedDate,t.Tags)}}]),e}(),qe=function(e){Ce(r,e);var t=Ee(r);function r(e,n,o){var i;return Oe(this,r),ke(Te(i=t.call(this,e,n)),"operation",void 0),i.name="SecretsManagerServiceError",i.operation=o,i}return Se(r)}(y)})();var o=exports;for(var i in n)o[i]=n[i];n.__esModule&&Object.defineProperty(o,"__esModule",{value:!0})})(); +(()=>{var e={877:(e,t,r)=>{var n=r(570),o=r(171),i=o;i.v1=n,i.v4=o,e.exports=i},327:e=>{for(var t=[],r=0;r<256;++r)t[r]=(r+256).toString(16).substr(1);e.exports=function(e,r){var n=r||0,o=t;return[o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]]].join("")}},217:e=>{var t="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof window.msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto);if(t){var r=new Uint8Array(16);e.exports=function(){return t(r),r}}else{var n=new Array(16);e.exports=function(){for(var e,t=0;t<16;t++)0==(3&t)&&(e=4294967296*Math.random()),n[t]=e>>>((3&t)<<3)&255;return n}}},570:(e,t,r)=>{var n,o,i=r(217),c=r(327),a=0,u=0;e.exports=function(e,t,r){var s=t&&r||0,f=t||[],l=(e=e||{}).node||n,p=void 0!==e.clockseq?e.clockseq:o;if(null==l||null==p){var h=i();null==l&&(l=n=[1|h[0],h[1],h[2],h[3],h[4],h[5]]),null==p&&(p=o=16383&(h[6]<<8|h[7]))}var y=void 0!==e.msecs?e.msecs:(new Date).getTime(),d=void 0!==e.nsecs?e.nsecs:u+1,b=y-a+(d-u)/1e4;if(b<0&&void 0===e.clockseq&&(p=p+1&16383),(b<0||y>a)&&void 0===e.nsecs&&(d=0),d>=1e4)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");a=y,u=d,o=p;var v=(1e4*(268435455&(y+=122192928e5))+d)%4294967296;f[s++]=v>>>24&255,f[s++]=v>>>16&255,f[s++]=v>>>8&255,f[s++]=255&v;var m=y/4294967296*1e4&268435455;f[s++]=m>>>8&255,f[s++]=255&m,f[s++]=m>>>24&15|16,f[s++]=m>>>16&255,f[s++]=p>>>8|128,f[s++]=255&p;for(var g=0;g<6;++g)f[s+g]=l[g];return t||c(f)}},171:(e,t,r)=>{var n=r(217),o=r(327);e.exports=function(e,t,r){var i=t&&r||0;"string"==typeof e&&(t="binary"===e?new Array(16):null,e=null);var c=(e=e||{}).random||(e.rng||n)();if(c[6]=15&c[6]|64,c[8]=63&c[8]|128,t)for(var a=0;a<16;++a)t[i+a]=c[a];return t||o(c)}}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var i=t[n]={exports:{}};return e[n](i,i.exports,r),i.exports}r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var n={};(()=>{"use strict";r.r(n),r.d(n,{AWSConfig:()=>V,InvalidAWSConfigError:()=>F,InvalidSignatureError:()=>R,S3Bucket:()=>ye,S3Client:()=>he,S3Object:()=>de,S3ServiceError:()=>be,Secret:()=>Ne,SecretsManagerClient:()=>De,SecretsManagerError:()=>qe,URIEncodingConfig:()=>D,signHeaders:()=>C});const e=require("k6/crypto");var t=r.n(e);const o=require("k6/html");function i(e){return i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i(e)}function c(e,t){for(var r=0;re.length)&&(t=e.length);for(var r=0,n=new Array(t);r="A"&&r<="Z"||r>="a"&&r<="z"||function(e){return e>="0"&&e<="9"}(e)||"-._~".includes(e)?e:" "==e?"%20":"/"==e&&t?"/":"%"+e.charCodeAt(0).toString(16).toUpperCase();var r})).join("")}var D=w((function e(t,r){O(this,e),b(this,"double",void 0),b(this,"path",void 0),this.double=t,this.path=r}));function N(e){return new Date(e).toISOString().replace(/[:\-]|\.\d{3}/g,"")}function q(e){return N(e).substring(0,8)}function I(e){return I="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},I(e)}function M(e,t){if(t&&("object"===I(t)||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e)}function z(e){var t="function"==typeof Map?new Map:void 0;return z=function(e){if(null===e||(r=e,-1===Function.toString.call(r).indexOf("[native code]")))return e;var r;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return H(e,arguments,X(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),U(n,e)},z(e)}function H(e,t,r){return H=L()?Reflect.construct:function(e,t,r){var n=[null];n.push.apply(n,t);var o=new(Function.bind.apply(e,n));return r&&U(o,r.prototype),o},H.apply(null,arguments)}function L(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}function U(e,t){return U=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},U(e,t)}function X(e){return X=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},X(e)}function B(e,t){for(var r=0;r=1400&&r<=1499){var o=n.Message||n.message||n.__type;if("InvalidSignatureException"===n.__type)throw new R(o,n.__type);throw new qe(o,n.__type,e)}if(1500===r)throw new qe("An error occured on the server side","InternalServiceError",e)}}}]),r}(Q),Ne=function(){function e(t,r,n,o,i,c){var a=arguments.length>6&&void 0!==arguments[6]?arguments[6]:[];Oe(this,e),ke(this,"name",void 0),ke(this,"arn",void 0),ke(this,"secret",void 0),ke(this,"createdDate",void 0),ke(this,"lastAccessedDate",void 0),ke(this,"lastChangedDate",void 0),ke(this,"tags",void 0),this.name=t,this.arn=r,this.secret=n,this.createdDate=o,this.lastAccessedDate=i,this.lastChangedDate=c,this.tags=a}return je(e,null,[{key:"fromJSON",value:function(t){return new e(t.Name,t.ARN,t.SecretString,t.CreatedDate,t.LastAccessedDate,t.LastChangedDate,t.Tags)}}]),e}(),qe=function(e){Ce(r,e);var t=Ae(r);function r(e,n,o){var i;return Oe(this,r),ke(Te(i=t.call(this,e,n)),"operation",void 0),i.name="SecretsManagerServiceError",i.operation=o,i}return je(r)}(y)})();var o=exports;for(var i in n)o[i]=n[i];n.__esModule&&Object.defineProperty(o,"__esModule",{value:!0})})(); //# sourceMappingURL=aws.min.js.map \ No newline at end of file diff --git a/build/aws.min.js.map b/build/aws.min.js.map index 9646b7a..7e52e2f 100644 --- a/build/aws.min.js.map +++ b/build/aws.min.js.map @@ -1 +1 @@ -{"version":3,"file":"aws.min.js","mappings":"2BAAA,IAAIA,EAAK,EAAQ,KACbC,EAAK,EAAQ,KAEbC,EAAOD,EACXC,EAAKF,GAAKA,EACVE,EAAKD,GAAKA,EAEVE,EAAOC,QAAUF,G,QCFjB,IADA,IAAIG,EAAY,GACPC,EAAI,EAAGA,EAAI,MAAOA,EACzBD,EAAUC,IAAMA,EAAI,KAAOC,SAAS,IAAIC,OAAO,GAmBjDL,EAAOC,QAhBP,SAAqBK,EAAKC,GACxB,IAAIJ,EAAII,GAAU,EACdC,EAAMN,EAEV,MAAO,CACLM,EAAIF,EAAIH,MAAOK,EAAIF,EAAIH,MACvBK,EAAIF,EAAIH,MAAOK,EAAIF,EAAIH,MAAO,IAC9BK,EAAIF,EAAIH,MAAOK,EAAIF,EAAIH,MAAO,IAC9BK,EAAIF,EAAIH,MAAOK,EAAIF,EAAIH,MAAO,IAC9BK,EAAIF,EAAIH,MAAOK,EAAIF,EAAIH,MAAO,IAC9BK,EAAIF,EAAIH,MAAOK,EAAIF,EAAIH,MACvBK,EAAIF,EAAIH,MAAOK,EAAIF,EAAIH,MACvBK,EAAIF,EAAIH,MAAOK,EAAIF,EAAIH,OACtBM,KAAK,M,QCfV,IAAIC,EAAqC,oBAAZ,QAA2BC,OAAOD,iBAAmBC,OAAOD,gBAAgBE,KAAKD,SACnE,oBAAd,UAAuE,mBAAnCE,OAAOC,SAASJ,iBAAiCI,SAASJ,gBAAgBE,KAAKE,UAEhJ,GAAIJ,EAAiB,CAEnB,IAAIK,EAAQ,IAAIC,WAAW,IAE3BhB,EAAOC,QAAU,WAEf,OADAS,EAAgBK,GACTA,OAEJ,CAKL,IAAIE,EAAO,IAAIC,MAAM,IAErBlB,EAAOC,QAAU,WACf,IAAK,IAAWkB,EAAPhB,EAAI,EAAMA,EAAI,GAAIA,IACN,IAAV,EAAJA,KAAiBgB,EAAoB,WAAhBC,KAAKC,UAC/BJ,EAAKd,GAAKgB,MAAY,EAAJhB,IAAa,GAAK,IAGtC,OAAOc,K,cC/BX,IAQIK,EACAC,EATAC,EAAM,EAAQ,KACdC,EAAc,EAAQ,KAWtBC,EAAa,EACbC,EAAa,EA+FjB3B,EAAOC,QA5FP,SAAY2B,EAAStB,EAAKC,GACxB,IAAIJ,EAAIG,GAAOC,GAAU,EACrBsB,EAAIvB,GAAO,GAGXwB,GADJF,EAAUA,GAAW,IACFE,MAAQR,EACvBS,OAAgCC,IAArBJ,EAAQG,SAAyBH,EAAQG,SAAWR,EAKnE,GAAY,MAARO,GAA4B,MAAZC,EAAkB,CACpC,IAAIE,EAAYT,IACJ,MAARM,IAEFA,EAAOR,EAAU,CACA,EAAfW,EAAU,GACVA,EAAU,GAAIA,EAAU,GAAIA,EAAU,GAAIA,EAAU,GAAIA,EAAU,KAGtD,MAAZF,IAEFA,EAAWR,EAAiD,OAApCU,EAAU,IAAM,EAAIA,EAAU,KAQ1D,IAAIC,OAA0BF,IAAlBJ,EAAQM,MAAsBN,EAAQM,OAAQ,IAAIC,MAAOC,UAIjEC,OAA0BL,IAAlBJ,EAAQS,MAAsBT,EAAQS,MAAQV,EAAa,EAGnEW,EAAMJ,EAAQR,GAAeW,EAAQV,GAAY,IAcrD,GAXIW,EAAK,QAA0BN,IAArBJ,EAAQG,WACpBA,EAAWA,EAAW,EAAI,QAKvBO,EAAK,GAAKJ,EAAQR,SAAiCM,IAAlBJ,EAAQS,QAC5CA,EAAQ,GAINA,GAAS,IACX,MAAM,IAAIE,MAAM,mDAGlBb,EAAaQ,EACbP,EAAaU,EACbd,EAAYQ,EAMZ,IAAIS,GAA4B,KAAb,WAHnBN,GAAS,cAG+BG,GAAS,WACjDR,EAAE1B,KAAOqC,IAAO,GAAK,IACrBX,EAAE1B,KAAOqC,IAAO,GAAK,IACrBX,EAAE1B,KAAOqC,IAAO,EAAI,IACpBX,EAAE1B,KAAY,IAALqC,EAGT,IAAIC,EAAOP,EAAQ,WAAc,IAAS,UAC1CL,EAAE1B,KAAOsC,IAAQ,EAAI,IACrBZ,EAAE1B,KAAa,IAANsC,EAGTZ,EAAE1B,KAAOsC,IAAQ,GAAK,GAAM,GAC5BZ,EAAE1B,KAAOsC,IAAQ,GAAK,IAGtBZ,EAAE1B,KAAO4B,IAAa,EAAI,IAG1BF,EAAE1B,KAAkB,IAAX4B,EAGT,IAAK,IAAIW,EAAI,EAAGA,EAAI,IAAKA,EACvBb,EAAE1B,EAAIuC,GAAKZ,EAAKY,GAGlB,OAAOpC,GAAYmB,EAAYI,K,cCzGjC,IAAIL,EAAM,EAAQ,KACdC,EAAc,EAAQ,KA2B1BzB,EAAOC,QAzBP,SAAY2B,EAAStB,EAAKC,GACxB,IAAIJ,EAAIG,GAAOC,GAAU,EAEF,iBAAb,IACRD,EAAkB,WAAZsB,EAAuB,IAAIV,MAAM,IAAM,KAC7CU,EAAU,MAIZ,IAAIX,GAFJW,EAAUA,GAAW,IAEFP,SAAWO,EAAQJ,KAAOA,KAO7C,GAJAP,EAAK,GAAgB,GAAVA,EAAK,GAAa,GAC7BA,EAAK,GAAgB,GAAVA,EAAK,GAAa,IAGzBX,EACF,IAAK,IAAIqC,EAAK,EAAGA,EAAK,KAAMA,EAC1BrC,EAAIH,EAAIwC,GAAM1B,EAAK0B,GAIvB,OAAOrC,GAAOmB,EAAYR,MCxBxB2B,EAA2B,GAG/B,SAASC,EAAoBC,GAE5B,IAAIC,EAAeH,EAAyBE,GAC5C,QAAqBd,IAAjBe,EACH,OAAOA,EAAa9C,QAGrB,IAAID,EAAS4C,EAAyBE,GAAY,CAGjD7C,QAAS,IAOV,OAHA+C,EAAoBF,GAAU9C,EAAQA,EAAOC,QAAS4C,GAG/C7C,EAAOC,QCpBf4C,EAAoBH,EAAK1C,IACxB,IAAIiD,EAASjD,GAAUA,EAAOkD,WAC7B,IAAOlD,EAAiB,QACxB,IAAM,EAEP,OADA6C,EAAoBM,EAAEF,EAAQ,CAAEG,EAAGH,IAC5BA,GCLRJ,EAAoBM,EAAI,CAAClD,EAASoD,KACjC,IAAI,IAAIC,KAAOD,EACXR,EAAoBU,EAAEF,EAAYC,KAAST,EAAoBU,EAAEtD,EAASqD,IAC5EE,OAAOC,eAAexD,EAASqD,EAAK,CAAEI,YAAY,EAAMC,IAAKN,EAAWC,MCJ3ET,EAAoBU,EAAI,CAACK,EAAKC,IAAUL,OAAOM,UAAUC,eAAeC,KAAKJ,EAAKC,GCClFhB,EAAoB1B,EAAKlB,IACH,oBAAXgE,QAA0BA,OAAOC,aAC1CV,OAAOC,eAAexD,EAASgE,OAAOC,YAAa,CAAEC,MAAO,WAE7DX,OAAOC,eAAexD,EAAS,aAAc,CAAEkE,OAAO,K,ySCLvD,MAAM,EAA+BC,QAAQ,a,aCA7C,MAAM,EAA+BA,QAAQ,W,q0DCUtC,IAAMC,EAAb,a,qRAAA,U,UAAA,G,EAAA,E,mJASI,WAAYC,EAAiBC,GAAc,M,MAAA,O,4FAAA,SACvC,cAAMD,G,EADiC,K,OAAA,G,EAAA,U,wFAEvC,EAAKE,KAAO,WACZ,EAAKD,KAAOA,EAH2B,EAT/C,O,EAAA,E,EAAA,uBAoBI,SAAgBE,GACZ,IAAMC,GAAMC,EAAAA,EAAAA,WAAUF,GACtB,OAAO,IAAIJ,EAASK,EAAIE,KAAK,WAAWC,OAAQH,EAAIE,KAAK,QAAQC,Y,EAtBzE,O,8EAAA,KAA8BtC,Q,6kFCiBvB,SAASuC,EACZC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,GAEA,IAAMC,EAgFH,SACHC,EACAC,EACAC,EACAL,GAEA,IAAMM,EAAUH,EACVI,EAAOC,EAAOJ,GAIdK,GAAaC,EAAAA,EAAAA,MAAK,SAAU,OAASJ,EAASC,EAAM,UACpDI,GAAeD,EAAAA,EAAAA,MAAK,SAAUD,EAAOJ,EAAQ,UAC7CO,GAAgBF,EAAAA,EAAAA,MAAK,SAAUC,EAASX,EAAS,UAGvD,OAFsBU,EAAAA,EAAAA,MAAK,SAAUE,EAAU,eAAgB,UA9FrCC,CACtBd,EAAUI,gBACVT,EACAK,EAAUM,OACVL,GAGEc,EAqLH,SACHnB,EACAoB,EACAC,EACAvB,EACAwB,EACAhB,GAEA,IAAMiB,EAAoBvB,EAAOwB,cAC3BC,EA4BH,SAA4BL,EAAad,GAC5C,GAAW,KAAPc,EACA,OAAOA,EAGX,IAAIK,EAAeL,EACQ,KAAvBA,EAAIA,EAAIM,OAAS,IAAsD,KAAzCD,EAAaA,EAAaC,OAAS,KACjED,GAAgB,KAKpB,OAFAA,EAAeE,EAAUF,EAAcnB,EAAkBL,MAElDK,EAAiB,OAAUqB,EAAUF,EAAcnB,EAAkBL,MAAQwB,EAxC/DG,CAAmBR,EAAKd,GACvCuB,EAmDH,SAAoCC,GACvC,GAAW,KAAPA,EACA,MAAO,GAoBX,OA8MG,SAA0BA,GAC7B,GAAkB,IAAdA,EAAGJ,OACH,MAAO,GAGX,OAAOI,EACFC,MAAM,KACNC,QAAO,SAACC,GAAD,OAAOA,KACdC,KAAI,SAACC,GACF,IAAMC,EAAQD,EAAEJ,MAAM,IAAK,GAC3B,MAAO,CAACM,mBAAmBD,EAAM,IAAKC,mBAAmBD,EAAM,QAElEE,MAAK,SAACnE,EAAqBvB,GACxB,OAAOuB,EAAE,GAAGoE,cAAc3F,EAAE,OA3N7B4F,CAAiBV,GACnBI,KAAI,YAA4C,aAA1C7D,EAA0C,KAArCa,EAAqC,KAC7C,OAAOuD,mBAAmBpE,GAAO,IAAMoE,mBAAmBvD,MAE7D1D,KAAK,KA7EmBkH,CAA2BrB,GAClDsB,EA4FH,SAAgC7C,GACnC,GAAIA,EAAQ8C,cAAgBrE,QAA6C,IAAnCA,OAAOsE,QAAQ/C,GAAS4B,OAC1D,MAAO,GAqBX,OAlByBnD,OAAOsE,QAAQ/C,GACnCoC,KAAI,YAAoB,aAAlB3C,EAAkB,KAAZuD,EAAY,KAYrB,OAXsBvD,EAAKwD,cAAcC,OAWlB,KAVE/G,MAAMgH,QAAQH,GAAUA,EAAS,CAACA,IAItDZ,KAAI,SAACC,GAEF,OAAOA,EAAEe,QAAQ,OAAQ,KAAKA,QAAQ,aAAc,OAEvD1H,KAAK,KAEqC,QAElD8G,OACA9G,KAAK,IAjHe2H,CAAuBrD,GAC1CsD,EAAgBC,EAAoBvD,GACpCwD,EAsKH,SAAgChC,GACnC,GAAIA,IAAYiC,EACZ,OAAOjC,EAMX,OAAO5F,IAAAA,OAAc4F,GAAW,GAAI,OAAOyB,cA9KpBS,CAAuBlC,GAW9C,MATyB,CACrBC,EACAE,EACAI,EACAc,EACAS,EACAE,GACF9H,KAAK,MA3MkBiI,CACrBzD,EACAC,EACAC,EACAJ,EACAK,EACAG,GAGEoD,EA2GH,SACH3D,EACAW,EACAL,EACAsD,GAGA,IAAMC,EAAkBC,EAAO9D,GAKzB+D,EAAkBC,EAAsBhE,EAAkBW,EAAQL,GAgBxE,MAdqB,CAEjB2D,EAGAJ,EAGAE,EAGAH,GACFnI,KAAK,MArIcyI,CACjBlE,EACAK,EAAUM,OACVL,GACA6D,EAAAA,EAAAA,QAAO/C,EAAkB,QAGvB2C,EAAkBC,EAAsBhE,EAAkBK,EAAUM,OAAQL,GAC5E+C,EAAgBC,EAAoBvD,GACpCqE,EAmCH,SAA4B5D,EAAgCmD,GAC/D,OAAO3C,EAAAA,EAAAA,MAAK,SAAUR,EAAmBmD,EAAc,OApCrCU,CAAmB7D,EAAmBmD,GAClDW,EAAsB,GAAH,OAAML,EAAN,uBAAqC5D,EAAUkE,YAA/C,YAA8DR,EAA9D,2BAAgGV,EAAhG,uBAA4He,GAIrJ,OAFArE,EAAO,cAAoBuE,EAEpBvE,EAWJ,IAAMyE,EAAb,a,qRAAA,iBAMI,WAAYlF,EAAiBC,GAAc,wBACvC,cAAMD,EAASC,IACVC,KAAO,wBAF2B,EAN/C,aAA2CH,GA2DpC,IAAM4E,EAAmB,mBAOnBT,EAAkB,mBA6DxB,SAASQ,EACZhE,EACAW,EACAL,GAEA,MAAO,CAACQ,EAAOd,GAAmBW,EAAQL,EAAS,gBAAgB7E,KAAK,KAgKrE,SAAS6H,EAAoBvD,GAChC,GAAIA,EAAQ8C,cAAgBrE,OACxB,MAAM,IAAIiG,UAAU,+BAGxB,GAAuC,IAAnCjG,OAAOsE,QAAQ/C,GAAS4B,OACxB,KAAM,8FAYV,OALenD,OAAOkG,KAAK3E,GACtBoC,KAAI,SAAC3C,GAAD,OAAUA,EAAKwD,cAAcC,UACjCV,OACA9G,KAAK,KAqDP,SAASmG,EAAUP,EAAanB,GACnC,MAAW,IAAPmB,EACOA,EAGJA,EACFW,MAAM,IACNG,KAAI,SAACwC,GACF,OAoFKC,EApFOD,IAqFP,KAAOC,GAAK,KAASA,GAAK,KAAOA,GAAK,KAGvD,SAAmBA,GACf,OAAOA,GAAK,KAAOA,GAAK,IAzFOC,CAAUF,IAAW,OAAOG,SAASH,GACjDA,EAIG,KAAVA,EACO,MAKG,KAAVA,GAAiBzE,EACV,IAGJ,IAAMyE,EAAOI,WAAW,GAAG3J,SAAS,IAAIqG,cAqE3D,IAAiBmD,KAnERnJ,KAAK,IAMP,IAAMuJ,EAAb,GAUI,WAAYC,EAAiB/E,GAAe,wDACxCgF,KAAA,OAAcD,EACdC,KAAKhF,KAAOA,KAWb,SAAS4D,EAAOqB,GACnB,OAAO,IAAIhI,KAAKgI,GAAWC,cAAcjC,QAAQ,iBAAkB,IAQhE,SAASrC,EAAOqE,GACnB,OAAOrB,EAAOqB,GAAWE,UAAU,EAAG,G,ooECvfnC,IAAMC,EAAb,GAaI,WAAY3E,EAAgB4D,EAAqB9D,GAC7C,GADsE,gGAChD,iBAAXE,GAAkC,KAAXA,EAC9B,MAAM,IAAI4E,EACN,4DAIR,GAA2B,iBAAhBhB,GAA4C,KAAhBA,EACnC,MAAM,IAAIgB,EACN,mEAIR,GAA+B,iBAApB9E,GAAoD,KAApBA,EACvC,MAAM,IAAI8E,EACN,uEAIRL,KAAKvE,OAASA,EACduE,KAAKX,YAAcA,EACnBW,KAAKzE,gBAAkBA,KAKlB8E,EAAb,a,qRAAA,U,IAAA,G,EAAA,E,mJACI,WAAYjG,GAAiB,6BACnBA,GAFd,eAA2C/B,QCxC3C,MAAM,EAA+B6B,QAAQ,W,2SCWtC,IAAMoG,EAAb,WAUI,WAAYnF,EAAsBoF,EAAqBlF,I,4FAAsC,oGACzF2E,KAAK7E,UAAYA,EACjB6E,KAAKO,YAAcA,EACnBP,KAAK3E,kBAAoBA,E,UAbjC,O,EAAA,G,EAAA,2BAgBI,SACIN,EACAyF,EACAxF,EACAC,EACAC,EACAL,GAEA,IAAMC,EAA2B7C,KAAKwI,MAChC9E,EAAeiD,EAAO9D,GAE5BD,EAAO,KAAW2F,EAClB3F,EAAQ,cAAgBc,EAExBd,EAAUD,EAENC,EAGAC,EAGAC,EAGAC,EAGAC,EAGAC,EAGA8E,KAAK7E,UAGL6E,KAAKO,YAKLP,KAAK3E,mBAITL,EAAgB,KAATA,EAAcA,EAAO,IAC5B,IAAI0F,EAAM,WAAH,OAAcF,GAAd,OAAqBxF,GAK5B,MAJoB,KAAhBC,IACAyF,GAAO,IAAJ,OAAQzF,IAGR,CAAEyF,IAAKA,EAAK7F,QAASA,Q,8EApEpC,K,6vECAO,IAAM8F,GAAb,gCAMI,WAAYxF,GAAsB,WAC9B,IAAME,EAAoB,IAAIyE,GAAkB,GAAO,GADzB,mBAExB3E,EAAW,KAAME,GAR/B,sCAoBI,WAEI,IACMmF,EAAO,GAAH,OAAMR,KAAKO,YAAX,YAA0BP,KAAK7E,UAAUM,OAAzC,kBAEJmF,EAA4B,GAAH,+CAHhB,MAG8CJ,EAAM,IAAK,GAD3D,GACqE,CAC9E,wBAAwBvB,EAAAA,EAAAA,QAFf,GAE4B,SAGnC4B,EAAMC,IAAAA,QAPG,MAOkBF,EAAcF,IALlC,GAK6C,CACtD7F,QAAS+F,EAAc/F,UAE3BmF,KAAKe,cAAcF,EAAIG,WAAYH,EAAII,MAAOJ,EAAI3F,MAElD,IAAIgG,EAA2B,GAwB/B,OAtBYzG,EAAAA,EAAAA,WAAUoG,EAAI3F,MAEtBR,KAAK,WACJyG,WACAC,MAAK,SAACC,EAAGC,GACN,IAAIC,EAAS,GAEbD,EAAiBH,WAAWK,SAAQ,SAACC,GACjC,OAAQA,EAAMC,YACV,IAAK,OACDpI,OAAOqI,OAAOJ,EAAQ,CAAEjH,KAAMmH,EAAMG,gBACpC,MACJ,IAAK,eACDtI,OAAOqI,OAAOJ,EAAQ,CAClBM,aAAc5J,KAAK6J,MAAML,EAAMG,qBAK/CV,EAAQa,KAAKR,MAGdL,IA1Df,yBAuEI,SAAYc,EAAoBC,GAE5B,IACMzB,EAAO,GAAH,OAAMwB,EAAN,YAAoBhC,KAAKO,YAAzB,YAAwCP,KAAK7E,UAAUM,OAAvD,kBAEJyG,EAAc,sBAAH,OAAyBD,GACpCrB,EAA4B,GAAH,+CAJhB,MAI8CJ,EAAM,IAAK0B,EAF3D,GAE8E,CACvF,wBAAwBjD,EAAAA,EAAAA,QAHf,GAG4B,OACrCkD,OAAQF,MAAAA,EAAAA,EAAU,KAGhBpB,EAAMC,IAAAA,QATG,MASkBF,EAAcF,IAPlC,GAO6C,CACtD7F,QAAS+F,EAAc/F,UAE3BmF,KAAKe,cAAcF,EAAIG,WAAYH,EAAII,MAAOJ,EAAI3F,MAElD,IAAIkH,EAA2B,GA+B/B,OA3BA3H,EAAAA,EAAAA,WAAUoG,EAAI3F,MACTR,KAAK,YACL0G,MAAK,SAACC,EAAGgB,GACN,IAAI3I,EAAM,GAEV2I,EAAiBlB,WAAWK,SAAQ,SAACC,GACjC,OAAQA,EAAMC,YACV,IAAK,MACDpI,OAAOqI,OAAOjI,EAAK,CAAEN,IAAKqI,EAAMG,gBAChC,MACJ,IAAK,eACDtI,OAAOqI,OAAOjI,EAAK,CAAE4I,aAAcrK,KAAK6J,MAAML,EAAMG,iBACpD,MACJ,IAAK,OACDtI,OAAOqI,OAAOjI,EAAK,CAAE6I,KAAMd,EAAMG,gBACjC,MACJ,IAAK,OACDtI,OAAOqI,OAAOjI,EAAK,CAAE8I,KAAMC,SAAShB,EAAMG,iBAC1C,MACJ,IAAK,eACDtI,OAAOqI,OAAOjI,EAAK,CAAEgJ,aAAcjB,EAAMG,oBAIrDQ,EAAQL,KAAKrI,MAGd0I,IAtHf,uBAmII,SAAUJ,EAAoBW,GAE1B,IACMnC,EAAO,GAAH,OAAMwB,EAAN,YAAoBhC,KAAKO,YAAzB,YAAwCP,KAAK7E,UAAUM,OAAvD,kBACJT,EAAO,IAAH,OAAO2H,GAEX/B,EAA4B,GAAH,+CAJhB,MAI8CJ,EAAMxF,EAAM,GAD5D,GACsE,CAC/E,wBAAwBiE,EAAAA,EAAAA,QAFf,GAE4B,SAGnC4B,EAAMC,IAAAA,QARG,MAQkBF,EAAcF,IALlC,GAK6C,CACtD7F,QAAS+F,EAAc/F,UAI3B,OAFAmF,KAAKe,cAAcF,EAAIG,WAAYH,EAAII,MAAOJ,EAAI3F,MAE3C,IAAI0H,GACPD,EACA1K,KAAK6J,MAAMjB,EAAIhG,QAAQ,kBACvBgG,EAAIhG,QAAJ,KACA4H,SAAS5B,EAAIhG,QAAQ,wBACrB/C,EACA+I,EAAI3F,QAxJhB,uBAsKI,SAAU8G,EAAoBW,EAAmBE,GAE7C,IACMrC,EAAO,GAAH,OAAMwB,EAAN,YAAoBhC,KAAKO,YAAzB,YAAwCP,KAAK7E,UAAUM,OAAvD,kBACJT,EAAO,IAAH,OAAO2H,GAEXzH,EAAO2H,EACPjC,EAA4B,GAAH,+CALhB,MAOXJ,EACAxF,EALgB,GAOhBE,EACA,CACI,wBAAwB+D,EAAAA,EAAAA,QAAO/D,EAAM,SAIvC2F,EAAMC,IAAAA,QAhBG,MAgBkBF,EAAcF,IAAKxF,EAAM,CACtDL,QAAS+F,EAAc/F,UAE3BmF,KAAKe,cAAcF,EAAIG,WAAYH,EAAII,MAAOJ,EAAI3F,QA3L1D,0BAuMI,SAAa8G,EAAoBW,GAE7B,IAAM5H,EAAS,SACTyF,EAAO,GAAH,OAAMwB,EAAN,YAAoBhC,KAAKO,YAAzB,YAAwCP,KAAK7E,UAAUM,OAAvD,kBACJT,EAAO,IAAH,OAAO2H,GAGX/B,EAA4B,GAAH,+CAC3B7F,EACAyF,EACAxF,EALgB,GACP,GAOT,CACI,wBAAwBiE,EAAAA,EAAAA,QARnB,GAQgC,SAIvC4B,EAAMC,IAAAA,QAAa/F,EAAQ6F,EAAcF,IAZlC,GAY6C,CACtD7F,QAAS+F,EAAc/F,UAE3BmF,KAAKe,cAAcF,EAAIG,WAAYH,EAAII,MAAOJ,EAAI3F,QA5N1D,2BAiOI,SAAc8F,EAAoB8B,EAAuBC,GACrD,GAAqB,IAAjBD,GAAsC,IAAf9B,EAA3B,CAOA,GAAI8B,GAAiBA,EAAcE,WAAW,OAE1C,MAAM,IAAIC,GAAe,qBAAsB,mBAAoB,aAGvE,IAAMC,EAAW/I,EAASgJ,SAASJ,GACnC,GACS,iCADDG,EAAS7I,KAET,MAAM,IAAIiF,EAAsB4D,EAAS9I,QAAS8I,EAAS7I,MAE3D,MAAM,IAAI4I,GAAeC,EAAS9I,QAAS8I,EAAS7I,KAAM,oBAnP1E,GAA8BiG,GA0PjB8C,GAAb,IAUI,WAAY9I,EAAcuH,GAAoB,iEAC1C7B,KAAK1F,KAAOA,EACZ0F,KAAK6B,aAAeA,KAMfe,GAAb,IAkBI,WACIxJ,EACAkJ,EACAC,EACAC,EACAE,EACAG,GACF,oKACE7C,KAAK5G,IAAMA,EACX4G,KAAKsC,aAAeA,EACpBtC,KAAKuC,KAAOA,EACZvC,KAAKwC,KAAOA,EACZxC,KAAK0C,aAAeA,EACpB1C,KAAK6C,KAAOA,KAYPI,GAAb,gCAUI,WAAY7I,EAAiBC,EAAcgJ,GAAmB,8BAC1D,cAAMjJ,EAASC,IAD2C,oBAE1D,EAAKC,KAAO,iBACZ,EAAK+I,UAAYA,EAHyC,EAVlE,cAAoClJ,G,20FCrT7B,IAAMmJ,GAAb,gCAQI,WAAYnI,GAAsB,iBAC9B,IAAME,EAAoB,IAAIyE,GAAkB,GAAM,GADxB,aAE9B,cAAM3E,EAAW,iBAAkBE,IAFL,kDAQ9B,EAAKN,OAAS,OAEd,EAAKwI,cAAgB,CACjB,kBAAmB,WACnB,eAAgB,8BAZU,EARtC,sCAgCI,WACI,IAAMrI,EAAOsI,KAAKC,UAAU,IAItB7C,EAA4B,kDAC9BZ,KAAKjF,OACLiF,KAAKQ,KACL,IACA,GACAtF,EAL2B,SAOpB8E,KAAKuD,eAPe,IAQvB,yBAAmBvD,KAAKO,YAAxB,mBAIFM,EAAMC,IAAAA,QAAad,KAAKjF,OAAQ6F,EAAcF,IAAKxF,EAAM,CAC3DL,QAAS+F,EAAc/F,UAK3B,OAHAmF,KAAKe,cAAc,cAAeF,GACVA,EAAI6C,KAAK,cAErBzG,KAAI,SAAC0G,GAAD,OAAOC,GAAOC,SAASF,QAvD/C,uBAkEI,SAAUG,GACN,IAAM5I,EAAOsI,KAAKC,UAAU,CAAEM,SAAUD,IAIlClD,EAA4B,kDAC9BZ,KAAKjF,OACLiF,KAAKQ,KACL,IACA,GACAtF,EAL2B,SAOpB8E,KAAKuD,eAPe,IAQvB,yBAAmBvD,KAAKO,YAAxB,sBAIFM,EAAMC,IAAAA,QAAad,KAAKjF,OAAQ6F,EAAcF,IAAKxF,EAAM,CAC3DL,QAAS+F,EAAc/F,UAI3B,OAFAmF,KAAKe,cAAc,iBAAkBF,GAE9B+C,GAAOC,SAAShD,EAAI6C,UAxFnC,0BA6GI,SACIpJ,EACA0J,EACAC,EACAC,EACAC,GAEAD,EAAYA,IAAaE,EAAAA,GAAAA,MAEzB,IAAMlJ,EAAOsI,KAAKC,UAAU,CACxBY,KAAM/J,EACNgK,YAAaL,EACbM,aAAcP,EACdQ,mBAAoBN,EACpBO,KAAMN,IAGJvD,EAA4B,kDAC9BZ,KAAKjF,OACLiF,KAAKQ,KACL,IACA,GACAtF,EAL2B,SAOpB8E,KAAKuD,eAPe,IAQvB,yBAAmBvD,KAAKO,YAAxB,oBAQFM,EAAMC,IAAAA,QAAad,KAAKjF,OAAQ6F,EAAcF,IAAKxF,EAAM,CAC3DL,QAAS+F,EAAc/F,UAI3B,OAFAmF,KAAKe,cAAc,eAAgBF,GAE5B+C,GAAOC,SAAShD,EAAI6C,UAnJnC,4BAiKI,SAAeI,EAAkBE,EAAsBE,GACnDA,EAAYA,IAAaE,EAAAA,GAAAA,MAEzB,IAAMlJ,EAAOsI,KAAKC,UAAU,CACxBM,SAAUD,EACVS,aAAcP,EACdQ,mBAAoBN,IAKlBtD,EAA4B,kDAC9BZ,KAAKjF,OACLiF,KAAKQ,KACL,IACA,GACAtF,EAL2B,SAOpB8E,KAAKuD,eAPe,IAQvB,yBAAmBvD,KAAKO,YAAxB,sBAIFM,EAAMC,IAAAA,QAAad,KAAKjF,OAAQ6F,EAAcF,IAAKxF,EAAM,CAC3DL,QAAS+F,EAAc/F,UAI3B,OAFAmF,KAAKe,cAAc,iBAAkBF,GAE9B+C,GAAOC,SAAShD,EAAI6C,UA7LnC,0BA4MI,SACII,EADJ,GAGE,QADIY,eAAAA,OACJ,MADqB,GACrB,MADyBC,WAEjBtI,EAAwD,CAC1D0H,SAAUD,IAIK,UANrB,UAOMzH,EAAO,4BAAiC,EAExCA,EAAO,qBAA2BqI,EAGtC,IAAMxJ,EAAOsI,KAAKC,UAAUpH,GAItBuE,EAA4B,kDAC9BZ,KAAKjF,OACLiF,KAAKQ,KACL,IACA,GACAtF,EAL2B,SAOpB8E,KAAKuD,eAPe,IAQvB,yBAAmBvD,KAAKO,YAAxB,oBAIFM,EAAMC,IAAAA,QAAad,KAAKjF,OAAQ6F,EAAcF,IAAKxF,EAAM,CAC3DL,QAAS+F,EAAc/F,UAE3BmF,KAAKe,cAAc,eAAgBF,KA9O3C,gBAiPI,WACI,gBAAUb,KAAKO,YAAf,YAA8BP,KAAK7E,UAAUM,OAA7C,oBAlPR,2BAsPI,SAAc4H,EAAmBuB,GAC7B,IAAMC,EAAYD,EAAS5D,WAC3B,GAAkB,IAAd6D,EAAJ,CAIA,IAAM5D,EAAQ2D,EAASlB,OACvB,GAAImB,GAAa,MAAQA,GAAa,KAAM,CAGxC,IAAMC,EACD7D,EAAM8D,SAAuB9D,EAAM7G,SAAuB6G,EAAM+D,OAGrE,GAAqB,8BAAjB/D,EAAM+D,OACN,MAAM,IAAI1F,EAAsBwF,EAAc7D,EAAM+D,QAIxD,MAAM,IAAIC,GAAoBH,EAAc7D,EAAM+D,OAAkB3B,GAGxE,GAAkB,OAAdwB,EACA,MAAM,IAAII,GACN,sCACA,uBACA5B,QAhRhB,GAA0C/C,GA2R7BsD,GAAb,WAoBI,WACItJ,EACA4K,EACAlB,EACAmB,EACAC,EACAC,GAEF,IADElB,EACF,uDAD2C,GAC3C,2MACEnE,KAAK1F,KAAOA,EACZ0F,KAAKkF,IAAMA,EACXlF,KAAKsF,OAAStB,EACdhE,KAAKmF,YAAcA,EACnBnF,KAAKoF,iBAAmBA,EACxBpF,KAAKqF,gBAAkBA,EACvBrF,KAAKmE,KAAOA,EAnCpB,wCA8CI,SAAgBT,GACZ,OAAO,IAAIE,EACPF,EAAKW,KACLX,EAAK6B,IACL7B,EAAKa,aACLb,EAAK8B,YACL9B,EAAK+B,iBACL/B,EAAKgC,gBACLhC,EAAKe,UAtDjB,KA2DaQ,GAAb,gCAUI,WAAY7K,EAAiBC,EAAcgJ,GAAmB,8BAC1D,cAAMjJ,EAASC,IAD2C,oBAE1D,EAAKC,KAAO,6BACZ,EAAK+I,UAAYA,EAHyC,EAVlE,cAAyClJ,I","sources":["webpack://k6-jslib-aws/./node_modules/uuid/index.js","webpack://k6-jslib-aws/./node_modules/uuid/lib/bytesToUuid.js","webpack://k6-jslib-aws/./node_modules/uuid/lib/rng-browser.js","webpack://k6-jslib-aws/./node_modules/uuid/v1.js","webpack://k6-jslib-aws/./node_modules/uuid/v4.js","webpack://k6-jslib-aws/webpack/bootstrap","webpack://k6-jslib-aws/webpack/runtime/compat get default export","webpack://k6-jslib-aws/webpack/runtime/define property getters","webpack://k6-jslib-aws/webpack/runtime/hasOwnProperty shorthand","webpack://k6-jslib-aws/webpack/runtime/make namespace object","webpack://k6-jslib-aws/external commonjs \"k6/crypto\"","webpack://k6-jslib-aws/external commonjs \"k6/html\"","webpack://k6-jslib-aws/./src/internal/error.ts","webpack://k6-jslib-aws/./src/internal/signature.ts","webpack://k6-jslib-aws/./src/internal/config.ts","webpack://k6-jslib-aws/external commonjs \"k6/http\"","webpack://k6-jslib-aws/./src/internal/client.ts","webpack://k6-jslib-aws/./src/internal/s3.ts","webpack://k6-jslib-aws/./src/internal/secrets-manager.ts"],"sourcesContent":["var v1 = require('./v1');\nvar v4 = require('./v4');\n\nvar uuid = v4;\nuuid.v1 = v1;\nuuid.v4 = v4;\n\nmodule.exports = uuid;\n","/**\n * Convert array of 16 byte values to UUID string format of the form:\n * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n */\nvar byteToHex = [];\nfor (var i = 0; i < 256; ++i) {\n byteToHex[i] = (i + 0x100).toString(16).substr(1);\n}\n\nfunction bytesToUuid(buf, offset) {\n var i = offset || 0;\n var bth = byteToHex;\n // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4\n return ([\n bth[buf[i++]], bth[buf[i++]],\n bth[buf[i++]], bth[buf[i++]], '-',\n bth[buf[i++]], bth[buf[i++]], '-',\n bth[buf[i++]], bth[buf[i++]], '-',\n bth[buf[i++]], bth[buf[i++]], '-',\n bth[buf[i++]], bth[buf[i++]],\n bth[buf[i++]], bth[buf[i++]],\n bth[buf[i++]], bth[buf[i++]]\n ]).join('');\n}\n\nmodule.exports = bytesToUuid;\n","// Unique ID creation requires a high quality random # generator. In the\n// browser this is a little complicated due to unknown quality of Math.random()\n// and inconsistent support for the `crypto` API. We do the best we can via\n// feature-detection\n\n// getRandomValues needs to be invoked in a context where \"this\" is a Crypto\n// implementation. Also, find the complete implementation of crypto on IE11.\nvar getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||\n (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));\n\nif (getRandomValues) {\n // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto\n var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef\n\n module.exports = function whatwgRNG() {\n getRandomValues(rnds8);\n return rnds8;\n };\n} else {\n // Math.random()-based (RNG)\n //\n // If all else fails, use Math.random(). It's fast, but is of unspecified\n // quality.\n var rnds = new Array(16);\n\n module.exports = function mathRNG() {\n for (var i = 0, r; i < 16; i++) {\n if ((i & 0x03) === 0) r = Math.random() * 0x100000000;\n rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;\n }\n\n return rnds;\n };\n}\n","var rng = require('./lib/rng');\nvar bytesToUuid = require('./lib/bytesToUuid');\n\n// **`v1()` - Generate time-based UUID**\n//\n// Inspired by https://github.com/LiosK/UUID.js\n// and http://docs.python.org/library/uuid.html\n\nvar _nodeId;\nvar _clockseq;\n\n// Previous uuid creation time\nvar _lastMSecs = 0;\nvar _lastNSecs = 0;\n\n// See https://github.com/uuidjs/uuid for API details\nfunction v1(options, buf, offset) {\n var i = buf && offset || 0;\n var b = buf || [];\n\n options = options || {};\n var node = options.node || _nodeId;\n var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq;\n\n // node and clockseq need to be initialized to random values if they're not\n // specified. We do this lazily to minimize issues related to insufficient\n // system entropy. See #189\n if (node == null || clockseq == null) {\n var seedBytes = rng();\n if (node == null) {\n // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)\n node = _nodeId = [\n seedBytes[0] | 0x01,\n seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]\n ];\n }\n if (clockseq == null) {\n // Per 4.2.2, randomize (14 bit) clockseq\n clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;\n }\n }\n\n // UUID timestamps are 100 nano-second units since the Gregorian epoch,\n // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so\n // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'\n // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.\n var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime();\n\n // Per 4.2.1.2, use count of uuid's generated during the current clock\n // cycle to simulate higher resolution clock\n var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1;\n\n // Time since last uuid creation (in msecs)\n var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;\n\n // Per 4.2.1.2, Bump clockseq on clock regression\n if (dt < 0 && options.clockseq === undefined) {\n clockseq = clockseq + 1 & 0x3fff;\n }\n\n // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new\n // time interval\n if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {\n nsecs = 0;\n }\n\n // Per 4.2.1.2 Throw error if too many uuids are requested\n if (nsecs >= 10000) {\n throw new Error('uuid.v1(): Can\\'t create more than 10M uuids/sec');\n }\n\n _lastMSecs = msecs;\n _lastNSecs = nsecs;\n _clockseq = clockseq;\n\n // Per 4.1.4 - Convert from unix epoch to Gregorian epoch\n msecs += 12219292800000;\n\n // `time_low`\n var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;\n b[i++] = tl >>> 24 & 0xff;\n b[i++] = tl >>> 16 & 0xff;\n b[i++] = tl >>> 8 & 0xff;\n b[i++] = tl & 0xff;\n\n // `time_mid`\n var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;\n b[i++] = tmh >>> 8 & 0xff;\n b[i++] = tmh & 0xff;\n\n // `time_high_and_version`\n b[i++] = tmh >>> 24 & 0xf | 0x10; // include version\n b[i++] = tmh >>> 16 & 0xff;\n\n // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)\n b[i++] = clockseq >>> 8 | 0x80;\n\n // `clock_seq_low`\n b[i++] = clockseq & 0xff;\n\n // `node`\n for (var n = 0; n < 6; ++n) {\n b[i + n] = node[n];\n }\n\n return buf ? buf : bytesToUuid(b);\n}\n\nmodule.exports = v1;\n","var rng = require('./lib/rng');\nvar bytesToUuid = require('./lib/bytesToUuid');\n\nfunction v4(options, buf, offset) {\n var i = buf && offset || 0;\n\n if (typeof(options) == 'string') {\n buf = options === 'binary' ? new Array(16) : null;\n options = null;\n }\n options = options || {};\n\n var rnds = options.random || (options.rng || rng)();\n\n // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n rnds[6] = (rnds[6] & 0x0f) | 0x40;\n rnds[8] = (rnds[8] & 0x3f) | 0x80;\n\n // Copy bytes to buffer, if provided\n if (buf) {\n for (var ii = 0; ii < 16; ++ii) {\n buf[i + ii] = rnds[ii];\n }\n }\n\n return buf || bytesToUuid(rnds);\n}\n\nmodule.exports = v4;\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/crypto\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/html\");","import { parseHTML } from 'k6/html'\n\n/**\n * Base class to derive errors from\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class AWSError extends Error {\n code: string\n\n /**\n * Create an AWSError\n *\n * @param {string} message - A longer human readable error message.\n * @param {string} code - A unique short code representing the error that was emitted\n */\n constructor(message: string, code: string) {\n super(message)\n this.name = 'AWSError'\n this.code = code\n }\n\n /**\n * Parse an AWSError from an XML document\n *\n * @param {string} xmlDocument - Serialized XML document to parse the error from\n */\n static parseXML(xmlDocument: string): AWSError {\n const doc = parseHTML(xmlDocument)\n return new AWSError(doc.find('Message').text(), doc.find('Code').text())\n }\n}\n","import crypto, { hmac, sha256 } from 'k6/crypto'\nimport { HTTPMethod, HTTPHeaders } from './http'\nimport { AWSConfig } from './config'\nimport { AWSError } from './error'\n\n/**\n * Includes AWS v4 signing information to the provided HTTP headers object.\n *\n * This function will compute the `Authorization` header signature for the\n * provided request components, and add it to `header`. It will do so by following\n * the procedure detailled AWS' API docs: https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html\n *\n * The resulting `Authorization` header value is computed for the provided\n * headers object. Thus, any modification of the headers past a call to `signHeaders`\n * would effectively invalidate their signature, and the function should be\n * called again to recompute it.\n *\n * @param {object} headers - HTTP headers request to sign.\n * @param {number} requestTimestamp - Timestamp of the request\n * @param {string} method - HTTP method used\n * @param {string} path - HTTP request URL's path\n * @param {string} queryString - HTTP request URL's querystring\n * @param {string | ArrayBuffer} body - HTTP request's payload\n * @param {AWSConfig} - AWS configuration\n * @param {string} service - AWS service name\n * @param {URIEncodingConfig} - URI encoding configuration\n */\nexport function signHeaders(\n headers: HTTPHeaders,\n requestTimestamp: number,\n method: HTTPMethod,\n path: string,\n queryString: string,\n body: string | ArrayBuffer,\n awsConfig: AWSConfig,\n service: string,\n URIencodingConfig: URIEncodingConfig\n): HTTPHeaders {\n const derivedSigningKey = deriveSigningKey(\n awsConfig.secretAccessKey,\n requestTimestamp,\n awsConfig.region,\n service\n )\n\n const canonicalRequest = createCanonicalRequest(\n method,\n path,\n queryString,\n headers,\n body,\n URIencodingConfig\n )\n\n const stringToSign = createStringToSign(\n requestTimestamp,\n awsConfig.region,\n service,\n sha256(canonicalRequest, 'hex')\n )\n\n const credentialScope = createCredentialScope(requestTimestamp, awsConfig.region, service)\n const signedHeaders = createSignedHeaders(headers)\n const signature = calculateSignature(derivedSigningKey, stringToSign)\n const authorizationHeader = `${HashingAlgorithm} Credential=${awsConfig.accessKeyID}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`\n\n headers['Authorization'] = authorizationHeader\n\n return headers\n}\n\n/**\n * Error indicating an Invalid signature has been sent to AWS services\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class InvalidSignatureError extends AWSError {\n /**\n * Constructs an InvalidSignatureError\n *\n * @param {string} message - human readable error message\n */\n constructor(message: string, code: string) {\n super(message, code)\n this.name = 'InvalidSignatureError'\n }\n}\n\n/**\n * Calculte the signature for AWS signature version 4\n *\n * @param {string} derivedSigningKey - dervied signing key as computed by `deriveSigningKey`\n * @param {string} stringToSign - String to sign as computed by `createStringToSign`\n * @return {string}\n */\nexport function calculateSignature(derivedSigningKey: ArrayBuffer, stringToSign: string): string {\n return hmac('sha256', derivedSigningKey, stringToSign, 'hex')\n}\n/**\n * Derives the signing key for authenticating requests signed with\n * the Signature version 4 authentication protocol.\n *\n * deriveSigningKey produces a signing key by creating a series of\n * hash-based message authentication codes (HMACs) represented in\n * a binary format.\n *\n * The derived signing key is specific to the date it's made at, as well as\n * the service and region it targets.\n *\n * @param {string} secretAccessKey - the AWS secret access key to derive the signing key for\n * @param {number} time - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service. MUST be UTF-8 encoded.\n * @return {string}\n */\nexport function deriveSigningKey(\n secretAccessKey: string,\n time: number,\n region: string,\n service: string\n): ArrayBuffer {\n const kSecret = secretAccessKey\n const date = toDate(time)\n\n // FIXME: hmac takes ArrayBuffer as input, but returns bytes (number[]).\n // How does one convert from one to the other?\n const kDate: any = hmac('sha256', 'AWS4' + kSecret, date, 'binary')\n const kRegion: any = hmac('sha256', kDate, region, 'binary')\n const kService: any = hmac('sha256', kRegion, service, 'binary')\n const kSigning: any = hmac('sha256', kService, 'aws4_request', 'binary')\n\n return kSigning\n}\n\n// Hashing Algorithm to use in the signature process\nexport const HashingAlgorithm = 'AWS4-HMAC-SHA256'\n\n/**\n * Certain services, such as S3, allow for unsigned payloads. If\n * producing a signed canonical request for such service, pass\n * the `UnsignedPayload` constant value as the payload parameter.\n */\nexport const UnsignedPayload = 'UNSIGNED-PAYLOAD'\n\n/**\n * Create the \"string to sign\" part of the signature Version 4 protocol.\n *\n * The \"string to sign\" includes meta information about your request and\n * about the canonical request that you created with `createCanonicalRequest`.\n * It is used hand in hand with the signing key to create the request signature.\n *\n * @param {number} requestTimestamp - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service name. MUST be UTF-8 encoded.\n * @param {string} hashedCanonicalRequest - canonical request as produced by calling the createCanonicalRequest function,\n * hashed using the SHA256 algorithm (encoded in hexadecimal format).\n * @return {string}\n */\nexport function createStringToSign(\n requestTimestamp: number,\n region: string,\n service: string,\n hashedCanonicalRequest: string\n): string {\n // the request date specified in ISO8601 format: YYYYMMDD'T'HHMMSS'Z'\n const requestDateTime = toTime(requestTimestamp)\n\n // The credential scope value, consisting of the date in YYYYMMDD format,\n // the targeted region, the targeted service, and a termination string.\n // Note that the region and service MUST be UTF-8 encoded.\n const credentialScope = createCredentialScope(requestTimestamp, region, service)\n\n const stringToSign = [\n // Algorithm\n HashingAlgorithm,\n\n // RequestDateTime\n requestDateTime,\n\n // CredentialScope\n credentialScope,\n\n // HashedCanonicalRequest\n hashedCanonicalRequest,\n ].join('\\n')\n\n return stringToSign\n}\n\n/**\n *\n * Helper function creating a credential scope string to use in the signature\n * version 4 process. A credential scope consists of the date of the request\n * in YYYYMMDD format, the targeted region, the targeted service, and a\n * termination string.\n *\n * Note that the region and service MUST be UTF-8 encoded.\n *\n * @param {number} requestTimestamp - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service name. MUST be UTF-8 encoded.\n * @return {string}\n */\nexport function createCredentialScope(\n requestTimestamp: number,\n region: string,\n service: string\n): string {\n return [toDate(requestTimestamp), region, service, 'aws4_request'].join('/')\n}\n\n/**\n * Create a string that includes information from your request\n * in a AWS signature v4 standardized (canonical) format.\n *\n * @param {string} method - the HTTP request method\n * @param {string} uri - URI-encoded version of the absolute path component of the URI\n * @param {string} query - request's query string\n * @param {Object} headers - all the HTTP headers that you wish to include with the signed request\n * @param {string | ArrayBuffer} payload - payload to include as the body of the request\n * @param {URIEncodingConfig} URIencodingConfig- URI encoding configuration\n * @return {string}\n */\nexport function createCanonicalRequest(\n method: HTTPMethod,\n uri: string,\n query: string,\n headers: HTTPHeaders,\n payload: string | ArrayBuffer,\n URIencodingConfig: URIEncodingConfig\n): string {\n const httpRequestMethod = method.toUpperCase()\n const canonicalURI = createCanonicalURI(uri, URIencodingConfig)\n const canonicalQueryString = createCanonicalQueryString(query)\n const canonicalHeaders = createCanonicalHeaders(headers)\n const signedHeaders = createSignedHeaders(headers)\n const requestPayload = createCanonicalPayload(payload)\n\n const canonicalRequest = [\n httpRequestMethod,\n canonicalURI,\n canonicalQueryString,\n canonicalHeaders,\n signedHeaders,\n requestPayload,\n ].join('\\n')\n\n return canonicalRequest\n}\n\n/**\n * Creates the (canonical) URI-encoded version of the\n * absolute path component of the URI: everything in the URI\n * from the HTTP host to the question mark character (\"?\")\n * that begins the query string parameters (if any).\n *\n * @param {string} uri - URI to canonize\n * @param {URIEncodingConfig} - URI encoding configuration\n * @return {string} - canonical URL\n */\nexport function createCanonicalURI(uri: string, URIencodingConfig: URIEncodingConfig): string {\n if (uri == '/') {\n return uri\n }\n\n let canonicalURI = uri\n if (uri[uri.length - 1] == '/' && canonicalURI[canonicalURI.length - 1] != '/') {\n canonicalURI += '/'\n }\n\n canonicalURI = URIEncode(canonicalURI, URIencodingConfig.path)\n\n return URIencodingConfig.double ? URIEncode(canonicalURI, URIencodingConfig.path) : canonicalURI\n}\n\n// FIXME: does it work as expected?\n/**\n * Creates the canonical form of the request's query\n * string. If the request does not include a query string,\n * provide an empty string.\n *\n * @param {String | Object} qs - query string to canonize\n * @return {string}\n */\nexport function createCanonicalQueryString(qs: string): string {\n if (qs === '') {\n return ''\n }\n\n // const intermediary: { [key: string]: string } = parseQueryString(qs)\n\n // return Object.keys(intermediary)\n // .sort()\n // .map((key: string) => {\n // // const values: string[] = Array.isArray(intermediary[key])\n // // ? intermediary[key]\n // // : [intermediary[key]]\n // const values = intermediary[key]\n\n // return values\n // .sort()\n // .map((val: string) => encodeURIComponent(key) + '=' + encodeURIComponent(val))\n // .join('&')\n // })\n // .join('&')\n\n return parseQueryString(qs)\n .map(([key, value]: [string, string]): string => {\n return encodeURIComponent(key) + '=' + encodeURIComponent(value)\n })\n .join('&')\n}\n/**\n * Create the canonical form of the request's headers.\n * Canonical headers consist of all the HTTP headers you\n * are including with the signed request.\n *\n * Note that:\n * * for HTTP/1.1 requests, the headers should at least\n * contain the `host` header.\n * * for HTTP/2, the `:authority` header must be used instead\n * of `host`.\n *\n * @param {Object} headers\n * @return {string}\n */\nexport function createCanonicalHeaders(headers: HTTPHeaders) {\n if (headers.constructor !== Object || Object.entries(headers).length === 0) {\n return ''\n }\n\n const canonicalHeaders = Object.entries(headers)\n .map(([name, values]) => {\n const canonicalName = name.toLowerCase().trim()\n const normalizedValues = Array.isArray(values) ? values : [values]\n\n // Note that we do not need to sort values\n const canonicalValues = normalizedValues\n .map((v) => {\n // convert sequential spaces to a single space\n return v.replace(/\\s+/g, ' ').replace(/^\\s+|\\s+$/g, '')\n })\n .join(',') // standard for multiple values in a HTTP header\n\n return canonicalName + ':' + canonicalValues + '\\n'\n })\n .sort()\n .join('')\n\n return canonicalHeaders\n}\n\n/**\n * Create the canonical request's signed headers.\n *\n * The signed headers part of the request contains the\n * list of headers included in the request's signing process.\n *\n * Note that:\n * * for HTTP/1.1 requests, the `host` header must be included.\n * * for HTTP/2 requests, the `:authority` header must be included instead\n * of host.\n * * if used, the `x-amz-date` header must be included.\n *\n * @param {Object} headers\n * @return {string}\n * @throws {TypeError} - on headers not being an Object, or being empty.\n */\nexport function createSignedHeaders(headers: { [key: string]: string }) {\n if (headers.constructor !== Object) {\n throw new TypeError('headers should be an object')\n }\n\n if (Object.entries(headers).length === 0) {\n throw 'headers should at least contain either the Host (HTTP 1.1) or :authority (HTTP 2) parameter'\n }\n\n // To create the signed headers list, convert\n // all header names to lowercase, sort them by\n // character code, and use a semicolon to separate\n // the header names.\n const result = Object.keys(headers)\n .map((name) => name.toLowerCase().trim())\n .sort()\n .join(';')\n\n return result\n}\n\n/**\n * Create the canonical form of the request's payload.\n *\n * The canonical payload consists in a lowercased, hex encoded,\n * SHA256 hash of the requests body/payload.\n *\n * Certain services, such as S3, allow for unsigned payload. If\n * producing a signed canonical request for such service, pass\n * the `UnsignedPayload` constant value as the payload parameter.\n *\n * @param {String | ArrayBuffer} payload\n * @return {string}\n */\nexport function createCanonicalPayload(payload: string | ArrayBuffer) {\n if (payload === UnsignedPayload) {\n return payload\n }\n\n // Note that if the paylaod is null, we convert it\n // to an empty string.\n // TODO: Should switching to empty string if null impact headers?\n return crypto.sha256(payload || '', 'hex').toLowerCase()\n}\n\n/**\n * URIEncodes encodes every bytes of a URI to be URL-safe.\n *\n * This implementation is specific to AWS; who intended to make it as\n * close as possible to the underlying RFC 3946. It:\n * * URI encode every byte except the unreserved characters: 'A'-'Z', 'a'-'z', '0'-'9',\n * '-', '.', '_', and '~'.\n * * considers the space character as a reserved character and must URI encodes\n * encodes it as \"%20\" (and not as \"+\").\n * * URI encodes every byte by prefixing with '%' the two-digit hexadecimal value of the byte.\n * * If the `path` argument is set, forward slashes are not encoded, to fit with\n * S3 requirements.\n *\n * N.B: this implementation differs with ES6' mainly in that it does\n * encode the \"'\" character.\n *\n * Based on AWS implementation: https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-core/src/main/java/com/amazonaws/util/SdkHttpUtils.java#L66\n * Encoding specs: https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html\n *\n * @param {string} uri - uri to encode\n * @param {boolean} path - slash characters should be encoded everywhere,\n * but in paths, set to false when encoding a path\n * @return {string} the URI encoded result\n */\nexport function URIEncode(uri: string, path: boolean): string {\n if (uri == '') {\n return uri\n }\n\n return uri\n .split('') // to be able to map over a string, because... javascript...\n .map((letter: string) => {\n if (isAlpha(letter) || isNumeric(letter) || '-._~'.includes(letter)) {\n return letter\n }\n\n // Space should be explicitly encoded to as %20.\n if (letter == ' ') {\n return '%20'\n }\n\n // If the URI is a path, the forward slash shouldn't\n // be encoded.\n if (letter == '/' && path) {\n return '/'\n }\n\n return '%' + letter.charCodeAt(0).toString(16).toUpperCase()\n })\n .join('')\n}\n\n/**\n * Class holding URI encoding configuration\n */\nexport class URIEncodingConfig {\n double: boolean\n path: boolean\n\n /**\n *\n * @param {boolean} double - should the URI be double encoded?\n * @param {boolean} path - is the URI a path? If so, its forward\n * slashes won't be URIencoded.\n */\n constructor(double: boolean, path: boolean) {\n this.double = double\n this.path = path\n }\n}\n\n/**\n * Compute the request time value as specified by the ISO8601\n * format: YYYYMMDD'T'HHMMSS'Z'\n *\n * @param {number} timestamp\n * @return {string}\n */\nexport function toTime(timestamp: number): string {\n return new Date(timestamp).toISOString().replace(/[:\\-]|\\.\\d{3}/g, '')\n}\n/**\n * Computethe request date value in the format: YYYMMDD\n *\n * @param {number} timestamp\n * @return {string}\n */\nexport function toDate(timestamp: number): string {\n return toTime(timestamp).substring(0, 8)\n}\n\n// FIXME: does it work as expected?\n/**\n * Parse a HTTP request URL's querystring into an object\n * containing its `key=value` pairs.\n *\n * @param {string} qs\n * @return {object}\n */\nexport function parseQueryString(qs: string): Array<[string, string]> {\n if (qs.length === 0) {\n return []\n }\n\n return qs\n .split('&')\n .filter((e) => e)\n .map((v: string): [string, string] => {\n const parts = v.split('=', 2) as [string, string]\n return [decodeURIComponent(parts[0]), decodeURIComponent(parts[1])]\n })\n .sort((a: [string, string], b: [string, string]) => {\n return a[0].localeCompare(b[0])\n })\n}\n\nfunction isAlpha(c: string): boolean {\n return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')\n}\n\nfunction isNumeric(c: string): boolean {\n return c >= '0' && c <= '9'\n}\n\n// FIXME: finish implementation when needed\n// See the following for more details:\n// * https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html\n// * https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html\n// export function signQueryString(\n// queryString,\n// requestTimestamp,\n// accessKeyID,\n// secretAccessKey,\n// region,\n// service,\n// ttl, // in seconds\n// headers,\n// doubleURIEncoding = true\n// ) {\n// const credential = [accessKeyID, toDate(requestTimestamp), region, service].join('/')\n//\n// const canonicalRequest = createCanonicalRequest(\n// method,\n// path,\n// queryString,\n// headers,\n// body,\n// doubleURIEncoding\n// )\n//\n// const derivedSigningKey = deriveSigningKey(secretAccessKey, requestTimestamp, region, service)\n//\n// const stringToSign = createStringToSign(\n// requestTimestamp,\n// region,\n// service,\n// sha256(canonicalRequest, 'hex')\n// )\n//\n// const signedHeaders = createSignedHeaders(headers)\n// const signature = calculateSignature(derivedSigningKey, stringToSign)\n//\n// return [\n// `X-Amz-Algorithm=${HashingAlgorithm}`,\n// `X-Amz-Credential=${crediental}`,\n// `X-Amz-Date=${toTime(requestTimestamp)}`,\n// `X-Amz-Expires=${ttl}`,\n// `X-Amz-SignedHeaders=${signedHeaders}`,\n// `X-Amz-Signature=${signature}`,\n//`X-Amz-Security-Token=`, // TODO: optional\n// ].join('&')\n// }\n","/** Class holding an AWS connection information */\nexport class AWSConfig {\n region: string\n accessKeyID: string\n secretAccessKey: string\n\n /**\n * Create an AWSConfig.\n *\n * @param {string} region - the AWS region to connect to, as listed: https://docs.aws.amazon.com/general/latest/gr/rande.html\n * @param {string} accessKeyID - Your user's AWS access key id credential\n * @param {string} secretAccessKey - Your user's AWS secret access key credential\n * @throws {InvalidArgumentException}\n */\n constructor(region: string, accessKeyID: string, secretAccessKey: string) {\n if (typeof region !== 'string' || region === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS region; reason: should be a non empty string'\n )\n }\n\n if (typeof accessKeyID !== 'string' || accessKeyID === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS access key ID; reason: should be a non empty string'\n )\n }\n\n if (typeof secretAccessKey !== 'string' || secretAccessKey === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS secret access key; reason: should be a non empty string'\n )\n }\n\n this.region = region\n this.accessKeyID = accessKeyID\n this.secretAccessKey = secretAccessKey\n }\n}\n\n/** Class representing an invalid AWS configuration */\nexport class InvalidAWSConfigError extends Error {\n constructor(message: string) {\n super(message)\n }\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/http\");","import { HTTPMethod, HTTPHeaders } from './http'\nimport { AWSConfig } from './config'\nimport { signHeaders, URIEncodingConfig, toTime } from './signature'\n\n/**\n * Class allowing to build requests targeting AWS APIs\n *\n * This class is meant to be used as a base class for specific\n * services clients. See S3Client or SecretsManagerClient for\n * usage examples.\n */\nexport class AWSClient {\n awsConfig: AWSConfig\n serviceName: string\n URIencodingConfig: URIEncodingConfig\n\n /**\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n * @param {string} serviceName - name of the service to target.\n * @param {URIEncodingConfig} URIencodingConfig - configures how requests URIs should be encoded.\n */\n constructor(awsConfig: AWSConfig, serviceName: string, URIencodingConfig: URIEncodingConfig) {\n this.awsConfig = awsConfig\n this.serviceName = serviceName\n this.URIencodingConfig = URIencodingConfig\n }\n\n buildRequest(\n method: HTTPMethod,\n host: string,\n path: string,\n queryString: string,\n body: string | ArrayBuffer,\n headers: HTTPHeaders\n ): AWSRequest {\n const requestTimestamp: number = Date.now()\n const date: string = toTime(requestTimestamp)\n\n headers['Host'] = host\n headers['X-Amz-Date'] = date\n\n headers = signHeaders(\n // headers\n headers,\n\n // requestTimestamp\n requestTimestamp,\n\n // method\n method,\n\n // path\n path,\n\n // querystring\n queryString,\n\n // body\n body,\n\n // AWS configuration\n this.awsConfig,\n\n // AwS target service name\n this.serviceName,\n\n // doubleEncoding: S3 does single-encoding of the uri component\n // pathURIEncoding: S3 manipulates object keys, and forward slashes\n // shouldn't be URI encoded\n this.URIencodingConfig\n )\n\n // '?' should not be part of the querystring when we sign the headers\n path = path !== '' ? path : '/'\n let url = `https://${host}${path}`\n if (queryString !== '') {\n url += `?${queryString}`\n }\n\n return { url: url, headers: headers }\n }\n}\n\n/**\n * Type alias representing the result of an AWSClient.buildRequest call\n */\nexport interface AWSRequest {\n url: string\n headers: HTTPHeaders\n}\n","import { bytes } from 'k6'\nimport http from 'k6/http'\nimport { parseHTML } from 'k6/html'\nimport { sha256 } from 'k6/crypto'\n\nimport { InvalidSignatureError, URIEncodingConfig } from './signature'\nimport { AWSClient, AWSRequest } from './client'\nimport { AWSError } from './error'\nimport { AWSConfig } from './config'\n\n/** Class allowing to interact with Amazon AWS's S3 service */\nexport class S3Client extends AWSClient {\n /**\n * Create a S3Client\n *\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n */\n constructor(awsConfig: AWSConfig) {\n const URIencodingConfig = new URIEncodingConfig(false, true)\n super(awsConfig, 's3', URIencodingConfig)\n }\n\n /**\n * Returns a list of all buckets owned by the authenticated sender of the request.\n * To use this operation, you must have the s3:ListAllMyBuckets permission.\n *\n * @return {Array.} buckets - An array of objects describing S3 buckets\n * with the following fields: name, and creationDate.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n listBuckets(): Array {\n // Prepare request\n const method = 'GET'\n const host = `${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(method, host, '/', '', body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n let buckets: Array = []\n\n const doc = parseHTML(res.body as string)\n\n doc.find('Buckets')\n .children()\n .each((_, bucketDefinition) => {\n let bucket = {}\n\n bucketDefinition.children().forEach((child) => {\n switch (child.nodeName()) {\n case 'name':\n Object.assign(bucket, { name: child.textContent() })\n break\n case 'creationdate':\n Object.assign(bucket, {\n creationDate: Date.parse(child.textContent()),\n })\n }\n })\n\n buckets.push(bucket as S3Bucket)\n })\n\n return buckets\n }\n\n /**\n * Returns some or all (up to 1,000) of the objects in a bucket.\n *\n * @param {string} bucketName - Bucket name to list.\n * @param {string?} prefix='' - Limits the response to keys that begin with the specified prefix.\n * @return {Array.} - returns an array of objects describing S3 objects\n * with the following fields: key, lastModified, etag, size and storageClass.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n listObjects(bucketName: string, prefix?: string): Array {\n // Prepare request\n const method = 'GET'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const body = ''\n const querystring = `list-type=2&prefix=${prefix}`\n const signedRequest: AWSRequest = super.buildRequest(method, host, '/', querystring, body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n Prefix: prefix ?? '',\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n let objects: Array = []\n\n // Extract the objects definition from\n // the XML response\n parseHTML(res.body as string)\n .find('Contents')\n .each((_, objectDefinition) => {\n let obj = {}\n\n objectDefinition.children().forEach((child) => {\n switch (child.nodeName()) {\n case 'key':\n Object.assign(obj, { key: child.textContent() })\n break\n case 'lastmodified':\n Object.assign(obj, { lastModified: Date.parse(child.textContent()) })\n break\n case 'etag':\n Object.assign(obj, { etag: child.textContent() })\n break\n case 'size':\n Object.assign(obj, { size: parseInt(child.textContent()) })\n break\n case 'storageclass':\n Object.assign(obj, { storageClass: child.textContent() })\n }\n })\n\n objects.push(obj as S3Object)\n })\n\n return objects\n }\n /**\n * Retrieves an Object from Amazon S3.\n *\n * To use getObject, you must have `READ` access to the object.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to get.\n * @return {S3Object} - returns the content of the fetched S3 Object.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n getObject(bucketName: string, objectKey: string): S3Object {\n // Prepare request\n const method = 'GET'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(method, host, path, '', body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n return new S3Object(\n objectKey,\n Date.parse(res.headers['Last-Modified']),\n res.headers['ETag'],\n parseInt(res.headers['Content-Length']),\n undefined, // FIXME: GetObject response doesn't contain the storage class\n res.body\n )\n }\n /**\n * Adds an object to a bucket.\n *\n * You must have WRITE permissions on a bucket to add an object to it.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to put.\n * @param {string | ArrayBuffer} data - the content of the S3 Object to upload.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n putObject(bucketName: string, objectKey: string, data: string | ArrayBuffer) {\n // Prepare request\n const method = 'PUT'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const queryString = ''\n const body = data\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n path,\n queryString,\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n }\n\n /**\n * Removes the null version (if there is one) of an object and inserts a delete marker,\n * which becomes the latest version of the object.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to delete.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n deleteObject(bucketName: string, objectKey: string): void {\n // Prepare request\n const method = 'DELETE'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const queryString = ''\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n path,\n queryString,\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n }\n\n // FIXME: remove dependency to `error_message`\n // FIXME: just pass it the response?\n _handle_error(error_code: number, error_message: string, error_body: string) {\n if (error_message == '' || error_code === 0) {\n return\n }\n\n // FIXME: should be error_code === 1301 instead\n // See: https://github.com/grafana/k6/issues/2474\n // See: https://github.com/golang/go/issues/49281\n if (error_message && error_message.startsWith('301')) {\n // Bucket not found\n throw new S3ServiceError('Resource not found', 'ResourceNotFound', 'getObject')\n }\n\n const awsError = AWSError.parseXML(error_body)\n switch (awsError.code) {\n case 'AuthorizationHeaderMalformed':\n throw new InvalidSignatureError(awsError.message, awsError.code)\n default:\n throw new S3ServiceError(awsError.message, awsError.code, 'listObjects')\n }\n }\n}\n\n// TODO: use interface instead?\n/** Class representing a S3 Bucket */\nexport class S3Bucket {\n name: string\n creationDate: Date\n\n /**\n * Create an S3 Bucket\n *\n * @param {string} name - S3 bucket's name\n * @param {Date} creationDate - S3 bucket's creation date\n */\n constructor(name: string, creationDate: Date) {\n this.name = name\n this.creationDate = creationDate\n }\n}\n\n// TODO: use interface instead?\n/** Class representing an S3 Object */\nexport class S3Object {\n key: string\n lastModified: number\n etag: string\n size: number\n storageClass: StorageClass\n data?: string | bytes | null\n\n /**\n * Create an S3 Object\n *\n * @param {string} key - S3 object's key\n * @param {Date} lastModified - S3 object last modification date\n * @param {string} etag - S3 object's etag\n * @param {number} size - S3 object's size\n * @param {StorageClass} storageClass - S3 object's storage class\n * @param {string | bytes | null} data=null - S3 Object's data\n */\n constructor(\n key: string,\n lastModified: number,\n etag: string,\n size: number,\n storageClass: StorageClass,\n data?: string | bytes | null\n ) {\n this.key = key\n this.lastModified = lastModified\n this.etag = etag\n this.size = size\n this.storageClass = storageClass\n this.data = data\n }\n}\n\n/**\n * Error indicating a S3 operation failed\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class S3ServiceError extends AWSError {\n operation: string\n\n /**\n * Constructs a S3ServiceError\n *\n * @param {string} message - human readable error message\n * @param {string} code - A unique short code representing the error that was emitted\n * @param {string} operation - Name of the failed Operation\n */\n constructor(message: string, code: string, operation: string) {\n super(message, code)\n this.name = 'S3ServiceError'\n this.operation = operation\n }\n}\n\n/**\n * Describes the class of storage used to store a S3 object.\n */\ntype StorageClass =\n | 'STANDARD'\n | 'REDUCED_REDUNDANCY'\n | 'GLACIER'\n | 'STANDARD_IA'\n | 'INTELLIGENT_TIERING'\n | 'DEEP_ARCHIVE'\n | 'OUTPOSTS'\n | 'GLACIER_IR'\n | undefined\n","import { JSONArray, JSONObject } from 'k6'\nimport http, { RefinedResponse, ResponseType } from 'k6/http'\n\nimport { AWSClient, AWSRequest } from './client'\nimport { AWSError } from './error'\nimport { AWSConfig } from './config'\nimport { InvalidSignatureError, URIEncodingConfig } from './signature'\nimport { v4 as uuidv4 } from 'uuid'\nimport { HTTPMethod, HTTPHeaders } from './http'\n\n/**\n * Class allowing to interact with Amazon AWS's SecretsManager service\n */\nexport class SecretsManagerClient extends AWSClient {\n method: HTTPMethod\n commonHeaders: HTTPHeaders\n\n /**\n * Create a SecretsManagerClient\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n */\n constructor(awsConfig: AWSConfig) {\n const URIencodingConfig = new URIEncodingConfig(true, false)\n super(awsConfig, 'secretsmanager', URIencodingConfig)\n\n // this.serviceName = 'secretsmanager'\n\n // All interactions with the Secrets Manager service\n // are made via the GET or POST method.\n this.method = 'POST'\n\n this.commonHeaders = {\n 'Accept-Encoding': 'identity',\n 'Content-Type': 'application/x-amz-json-1.1',\n }\n }\n\n /**\n * Returns a list of all secrets owned by the authenticated sender of the request.\n * To use this operation, you must have the secretsmanager:ListSecrets permission.\n *\n * @return {Array.} secrets - An array of objects describing Secret Manager's secrets\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n listSecrets(): Array {\n const body = JSON.stringify({})\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.ListSecrets`,\n }\n )\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('ListSecrets', res)\n const json: JSONArray = res.json('SecretList') as JSONArray\n\n return json.map((s) => Secret.fromJSON(s as JSONObject))\n }\n\n /**\n * Retrieves a secret from Amazon Sercets Manager\n *\n * @param {string} secretID - The ARN or name of the secret to retrieve.\n * @returns {Secret} - returns the content of the fetched Secret object.\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n getSecret(secretID: string): Secret | undefined {\n const body = JSON.stringify({ SecretId: secretID })\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.GetSecretValue`,\n }\n )\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('GetSecretValue', res)\n\n return Secret.fromJSON(res.json() as JSONObject)\n }\n\n /**\n * Creates a new secret\n *\n * Note that this method only supports string-based values at the moment.\n *\n * @param {string} name - The name of the new secret.\n * The secret name can contain ASCII letters, numbers, and the following characters: /_+=.@\n * @param {string} secretString - The text data to encrypt and store in this new version of the secret.\n * @param {string} description - The description of the secret.\n * @param {string} versionID=null - Version of the secret. This value helps ensure idempotency.\n * As a default, if no versionID is provided, one will be created for you using the UUID v4\n * algorithm.\n * @param {Array.} tags=[] - A list of tags to attach to the secret. Each tag is a key and\n * value pair of strings in a JSON text string. Note that tag key names are case sensitive.\n * @returns {Secret} - returns the created secret\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n createSecret(\n name: string,\n secretString: string,\n description: string,\n versionID?: string,\n tags?: Array\n ): Secret {\n versionID = versionID || uuidv4()\n\n const body = JSON.stringify({\n Name: name,\n Description: description,\n SecretString: secretString,\n ClientRequestToken: versionID,\n Tags: tags,\n })\n\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.CreateSecret`,\n }\n )\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n // headers['X-Amz-Target'] = `${this.serviceName}.CreateSecret`\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('CreateSecret', res)\n\n return Secret.fromJSON(res.json() as JSONObject)\n }\n /**\n * Update a secret's value.\n *\n * Note that this method only support string-based values at the moment.\n *\n * @param {string} secretID - The ARN or name of the secret to update.\n * @param {string} secretString - The text data to encrypt and store in this new version of the secret.\n * @param {} versionID=null - A unique identifier for the new version of the secret. This value helps ensure idempotency.\n * As a default, if no versionID is provided, one will be created for you using the UUID v4\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n putSecretValue(secretID: string, secretString: string, versionID?: string): Secret {\n versionID = versionID || uuidv4()\n\n const body = JSON.stringify({\n SecretId: secretID,\n SecretString: secretString,\n ClientRequestToken: versionID,\n })\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.PutSecretValue`,\n }\n )\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('PutSecretValue', res)\n\n return Secret.fromJSON(res.json() as JSONObject)\n }\n\n /**\n * Deletes a secret and all of its versions.\n *\n * You can specify a recovery window during which you can restore the secret.\n * The minimum recovery window is 7 days. The default recovery window is 30 days.\n *\n * @param {string} secretID - The ARN or name of the secret to delete.\n * @param {number} recoveryWindow - The number of days from 7 to 30 that Secrets Manager\n * waits before permanently deleting the secret.\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n deleteSecret(\n secretID: string,\n { recoveryWindow = 30, noRecovery = false }: { recoveryWindow: number; noRecovery: boolean }\n ) {\n const payload: { [key: string]: string | boolean | number } = {\n SecretId: secretID,\n }\n\n // noRecovery and recoveryWindow are exclusive parameters\n if (noRecovery === true) {\n payload['ForceDeleteWithoutRecovery'] = true\n } else {\n payload['RecoveryWindowInDays'] = recoveryWindow\n }\n\n const body = JSON.stringify(payload)\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.DeleteSecret`,\n }\n )\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('DeleteSecret', res)\n }\n\n get host() {\n return `${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n }\n\n // TODO: operation should be an enum\n _handle_error(operation: string, response: RefinedResponse) {\n const errorCode = response.error_code\n if (errorCode === 0) {\n return\n }\n\n const error = response.json() as JSONObject\n if (errorCode >= 1400 && errorCode <= 1499) {\n // In the event of certain errors, the message is not set.\n // Also, note the inconsistency in casing...\n const errorMessage: string =\n (error.Message as string) || (error.message as string) || (error.__type as string)\n\n // Handle specifically the case of an invalid signature\n if (error.__type === 'InvalidSignatureException') {\n throw new InvalidSignatureError(errorMessage, error.__type)\n }\n\n // Otherwise throw a standard service error\n throw new SecretsManagerError(errorMessage, error.__type as string, operation)\n }\n\n if (errorCode === 1500) {\n throw new SecretsManagerError(\n 'An error occured on the server side',\n 'InternalServiceError',\n operation\n )\n }\n }\n}\n\n// TODO: create a Tags type\n\n/**\n * Class representing a Secret Manager's secret\n */\nexport class Secret {\n name: string\n arn: string\n secret: string\n createdDate: number\n lastAccessedDate: number\n lastChangedDate: number\n tags: Array<{ [key: string]: string }>\n\n /**\n * Constructs a Secret Manager's Secret\n *\n * @param {string} name - The friendly name of the secret.\n * @param {string} arn - The ARN of the secret.\n * @param {number} createdDate - The date and time that this version of the secret was created.\n * @param {number} lastAccessedDate - The last date that this secret was accessed. This value is\n * truncated to midnight of the date and therefore shows only the date, not the time.\n * @param {number} lastChangedDate - The last date and time that this secret was modified in any way.\n * @param {Array.} tags - The list of user-defined tags associated with the secret.\n */\n constructor(\n name: string,\n arn: string,\n secretString: string,\n createdDate: number,\n lastAccessedDate: number,\n lastChangedDate: number,\n tags: Array<{ [key: string]: string }> = []\n ) {\n this.name = name\n this.arn = arn\n this.secret = secretString\n this.createdDate = createdDate\n this.lastAccessedDate = lastAccessedDate\n this.lastChangedDate = lastChangedDate\n this.tags = tags\n }\n\n /**\n * Parses and constructs a Secret Manager's Secret from the content\n * of a JSON response returned by the AWS service\n *\n * @param {Object} json - JSON object as returned and parsed from\n * the AWS service's API call.\n * @returns {Secret}\n */\n static fromJSON(json: JSONObject) {\n return new Secret(\n json.Name as string,\n json.ARN as string,\n json.SecretString as string,\n json.CreatedDate as number,\n json.LastAccessedDate as number,\n json.LastChangedDate as number,\n json.Tags as Array<{ [key: string]: string }>\n )\n }\n}\n\nexport class SecretsManagerError extends AWSError {\n operation: string\n\n /**\n * Constructs a SecretsManagerError\n *\n * @param {string} message - human readable error message\n * @param {string} code - A unique short code representing the error that was emitted\n * @param {string} operation - Name of the failed Operation\n */\n constructor(message: string, code: string, operation: string) {\n super(message, code)\n this.name = 'SecretsManagerServiceError'\n this.operation = operation\n }\n}\n"],"names":["v1","v4","uuid","module","exports","byteToHex","i","toString","substr","buf","offset","bth","join","getRandomValues","crypto","bind","window","msCrypto","rnds8","Uint8Array","rnds","Array","r","Math","random","_nodeId","_clockseq","rng","bytesToUuid","_lastMSecs","_lastNSecs","options","b","node","clockseq","undefined","seedBytes","msecs","Date","getTime","nsecs","dt","Error","tl","tmh","n","ii","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","__webpack_modules__","getter","__esModule","d","a","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","require","AWSError","message","code","name","xmlDocument","doc","parseHTML","find","text","signHeaders","headers","requestTimestamp","method","path","queryString","body","awsConfig","service","URIencodingConfig","derivedSigningKey","secretAccessKey","time","region","kSecret","date","toDate","kDate","hmac","kRegion","kService","deriveSigningKey","canonicalRequest","uri","query","payload","httpRequestMethod","toUpperCase","canonicalURI","length","URIEncode","createCanonicalURI","canonicalQueryString","qs","split","filter","e","map","v","parts","decodeURIComponent","sort","localeCompare","parseQueryString","encodeURIComponent","createCanonicalQueryString","canonicalHeaders","constructor","entries","values","toLowerCase","trim","isArray","replace","createCanonicalHeaders","signedHeaders","createSignedHeaders","requestPayload","UnsignedPayload","createCanonicalPayload","createCanonicalRequest","stringToSign","hashedCanonicalRequest","requestDateTime","toTime","credentialScope","createCredentialScope","HashingAlgorithm","createStringToSign","sha256","signature","calculateSignature","authorizationHeader","accessKeyID","InvalidSignatureError","TypeError","keys","letter","c","isNumeric","includes","charCodeAt","URIEncodingConfig","double","this","timestamp","toISOString","substring","AWSConfig","InvalidAWSConfigError","AWSClient","serviceName","host","now","url","S3Client","signedRequest","res","http","_handle_error","error_code","error","buckets","children","each","_","bucketDefinition","bucket","forEach","child","nodeName","assign","textContent","creationDate","parse","push","bucketName","prefix","querystring","Prefix","objects","objectDefinition","lastModified","etag","size","parseInt","storageClass","objectKey","S3Object","data","error_message","error_body","startsWith","S3ServiceError","awsError","parseXML","S3Bucket","operation","SecretsManagerClient","commonHeaders","JSON","stringify","json","s","Secret","fromJSON","secretID","SecretId","secretString","description","versionID","tags","uuidv4","Name","Description","SecretString","ClientRequestToken","Tags","recoveryWindow","noRecovery","response","errorCode","errorMessage","Message","__type","SecretsManagerError","arn","createdDate","lastAccessedDate","lastChangedDate","secret","ARN","CreatedDate","LastAccessedDate","LastChangedDate"],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"aws.min.js","mappings":"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","sources":["webpack://k6-jslib-aws/./node_modules/uuid/index.js","webpack://k6-jslib-aws/./node_modules/uuid/lib/bytesToUuid.js","webpack://k6-jslib-aws/./node_modules/uuid/lib/rng-browser.js","webpack://k6-jslib-aws/./node_modules/uuid/v1.js","webpack://k6-jslib-aws/./node_modules/uuid/v4.js","webpack://k6-jslib-aws/webpack/bootstrap","webpack://k6-jslib-aws/webpack/runtime/compat get default export","webpack://k6-jslib-aws/webpack/runtime/define property getters","webpack://k6-jslib-aws/webpack/runtime/hasOwnProperty shorthand","webpack://k6-jslib-aws/webpack/runtime/make namespace object","webpack://k6-jslib-aws/external commonjs \"k6/crypto\"","webpack://k6-jslib-aws/external commonjs \"k6/html\"","webpack://k6-jslib-aws/./src/internal/error.ts","webpack://k6-jslib-aws/./src/internal/signature.ts","webpack://k6-jslib-aws/./src/internal/config.ts","webpack://k6-jslib-aws/external commonjs \"k6/http\"","webpack://k6-jslib-aws/./src/internal/client.ts","webpack://k6-jslib-aws/./src/internal/s3.ts","webpack://k6-jslib-aws/./src/internal/secrets-manager.ts"],"sourcesContent":["var v1 = require('./v1');\nvar v4 = require('./v4');\n\nvar uuid = v4;\nuuid.v1 = v1;\nuuid.v4 = v4;\n\nmodule.exports = uuid;\n","/**\n * Convert array of 16 byte values to UUID string format of the form:\n * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n */\nvar byteToHex = [];\nfor (var i = 0; i < 256; ++i) {\n byteToHex[i] = (i + 0x100).toString(16).substr(1);\n}\n\nfunction bytesToUuid(buf, offset) {\n var i = offset || 0;\n var bth = byteToHex;\n // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4\n return ([\n bth[buf[i++]], bth[buf[i++]],\n bth[buf[i++]], bth[buf[i++]], '-',\n bth[buf[i++]], bth[buf[i++]], '-',\n bth[buf[i++]], bth[buf[i++]], '-',\n bth[buf[i++]], bth[buf[i++]], '-',\n bth[buf[i++]], bth[buf[i++]],\n bth[buf[i++]], bth[buf[i++]],\n bth[buf[i++]], bth[buf[i++]]\n ]).join('');\n}\n\nmodule.exports = bytesToUuid;\n","// Unique ID creation requires a high quality random # generator. In the\n// browser this is a little complicated due to unknown quality of Math.random()\n// and inconsistent support for the `crypto` API. We do the best we can via\n// feature-detection\n\n// getRandomValues needs to be invoked in a context where \"this\" is a Crypto\n// implementation. Also, find the complete implementation of crypto on IE11.\nvar getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||\n (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));\n\nif (getRandomValues) {\n // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto\n var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef\n\n module.exports = function whatwgRNG() {\n getRandomValues(rnds8);\n return rnds8;\n };\n} else {\n // Math.random()-based (RNG)\n //\n // If all else fails, use Math.random(). It's fast, but is of unspecified\n // quality.\n var rnds = new Array(16);\n\n module.exports = function mathRNG() {\n for (var i = 0, r; i < 16; i++) {\n if ((i & 0x03) === 0) r = Math.random() * 0x100000000;\n rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;\n }\n\n return rnds;\n };\n}\n","var rng = require('./lib/rng');\nvar bytesToUuid = require('./lib/bytesToUuid');\n\n// **`v1()` - Generate time-based UUID**\n//\n// Inspired by https://github.com/LiosK/UUID.js\n// and http://docs.python.org/library/uuid.html\n\nvar _nodeId;\nvar _clockseq;\n\n// Previous uuid creation time\nvar _lastMSecs = 0;\nvar _lastNSecs = 0;\n\n// See https://github.com/uuidjs/uuid for API details\nfunction v1(options, buf, offset) {\n var i = buf && offset || 0;\n var b = buf || [];\n\n options = options || {};\n var node = options.node || _nodeId;\n var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq;\n\n // node and clockseq need to be initialized to random values if they're not\n // specified. We do this lazily to minimize issues related to insufficient\n // system entropy. See #189\n if (node == null || clockseq == null) {\n var seedBytes = rng();\n if (node == null) {\n // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)\n node = _nodeId = [\n seedBytes[0] | 0x01,\n seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]\n ];\n }\n if (clockseq == null) {\n // Per 4.2.2, randomize (14 bit) clockseq\n clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;\n }\n }\n\n // UUID timestamps are 100 nano-second units since the Gregorian epoch,\n // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so\n // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'\n // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.\n var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime();\n\n // Per 4.2.1.2, use count of uuid's generated during the current clock\n // cycle to simulate higher resolution clock\n var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1;\n\n // Time since last uuid creation (in msecs)\n var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;\n\n // Per 4.2.1.2, Bump clockseq on clock regression\n if (dt < 0 && options.clockseq === undefined) {\n clockseq = clockseq + 1 & 0x3fff;\n }\n\n // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new\n // time interval\n if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {\n nsecs = 0;\n }\n\n // Per 4.2.1.2 Throw error if too many uuids are requested\n if (nsecs >= 10000) {\n throw new Error('uuid.v1(): Can\\'t create more than 10M uuids/sec');\n }\n\n _lastMSecs = msecs;\n _lastNSecs = nsecs;\n _clockseq = clockseq;\n\n // Per 4.1.4 - Convert from unix epoch to Gregorian epoch\n msecs += 12219292800000;\n\n // `time_low`\n var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;\n b[i++] = tl >>> 24 & 0xff;\n b[i++] = tl >>> 16 & 0xff;\n b[i++] = tl >>> 8 & 0xff;\n b[i++] = tl & 0xff;\n\n // `time_mid`\n var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;\n b[i++] = tmh >>> 8 & 0xff;\n b[i++] = tmh & 0xff;\n\n // `time_high_and_version`\n b[i++] = tmh >>> 24 & 0xf | 0x10; // include version\n b[i++] = tmh >>> 16 & 0xff;\n\n // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)\n b[i++] = clockseq >>> 8 | 0x80;\n\n // `clock_seq_low`\n b[i++] = clockseq & 0xff;\n\n // `node`\n for (var n = 0; n < 6; ++n) {\n b[i + n] = node[n];\n }\n\n return buf ? buf : bytesToUuid(b);\n}\n\nmodule.exports = v1;\n","var rng = require('./lib/rng');\nvar bytesToUuid = require('./lib/bytesToUuid');\n\nfunction v4(options, buf, offset) {\n var i = buf && offset || 0;\n\n if (typeof(options) == 'string') {\n buf = options === 'binary' ? new Array(16) : null;\n options = null;\n }\n options = options || {};\n\n var rnds = options.random || (options.rng || rng)();\n\n // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n rnds[6] = (rnds[6] & 0x0f) | 0x40;\n rnds[8] = (rnds[8] & 0x3f) | 0x80;\n\n // Copy bytes to buffer, if provided\n if (buf) {\n for (var ii = 0; ii < 16; ++ii) {\n buf[i + ii] = rnds[ii];\n }\n }\n\n return buf || bytesToUuid(rnds);\n}\n\nmodule.exports = v4;\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/crypto\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/html\");","import { parseHTML } from 'k6/html'\n\n/**\n * Base class to derive errors from\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class AWSError extends Error {\n code: string\n\n /**\n * Create an AWSError\n *\n * @param {string} message - A longer human readable error message.\n * @param {string} code - A unique short code representing the error that was emitted\n */\n constructor(message: string, code: string) {\n super(message)\n this.name = 'AWSError'\n this.code = code\n }\n\n /**\n * Parse an AWSError from an XML document\n *\n * @param {string} xmlDocument - Serialized XML document to parse the error from\n */\n static parseXML(xmlDocument: string): AWSError {\n const doc = parseHTML(xmlDocument)\n return new AWSError(doc.find('Message').text(), doc.find('Code').text())\n }\n}\n","import crypto, { hmac, sha256 } from 'k6/crypto'\nimport { HTTPMethod, HTTPHeaders } from './http'\nimport { AWSConfig } from './config'\nimport { AWSError } from './error'\n\n/**\n * Includes AWS v4 signing information to the provided HTTP headers object.\n *\n * This function will compute the `Authorization` header signature for the\n * provided request components, and add it to `header`. It will do so by following\n * the procedure detailled AWS' API docs: https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html\n *\n * The resulting `Authorization` header value is computed for the provided\n * headers object. Thus, any modification of the headers past a call to `signHeaders`\n * would effectively invalidate their signature, and the function should be\n * called again to recompute it.\n *\n * @param {object} headers - HTTP headers request to sign.\n * @param {number} requestTimestamp - Timestamp of the request\n * @param {string} method - HTTP method used\n * @param {string} path - HTTP request URL's path\n * @param {string} queryString - HTTP request URL's querystring\n * @param {string | ArrayBuffer} body - HTTP request's payload\n * @param {AWSConfig} - AWS configuration\n * @param {string} service - AWS service name\n * @param {URIEncodingConfig} - URI encoding configuration\n */\nexport function signHeaders(\n headers: HTTPHeaders,\n requestTimestamp: number,\n method: HTTPMethod,\n path: string,\n queryString: string,\n body: string | ArrayBuffer,\n awsConfig: AWSConfig,\n service: string,\n URIencodingConfig: URIEncodingConfig\n): HTTPHeaders {\n const derivedSigningKey = deriveSigningKey(\n awsConfig.secretAccessKey,\n requestTimestamp,\n awsConfig.region,\n service\n )\n\n const canonicalRequest = createCanonicalRequest(\n method,\n path,\n queryString,\n headers,\n body,\n URIencodingConfig\n )\n\n const stringToSign = createStringToSign(\n requestTimestamp,\n awsConfig.region,\n service,\n sha256(canonicalRequest, 'hex')\n )\n\n const credentialScope = createCredentialScope(requestTimestamp, awsConfig.region, service)\n const signedHeaders = createSignedHeaders(headers)\n const signature = calculateSignature(derivedSigningKey, stringToSign)\n const authorizationHeader = `${HashingAlgorithm} Credential=${awsConfig.accessKeyID}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`\n\n headers['Authorization'] = authorizationHeader\n\n return headers\n}\n\n/**\n * Error indicating an Invalid signature has been sent to AWS services\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class InvalidSignatureError extends AWSError {\n /**\n * Constructs an InvalidSignatureError\n *\n * @param {string} message - human readable error message\n */\n constructor(message: string, code: string) {\n super(message, code)\n this.name = 'InvalidSignatureError'\n }\n}\n\n/**\n * Calculte the signature for AWS signature version 4\n *\n * @param {string} derivedSigningKey - dervied signing key as computed by `deriveSigningKey`\n * @param {string} stringToSign - String to sign as computed by `createStringToSign`\n * @return {string}\n */\nexport function calculateSignature(derivedSigningKey: ArrayBuffer, stringToSign: string): string {\n return hmac('sha256', derivedSigningKey, stringToSign, 'hex')\n}\n/**\n * Derives the signing key for authenticating requests signed with\n * the Signature version 4 authentication protocol.\n *\n * deriveSigningKey produces a signing key by creating a series of\n * hash-based message authentication codes (HMACs) represented in\n * a binary format.\n *\n * The derived signing key is specific to the date it's made at, as well as\n * the service and region it targets.\n *\n * @param {string} secretAccessKey - the AWS secret access key to derive the signing key for\n * @param {number} time - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service. MUST be UTF-8 encoded.\n * @return {string}\n */\nexport function deriveSigningKey(\n secretAccessKey: string,\n time: number,\n region: string,\n service: string\n): ArrayBuffer {\n const kSecret = secretAccessKey\n const date = toDate(time)\n\n // FIXME: hmac takes ArrayBuffer as input, but returns bytes (number[]).\n // How does one convert from one to the other?\n const kDate: any = hmac('sha256', 'AWS4' + kSecret, date, 'binary')\n const kRegion: any = hmac('sha256', kDate, region, 'binary')\n const kService: any = hmac('sha256', kRegion, service, 'binary')\n const kSigning: any = hmac('sha256', kService, 'aws4_request', 'binary')\n\n return kSigning\n}\n\n// Hashing Algorithm to use in the signature process\nexport const HashingAlgorithm = 'AWS4-HMAC-SHA256'\n\n/**\n * Certain services, such as S3, allow for unsigned payloads. If\n * producing a signed canonical request for such service, pass\n * the `UnsignedPayload` constant value as the payload parameter.\n */\nexport const UnsignedPayload = 'UNSIGNED-PAYLOAD'\n\n/**\n * Create the \"string to sign\" part of the signature Version 4 protocol.\n *\n * The \"string to sign\" includes meta information about your request and\n * about the canonical request that you created with `createCanonicalRequest`.\n * It is used hand in hand with the signing key to create the request signature.\n *\n * @param {number} requestTimestamp - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service name. MUST be UTF-8 encoded.\n * @param {string} hashedCanonicalRequest - canonical request as produced by calling the createCanonicalRequest function,\n * hashed using the SHA256 algorithm (encoded in hexadecimal format).\n * @return {string}\n */\nexport function createStringToSign(\n requestTimestamp: number,\n region: string,\n service: string,\n hashedCanonicalRequest: string\n): string {\n // the request date specified in ISO8601 format: YYYYMMDD'T'HHMMSS'Z'\n const requestDateTime = toTime(requestTimestamp)\n\n // The credential scope value, consisting of the date in YYYYMMDD format,\n // the targeted region, the targeted service, and a termination string.\n // Note that the region and service MUST be UTF-8 encoded.\n const credentialScope = createCredentialScope(requestTimestamp, region, service)\n\n const stringToSign = [\n // Algorithm\n HashingAlgorithm,\n\n // RequestDateTime\n requestDateTime,\n\n // CredentialScope\n credentialScope,\n\n // HashedCanonicalRequest\n hashedCanonicalRequest,\n ].join('\\n')\n\n return stringToSign\n}\n\n/**\n *\n * Helper function creating a credential scope string to use in the signature\n * version 4 process. A credential scope consists of the date of the request\n * in YYYYMMDD format, the targeted region, the targeted service, and a\n * termination string.\n *\n * Note that the region and service MUST be UTF-8 encoded.\n *\n * @param {number} requestTimestamp - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service name. MUST be UTF-8 encoded.\n * @return {string}\n */\nexport function createCredentialScope(\n requestTimestamp: number,\n region: string,\n service: string\n): string {\n return [toDate(requestTimestamp), region, service, 'aws4_request'].join('/')\n}\n\n/**\n * Create a string that includes information from your request\n * in a AWS signature v4 standardized (canonical) format.\n *\n * @param {string} method - the HTTP request method\n * @param {string} uri - URI-encoded version of the absolute path component of the URI\n * @param {string} query - request's query string\n * @param {Object} headers - all the HTTP headers that you wish to include with the signed request\n * @param {string | ArrayBuffer} payload - payload to include as the body of the request\n * @param {URIEncodingConfig} URIencodingConfig- URI encoding configuration\n * @return {string}\n */\nexport function createCanonicalRequest(\n method: HTTPMethod,\n uri: string,\n query: string,\n headers: HTTPHeaders,\n payload: string | ArrayBuffer,\n URIencodingConfig: URIEncodingConfig\n): string {\n const httpRequestMethod = method.toUpperCase()\n const canonicalURI = createCanonicalURI(uri, URIencodingConfig)\n const canonicalQueryString = createCanonicalQueryString(query)\n const canonicalHeaders = createCanonicalHeaders(headers)\n const signedHeaders = createSignedHeaders(headers)\n const requestPayload = createCanonicalPayload(payload)\n\n const canonicalRequest = [\n httpRequestMethod,\n canonicalURI,\n canonicalQueryString,\n canonicalHeaders,\n signedHeaders,\n requestPayload,\n ].join('\\n')\n\n return canonicalRequest\n}\n\n/**\n * Creates the (canonical) URI-encoded version of the\n * absolute path component of the URI: everything in the URI\n * from the HTTP host to the question mark character (\"?\")\n * that begins the query string parameters (if any).\n *\n * @param {string} uri - URI to canonize\n * @param {URIEncodingConfig} - URI encoding configuration\n * @return {string} - canonical URL\n */\nexport function createCanonicalURI(uri: string, URIencodingConfig: URIEncodingConfig): string {\n if (uri == '/') {\n return uri\n }\n\n let canonicalURI = uri\n if (uri[uri.length - 1] == '/' && canonicalURI[canonicalURI.length - 1] != '/') {\n canonicalURI += '/'\n }\n\n canonicalURI = URIEncode(canonicalURI, URIencodingConfig.path)\n\n return URIencodingConfig.double ? URIEncode(canonicalURI, URIencodingConfig.path) : canonicalURI\n}\n\n// FIXME: does it work as expected?\n/**\n * Creates the canonical form of the request's query\n * string. If the request does not include a query string,\n * provide an empty string.\n *\n * @param {String | Object} qs - query string to canonize\n * @return {string}\n */\nexport function createCanonicalQueryString(qs: string): string {\n if (qs === '') {\n return ''\n }\n\n // const intermediary: { [key: string]: string } = parseQueryString(qs)\n\n // return Object.keys(intermediary)\n // .sort()\n // .map((key: string) => {\n // // const values: string[] = Array.isArray(intermediary[key])\n // // ? intermediary[key]\n // // : [intermediary[key]]\n // const values = intermediary[key]\n\n // return values\n // .sort()\n // .map((val: string) => encodeURIComponent(key) + '=' + encodeURIComponent(val))\n // .join('&')\n // })\n // .join('&')\n\n return parseQueryString(qs)\n .map(([key, value]: [string, string]): string => {\n return encodeURIComponent(key) + '=' + encodeURIComponent(value)\n })\n .join('&')\n}\n/**\n * Create the canonical form of the request's headers.\n * Canonical headers consist of all the HTTP headers you\n * are including with the signed request.\n *\n * Note that:\n * * for HTTP/1.1 requests, the headers should at least\n * contain the `host` header.\n * * for HTTP/2, the `:authority` header must be used instead\n * of `host`.\n *\n * @param {Object} headers\n * @return {string}\n */\nexport function createCanonicalHeaders(headers: HTTPHeaders) {\n if (headers.constructor !== Object || Object.entries(headers).length === 0) {\n return ''\n }\n\n const canonicalHeaders = Object.entries(headers)\n .map(([name, values]) => {\n const canonicalName = name.toLowerCase().trim()\n const normalizedValues = Array.isArray(values) ? values : [values]\n\n // Note that we do not need to sort values\n const canonicalValues = normalizedValues\n .map((v) => {\n // convert sequential spaces to a single space\n return v.replace(/\\s+/g, ' ').replace(/^\\s+|\\s+$/g, '')\n })\n .join(',') // standard for multiple values in a HTTP header\n\n return canonicalName + ':' + canonicalValues + '\\n'\n })\n .sort()\n .join('')\n\n return canonicalHeaders\n}\n\n/**\n * Create the canonical request's signed headers.\n *\n * The signed headers part of the request contains the\n * list of headers included in the request's signing process.\n *\n * Note that:\n * * for HTTP/1.1 requests, the `host` header must be included.\n * * for HTTP/2 requests, the `:authority` header must be included instead\n * of host.\n * * if used, the `x-amz-date` header must be included.\n *\n * @param {Object} headers\n * @return {string}\n * @throws {TypeError} - on headers not being an Object, or being empty.\n */\nexport function createSignedHeaders(headers: { [key: string]: string }) {\n if (headers.constructor !== Object) {\n throw new TypeError('headers should be an object')\n }\n\n if (Object.entries(headers).length === 0) {\n throw 'headers should at least contain either the Host (HTTP 1.1) or :authority (HTTP 2) parameter'\n }\n\n // To create the signed headers list, convert\n // all header names to lowercase, sort them by\n // character code, and use a semicolon to separate\n // the header names.\n const result = Object.keys(headers)\n .map((name) => name.toLowerCase().trim())\n .sort()\n .join(';')\n\n return result\n}\n\n/**\n * Create the canonical form of the request's payload.\n *\n * The canonical payload consists in a lowercased, hex encoded,\n * SHA256 hash of the requests body/payload.\n *\n * Certain services, such as S3, allow for unsigned payload. If\n * producing a signed canonical request for such service, pass\n * the `UnsignedPayload` constant value as the payload parameter.\n *\n * @param {String | ArrayBuffer} payload\n * @return {string}\n */\nexport function createCanonicalPayload(payload: string | ArrayBuffer) {\n if (payload === UnsignedPayload) {\n return payload\n }\n\n // Note that if the paylaod is null, we convert it\n // to an empty string.\n // TODO: Should switching to empty string if null impact headers?\n return crypto.sha256(payload || '', 'hex').toLowerCase()\n}\n\n/**\n * URIEncodes encodes every bytes of a URI to be URL-safe.\n *\n * This implementation is specific to AWS; who intended to make it as\n * close as possible to the underlying RFC 3946. It:\n * * URI encode every byte except the unreserved characters: 'A'-'Z', 'a'-'z', '0'-'9',\n * '-', '.', '_', and '~'.\n * * considers the space character as a reserved character and must URI encodes\n * encodes it as \"%20\" (and not as \"+\").\n * * URI encodes every byte by prefixing with '%' the two-digit hexadecimal value of the byte.\n * * If the `path` argument is set, forward slashes are not encoded, to fit with\n * S3 requirements.\n *\n * N.B: this implementation differs with ES6' mainly in that it does\n * encode the \"'\" character.\n *\n * Based on AWS implementation: https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-core/src/main/java/com/amazonaws/util/SdkHttpUtils.java#L66\n * Encoding specs: https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html\n *\n * @param {string} uri - uri to encode\n * @param {boolean} path - slash characters should be encoded everywhere,\n * but in paths, set to false when encoding a path\n * @return {string} the URI encoded result\n */\nexport function URIEncode(uri: string, path: boolean): string {\n if (uri == '') {\n return uri\n }\n\n return uri\n .split('') // to be able to map over a string, because... javascript...\n .map((letter: string) => {\n if (isAlpha(letter) || isNumeric(letter) || '-._~'.includes(letter)) {\n return letter\n }\n\n // Space should be explicitly encoded to as %20.\n if (letter == ' ') {\n return '%20'\n }\n\n // If the URI is a path, the forward slash shouldn't\n // be encoded.\n if (letter == '/' && path) {\n return '/'\n }\n\n return '%' + letter.charCodeAt(0).toString(16).toUpperCase()\n })\n .join('')\n}\n\n/**\n * Class holding URI encoding configuration\n */\nexport class URIEncodingConfig {\n double: boolean\n path: boolean\n\n /**\n *\n * @param {boolean} double - should the URI be double encoded?\n * @param {boolean} path - is the URI a path? If so, its forward\n * slashes won't be URIencoded.\n */\n constructor(double: boolean, path: boolean) {\n this.double = double\n this.path = path\n }\n}\n\n/**\n * Compute the request time value as specified by the ISO8601\n * format: YYYYMMDD'T'HHMMSS'Z'\n *\n * @param {number} timestamp\n * @return {string}\n */\nexport function toTime(timestamp: number): string {\n return new Date(timestamp).toISOString().replace(/[:\\-]|\\.\\d{3}/g, '')\n}\n/**\n * Computethe request date value in the format: YYYMMDD\n *\n * @param {number} timestamp\n * @return {string}\n */\nexport function toDate(timestamp: number): string {\n return toTime(timestamp).substring(0, 8)\n}\n\n// FIXME: does it work as expected?\n/**\n * Parse a HTTP request URL's querystring into an object\n * containing its `key=value` pairs.\n *\n * @param {string} qs\n * @return {object}\n */\nexport function parseQueryString(qs: string): Array<[string, string]> {\n if (qs.length === 0) {\n return []\n }\n\n return qs\n .split('&')\n .filter((e) => e)\n .map((v: string): [string, string] => {\n const parts = v.split('=', 2) as [string, string]\n return [decodeURIComponent(parts[0]), decodeURIComponent(parts[1])]\n })\n .sort((a: [string, string], b: [string, string]) => {\n return a[0].localeCompare(b[0])\n })\n}\n\nfunction isAlpha(c: string): boolean {\n return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')\n}\n\nfunction isNumeric(c: string): boolean {\n return c >= '0' && c <= '9'\n}\n\n// FIXME: finish implementation when needed\n// See the following for more details:\n// * https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html\n// * https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html\n// export function signQueryString(\n// queryString,\n// requestTimestamp,\n// accessKeyID,\n// secretAccessKey,\n// region,\n// service,\n// ttl, // in seconds\n// headers,\n// doubleURIEncoding = true\n// ) {\n// const credential = [accessKeyID, toDate(requestTimestamp), region, service].join('/')\n//\n// const canonicalRequest = createCanonicalRequest(\n// method,\n// path,\n// queryString,\n// headers,\n// body,\n// doubleURIEncoding\n// )\n//\n// const derivedSigningKey = deriveSigningKey(secretAccessKey, requestTimestamp, region, service)\n//\n// const stringToSign = createStringToSign(\n// requestTimestamp,\n// region,\n// service,\n// sha256(canonicalRequest, 'hex')\n// )\n//\n// const signedHeaders = createSignedHeaders(headers)\n// const signature = calculateSignature(derivedSigningKey, stringToSign)\n//\n// return [\n// `X-Amz-Algorithm=${HashingAlgorithm}`,\n// `X-Amz-Credential=${crediental}`,\n// `X-Amz-Date=${toTime(requestTimestamp)}`,\n// `X-Amz-Expires=${ttl}`,\n// `X-Amz-SignedHeaders=${signedHeaders}`,\n// `X-Amz-Signature=${signature}`,\n//`X-Amz-Security-Token=`, // TODO: optional\n// ].join('&')\n// }\n","/** Class holding an AWS connection information */\nexport class AWSConfig {\n region: string\n accessKeyID: string\n secretAccessKey: string\n\n /**\n * Create an AWSConfig.\n *\n * @param {string} region - the AWS region to connect to, as listed: https://docs.aws.amazon.com/general/latest/gr/rande.html\n * @param {string} accessKeyID - Your user's AWS access key id credential\n * @param {string} secretAccessKey - Your user's AWS secret access key credential\n * @throws {InvalidArgumentException}\n */\n constructor(region: string, accessKeyID: string, secretAccessKey: string) {\n if (typeof region !== 'string' || region === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS region; reason: should be a non empty string'\n )\n }\n\n if (typeof accessKeyID !== 'string' || accessKeyID === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS access key ID; reason: should be a non empty string'\n )\n }\n\n if (typeof secretAccessKey !== 'string' || secretAccessKey === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS secret access key; reason: should be a non empty string'\n )\n }\n\n this.region = region\n this.accessKeyID = accessKeyID\n this.secretAccessKey = secretAccessKey\n }\n}\n\n/** Class representing an invalid AWS configuration */\nexport class InvalidAWSConfigError extends Error {\n constructor(message: string) {\n super(message)\n }\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/http\");","import { HTTPMethod, HTTPHeaders } from './http'\nimport { AWSConfig } from './config'\nimport { signHeaders, URIEncodingConfig, toTime } from './signature'\n\n/**\n * Class allowing to build requests targeting AWS APIs\n *\n * This class is meant to be used as a base class for specific\n * services clients. See S3Client or SecretsManagerClient for\n * usage examples.\n */\nexport class AWSClient {\n awsConfig: AWSConfig\n serviceName: string\n URIencodingConfig: URIEncodingConfig\n\n /**\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n * @param {string} serviceName - name of the service to target.\n * @param {URIEncodingConfig} URIencodingConfig - configures how requests URIs should be encoded.\n */\n constructor(awsConfig: AWSConfig, serviceName: string, URIencodingConfig: URIEncodingConfig) {\n this.awsConfig = awsConfig\n this.serviceName = serviceName\n this.URIencodingConfig = URIencodingConfig\n }\n\n buildRequest(\n method: HTTPMethod,\n host: string,\n path: string,\n queryString: string,\n body: string | ArrayBuffer,\n headers: HTTPHeaders\n ): AWSRequest {\n const requestTimestamp: number = Date.now()\n const date: string = toTime(requestTimestamp)\n\n headers['Host'] = host\n headers['X-Amz-Date'] = date\n\n headers = signHeaders(\n // headers\n headers,\n\n // requestTimestamp\n requestTimestamp,\n\n // method\n method,\n\n // path\n path,\n\n // querystring\n queryString,\n\n // body\n body,\n\n // AWS configuration\n this.awsConfig,\n\n // AwS target service name\n this.serviceName,\n\n // doubleEncoding: S3 does single-encoding of the uri component\n // pathURIEncoding: S3 manipulates object keys, and forward slashes\n // shouldn't be URI encoded\n this.URIencodingConfig\n )\n\n // '?' should not be part of the querystring when we sign the headers\n path = path !== '' ? path : '/'\n let url = `https://${host}${path}`\n if (queryString !== '') {\n url += `?${queryString}`\n }\n\n return { url: url, headers: headers }\n }\n}\n\n/**\n * Type alias representing the result of an AWSClient.buildRequest call\n */\nexport interface AWSRequest {\n url: string\n headers: HTTPHeaders\n}\n","import { bytes } from 'k6'\nimport http from 'k6/http'\nimport { parseHTML } from 'k6/html'\nimport { sha256 } from 'k6/crypto'\n\nimport { InvalidSignatureError, URIEncodingConfig } from './signature'\nimport { AWSClient, AWSRequest } from './client'\nimport { AWSError } from './error'\nimport { AWSConfig } from './config'\n\n/** Class allowing to interact with Amazon AWS's S3 service */\nexport class S3Client extends AWSClient {\n /**\n * Create a S3Client\n *\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n */\n constructor(awsConfig: AWSConfig) {\n const URIencodingConfig = new URIEncodingConfig(false, true)\n super(awsConfig, 's3', URIencodingConfig)\n }\n\n /**\n * Returns a list of all buckets owned by the authenticated sender of the request.\n * To use this operation, you must have the s3:ListAllMyBuckets permission.\n *\n * @return {Array.} buckets - An array of objects describing S3 buckets\n * with the following fields: name, and creationDate.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n listBuckets(): Array {\n // Prepare request\n const method = 'GET'\n const host = `${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(method, host, '/', '', body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n let buckets: Array = []\n\n const doc = parseHTML(res.body as string)\n\n doc.find('Buckets')\n .children()\n .each((_, bucketDefinition) => {\n let bucket = {}\n\n bucketDefinition.children().forEach((child) => {\n switch (child.nodeName()) {\n case 'name':\n Object.assign(bucket, { name: child.textContent() })\n break\n case 'creationdate':\n Object.assign(bucket, {\n creationDate: Date.parse(child.textContent()),\n })\n }\n })\n\n buckets.push(bucket as S3Bucket)\n })\n\n return buckets\n }\n\n /**\n * Returns some or all (up to 1,000) of the objects in a bucket.\n *\n * @param {string} bucketName - Bucket name to list.\n * @param {string?} prefix='' - Limits the response to keys that begin with the specified prefix.\n * @return {Array.} - returns an array of objects describing S3 objects\n * with the following fields: key, lastModified, etag, size and storageClass.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n listObjects(bucketName: string, prefix?: string): Array {\n // Prepare request\n const method = 'GET'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const body = ''\n const querystring = `list-type=2&prefix=${prefix}`\n const signedRequest: AWSRequest = super.buildRequest(method, host, '/', querystring, body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n Prefix: prefix ?? '',\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n let objects: Array = []\n\n // Extract the objects definition from\n // the XML response\n parseHTML(res.body as string)\n .find('Contents')\n .each((_, objectDefinition) => {\n let obj = {}\n\n objectDefinition.children().forEach((child) => {\n switch (child.nodeName()) {\n case 'key':\n Object.assign(obj, { key: child.textContent() })\n break\n case 'lastmodified':\n Object.assign(obj, { lastModified: Date.parse(child.textContent()) })\n break\n case 'etag':\n Object.assign(obj, { etag: child.textContent() })\n break\n case 'size':\n Object.assign(obj, { size: parseInt(child.textContent()) })\n break\n case 'storageclass':\n Object.assign(obj, { storageClass: child.textContent() })\n }\n })\n\n objects.push(obj as S3Object)\n })\n\n return objects\n }\n /**\n * Retrieves an Object from Amazon S3.\n *\n * To use getObject, you must have `READ` access to the object.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to get.\n * @return {S3Object} - returns the content of the fetched S3 Object.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n getObject(bucketName: string, objectKey: string): S3Object {\n // Prepare request\n const method = 'GET'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(method, host, path, '', body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n console.log(`s3 objects response headers: ${JSON.stringify(res.headers, null, ' ')}`)\n\n return new S3Object(\n objectKey,\n Date.parse(res.headers['Last-Modified']),\n res.headers['ETag'],\n parseInt(res.headers['Content-Length']),\n (res.headers['X-Amz-Storage-Class'] ?? 'STANDARD') as StorageClass, // FIXME: GetObject response doesn't contain the storage class\n res.body\n )\n }\n /**\n * Adds an object to a bucket.\n *\n * You must have WRITE permissions on a bucket to add an object to it.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to put.\n * @param {string | ArrayBuffer} data - the content of the S3 Object to upload.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n putObject(bucketName: string, objectKey: string, data: string | ArrayBuffer) {\n // Prepare request\n const method = 'PUT'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const queryString = ''\n const body = data\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n path,\n queryString,\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n }\n\n /**\n * Removes the null version (if there is one) of an object and inserts a delete marker,\n * which becomes the latest version of the object.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to delete.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n deleteObject(bucketName: string, objectKey: string): void {\n // Prepare request\n const method = 'DELETE'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const queryString = ''\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n path,\n queryString,\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n }\n\n // FIXME: remove dependency to `error_message`\n // FIXME: just pass it the response?\n _handle_error(error_code: number, error_message: string, error_body: string) {\n if (error_message == '' || error_code === 0) {\n return\n }\n\n // FIXME: should be error_code === 1301 instead\n // See: https://github.com/grafana/k6/issues/2474\n // See: https://github.com/golang/go/issues/49281\n if (error_message && error_message.startsWith('301')) {\n // Bucket not found\n throw new S3ServiceError('Resource not found', 'ResourceNotFound', 'getObject')\n }\n\n const awsError = AWSError.parseXML(error_body)\n switch (awsError.code) {\n case 'AuthorizationHeaderMalformed':\n throw new InvalidSignatureError(awsError.message, awsError.code)\n default:\n throw new S3ServiceError(awsError.message, awsError.code, 'listObjects')\n }\n }\n}\n\n// TODO: use interface instead?\n/** Class representing a S3 Bucket */\nexport class S3Bucket {\n name: string\n creationDate: Date\n\n /**\n * Create an S3 Bucket\n *\n * @param {string} name - S3 bucket's name\n * @param {Date} creationDate - S3 bucket's creation date\n */\n constructor(name: string, creationDate: Date) {\n this.name = name\n this.creationDate = creationDate\n }\n}\n\n// TODO: use interface instead?\n/** Class representing an S3 Object */\nexport class S3Object {\n key: string\n lastModified: number\n etag: string\n size: number\n storageClass: StorageClass\n data?: string | bytes | null\n\n /**\n * Create an S3 Object\n *\n * @param {string} key - S3 object's key\n * @param {Date} lastModified - S3 object last modification date\n * @param {string} etag - S3 object's etag\n * @param {number} size - S3 object's size\n * @param {StorageClass} storageClass - S3 object's storage class\n * @param {string | bytes | null} data=null - S3 Object's data\n */\n constructor(\n key: string,\n lastModified: number,\n etag: string,\n size: number,\n storageClass: StorageClass,\n data?: string | bytes | null\n ) {\n this.key = key\n this.lastModified = lastModified\n this.etag = etag\n this.size = size\n this.storageClass = storageClass\n this.data = data\n }\n}\n\n/**\n * Error indicating a S3 operation failed\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class S3ServiceError extends AWSError {\n operation: string\n\n /**\n * Constructs a S3ServiceError\n *\n * @param {string} message - human readable error message\n * @param {string} code - A unique short code representing the error that was emitted\n * @param {string} operation - Name of the failed Operation\n */\n constructor(message: string, code: string, operation: string) {\n super(message, code)\n this.name = 'S3ServiceError'\n this.operation = operation\n }\n}\n\n/**\n * Describes the class of storage used to store a S3 object.\n */\ntype StorageClass =\n | 'STANDARD'\n | 'REDUCED_REDUNDANCY'\n | 'GLACIER'\n | 'STANDARD_IA'\n | 'INTELLIGENT_TIERING'\n | 'DEEP_ARCHIVE'\n | 'OUTPOSTS'\n | 'GLACIER_IR'\n | undefined\n","import { JSONArray, JSONObject } from 'k6'\nimport http, { RefinedResponse, ResponseType } from 'k6/http'\n\nimport { AWSClient, AWSRequest } from './client'\nimport { AWSError } from './error'\nimport { AWSConfig } from './config'\nimport { InvalidSignatureError, URIEncodingConfig } from './signature'\nimport { v4 as uuidv4 } from 'uuid'\nimport { HTTPMethod, HTTPHeaders } from './http'\n\n/**\n * Class allowing to interact with Amazon AWS's SecretsManager service\n */\nexport class SecretsManagerClient extends AWSClient {\n method: HTTPMethod\n commonHeaders: HTTPHeaders\n\n /**\n * Create a SecretsManagerClient\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n */\n constructor(awsConfig: AWSConfig) {\n const URIencodingConfig = new URIEncodingConfig(true, false)\n super(awsConfig, 'secretsmanager', URIencodingConfig)\n\n // this.serviceName = 'secretsmanager'\n\n // All interactions with the Secrets Manager service\n // are made via the GET or POST method.\n this.method = 'POST'\n\n this.commonHeaders = {\n 'Accept-Encoding': 'identity',\n 'Content-Type': 'application/x-amz-json-1.1',\n }\n }\n\n /**\n * Returns a list of all secrets owned by the authenticated sender of the request.\n * To use this operation, you must have the secretsmanager:ListSecrets permission.\n *\n * @return {Array.} secrets - An array of objects describing Secret Manager's secrets\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n listSecrets(): Array {\n const body = JSON.stringify({})\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.ListSecrets`,\n }\n )\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('ListSecrets', res)\n const json: JSONArray = res.json('SecretList') as JSONArray\n\n return json.map((s) => Secret.fromJSON(s as JSONObject))\n }\n\n /**\n * Retrieves a secret from Amazon Sercets Manager\n *\n * @param {string} secretID - The ARN or name of the secret to retrieve.\n * @returns {Secret} - returns the content of the fetched Secret object.\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n getSecret(secretID: string): Secret | undefined {\n const body = JSON.stringify({ SecretId: secretID })\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.GetSecretValue`,\n }\n )\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('GetSecretValue', res)\n\n return Secret.fromJSON(res.json() as JSONObject)\n }\n\n /**\n * Creates a new secret\n *\n * Note that this method only supports string-based values at the moment.\n *\n * @param {string} name - The name of the new secret.\n * The secret name can contain ASCII letters, numbers, and the following characters: /_+=.@\n * @param {string} secretString - The text data to encrypt and store in this new version of the secret.\n * @param {string} description - The description of the secret.\n * @param {string} versionID=null - Version of the secret. This value helps ensure idempotency.\n * As a default, if no versionID is provided, one will be created for you using the UUID v4\n * algorithm.\n * @param {Array.} tags=[] - A list of tags to attach to the secret. Each tag is a key and\n * value pair of strings in a JSON text string. Note that tag key names are case sensitive.\n * @returns {Secret} - returns the created secret\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n createSecret(\n name: string,\n secretString: string,\n description: string,\n versionID?: string,\n tags?: Array\n ): Secret {\n versionID = versionID || uuidv4()\n\n const body = JSON.stringify({\n Name: name,\n Description: description,\n SecretString: secretString,\n ClientRequestToken: versionID,\n Tags: tags,\n })\n\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.CreateSecret`,\n }\n )\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n // headers['X-Amz-Target'] = `${this.serviceName}.CreateSecret`\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('CreateSecret', res)\n\n return Secret.fromJSON(res.json() as JSONObject)\n }\n /**\n * Update a secret's value.\n *\n * Note that this method only support string-based values at the moment.\n *\n * @param {string} secretID - The ARN or name of the secret to update.\n * @param {string} secretString - The text data to encrypt and store in this new version of the secret.\n * @param {} versionID=null - A unique identifier for the new version of the secret. This value helps ensure idempotency.\n * As a default, if no versionID is provided, one will be created for you using the UUID v4\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n putSecretValue(secretID: string, secretString: string, versionID?: string): Secret {\n versionID = versionID || uuidv4()\n\n const body = JSON.stringify({\n SecretId: secretID,\n SecretString: secretString,\n ClientRequestToken: versionID,\n })\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.PutSecretValue`,\n }\n )\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('PutSecretValue', res)\n\n return Secret.fromJSON(res.json() as JSONObject)\n }\n\n /**\n * Deletes a secret and all of its versions.\n *\n * You can specify a recovery window during which you can restore the secret.\n * The minimum recovery window is 7 days. The default recovery window is 30 days.\n *\n * @param {string} secretID - The ARN or name of the secret to delete.\n * @param {number} recoveryWindow - The number of days from 7 to 30 that Secrets Manager\n * waits before permanently deleting the secret.\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n deleteSecret(\n secretID: string,\n { recoveryWindow = 30, noRecovery = false }: { recoveryWindow: number; noRecovery: boolean }\n ) {\n const payload: { [key: string]: string | boolean | number } = {\n SecretId: secretID,\n }\n\n // noRecovery and recoveryWindow are exclusive parameters\n if (noRecovery === true) {\n payload['ForceDeleteWithoutRecovery'] = true\n } else {\n payload['RecoveryWindowInDays'] = recoveryWindow\n }\n\n const body = JSON.stringify(payload)\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.DeleteSecret`,\n }\n )\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('DeleteSecret', res)\n }\n\n get host() {\n return `${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n }\n\n // TODO: operation should be an enum\n _handle_error(operation: string, response: RefinedResponse) {\n const errorCode = response.error_code\n if (errorCode === 0) {\n return\n }\n\n const error = response.json() as JSONObject\n if (errorCode >= 1400 && errorCode <= 1499) {\n // In the event of certain errors, the message is not set.\n // Also, note the inconsistency in casing...\n const errorMessage: string =\n (error.Message as string) || (error.message as string) || (error.__type as string)\n\n // Handle specifically the case of an invalid signature\n if (error.__type === 'InvalidSignatureException') {\n throw new InvalidSignatureError(errorMessage, error.__type)\n }\n\n // Otherwise throw a standard service error\n throw new SecretsManagerError(errorMessage, error.__type as string, operation)\n }\n\n if (errorCode === 1500) {\n throw new SecretsManagerError(\n 'An error occured on the server side',\n 'InternalServiceError',\n operation\n )\n }\n }\n}\n\n// TODO: create a Tags type\n\n/**\n * Class representing a Secret Manager's secret\n */\nexport class Secret {\n name: string\n arn: string\n secret: string\n createdDate: number\n lastAccessedDate: number\n lastChangedDate: number\n tags: Array<{ [key: string]: string }>\n\n /**\n * Constructs a Secret Manager's Secret\n *\n * @param {string} name - The friendly name of the secret.\n * @param {string} arn - The ARN of the secret.\n * @param {number} createdDate - The date and time that this version of the secret was created.\n * @param {number} lastAccessedDate - The last date that this secret was accessed. This value is\n * truncated to midnight of the date and therefore shows only the date, not the time.\n * @param {number} lastChangedDate - The last date and time that this secret was modified in any way.\n * @param {Array.} tags - The list of user-defined tags associated with the secret.\n */\n constructor(\n name: string,\n arn: string,\n secretString: string,\n createdDate: number,\n lastAccessedDate: number,\n lastChangedDate: number,\n tags: Array<{ [key: string]: string }> = []\n ) {\n this.name = name\n this.arn = arn\n this.secret = secretString\n this.createdDate = createdDate\n this.lastAccessedDate = lastAccessedDate\n this.lastChangedDate = lastChangedDate\n this.tags = tags\n }\n\n /**\n * Parses and constructs a Secret Manager's Secret from the content\n * of a JSON response returned by the AWS service\n *\n * @param {Object} json - JSON object as returned and parsed from\n * the AWS service's API call.\n * @returns {Secret}\n */\n static fromJSON(json: JSONObject) {\n return new Secret(\n json.Name as string,\n json.ARN as string,\n json.SecretString as string,\n json.CreatedDate as number,\n json.LastAccessedDate as number,\n json.LastChangedDate as number,\n json.Tags as Array<{ [key: string]: string }>\n )\n }\n}\n\nexport class SecretsManagerError extends AWSError {\n operation: string\n\n /**\n * Constructs a SecretsManagerError\n *\n * @param {string} message - human readable error message\n * @param {string} code - A unique short code representing the error that was emitted\n * @param {string} operation - Name of the failed Operation\n */\n constructor(message: string, code: string, operation: string) {\n super(message, code)\n this.name = 'SecretsManagerServiceError'\n this.operation = operation\n }\n}\n"],"names":["v1","v4","uuid","module","exports","byteToHex","i","toString","substr","buf","offset","bth","join","getRandomValues","crypto","bind","window","msCrypto","rnds8","Uint8Array","rnds","Array","r","Math","random","_nodeId","_clockseq","rng","bytesToUuid","_lastMSecs","_lastNSecs","options","b","node","clockseq","undefined","seedBytes","msecs","Date","getTime","nsecs","dt","Error","tl","tmh","n","ii","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","__webpack_modules__","getter","__esModule","d","a","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","require","AWSError","message","code","name","xmlDocument","doc","parseHTML","find","text","signHeaders","headers","requestTimestamp","method","path","queryString","body","awsConfig","service","URIencodingConfig","derivedSigningKey","secretAccessKey","time","region","kSecret","date","toDate","kDate","hmac","kRegion","kService","deriveSigningKey","canonicalRequest","uri","query","payload","httpRequestMethod","toUpperCase","canonicalURI","length","URIEncode","createCanonicalURI","canonicalQueryString","qs","split","filter","e","map","v","parts","decodeURIComponent","sort","localeCompare","parseQueryString","encodeURIComponent","createCanonicalQueryString","canonicalHeaders","constructor","entries","values","toLowerCase","trim","isArray","replace","createCanonicalHeaders","signedHeaders","createSignedHeaders","requestPayload","UnsignedPayload","createCanonicalPayload","createCanonicalRequest","stringToSign","hashedCanonicalRequest","requestDateTime","toTime","credentialScope","createCredentialScope","HashingAlgorithm","createStringToSign","sha256","signature","calculateSignature","authorizationHeader","accessKeyID","InvalidSignatureError","TypeError","keys","letter","c","isNumeric","includes","charCodeAt","URIEncodingConfig","double","this","timestamp","toISOString","substring","AWSConfig","InvalidAWSConfigError","AWSClient","serviceName","host","now","url","S3Client","signedRequest","res","http","_handle_error","error_code","error","buckets","children","each","_","bucketDefinition","bucket","forEach","child","nodeName","assign","textContent","creationDate","parse","push","bucketName","prefix","querystring","Prefix","objects","objectDefinition","lastModified","etag","size","parseInt","storageClass","objectKey","console","log","JSON","stringify","S3Object","data","error_message","error_body","startsWith","S3ServiceError","awsError","parseXML","S3Bucket","operation","SecretsManagerClient","commonHeaders","json","s","Secret","fromJSON","secretID","SecretId","secretString","description","versionID","tags","uuidv4","Name","Description","SecretString","ClientRequestToken","Tags","recoveryWindow","noRecovery","response","errorCode","errorMessage","Message","__type","SecretsManagerError","arn","createdDate","lastAccessedDate","lastChangedDate","secret","ARN","CreatedDate","LastAccessedDate","LastChangedDate"],"sourceRoot":""} \ No newline at end of file diff --git a/build/s3.min.js b/build/s3.min.js index 2778ae3..5b52dc8 100644 --- a/build/s3.min.js +++ b/build/s3.min.js @@ -1,2 +1,2 @@ -(()=>{"use strict";var e={n:t=>{var r=t&&t.__esModule?()=>t.default:()=>t;return e.d(r,{a:r}),r},d:(t,r)=>{for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{AWSConfig:()=>F,InvalidAWSConfigError:()=>$,InvalidSignatureError:()=>R,S3Bucket:()=>ye,S3Client:()=>pe,S3Object:()=>he,S3ServiceError:()=>be,URIEncodingConfig:()=>I});const r=require("k6/crypto");var n=e.n(r);const o=require("k6/html");function i(e){return i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i(e)}function c(e,t){for(var r=0;re.length)&&(t=e.length);for(var r=0,n=new Array(t);r="A"&&r<="Z"||r>="a"&&r<="z"||function(e){return e>="0"&&e<="9"}(e)||"-._~".includes(e)?e:" "==e?"%20":"/"==e&&t?"/":"%"+e.charCodeAt(0).toString(16).toUpperCase();var r})).join("")}var I=w((function e(t,r){O(this,e),d(this,"double",void 0),d(this,"path",void 0),this.double=t,this.path=r}));function M(e){return new Date(e).toISOString().replace(/[:\-]|\.\d{3}/g,"")}function D(e){return M(e).substring(0,8)}function z(e){return z="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},z(e)}function q(e,t){if(t&&("object"===z(t)||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e)}function H(e){var t="function"==typeof Map?new Map:void 0;return H=function(e){if(null===e||(r=e,-1===Function.toString.call(r).indexOf("[native code]")))return e;var r;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return U(e,arguments,B(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),L(n,e)},H(e)}function U(e,t,r){return U=N()?Reflect.construct:function(e,t,r){var n=[null];n.push.apply(n,t);var o=new(Function.bind.apply(e,n));return r&&L(o,r.prototype),o},U.apply(null,arguments)}function N(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}function L(e,t){return L=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},L(e,t)}function B(e){return B=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},B(e)}function W(e,t){for(var r=0;r{"use strict";var e={n:t=>{var r=t&&t.__esModule?()=>t.default:()=>t;return e.d(r,{a:r}),r},d:(t,r)=>{for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{AWSConfig:()=>F,InvalidAWSConfigError:()=>$,InvalidSignatureError:()=>R,S3Bucket:()=>ye,S3Client:()=>pe,S3Object:()=>he,S3ServiceError:()=>be,URIEncodingConfig:()=>D});const r=require("k6/crypto");var n=e.n(r);const o=require("k6/html");function i(e){return i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i(e)}function c(e,t){for(var r=0;re.length)&&(t=e.length);for(var r=0,n=new Array(t);r="A"&&r<="Z"||r>="a"&&r<="z"||function(e){return e>="0"&&e<="9"}(e)||"-._~".includes(e)?e:" "==e?"%20":"/"==e&&t?"/":"%"+e.charCodeAt(0).toString(16).toUpperCase();var r})).join("")}var D=w((function e(t,r){O(this,e),d(this,"double",void 0),d(this,"path",void 0),this.double=t,this.path=r}));function I(e){return new Date(e).toISOString().replace(/[:\-]|\.\d{3}/g,"")}function M(e){return I(e).substring(0,8)}function z(e){return z="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},z(e)}function q(e,t){if(t&&("object"===z(t)||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e)}function H(e){var t="function"==typeof Map?new Map:void 0;return H=function(e){if(null===e||(r=e,-1===Function.toString.call(r).indexOf("[native code]")))return e;var r;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return N(e,arguments,B(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),L(n,e)},H(e)}function N(e,t,r){return N=U()?Reflect.construct:function(e,t,r){var n=[null];n.push.apply(n,t);var o=new(Function.bind.apply(e,n));return r&&L(o,r.prototype),o},N.apply(null,arguments)}function U(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}function L(e,t){return L=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},L(e,t)}function B(e){return B=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},B(e)}function W(e,t){for(var r=0;r {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/crypto\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/html\");","import { parseHTML } from 'k6/html'\n\n/**\n * Base class to derive errors from\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class AWSError extends Error {\n code: string\n\n /**\n * Create an AWSError\n *\n * @param {string} message - A longer human readable error message.\n * @param {string} code - A unique short code representing the error that was emitted\n */\n constructor(message: string, code: string) {\n super(message)\n this.name = 'AWSError'\n this.code = code\n }\n\n /**\n * Parse an AWSError from an XML document\n *\n * @param {string} xmlDocument - Serialized XML document to parse the error from\n */\n static parseXML(xmlDocument: string): AWSError {\n const doc = parseHTML(xmlDocument)\n return new AWSError(doc.find('Message').text(), doc.find('Code').text())\n }\n}\n","import crypto, { hmac, sha256 } from 'k6/crypto'\nimport { HTTPMethod, HTTPHeaders } from './http'\nimport { AWSConfig } from './config'\nimport { AWSError } from './error'\n\n/**\n * Includes AWS v4 signing information to the provided HTTP headers object.\n *\n * This function will compute the `Authorization` header signature for the\n * provided request components, and add it to `header`. It will do so by following\n * the procedure detailled AWS' API docs: https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html\n *\n * The resulting `Authorization` header value is computed for the provided\n * headers object. Thus, any modification of the headers past a call to `signHeaders`\n * would effectively invalidate their signature, and the function should be\n * called again to recompute it.\n *\n * @param {object} headers - HTTP headers request to sign.\n * @param {number} requestTimestamp - Timestamp of the request\n * @param {string} method - HTTP method used\n * @param {string} path - HTTP request URL's path\n * @param {string} queryString - HTTP request URL's querystring\n * @param {string | ArrayBuffer} body - HTTP request's payload\n * @param {AWSConfig} - AWS configuration\n * @param {string} service - AWS service name\n * @param {URIEncodingConfig} - URI encoding configuration\n */\nexport function signHeaders(\n headers: HTTPHeaders,\n requestTimestamp: number,\n method: HTTPMethod,\n path: string,\n queryString: string,\n body: string | ArrayBuffer,\n awsConfig: AWSConfig,\n service: string,\n URIencodingConfig: URIEncodingConfig\n): HTTPHeaders {\n const derivedSigningKey = deriveSigningKey(\n awsConfig.secretAccessKey,\n requestTimestamp,\n awsConfig.region,\n service\n )\n\n const canonicalRequest = createCanonicalRequest(\n method,\n path,\n queryString,\n headers,\n body,\n URIencodingConfig\n )\n\n const stringToSign = createStringToSign(\n requestTimestamp,\n awsConfig.region,\n service,\n sha256(canonicalRequest, 'hex')\n )\n\n const credentialScope = createCredentialScope(requestTimestamp, awsConfig.region, service)\n const signedHeaders = createSignedHeaders(headers)\n const signature = calculateSignature(derivedSigningKey, stringToSign)\n const authorizationHeader = `${HashingAlgorithm} Credential=${awsConfig.accessKeyID}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`\n\n headers['Authorization'] = authorizationHeader\n\n return headers\n}\n\n/**\n * Error indicating an Invalid signature has been sent to AWS services\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class InvalidSignatureError extends AWSError {\n /**\n * Constructs an InvalidSignatureError\n *\n * @param {string} message - human readable error message\n */\n constructor(message: string, code: string) {\n super(message, code)\n this.name = 'InvalidSignatureError'\n }\n}\n\n/**\n * Calculte the signature for AWS signature version 4\n *\n * @param {string} derivedSigningKey - dervied signing key as computed by `deriveSigningKey`\n * @param {string} stringToSign - String to sign as computed by `createStringToSign`\n * @return {string}\n */\nexport function calculateSignature(derivedSigningKey: ArrayBuffer, stringToSign: string): string {\n return hmac('sha256', derivedSigningKey, stringToSign, 'hex')\n}\n/**\n * Derives the signing key for authenticating requests signed with\n * the Signature version 4 authentication protocol.\n *\n * deriveSigningKey produces a signing key by creating a series of\n * hash-based message authentication codes (HMACs) represented in\n * a binary format.\n *\n * The derived signing key is specific to the date it's made at, as well as\n * the service and region it targets.\n *\n * @param {string} secretAccessKey - the AWS secret access key to derive the signing key for\n * @param {number} time - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service. MUST be UTF-8 encoded.\n * @return {string}\n */\nexport function deriveSigningKey(\n secretAccessKey: string,\n time: number,\n region: string,\n service: string\n): ArrayBuffer {\n const kSecret = secretAccessKey\n const date = toDate(time)\n\n // FIXME: hmac takes ArrayBuffer as input, but returns bytes (number[]).\n // How does one convert from one to the other?\n const kDate: any = hmac('sha256', 'AWS4' + kSecret, date, 'binary')\n const kRegion: any = hmac('sha256', kDate, region, 'binary')\n const kService: any = hmac('sha256', kRegion, service, 'binary')\n const kSigning: any = hmac('sha256', kService, 'aws4_request', 'binary')\n\n return kSigning\n}\n\n// Hashing Algorithm to use in the signature process\nexport const HashingAlgorithm = 'AWS4-HMAC-SHA256'\n\n/**\n * Certain services, such as S3, allow for unsigned payloads. If\n * producing a signed canonical request for such service, pass\n * the `UnsignedPayload` constant value as the payload parameter.\n */\nexport const UnsignedPayload = 'UNSIGNED-PAYLOAD'\n\n/**\n * Create the \"string to sign\" part of the signature Version 4 protocol.\n *\n * The \"string to sign\" includes meta information about your request and\n * about the canonical request that you created with `createCanonicalRequest`.\n * It is used hand in hand with the signing key to create the request signature.\n *\n * @param {number} requestTimestamp - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service name. MUST be UTF-8 encoded.\n * @param {string} hashedCanonicalRequest - canonical request as produced by calling the createCanonicalRequest function,\n * hashed using the SHA256 algorithm (encoded in hexadecimal format).\n * @return {string}\n */\nexport function createStringToSign(\n requestTimestamp: number,\n region: string,\n service: string,\n hashedCanonicalRequest: string\n): string {\n // the request date specified in ISO8601 format: YYYYMMDD'T'HHMMSS'Z'\n const requestDateTime = toTime(requestTimestamp)\n\n // The credential scope value, consisting of the date in YYYYMMDD format,\n // the targeted region, the targeted service, and a termination string.\n // Note that the region and service MUST be UTF-8 encoded.\n const credentialScope = createCredentialScope(requestTimestamp, region, service)\n\n const stringToSign = [\n // Algorithm\n HashingAlgorithm,\n\n // RequestDateTime\n requestDateTime,\n\n // CredentialScope\n credentialScope,\n\n // HashedCanonicalRequest\n hashedCanonicalRequest,\n ].join('\\n')\n\n return stringToSign\n}\n\n/**\n *\n * Helper function creating a credential scope string to use in the signature\n * version 4 process. A credential scope consists of the date of the request\n * in YYYYMMDD format, the targeted region, the targeted service, and a\n * termination string.\n *\n * Note that the region and service MUST be UTF-8 encoded.\n *\n * @param {number} requestTimestamp - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service name. MUST be UTF-8 encoded.\n * @return {string}\n */\nexport function createCredentialScope(\n requestTimestamp: number,\n region: string,\n service: string\n): string {\n return [toDate(requestTimestamp), region, service, 'aws4_request'].join('/')\n}\n\n/**\n * Create a string that includes information from your request\n * in a AWS signature v4 standardized (canonical) format.\n *\n * @param {string} method - the HTTP request method\n * @param {string} uri - URI-encoded version of the absolute path component of the URI\n * @param {string} query - request's query string\n * @param {Object} headers - all the HTTP headers that you wish to include with the signed request\n * @param {string | ArrayBuffer} payload - payload to include as the body of the request\n * @param {URIEncodingConfig} URIencodingConfig- URI encoding configuration\n * @return {string}\n */\nexport function createCanonicalRequest(\n method: HTTPMethod,\n uri: string,\n query: string,\n headers: HTTPHeaders,\n payload: string | ArrayBuffer,\n URIencodingConfig: URIEncodingConfig\n): string {\n const httpRequestMethod = method.toUpperCase()\n const canonicalURI = createCanonicalURI(uri, URIencodingConfig)\n const canonicalQueryString = createCanonicalQueryString(query)\n const canonicalHeaders = createCanonicalHeaders(headers)\n const signedHeaders = createSignedHeaders(headers)\n const requestPayload = createCanonicalPayload(payload)\n\n const canonicalRequest = [\n httpRequestMethod,\n canonicalURI,\n canonicalQueryString,\n canonicalHeaders,\n signedHeaders,\n requestPayload,\n ].join('\\n')\n\n return canonicalRequest\n}\n\n/**\n * Creates the (canonical) URI-encoded version of the\n * absolute path component of the URI: everything in the URI\n * from the HTTP host to the question mark character (\"?\")\n * that begins the query string parameters (if any).\n *\n * @param {string} uri - URI to canonize\n * @param {URIEncodingConfig} - URI encoding configuration\n * @return {string} - canonical URL\n */\nexport function createCanonicalURI(uri: string, URIencodingConfig: URIEncodingConfig): string {\n if (uri == '/') {\n return uri\n }\n\n let canonicalURI = uri\n if (uri[uri.length - 1] == '/' && canonicalURI[canonicalURI.length - 1] != '/') {\n canonicalURI += '/'\n }\n\n canonicalURI = URIEncode(canonicalURI, URIencodingConfig.path)\n\n return URIencodingConfig.double ? URIEncode(canonicalURI, URIencodingConfig.path) : canonicalURI\n}\n\n// FIXME: does it work as expected?\n/**\n * Creates the canonical form of the request's query\n * string. If the request does not include a query string,\n * provide an empty string.\n *\n * @param {String | Object} qs - query string to canonize\n * @return {string}\n */\nexport function createCanonicalQueryString(qs: string): string {\n if (qs === '') {\n return ''\n }\n\n // const intermediary: { [key: string]: string } = parseQueryString(qs)\n\n // return Object.keys(intermediary)\n // .sort()\n // .map((key: string) => {\n // // const values: string[] = Array.isArray(intermediary[key])\n // // ? intermediary[key]\n // // : [intermediary[key]]\n // const values = intermediary[key]\n\n // return values\n // .sort()\n // .map((val: string) => encodeURIComponent(key) + '=' + encodeURIComponent(val))\n // .join('&')\n // })\n // .join('&')\n\n return parseQueryString(qs)\n .map(([key, value]: [string, string]): string => {\n return encodeURIComponent(key) + '=' + encodeURIComponent(value)\n })\n .join('&')\n}\n/**\n * Create the canonical form of the request's headers.\n * Canonical headers consist of all the HTTP headers you\n * are including with the signed request.\n *\n * Note that:\n * * for HTTP/1.1 requests, the headers should at least\n * contain the `host` header.\n * * for HTTP/2, the `:authority` header must be used instead\n * of `host`.\n *\n * @param {Object} headers\n * @return {string}\n */\nexport function createCanonicalHeaders(headers: HTTPHeaders) {\n if (headers.constructor !== Object || Object.entries(headers).length === 0) {\n return ''\n }\n\n const canonicalHeaders = Object.entries(headers)\n .map(([name, values]) => {\n const canonicalName = name.toLowerCase().trim()\n const normalizedValues = Array.isArray(values) ? values : [values]\n\n // Note that we do not need to sort values\n const canonicalValues = normalizedValues\n .map((v) => {\n // convert sequential spaces to a single space\n return v.replace(/\\s+/g, ' ').replace(/^\\s+|\\s+$/g, '')\n })\n .join(',') // standard for multiple values in a HTTP header\n\n return canonicalName + ':' + canonicalValues + '\\n'\n })\n .sort()\n .join('')\n\n return canonicalHeaders\n}\n\n/**\n * Create the canonical request's signed headers.\n *\n * The signed headers part of the request contains the\n * list of headers included in the request's signing process.\n *\n * Note that:\n * * for HTTP/1.1 requests, the `host` header must be included.\n * * for HTTP/2 requests, the `:authority` header must be included instead\n * of host.\n * * if used, the `x-amz-date` header must be included.\n *\n * @param {Object} headers\n * @return {string}\n * @throws {TypeError} - on headers not being an Object, or being empty.\n */\nexport function createSignedHeaders(headers: { [key: string]: string }) {\n if (headers.constructor !== Object) {\n throw new TypeError('headers should be an object')\n }\n\n if (Object.entries(headers).length === 0) {\n throw 'headers should at least contain either the Host (HTTP 1.1) or :authority (HTTP 2) parameter'\n }\n\n // To create the signed headers list, convert\n // all header names to lowercase, sort them by\n // character code, and use a semicolon to separate\n // the header names.\n const result = Object.keys(headers)\n .map((name) => name.toLowerCase().trim())\n .sort()\n .join(';')\n\n return result\n}\n\n/**\n * Create the canonical form of the request's payload.\n *\n * The canonical payload consists in a lowercased, hex encoded,\n * SHA256 hash of the requests body/payload.\n *\n * Certain services, such as S3, allow for unsigned payload. If\n * producing a signed canonical request for such service, pass\n * the `UnsignedPayload` constant value as the payload parameter.\n *\n * @param {String | ArrayBuffer} payload\n * @return {string}\n */\nexport function createCanonicalPayload(payload: string | ArrayBuffer) {\n if (payload === UnsignedPayload) {\n return payload\n }\n\n // Note that if the paylaod is null, we convert it\n // to an empty string.\n // TODO: Should switching to empty string if null impact headers?\n return crypto.sha256(payload || '', 'hex').toLowerCase()\n}\n\n/**\n * URIEncodes encodes every bytes of a URI to be URL-safe.\n *\n * This implementation is specific to AWS; who intended to make it as\n * close as possible to the underlying RFC 3946. It:\n * * URI encode every byte except the unreserved characters: 'A'-'Z', 'a'-'z', '0'-'9',\n * '-', '.', '_', and '~'.\n * * considers the space character as a reserved character and must URI encodes\n * encodes it as \"%20\" (and not as \"+\").\n * * URI encodes every byte by prefixing with '%' the two-digit hexadecimal value of the byte.\n * * If the `path` argument is set, forward slashes are not encoded, to fit with\n * S3 requirements.\n *\n * N.B: this implementation differs with ES6' mainly in that it does\n * encode the \"'\" character.\n *\n * Based on AWS implementation: https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-core/src/main/java/com/amazonaws/util/SdkHttpUtils.java#L66\n * Encoding specs: https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html\n *\n * @param {string} uri - uri to encode\n * @param {boolean} path - slash characters should be encoded everywhere,\n * but in paths, set to false when encoding a path\n * @return {string} the URI encoded result\n */\nexport function URIEncode(uri: string, path: boolean): string {\n if (uri == '') {\n return uri\n }\n\n return uri\n .split('') // to be able to map over a string, because... javascript...\n .map((letter: string) => {\n if (isAlpha(letter) || isNumeric(letter) || '-._~'.includes(letter)) {\n return letter\n }\n\n // Space should be explicitly encoded to as %20.\n if (letter == ' ') {\n return '%20'\n }\n\n // If the URI is a path, the forward slash shouldn't\n // be encoded.\n if (letter == '/' && path) {\n return '/'\n }\n\n return '%' + letter.charCodeAt(0).toString(16).toUpperCase()\n })\n .join('')\n}\n\n/**\n * Class holding URI encoding configuration\n */\nexport class URIEncodingConfig {\n double: boolean\n path: boolean\n\n /**\n *\n * @param {boolean} double - should the URI be double encoded?\n * @param {boolean} path - is the URI a path? If so, its forward\n * slashes won't be URIencoded.\n */\n constructor(double: boolean, path: boolean) {\n this.double = double\n this.path = path\n }\n}\n\n/**\n * Compute the request time value as specified by the ISO8601\n * format: YYYYMMDD'T'HHMMSS'Z'\n *\n * @param {number} timestamp\n * @return {string}\n */\nexport function toTime(timestamp: number): string {\n return new Date(timestamp).toISOString().replace(/[:\\-]|\\.\\d{3}/g, '')\n}\n/**\n * Computethe request date value in the format: YYYMMDD\n *\n * @param {number} timestamp\n * @return {string}\n */\nexport function toDate(timestamp: number): string {\n return toTime(timestamp).substring(0, 8)\n}\n\n// FIXME: does it work as expected?\n/**\n * Parse a HTTP request URL's querystring into an object\n * containing its `key=value` pairs.\n *\n * @param {string} qs\n * @return {object}\n */\nexport function parseQueryString(qs: string): Array<[string, string]> {\n if (qs.length === 0) {\n return []\n }\n\n return qs\n .split('&')\n .filter((e) => e)\n .map((v: string): [string, string] => {\n const parts = v.split('=', 2) as [string, string]\n return [decodeURIComponent(parts[0]), decodeURIComponent(parts[1])]\n })\n .sort((a: [string, string], b: [string, string]) => {\n return a[0].localeCompare(b[0])\n })\n}\n\nfunction isAlpha(c: string): boolean {\n return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')\n}\n\nfunction isNumeric(c: string): boolean {\n return c >= '0' && c <= '9'\n}\n\n// FIXME: finish implementation when needed\n// See the following for more details:\n// * https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html\n// * https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html\n// export function signQueryString(\n// queryString,\n// requestTimestamp,\n// accessKeyID,\n// secretAccessKey,\n// region,\n// service,\n// ttl, // in seconds\n// headers,\n// doubleURIEncoding = true\n// ) {\n// const credential = [accessKeyID, toDate(requestTimestamp), region, service].join('/')\n//\n// const canonicalRequest = createCanonicalRequest(\n// method,\n// path,\n// queryString,\n// headers,\n// body,\n// doubleURIEncoding\n// )\n//\n// const derivedSigningKey = deriveSigningKey(secretAccessKey, requestTimestamp, region, service)\n//\n// const stringToSign = createStringToSign(\n// requestTimestamp,\n// region,\n// service,\n// sha256(canonicalRequest, 'hex')\n// )\n//\n// const signedHeaders = createSignedHeaders(headers)\n// const signature = calculateSignature(derivedSigningKey, stringToSign)\n//\n// return [\n// `X-Amz-Algorithm=${HashingAlgorithm}`,\n// `X-Amz-Credential=${crediental}`,\n// `X-Amz-Date=${toTime(requestTimestamp)}`,\n// `X-Amz-Expires=${ttl}`,\n// `X-Amz-SignedHeaders=${signedHeaders}`,\n// `X-Amz-Signature=${signature}`,\n//`X-Amz-Security-Token=`, // TODO: optional\n// ].join('&')\n// }\n","/** Class holding an AWS connection information */\nexport class AWSConfig {\n region: string\n accessKeyID: string\n secretAccessKey: string\n\n /**\n * Create an AWSConfig.\n *\n * @param {string} region - the AWS region to connect to, as listed: https://docs.aws.amazon.com/general/latest/gr/rande.html\n * @param {string} accessKeyID - Your user's AWS access key id credential\n * @param {string} secretAccessKey - Your user's AWS secret access key credential\n * @throws {InvalidArgumentException}\n */\n constructor(region: string, accessKeyID: string, secretAccessKey: string) {\n if (typeof region !== 'string' || region === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS region; reason: should be a non empty string'\n )\n }\n\n if (typeof accessKeyID !== 'string' || accessKeyID === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS access key ID; reason: should be a non empty string'\n )\n }\n\n if (typeof secretAccessKey !== 'string' || secretAccessKey === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS secret access key; reason: should be a non empty string'\n )\n }\n\n this.region = region\n this.accessKeyID = accessKeyID\n this.secretAccessKey = secretAccessKey\n }\n}\n\n/** Class representing an invalid AWS configuration */\nexport class InvalidAWSConfigError extends Error {\n constructor(message: string) {\n super(message)\n }\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/http\");","import { bytes } from 'k6'\nimport http from 'k6/http'\nimport { parseHTML } from 'k6/html'\nimport { sha256 } from 'k6/crypto'\n\nimport { InvalidSignatureError, URIEncodingConfig } from './signature'\nimport { AWSClient, AWSRequest } from './client'\nimport { AWSError } from './error'\nimport { AWSConfig } from './config'\n\n/** Class allowing to interact with Amazon AWS's S3 service */\nexport class S3Client extends AWSClient {\n /**\n * Create a S3Client\n *\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n */\n constructor(awsConfig: AWSConfig) {\n const URIencodingConfig = new URIEncodingConfig(false, true)\n super(awsConfig, 's3', URIencodingConfig)\n }\n\n /**\n * Returns a list of all buckets owned by the authenticated sender of the request.\n * To use this operation, you must have the s3:ListAllMyBuckets permission.\n *\n * @return {Array.} buckets - An array of objects describing S3 buckets\n * with the following fields: name, and creationDate.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n listBuckets(): Array {\n // Prepare request\n const method = 'GET'\n const host = `${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(method, host, '/', '', body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n let buckets: Array = []\n\n const doc = parseHTML(res.body as string)\n\n doc.find('Buckets')\n .children()\n .each((_, bucketDefinition) => {\n let bucket = {}\n\n bucketDefinition.children().forEach((child) => {\n switch (child.nodeName()) {\n case 'name':\n Object.assign(bucket, { name: child.textContent() })\n break\n case 'creationdate':\n Object.assign(bucket, {\n creationDate: Date.parse(child.textContent()),\n })\n }\n })\n\n buckets.push(bucket as S3Bucket)\n })\n\n return buckets\n }\n\n /**\n * Returns some or all (up to 1,000) of the objects in a bucket.\n *\n * @param {string} bucketName - Bucket name to list.\n * @param {string?} prefix='' - Limits the response to keys that begin with the specified prefix.\n * @return {Array.} - returns an array of objects describing S3 objects\n * with the following fields: key, lastModified, etag, size and storageClass.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n listObjects(bucketName: string, prefix?: string): Array {\n // Prepare request\n const method = 'GET'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const body = ''\n const querystring = `list-type=2&prefix=${prefix}`\n const signedRequest: AWSRequest = super.buildRequest(method, host, '/', querystring, body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n Prefix: prefix ?? '',\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n let objects: Array = []\n\n // Extract the objects definition from\n // the XML response\n parseHTML(res.body as string)\n .find('Contents')\n .each((_, objectDefinition) => {\n let obj = {}\n\n objectDefinition.children().forEach((child) => {\n switch (child.nodeName()) {\n case 'key':\n Object.assign(obj, { key: child.textContent() })\n break\n case 'lastmodified':\n Object.assign(obj, { lastModified: Date.parse(child.textContent()) })\n break\n case 'etag':\n Object.assign(obj, { etag: child.textContent() })\n break\n case 'size':\n Object.assign(obj, { size: parseInt(child.textContent()) })\n break\n case 'storageclass':\n Object.assign(obj, { storageClass: child.textContent() })\n }\n })\n\n objects.push(obj as S3Object)\n })\n\n return objects\n }\n /**\n * Retrieves an Object from Amazon S3.\n *\n * To use getObject, you must have `READ` access to the object.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to get.\n * @return {S3Object} - returns the content of the fetched S3 Object.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n getObject(bucketName: string, objectKey: string): S3Object {\n // Prepare request\n const method = 'GET'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(method, host, path, '', body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n return new S3Object(\n objectKey,\n Date.parse(res.headers['Last-Modified']),\n res.headers['ETag'],\n parseInt(res.headers['Content-Length']),\n undefined, // FIXME: GetObject response doesn't contain the storage class\n res.body\n )\n }\n /**\n * Adds an object to a bucket.\n *\n * You must have WRITE permissions on a bucket to add an object to it.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to put.\n * @param {string | ArrayBuffer} data - the content of the S3 Object to upload.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n putObject(bucketName: string, objectKey: string, data: string | ArrayBuffer) {\n // Prepare request\n const method = 'PUT'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const queryString = ''\n const body = data\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n path,\n queryString,\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n }\n\n /**\n * Removes the null version (if there is one) of an object and inserts a delete marker,\n * which becomes the latest version of the object.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to delete.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n deleteObject(bucketName: string, objectKey: string): void {\n // Prepare request\n const method = 'DELETE'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const queryString = ''\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n path,\n queryString,\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n }\n\n // FIXME: remove dependency to `error_message`\n // FIXME: just pass it the response?\n _handle_error(error_code: number, error_message: string, error_body: string) {\n if (error_message == '' || error_code === 0) {\n return\n }\n\n // FIXME: should be error_code === 1301 instead\n // See: https://github.com/grafana/k6/issues/2474\n // See: https://github.com/golang/go/issues/49281\n if (error_message && error_message.startsWith('301')) {\n // Bucket not found\n throw new S3ServiceError('Resource not found', 'ResourceNotFound', 'getObject')\n }\n\n const awsError = AWSError.parseXML(error_body)\n switch (awsError.code) {\n case 'AuthorizationHeaderMalformed':\n throw new InvalidSignatureError(awsError.message, awsError.code)\n default:\n throw new S3ServiceError(awsError.message, awsError.code, 'listObjects')\n }\n }\n}\n\n// TODO: use interface instead?\n/** Class representing a S3 Bucket */\nexport class S3Bucket {\n name: string\n creationDate: Date\n\n /**\n * Create an S3 Bucket\n *\n * @param {string} name - S3 bucket's name\n * @param {Date} creationDate - S3 bucket's creation date\n */\n constructor(name: string, creationDate: Date) {\n this.name = name\n this.creationDate = creationDate\n }\n}\n\n// TODO: use interface instead?\n/** Class representing an S3 Object */\nexport class S3Object {\n key: string\n lastModified: number\n etag: string\n size: number\n storageClass: StorageClass\n data?: string | bytes | null\n\n /**\n * Create an S3 Object\n *\n * @param {string} key - S3 object's key\n * @param {Date} lastModified - S3 object last modification date\n * @param {string} etag - S3 object's etag\n * @param {number} size - S3 object's size\n * @param {StorageClass} storageClass - S3 object's storage class\n * @param {string | bytes | null} data=null - S3 Object's data\n */\n constructor(\n key: string,\n lastModified: number,\n etag: string,\n size: number,\n storageClass: StorageClass,\n data?: string | bytes | null\n ) {\n this.key = key\n this.lastModified = lastModified\n this.etag = etag\n this.size = size\n this.storageClass = storageClass\n this.data = data\n }\n}\n\n/**\n * Error indicating a S3 operation failed\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class S3ServiceError extends AWSError {\n operation: string\n\n /**\n * Constructs a S3ServiceError\n *\n * @param {string} message - human readable error message\n * @param {string} code - A unique short code representing the error that was emitted\n * @param {string} operation - Name of the failed Operation\n */\n constructor(message: string, code: string, operation: string) {\n super(message, code)\n this.name = 'S3ServiceError'\n this.operation = operation\n }\n}\n\n/**\n * Describes the class of storage used to store a S3 object.\n */\ntype StorageClass =\n | 'STANDARD'\n | 'REDUCED_REDUNDANCY'\n | 'GLACIER'\n | 'STANDARD_IA'\n | 'INTELLIGENT_TIERING'\n | 'DEEP_ARCHIVE'\n | 'OUTPOSTS'\n | 'GLACIER_IR'\n | undefined\n","import { HTTPMethod, HTTPHeaders } from './http'\nimport { AWSConfig } from './config'\nimport { signHeaders, URIEncodingConfig, toTime } from './signature'\n\n/**\n * Class allowing to build requests targeting AWS APIs\n *\n * This class is meant to be used as a base class for specific\n * services clients. See S3Client or SecretsManagerClient for\n * usage examples.\n */\nexport class AWSClient {\n awsConfig: AWSConfig\n serviceName: string\n URIencodingConfig: URIEncodingConfig\n\n /**\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n * @param {string} serviceName - name of the service to target.\n * @param {URIEncodingConfig} URIencodingConfig - configures how requests URIs should be encoded.\n */\n constructor(awsConfig: AWSConfig, serviceName: string, URIencodingConfig: URIEncodingConfig) {\n this.awsConfig = awsConfig\n this.serviceName = serviceName\n this.URIencodingConfig = URIencodingConfig\n }\n\n buildRequest(\n method: HTTPMethod,\n host: string,\n path: string,\n queryString: string,\n body: string | ArrayBuffer,\n headers: HTTPHeaders\n ): AWSRequest {\n const requestTimestamp: number = Date.now()\n const date: string = toTime(requestTimestamp)\n\n headers['Host'] = host\n headers['X-Amz-Date'] = date\n\n headers = signHeaders(\n // headers\n headers,\n\n // requestTimestamp\n requestTimestamp,\n\n // method\n method,\n\n // path\n path,\n\n // querystring\n queryString,\n\n // body\n body,\n\n // AWS configuration\n this.awsConfig,\n\n // AwS target service name\n this.serviceName,\n\n // doubleEncoding: S3 does single-encoding of the uri component\n // pathURIEncoding: S3 manipulates object keys, and forward slashes\n // shouldn't be URI encoded\n this.URIencodingConfig\n )\n\n // '?' should not be part of the querystring when we sign the headers\n path = path !== '' ? path : '/'\n let url = `https://${host}${path}`\n if (queryString !== '') {\n url += `?${queryString}`\n }\n\n return { url: url, headers: headers }\n }\n}\n\n/**\n * Type alias representing the result of an AWSClient.buildRequest call\n */\nexport interface AWSRequest {\n url: string\n headers: HTTPHeaders\n}\n"],"names":["__webpack_require__","module","getter","__esModule","d","a","exports","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","require","AWSError","message","code","name","xmlDocument","doc","parseHTML","find","text","Error","signHeaders","headers","requestTimestamp","method","path","queryString","body","awsConfig","service","URIencodingConfig","derivedSigningKey","secretAccessKey","time","region","kSecret","date","toDate","kDate","hmac","kRegion","kService","deriveSigningKey","canonicalRequest","uri","query","payload","httpRequestMethod","toUpperCase","canonicalURI","length","URIEncode","createCanonicalURI","canonicalQueryString","qs","split","filter","e","map","v","parts","decodeURIComponent","sort","b","localeCompare","parseQueryString","encodeURIComponent","join","createCanonicalQueryString","canonicalHeaders","constructor","entries","values","toLowerCase","trim","Array","isArray","replace","createCanonicalHeaders","signedHeaders","createSignedHeaders","requestPayload","UnsignedPayload","crypto","createCanonicalPayload","createCanonicalRequest","stringToSign","hashedCanonicalRequest","requestDateTime","toTime","credentialScope","createCredentialScope","HashingAlgorithm","createStringToSign","sha256","signature","calculateSignature","authorizationHeader","accessKeyID","InvalidSignatureError","TypeError","keys","letter","c","isNumeric","includes","charCodeAt","toString","URIEncodingConfig","double","this","timestamp","Date","toISOString","substring","AWSConfig","InvalidAWSConfigError","S3Client","host","serviceName","signedRequest","res","http","url","_handle_error","error_code","error","buckets","children","each","_","bucketDefinition","bucket","forEach","child","nodeName","assign","textContent","creationDate","parse","push","bucketName","prefix","querystring","Prefix","objects","objectDefinition","lastModified","etag","size","parseInt","storageClass","objectKey","S3Object","undefined","data","error_message","error_body","startsWith","S3ServiceError","awsError","parseXML","now","S3Bucket","operation"],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"s3.min.js","mappings":"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","sources":["webpack://k6-jslib-aws/webpack/bootstrap","webpack://k6-jslib-aws/webpack/runtime/compat get default export","webpack://k6-jslib-aws/webpack/runtime/define property getters","webpack://k6-jslib-aws/webpack/runtime/hasOwnProperty shorthand","webpack://k6-jslib-aws/webpack/runtime/make namespace object","webpack://k6-jslib-aws/external commonjs \"k6/crypto\"","webpack://k6-jslib-aws/external commonjs \"k6/html\"","webpack://k6-jslib-aws/./src/internal/error.ts","webpack://k6-jslib-aws/./src/internal/signature.ts","webpack://k6-jslib-aws/./src/internal/config.ts","webpack://k6-jslib-aws/external commonjs \"k6/http\"","webpack://k6-jslib-aws/./src/internal/s3.ts","webpack://k6-jslib-aws/./src/internal/client.ts"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/crypto\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/html\");","import { parseHTML } from 'k6/html'\n\n/**\n * Base class to derive errors from\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class AWSError extends Error {\n code: string\n\n /**\n * Create an AWSError\n *\n * @param {string} message - A longer human readable error message.\n * @param {string} code - A unique short code representing the error that was emitted\n */\n constructor(message: string, code: string) {\n super(message)\n this.name = 'AWSError'\n this.code = code\n }\n\n /**\n * Parse an AWSError from an XML document\n *\n * @param {string} xmlDocument - Serialized XML document to parse the error from\n */\n static parseXML(xmlDocument: string): AWSError {\n const doc = parseHTML(xmlDocument)\n return new AWSError(doc.find('Message').text(), doc.find('Code').text())\n }\n}\n","import crypto, { hmac, sha256 } from 'k6/crypto'\nimport { HTTPMethod, HTTPHeaders } from './http'\nimport { AWSConfig } from './config'\nimport { AWSError } from './error'\n\n/**\n * Includes AWS v4 signing information to the provided HTTP headers object.\n *\n * This function will compute the `Authorization` header signature for the\n * provided request components, and add it to `header`. It will do so by following\n * the procedure detailled AWS' API docs: https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html\n *\n * The resulting `Authorization` header value is computed for the provided\n * headers object. Thus, any modification of the headers past a call to `signHeaders`\n * would effectively invalidate their signature, and the function should be\n * called again to recompute it.\n *\n * @param {object} headers - HTTP headers request to sign.\n * @param {number} requestTimestamp - Timestamp of the request\n * @param {string} method - HTTP method used\n * @param {string} path - HTTP request URL's path\n * @param {string} queryString - HTTP request URL's querystring\n * @param {string | ArrayBuffer} body - HTTP request's payload\n * @param {AWSConfig} - AWS configuration\n * @param {string} service - AWS service name\n * @param {URIEncodingConfig} - URI encoding configuration\n */\nexport function signHeaders(\n headers: HTTPHeaders,\n requestTimestamp: number,\n method: HTTPMethod,\n path: string,\n queryString: string,\n body: string | ArrayBuffer,\n awsConfig: AWSConfig,\n service: string,\n URIencodingConfig: URIEncodingConfig\n): HTTPHeaders {\n const derivedSigningKey = deriveSigningKey(\n awsConfig.secretAccessKey,\n requestTimestamp,\n awsConfig.region,\n service\n )\n\n const canonicalRequest = createCanonicalRequest(\n method,\n path,\n queryString,\n headers,\n body,\n URIencodingConfig\n )\n\n const stringToSign = createStringToSign(\n requestTimestamp,\n awsConfig.region,\n service,\n sha256(canonicalRequest, 'hex')\n )\n\n const credentialScope = createCredentialScope(requestTimestamp, awsConfig.region, service)\n const signedHeaders = createSignedHeaders(headers)\n const signature = calculateSignature(derivedSigningKey, stringToSign)\n const authorizationHeader = `${HashingAlgorithm} Credential=${awsConfig.accessKeyID}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`\n\n headers['Authorization'] = authorizationHeader\n\n return headers\n}\n\n/**\n * Error indicating an Invalid signature has been sent to AWS services\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class InvalidSignatureError extends AWSError {\n /**\n * Constructs an InvalidSignatureError\n *\n * @param {string} message - human readable error message\n */\n constructor(message: string, code: string) {\n super(message, code)\n this.name = 'InvalidSignatureError'\n }\n}\n\n/**\n * Calculte the signature for AWS signature version 4\n *\n * @param {string} derivedSigningKey - dervied signing key as computed by `deriveSigningKey`\n * @param {string} stringToSign - String to sign as computed by `createStringToSign`\n * @return {string}\n */\nexport function calculateSignature(derivedSigningKey: ArrayBuffer, stringToSign: string): string {\n return hmac('sha256', derivedSigningKey, stringToSign, 'hex')\n}\n/**\n * Derives the signing key for authenticating requests signed with\n * the Signature version 4 authentication protocol.\n *\n * deriveSigningKey produces a signing key by creating a series of\n * hash-based message authentication codes (HMACs) represented in\n * a binary format.\n *\n * The derived signing key is specific to the date it's made at, as well as\n * the service and region it targets.\n *\n * @param {string} secretAccessKey - the AWS secret access key to derive the signing key for\n * @param {number} time - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service. MUST be UTF-8 encoded.\n * @return {string}\n */\nexport function deriveSigningKey(\n secretAccessKey: string,\n time: number,\n region: string,\n service: string\n): ArrayBuffer {\n const kSecret = secretAccessKey\n const date = toDate(time)\n\n // FIXME: hmac takes ArrayBuffer as input, but returns bytes (number[]).\n // How does one convert from one to the other?\n const kDate: any = hmac('sha256', 'AWS4' + kSecret, date, 'binary')\n const kRegion: any = hmac('sha256', kDate, region, 'binary')\n const kService: any = hmac('sha256', kRegion, service, 'binary')\n const kSigning: any = hmac('sha256', kService, 'aws4_request', 'binary')\n\n return kSigning\n}\n\n// Hashing Algorithm to use in the signature process\nexport const HashingAlgorithm = 'AWS4-HMAC-SHA256'\n\n/**\n * Certain services, such as S3, allow for unsigned payloads. If\n * producing a signed canonical request for such service, pass\n * the `UnsignedPayload` constant value as the payload parameter.\n */\nexport const UnsignedPayload = 'UNSIGNED-PAYLOAD'\n\n/**\n * Create the \"string to sign\" part of the signature Version 4 protocol.\n *\n * The \"string to sign\" includes meta information about your request and\n * about the canonical request that you created with `createCanonicalRequest`.\n * It is used hand in hand with the signing key to create the request signature.\n *\n * @param {number} requestTimestamp - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service name. MUST be UTF-8 encoded.\n * @param {string} hashedCanonicalRequest - canonical request as produced by calling the createCanonicalRequest function,\n * hashed using the SHA256 algorithm (encoded in hexadecimal format).\n * @return {string}\n */\nexport function createStringToSign(\n requestTimestamp: number,\n region: string,\n service: string,\n hashedCanonicalRequest: string\n): string {\n // the request date specified in ISO8601 format: YYYYMMDD'T'HHMMSS'Z'\n const requestDateTime = toTime(requestTimestamp)\n\n // The credential scope value, consisting of the date in YYYYMMDD format,\n // the targeted region, the targeted service, and a termination string.\n // Note that the region and service MUST be UTF-8 encoded.\n const credentialScope = createCredentialScope(requestTimestamp, region, service)\n\n const stringToSign = [\n // Algorithm\n HashingAlgorithm,\n\n // RequestDateTime\n requestDateTime,\n\n // CredentialScope\n credentialScope,\n\n // HashedCanonicalRequest\n hashedCanonicalRequest,\n ].join('\\n')\n\n return stringToSign\n}\n\n/**\n *\n * Helper function creating a credential scope string to use in the signature\n * version 4 process. A credential scope consists of the date of the request\n * in YYYYMMDD format, the targeted region, the targeted service, and a\n * termination string.\n *\n * Note that the region and service MUST be UTF-8 encoded.\n *\n * @param {number} requestTimestamp - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service name. MUST be UTF-8 encoded.\n * @return {string}\n */\nexport function createCredentialScope(\n requestTimestamp: number,\n region: string,\n service: string\n): string {\n return [toDate(requestTimestamp), region, service, 'aws4_request'].join('/')\n}\n\n/**\n * Create a string that includes information from your request\n * in a AWS signature v4 standardized (canonical) format.\n *\n * @param {string} method - the HTTP request method\n * @param {string} uri - URI-encoded version of the absolute path component of the URI\n * @param {string} query - request's query string\n * @param {Object} headers - all the HTTP headers that you wish to include with the signed request\n * @param {string | ArrayBuffer} payload - payload to include as the body of the request\n * @param {URIEncodingConfig} URIencodingConfig- URI encoding configuration\n * @return {string}\n */\nexport function createCanonicalRequest(\n method: HTTPMethod,\n uri: string,\n query: string,\n headers: HTTPHeaders,\n payload: string | ArrayBuffer,\n URIencodingConfig: URIEncodingConfig\n): string {\n const httpRequestMethod = method.toUpperCase()\n const canonicalURI = createCanonicalURI(uri, URIencodingConfig)\n const canonicalQueryString = createCanonicalQueryString(query)\n const canonicalHeaders = createCanonicalHeaders(headers)\n const signedHeaders = createSignedHeaders(headers)\n const requestPayload = createCanonicalPayload(payload)\n\n const canonicalRequest = [\n httpRequestMethod,\n canonicalURI,\n canonicalQueryString,\n canonicalHeaders,\n signedHeaders,\n requestPayload,\n ].join('\\n')\n\n return canonicalRequest\n}\n\n/**\n * Creates the (canonical) URI-encoded version of the\n * absolute path component of the URI: everything in the URI\n * from the HTTP host to the question mark character (\"?\")\n * that begins the query string parameters (if any).\n *\n * @param {string} uri - URI to canonize\n * @param {URIEncodingConfig} - URI encoding configuration\n * @return {string} - canonical URL\n */\nexport function createCanonicalURI(uri: string, URIencodingConfig: URIEncodingConfig): string {\n if (uri == '/') {\n return uri\n }\n\n let canonicalURI = uri\n if (uri[uri.length - 1] == '/' && canonicalURI[canonicalURI.length - 1] != '/') {\n canonicalURI += '/'\n }\n\n canonicalURI = URIEncode(canonicalURI, URIencodingConfig.path)\n\n return URIencodingConfig.double ? URIEncode(canonicalURI, URIencodingConfig.path) : canonicalURI\n}\n\n// FIXME: does it work as expected?\n/**\n * Creates the canonical form of the request's query\n * string. If the request does not include a query string,\n * provide an empty string.\n *\n * @param {String | Object} qs - query string to canonize\n * @return {string}\n */\nexport function createCanonicalQueryString(qs: string): string {\n if (qs === '') {\n return ''\n }\n\n // const intermediary: { [key: string]: string } = parseQueryString(qs)\n\n // return Object.keys(intermediary)\n // .sort()\n // .map((key: string) => {\n // // const values: string[] = Array.isArray(intermediary[key])\n // // ? intermediary[key]\n // // : [intermediary[key]]\n // const values = intermediary[key]\n\n // return values\n // .sort()\n // .map((val: string) => encodeURIComponent(key) + '=' + encodeURIComponent(val))\n // .join('&')\n // })\n // .join('&')\n\n return parseQueryString(qs)\n .map(([key, value]: [string, string]): string => {\n return encodeURIComponent(key) + '=' + encodeURIComponent(value)\n })\n .join('&')\n}\n/**\n * Create the canonical form of the request's headers.\n * Canonical headers consist of all the HTTP headers you\n * are including with the signed request.\n *\n * Note that:\n * * for HTTP/1.1 requests, the headers should at least\n * contain the `host` header.\n * * for HTTP/2, the `:authority` header must be used instead\n * of `host`.\n *\n * @param {Object} headers\n * @return {string}\n */\nexport function createCanonicalHeaders(headers: HTTPHeaders) {\n if (headers.constructor !== Object || Object.entries(headers).length === 0) {\n return ''\n }\n\n const canonicalHeaders = Object.entries(headers)\n .map(([name, values]) => {\n const canonicalName = name.toLowerCase().trim()\n const normalizedValues = Array.isArray(values) ? values : [values]\n\n // Note that we do not need to sort values\n const canonicalValues = normalizedValues\n .map((v) => {\n // convert sequential spaces to a single space\n return v.replace(/\\s+/g, ' ').replace(/^\\s+|\\s+$/g, '')\n })\n .join(',') // standard for multiple values in a HTTP header\n\n return canonicalName + ':' + canonicalValues + '\\n'\n })\n .sort()\n .join('')\n\n return canonicalHeaders\n}\n\n/**\n * Create the canonical request's signed headers.\n *\n * The signed headers part of the request contains the\n * list of headers included in the request's signing process.\n *\n * Note that:\n * * for HTTP/1.1 requests, the `host` header must be included.\n * * for HTTP/2 requests, the `:authority` header must be included instead\n * of host.\n * * if used, the `x-amz-date` header must be included.\n *\n * @param {Object} headers\n * @return {string}\n * @throws {TypeError} - on headers not being an Object, or being empty.\n */\nexport function createSignedHeaders(headers: { [key: string]: string }) {\n if (headers.constructor !== Object) {\n throw new TypeError('headers should be an object')\n }\n\n if (Object.entries(headers).length === 0) {\n throw 'headers should at least contain either the Host (HTTP 1.1) or :authority (HTTP 2) parameter'\n }\n\n // To create the signed headers list, convert\n // all header names to lowercase, sort them by\n // character code, and use a semicolon to separate\n // the header names.\n const result = Object.keys(headers)\n .map((name) => name.toLowerCase().trim())\n .sort()\n .join(';')\n\n return result\n}\n\n/**\n * Create the canonical form of the request's payload.\n *\n * The canonical payload consists in a lowercased, hex encoded,\n * SHA256 hash of the requests body/payload.\n *\n * Certain services, such as S3, allow for unsigned payload. If\n * producing a signed canonical request for such service, pass\n * the `UnsignedPayload` constant value as the payload parameter.\n *\n * @param {String | ArrayBuffer} payload\n * @return {string}\n */\nexport function createCanonicalPayload(payload: string | ArrayBuffer) {\n if (payload === UnsignedPayload) {\n return payload\n }\n\n // Note that if the paylaod is null, we convert it\n // to an empty string.\n // TODO: Should switching to empty string if null impact headers?\n return crypto.sha256(payload || '', 'hex').toLowerCase()\n}\n\n/**\n * URIEncodes encodes every bytes of a URI to be URL-safe.\n *\n * This implementation is specific to AWS; who intended to make it as\n * close as possible to the underlying RFC 3946. It:\n * * URI encode every byte except the unreserved characters: 'A'-'Z', 'a'-'z', '0'-'9',\n * '-', '.', '_', and '~'.\n * * considers the space character as a reserved character and must URI encodes\n * encodes it as \"%20\" (and not as \"+\").\n * * URI encodes every byte by prefixing with '%' the two-digit hexadecimal value of the byte.\n * * If the `path` argument is set, forward slashes are not encoded, to fit with\n * S3 requirements.\n *\n * N.B: this implementation differs with ES6' mainly in that it does\n * encode the \"'\" character.\n *\n * Based on AWS implementation: https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-core/src/main/java/com/amazonaws/util/SdkHttpUtils.java#L66\n * Encoding specs: https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html\n *\n * @param {string} uri - uri to encode\n * @param {boolean} path - slash characters should be encoded everywhere,\n * but in paths, set to false when encoding a path\n * @return {string} the URI encoded result\n */\nexport function URIEncode(uri: string, path: boolean): string {\n if (uri == '') {\n return uri\n }\n\n return uri\n .split('') // to be able to map over a string, because... javascript...\n .map((letter: string) => {\n if (isAlpha(letter) || isNumeric(letter) || '-._~'.includes(letter)) {\n return letter\n }\n\n // Space should be explicitly encoded to as %20.\n if (letter == ' ') {\n return '%20'\n }\n\n // If the URI is a path, the forward slash shouldn't\n // be encoded.\n if (letter == '/' && path) {\n return '/'\n }\n\n return '%' + letter.charCodeAt(0).toString(16).toUpperCase()\n })\n .join('')\n}\n\n/**\n * Class holding URI encoding configuration\n */\nexport class URIEncodingConfig {\n double: boolean\n path: boolean\n\n /**\n *\n * @param {boolean} double - should the URI be double encoded?\n * @param {boolean} path - is the URI a path? If so, its forward\n * slashes won't be URIencoded.\n */\n constructor(double: boolean, path: boolean) {\n this.double = double\n this.path = path\n }\n}\n\n/**\n * Compute the request time value as specified by the ISO8601\n * format: YYYYMMDD'T'HHMMSS'Z'\n *\n * @param {number} timestamp\n * @return {string}\n */\nexport function toTime(timestamp: number): string {\n return new Date(timestamp).toISOString().replace(/[:\\-]|\\.\\d{3}/g, '')\n}\n/**\n * Computethe request date value in the format: YYYMMDD\n *\n * @param {number} timestamp\n * @return {string}\n */\nexport function toDate(timestamp: number): string {\n return toTime(timestamp).substring(0, 8)\n}\n\n// FIXME: does it work as expected?\n/**\n * Parse a HTTP request URL's querystring into an object\n * containing its `key=value` pairs.\n *\n * @param {string} qs\n * @return {object}\n */\nexport function parseQueryString(qs: string): Array<[string, string]> {\n if (qs.length === 0) {\n return []\n }\n\n return qs\n .split('&')\n .filter((e) => e)\n .map((v: string): [string, string] => {\n const parts = v.split('=', 2) as [string, string]\n return [decodeURIComponent(parts[0]), decodeURIComponent(parts[1])]\n })\n .sort((a: [string, string], b: [string, string]) => {\n return a[0].localeCompare(b[0])\n })\n}\n\nfunction isAlpha(c: string): boolean {\n return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')\n}\n\nfunction isNumeric(c: string): boolean {\n return c >= '0' && c <= '9'\n}\n\n// FIXME: finish implementation when needed\n// See the following for more details:\n// * https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html\n// * https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html\n// export function signQueryString(\n// queryString,\n// requestTimestamp,\n// accessKeyID,\n// secretAccessKey,\n// region,\n// service,\n// ttl, // in seconds\n// headers,\n// doubleURIEncoding = true\n// ) {\n// const credential = [accessKeyID, toDate(requestTimestamp), region, service].join('/')\n//\n// const canonicalRequest = createCanonicalRequest(\n// method,\n// path,\n// queryString,\n// headers,\n// body,\n// doubleURIEncoding\n// )\n//\n// const derivedSigningKey = deriveSigningKey(secretAccessKey, requestTimestamp, region, service)\n//\n// const stringToSign = createStringToSign(\n// requestTimestamp,\n// region,\n// service,\n// sha256(canonicalRequest, 'hex')\n// )\n//\n// const signedHeaders = createSignedHeaders(headers)\n// const signature = calculateSignature(derivedSigningKey, stringToSign)\n//\n// return [\n// `X-Amz-Algorithm=${HashingAlgorithm}`,\n// `X-Amz-Credential=${crediental}`,\n// `X-Amz-Date=${toTime(requestTimestamp)}`,\n// `X-Amz-Expires=${ttl}`,\n// `X-Amz-SignedHeaders=${signedHeaders}`,\n// `X-Amz-Signature=${signature}`,\n//`X-Amz-Security-Token=`, // TODO: optional\n// ].join('&')\n// }\n","/** Class holding an AWS connection information */\nexport class AWSConfig {\n region: string\n accessKeyID: string\n secretAccessKey: string\n\n /**\n * Create an AWSConfig.\n *\n * @param {string} region - the AWS region to connect to, as listed: https://docs.aws.amazon.com/general/latest/gr/rande.html\n * @param {string} accessKeyID - Your user's AWS access key id credential\n * @param {string} secretAccessKey - Your user's AWS secret access key credential\n * @throws {InvalidArgumentException}\n */\n constructor(region: string, accessKeyID: string, secretAccessKey: string) {\n if (typeof region !== 'string' || region === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS region; reason: should be a non empty string'\n )\n }\n\n if (typeof accessKeyID !== 'string' || accessKeyID === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS access key ID; reason: should be a non empty string'\n )\n }\n\n if (typeof secretAccessKey !== 'string' || secretAccessKey === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS secret access key; reason: should be a non empty string'\n )\n }\n\n this.region = region\n this.accessKeyID = accessKeyID\n this.secretAccessKey = secretAccessKey\n }\n}\n\n/** Class representing an invalid AWS configuration */\nexport class InvalidAWSConfigError extends Error {\n constructor(message: string) {\n super(message)\n }\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/http\");","import { bytes } from 'k6'\nimport http from 'k6/http'\nimport { parseHTML } from 'k6/html'\nimport { sha256 } from 'k6/crypto'\n\nimport { InvalidSignatureError, URIEncodingConfig } from './signature'\nimport { AWSClient, AWSRequest } from './client'\nimport { AWSError } from './error'\nimport { AWSConfig } from './config'\n\n/** Class allowing to interact with Amazon AWS's S3 service */\nexport class S3Client extends AWSClient {\n /**\n * Create a S3Client\n *\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n */\n constructor(awsConfig: AWSConfig) {\n const URIencodingConfig = new URIEncodingConfig(false, true)\n super(awsConfig, 's3', URIencodingConfig)\n }\n\n /**\n * Returns a list of all buckets owned by the authenticated sender of the request.\n * To use this operation, you must have the s3:ListAllMyBuckets permission.\n *\n * @return {Array.} buckets - An array of objects describing S3 buckets\n * with the following fields: name, and creationDate.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n listBuckets(): Array {\n // Prepare request\n const method = 'GET'\n const host = `${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(method, host, '/', '', body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n let buckets: Array = []\n\n const doc = parseHTML(res.body as string)\n\n doc.find('Buckets')\n .children()\n .each((_, bucketDefinition) => {\n let bucket = {}\n\n bucketDefinition.children().forEach((child) => {\n switch (child.nodeName()) {\n case 'name':\n Object.assign(bucket, { name: child.textContent() })\n break\n case 'creationdate':\n Object.assign(bucket, {\n creationDate: Date.parse(child.textContent()),\n })\n }\n })\n\n buckets.push(bucket as S3Bucket)\n })\n\n return buckets\n }\n\n /**\n * Returns some or all (up to 1,000) of the objects in a bucket.\n *\n * @param {string} bucketName - Bucket name to list.\n * @param {string?} prefix='' - Limits the response to keys that begin with the specified prefix.\n * @return {Array.} - returns an array of objects describing S3 objects\n * with the following fields: key, lastModified, etag, size and storageClass.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n listObjects(bucketName: string, prefix?: string): Array {\n // Prepare request\n const method = 'GET'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const body = ''\n const querystring = `list-type=2&prefix=${prefix}`\n const signedRequest: AWSRequest = super.buildRequest(method, host, '/', querystring, body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n Prefix: prefix ?? '',\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n let objects: Array = []\n\n // Extract the objects definition from\n // the XML response\n parseHTML(res.body as string)\n .find('Contents')\n .each((_, objectDefinition) => {\n let obj = {}\n\n objectDefinition.children().forEach((child) => {\n switch (child.nodeName()) {\n case 'key':\n Object.assign(obj, { key: child.textContent() })\n break\n case 'lastmodified':\n Object.assign(obj, { lastModified: Date.parse(child.textContent()) })\n break\n case 'etag':\n Object.assign(obj, { etag: child.textContent() })\n break\n case 'size':\n Object.assign(obj, { size: parseInt(child.textContent()) })\n break\n case 'storageclass':\n Object.assign(obj, { storageClass: child.textContent() })\n }\n })\n\n objects.push(obj as S3Object)\n })\n\n return objects\n }\n /**\n * Retrieves an Object from Amazon S3.\n *\n * To use getObject, you must have `READ` access to the object.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to get.\n * @return {S3Object} - returns the content of the fetched S3 Object.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n getObject(bucketName: string, objectKey: string): S3Object {\n // Prepare request\n const method = 'GET'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(method, host, path, '', body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n console.log(`s3 objects response headers: ${JSON.stringify(res.headers, null, ' ')}`)\n\n return new S3Object(\n objectKey,\n Date.parse(res.headers['Last-Modified']),\n res.headers['ETag'],\n parseInt(res.headers['Content-Length']),\n (res.headers['X-Amz-Storage-Class'] ?? 'STANDARD') as StorageClass, // FIXME: GetObject response doesn't contain the storage class\n res.body\n )\n }\n /**\n * Adds an object to a bucket.\n *\n * You must have WRITE permissions on a bucket to add an object to it.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to put.\n * @param {string | ArrayBuffer} data - the content of the S3 Object to upload.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n putObject(bucketName: string, objectKey: string, data: string | ArrayBuffer) {\n // Prepare request\n const method = 'PUT'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const queryString = ''\n const body = data\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n path,\n queryString,\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n }\n\n /**\n * Removes the null version (if there is one) of an object and inserts a delete marker,\n * which becomes the latest version of the object.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to delete.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n deleteObject(bucketName: string, objectKey: string): void {\n // Prepare request\n const method = 'DELETE'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const queryString = ''\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n path,\n queryString,\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n }\n\n // FIXME: remove dependency to `error_message`\n // FIXME: just pass it the response?\n _handle_error(error_code: number, error_message: string, error_body: string) {\n if (error_message == '' || error_code === 0) {\n return\n }\n\n // FIXME: should be error_code === 1301 instead\n // See: https://github.com/grafana/k6/issues/2474\n // See: https://github.com/golang/go/issues/49281\n if (error_message && error_message.startsWith('301')) {\n // Bucket not found\n throw new S3ServiceError('Resource not found', 'ResourceNotFound', 'getObject')\n }\n\n const awsError = AWSError.parseXML(error_body)\n switch (awsError.code) {\n case 'AuthorizationHeaderMalformed':\n throw new InvalidSignatureError(awsError.message, awsError.code)\n default:\n throw new S3ServiceError(awsError.message, awsError.code, 'listObjects')\n }\n }\n}\n\n// TODO: use interface instead?\n/** Class representing a S3 Bucket */\nexport class S3Bucket {\n name: string\n creationDate: Date\n\n /**\n * Create an S3 Bucket\n *\n * @param {string} name - S3 bucket's name\n * @param {Date} creationDate - S3 bucket's creation date\n */\n constructor(name: string, creationDate: Date) {\n this.name = name\n this.creationDate = creationDate\n }\n}\n\n// TODO: use interface instead?\n/** Class representing an S3 Object */\nexport class S3Object {\n key: string\n lastModified: number\n etag: string\n size: number\n storageClass: StorageClass\n data?: string | bytes | null\n\n /**\n * Create an S3 Object\n *\n * @param {string} key - S3 object's key\n * @param {Date} lastModified - S3 object last modification date\n * @param {string} etag - S3 object's etag\n * @param {number} size - S3 object's size\n * @param {StorageClass} storageClass - S3 object's storage class\n * @param {string | bytes | null} data=null - S3 Object's data\n */\n constructor(\n key: string,\n lastModified: number,\n etag: string,\n size: number,\n storageClass: StorageClass,\n data?: string | bytes | null\n ) {\n this.key = key\n this.lastModified = lastModified\n this.etag = etag\n this.size = size\n this.storageClass = storageClass\n this.data = data\n }\n}\n\n/**\n * Error indicating a S3 operation failed\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class S3ServiceError extends AWSError {\n operation: string\n\n /**\n * Constructs a S3ServiceError\n *\n * @param {string} message - human readable error message\n * @param {string} code - A unique short code representing the error that was emitted\n * @param {string} operation - Name of the failed Operation\n */\n constructor(message: string, code: string, operation: string) {\n super(message, code)\n this.name = 'S3ServiceError'\n this.operation = operation\n }\n}\n\n/**\n * Describes the class of storage used to store a S3 object.\n */\ntype StorageClass =\n | 'STANDARD'\n | 'REDUCED_REDUNDANCY'\n | 'GLACIER'\n | 'STANDARD_IA'\n | 'INTELLIGENT_TIERING'\n | 'DEEP_ARCHIVE'\n | 'OUTPOSTS'\n | 'GLACIER_IR'\n | undefined\n","import { HTTPMethod, HTTPHeaders } from './http'\nimport { AWSConfig } from './config'\nimport { signHeaders, URIEncodingConfig, toTime } from './signature'\n\n/**\n * Class allowing to build requests targeting AWS APIs\n *\n * This class is meant to be used as a base class for specific\n * services clients. See S3Client or SecretsManagerClient for\n * usage examples.\n */\nexport class AWSClient {\n awsConfig: AWSConfig\n serviceName: string\n URIencodingConfig: URIEncodingConfig\n\n /**\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n * @param {string} serviceName - name of the service to target.\n * @param {URIEncodingConfig} URIencodingConfig - configures how requests URIs should be encoded.\n */\n constructor(awsConfig: AWSConfig, serviceName: string, URIencodingConfig: URIEncodingConfig) {\n this.awsConfig = awsConfig\n this.serviceName = serviceName\n this.URIencodingConfig = URIencodingConfig\n }\n\n buildRequest(\n method: HTTPMethod,\n host: string,\n path: string,\n queryString: string,\n body: string | ArrayBuffer,\n headers: HTTPHeaders\n ): AWSRequest {\n const requestTimestamp: number = Date.now()\n const date: string = toTime(requestTimestamp)\n\n headers['Host'] = host\n headers['X-Amz-Date'] = date\n\n headers = signHeaders(\n // headers\n headers,\n\n // requestTimestamp\n requestTimestamp,\n\n // method\n method,\n\n // path\n path,\n\n // querystring\n queryString,\n\n // body\n body,\n\n // AWS configuration\n this.awsConfig,\n\n // AwS target service name\n this.serviceName,\n\n // doubleEncoding: S3 does single-encoding of the uri component\n // pathURIEncoding: S3 manipulates object keys, and forward slashes\n // shouldn't be URI encoded\n this.URIencodingConfig\n )\n\n // '?' should not be part of the querystring when we sign the headers\n path = path !== '' ? path : '/'\n let url = `https://${host}${path}`\n if (queryString !== '') {\n url += `?${queryString}`\n }\n\n return { url: url, headers: headers }\n }\n}\n\n/**\n * Type alias representing the result of an AWSClient.buildRequest call\n */\nexport interface AWSRequest {\n url: string\n headers: HTTPHeaders\n}\n"],"names":["__webpack_require__","module","getter","__esModule","d","a","exports","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","require","AWSError","message","code","name","xmlDocument","doc","parseHTML","find","text","Error","signHeaders","headers","requestTimestamp","method","path","queryString","body","awsConfig","service","URIencodingConfig","derivedSigningKey","secretAccessKey","time","region","kSecret","date","toDate","kDate","hmac","kRegion","kService","deriveSigningKey","canonicalRequest","uri","query","payload","httpRequestMethod","toUpperCase","canonicalURI","length","URIEncode","createCanonicalURI","canonicalQueryString","qs","split","filter","e","map","v","parts","decodeURIComponent","sort","b","localeCompare","parseQueryString","encodeURIComponent","join","createCanonicalQueryString","canonicalHeaders","constructor","entries","values","toLowerCase","trim","Array","isArray","replace","createCanonicalHeaders","signedHeaders","createSignedHeaders","requestPayload","UnsignedPayload","crypto","createCanonicalPayload","createCanonicalRequest","stringToSign","hashedCanonicalRequest","requestDateTime","toTime","credentialScope","createCredentialScope","HashingAlgorithm","createStringToSign","sha256","signature","calculateSignature","authorizationHeader","accessKeyID","InvalidSignatureError","TypeError","keys","letter","c","isNumeric","includes","charCodeAt","toString","URIEncodingConfig","double","this","timestamp","Date","toISOString","substring","AWSConfig","InvalidAWSConfigError","S3Client","host","serviceName","signedRequest","res","http","url","_handle_error","error_code","error","buckets","children","each","_","bucketDefinition","bucket","forEach","child","nodeName","assign","textContent","creationDate","parse","push","bucketName","prefix","querystring","Prefix","objects","objectDefinition","lastModified","etag","size","parseInt","storageClass","objectKey","console","log","JSON","stringify","S3Object","data","error_message","error_body","startsWith","S3ServiceError","awsError","parseXML","now","S3Bucket","operation"],"sourceRoot":""} \ No newline at end of file diff --git a/src/internal/s3.ts b/src/internal/s3.ts index a0c0353..aa55dba 100644 --- a/src/internal/s3.ts +++ b/src/internal/s3.ts @@ -164,7 +164,11 @@ export class S3Client extends AWSClient { Date.parse(res.headers['Last-Modified']), res.headers['ETag'], parseInt(res.headers['Content-Length']), - undefined, // GetObject response doesn't contain the storage class + + // The X-Amz-Storage-Class header is only set if the storage class is + // not the default 'STANDARD' one. + (res.headers['X-Amz-Storage-Class'] ?? 'STANDARD') as StorageClass, + res.body ) } From da471ffaf7f3346ac1421cce69439db8583e76ed Mon Sep 17 00:00:00 2001 From: oleiade Date: Mon, 25 Apr 2022 14:16:57 +0200 Subject: [PATCH 3/7] Align S3 and SecretsManager error handling API --- build/aws.min.js | 2 +- build/aws.min.js.map | 2 +- build/s3.min.js | 2 +- build/s3.min.js.map | 2 +- src/internal/s3.ts | 40 ++++++++++++++++++++++------------------ 5 files changed, 26 insertions(+), 22 deletions(-) diff --git a/build/aws.min.js b/build/aws.min.js index 4dbf015..ef9737c 100644 --- a/build/aws.min.js +++ b/build/aws.min.js @@ -1,2 +1,2 @@ -(()=>{var e={877:(e,t,r)=>{var n=r(570),o=r(171),i=o;i.v1=n,i.v4=o,e.exports=i},327:e=>{for(var t=[],r=0;r<256;++r)t[r]=(r+256).toString(16).substr(1);e.exports=function(e,r){var n=r||0,o=t;return[o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]]].join("")}},217:e=>{var t="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof window.msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto);if(t){var r=new Uint8Array(16);e.exports=function(){return t(r),r}}else{var n=new Array(16);e.exports=function(){for(var e,t=0;t<16;t++)0==(3&t)&&(e=4294967296*Math.random()),n[t]=e>>>((3&t)<<3)&255;return n}}},570:(e,t,r)=>{var n,o,i=r(217),c=r(327),a=0,u=0;e.exports=function(e,t,r){var s=t&&r||0,f=t||[],l=(e=e||{}).node||n,p=void 0!==e.clockseq?e.clockseq:o;if(null==l||null==p){var h=i();null==l&&(l=n=[1|h[0],h[1],h[2],h[3],h[4],h[5]]),null==p&&(p=o=16383&(h[6]<<8|h[7]))}var y=void 0!==e.msecs?e.msecs:(new Date).getTime(),d=void 0!==e.nsecs?e.nsecs:u+1,b=y-a+(d-u)/1e4;if(b<0&&void 0===e.clockseq&&(p=p+1&16383),(b<0||y>a)&&void 0===e.nsecs&&(d=0),d>=1e4)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");a=y,u=d,o=p;var v=(1e4*(268435455&(y+=122192928e5))+d)%4294967296;f[s++]=v>>>24&255,f[s++]=v>>>16&255,f[s++]=v>>>8&255,f[s++]=255&v;var m=y/4294967296*1e4&268435455;f[s++]=m>>>8&255,f[s++]=255&m,f[s++]=m>>>24&15|16,f[s++]=m>>>16&255,f[s++]=p>>>8|128,f[s++]=255&p;for(var g=0;g<6;++g)f[s+g]=l[g];return t||c(f)}},171:(e,t,r)=>{var n=r(217),o=r(327);e.exports=function(e,t,r){var i=t&&r||0;"string"==typeof e&&(t="binary"===e?new Array(16):null,e=null);var c=(e=e||{}).random||(e.rng||n)();if(c[6]=15&c[6]|64,c[8]=63&c[8]|128,t)for(var a=0;a<16;++a)t[i+a]=c[a];return t||o(c)}}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var i=t[n]={exports:{}};return e[n](i,i.exports,r),i.exports}r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var n={};(()=>{"use strict";r.r(n),r.d(n,{AWSConfig:()=>V,InvalidAWSConfigError:()=>F,InvalidSignatureError:()=>R,S3Bucket:()=>ye,S3Client:()=>he,S3Object:()=>de,S3ServiceError:()=>be,Secret:()=>Ne,SecretsManagerClient:()=>De,SecretsManagerError:()=>qe,URIEncodingConfig:()=>D,signHeaders:()=>C});const e=require("k6/crypto");var t=r.n(e);const o=require("k6/html");function i(e){return i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i(e)}function c(e,t){for(var r=0;re.length)&&(t=e.length);for(var r=0,n=new Array(t);r="A"&&r<="Z"||r>="a"&&r<="z"||function(e){return e>="0"&&e<="9"}(e)||"-._~".includes(e)?e:" "==e?"%20":"/"==e&&t?"/":"%"+e.charCodeAt(0).toString(16).toUpperCase();var r})).join("")}var D=w((function e(t,r){O(this,e),b(this,"double",void 0),b(this,"path",void 0),this.double=t,this.path=r}));function N(e){return new Date(e).toISOString().replace(/[:\-]|\.\d{3}/g,"")}function q(e){return N(e).substring(0,8)}function I(e){return I="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},I(e)}function M(e,t){if(t&&("object"===I(t)||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e)}function z(e){var t="function"==typeof Map?new Map:void 0;return z=function(e){if(null===e||(r=e,-1===Function.toString.call(r).indexOf("[native code]")))return e;var r;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return H(e,arguments,X(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),U(n,e)},z(e)}function H(e,t,r){return H=L()?Reflect.construct:function(e,t,r){var n=[null];n.push.apply(n,t);var o=new(Function.bind.apply(e,n));return r&&U(o,r.prototype),o},H.apply(null,arguments)}function L(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}function U(e,t){return U=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},U(e,t)}function X(e){return X=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},X(e)}function B(e,t){for(var r=0;r=1400&&r<=1499){var o=n.Message||n.message||n.__type;if("InvalidSignatureException"===n.__type)throw new R(o,n.__type);throw new qe(o,n.__type,e)}if(1500===r)throw new qe("An error occured on the server side","InternalServiceError",e)}}}]),r}(Q),Ne=function(){function e(t,r,n,o,i,c){var a=arguments.length>6&&void 0!==arguments[6]?arguments[6]:[];Oe(this,e),ke(this,"name",void 0),ke(this,"arn",void 0),ke(this,"secret",void 0),ke(this,"createdDate",void 0),ke(this,"lastAccessedDate",void 0),ke(this,"lastChangedDate",void 0),ke(this,"tags",void 0),this.name=t,this.arn=r,this.secret=n,this.createdDate=o,this.lastAccessedDate=i,this.lastChangedDate=c,this.tags=a}return je(e,null,[{key:"fromJSON",value:function(t){return new e(t.Name,t.ARN,t.SecretString,t.CreatedDate,t.LastAccessedDate,t.LastChangedDate,t.Tags)}}]),e}(),qe=function(e){Ce(r,e);var t=Ae(r);function r(e,n,o){var i;return Oe(this,r),ke(Te(i=t.call(this,e,n)),"operation",void 0),i.name="SecretsManagerServiceError",i.operation=o,i}return je(r)}(y)})();var o=exports;for(var i in n)o[i]=n[i];n.__esModule&&Object.defineProperty(o,"__esModule",{value:!0})})(); +(()=>{var e={877:(e,t,r)=>{var n=r(570),o=r(171),i=o;i.v1=n,i.v4=o,e.exports=i},327:e=>{for(var t=[],r=0;r<256;++r)t[r]=(r+256).toString(16).substr(1);e.exports=function(e,r){var n=r||0,o=t;return[o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]]].join("")}},217:e=>{var t="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof window.msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto);if(t){var r=new Uint8Array(16);e.exports=function(){return t(r),r}}else{var n=new Array(16);e.exports=function(){for(var e,t=0;t<16;t++)0==(3&t)&&(e=4294967296*Math.random()),n[t]=e>>>((3&t)<<3)&255;return n}}},570:(e,t,r)=>{var n,o,i=r(217),c=r(327),a=0,u=0;e.exports=function(e,t,r){var s=t&&r||0,f=t||[],l=(e=e||{}).node||n,p=void 0!==e.clockseq?e.clockseq:o;if(null==l||null==p){var h=i();null==l&&(l=n=[1|h[0],h[1],h[2],h[3],h[4],h[5]]),null==p&&(p=o=16383&(h[6]<<8|h[7]))}var y=void 0!==e.msecs?e.msecs:(new Date).getTime(),d=void 0!==e.nsecs?e.nsecs:u+1,b=y-a+(d-u)/1e4;if(b<0&&void 0===e.clockseq&&(p=p+1&16383),(b<0||y>a)&&void 0===e.nsecs&&(d=0),d>=1e4)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");a=y,u=d,o=p;var v=(1e4*(268435455&(y+=122192928e5))+d)%4294967296;f[s++]=v>>>24&255,f[s++]=v>>>16&255,f[s++]=v>>>8&255,f[s++]=255&v;var m=y/4294967296*1e4&268435455;f[s++]=m>>>8&255,f[s++]=255&m,f[s++]=m>>>24&15|16,f[s++]=m>>>16&255,f[s++]=p>>>8|128,f[s++]=255&p;for(var g=0;g<6;++g)f[s+g]=l[g];return t||c(f)}},171:(e,t,r)=>{var n=r(217),o=r(327);e.exports=function(e,t,r){var i=t&&r||0;"string"==typeof e&&(t="binary"===e?new Array(16):null,e=null);var c=(e=e||{}).random||(e.rng||n)();if(c[6]=15&c[6]|64,c[8]=63&c[8]|128,t)for(var a=0;a<16;++a)t[i+a]=c[a];return t||o(c)}}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var i=t[n]={exports:{}};return e[n](i,i.exports,r),i.exports}r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var n={};(()=>{"use strict";r.r(n),r.d(n,{AWSConfig:()=>V,InvalidAWSConfigError:()=>F,InvalidSignatureError:()=>R,S3Bucket:()=>ye,S3Client:()=>he,S3Object:()=>de,S3ServiceError:()=>be,Secret:()=>Ne,SecretsManagerClient:()=>De,SecretsManagerError:()=>qe,URIEncodingConfig:()=>D,signHeaders:()=>C});const e=require("k6/crypto");var t=r.n(e);const o=require("k6/html");function i(e){return i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i(e)}function c(e,t){for(var r=0;re.length)&&(t=e.length);for(var r=0,n=new Array(t);r="A"&&r<="Z"||r>="a"&&r<="z"||function(e){return e>="0"&&e<="9"}(e)||"-._~".includes(e)?e:" "==e?"%20":"/"==e&&t?"/":"%"+e.charCodeAt(0).toString(16).toUpperCase();var r})).join("")}var D=w((function e(t,r){O(this,e),b(this,"double",void 0),b(this,"path",void 0),this.double=t,this.path=r}));function N(e){return new Date(e).toISOString().replace(/[:\-]|\.\d{3}/g,"")}function q(e){return N(e).substring(0,8)}function I(e){return I="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},I(e)}function M(e,t){if(t&&("object"===I(t)||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e)}function z(e){var t="function"==typeof Map?new Map:void 0;return z=function(e){if(null===e||(r=e,-1===Function.toString.call(r).indexOf("[native code]")))return e;var r;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return H(e,arguments,B(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),U(n,e)},z(e)}function H(e,t,r){return H=L()?Reflect.construct:function(e,t,r){var n=[null];n.push.apply(n,t);var o=new(Function.bind.apply(e,n));return r&&U(o,r.prototype),o},H.apply(null,arguments)}function L(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}function U(e,t){return U=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},U(e,t)}function B(e){return B=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},B(e)}function X(e,t){for(var r=0;r=1400&&r<=1499){var o=n.Message||n.message||n.__type;if("InvalidSignatureException"===n.__type)throw new R(o,n.__type);throw new qe(o,n.__type,e)}if(1500===r)throw new qe("An error occured on the server side","InternalServiceError",e)}}}]),r}(Q),Ne=function(){function e(t,r,n,o,i,c){var a=arguments.length>6&&void 0!==arguments[6]?arguments[6]:[];Oe(this,e),xe(this,"name",void 0),xe(this,"arn",void 0),xe(this,"secret",void 0),xe(this,"createdDate",void 0),xe(this,"lastAccessedDate",void 0),xe(this,"lastChangedDate",void 0),xe(this,"tags",void 0),this.name=t,this.arn=r,this.secret=n,this.createdDate=o,this.lastAccessedDate=i,this.lastChangedDate=c,this.tags=a}return Se(e,null,[{key:"fromJSON",value:function(t){return new e(t.Name,t.ARN,t.SecretString,t.CreatedDate,t.LastAccessedDate,t.LastChangedDate,t.Tags)}}]),e}(),qe=function(e){Ce(r,e);var t=Ae(r);function r(e,n,o){var i;return Oe(this,r),xe(Te(i=t.call(this,e,n)),"operation",void 0),i.name="SecretsManagerServiceError",i.operation=o,i}return Se(r)}(y)})();var o=exports;for(var i in n)o[i]=n[i];n.__esModule&&Object.defineProperty(o,"__esModule",{value:!0})})(); //# sourceMappingURL=aws.min.js.map \ No newline at end of file diff --git a/build/aws.min.js.map b/build/aws.min.js.map index 7e52e2f..e81c05a 100644 --- a/build/aws.min.js.map +++ b/build/aws.min.js.map @@ -1 +1 @@ -{"version":3,"file":"aws.min.js","mappings":"2BAAA,IAAIA,EAAK,EAAQ,KACbC,EAAK,EAAQ,KAEbC,EAAOD,EACXC,EAAKF,GAAKA,EACVE,EAAKD,GAAKA,EAEVE,EAAOC,QAAUF,G,QCFjB,IADA,IAAIG,EAAY,GACPC,EAAI,EAAGA,EAAI,MAAOA,EACzBD,EAAUC,IAAMA,EAAI,KAAOC,SAAS,IAAIC,OAAO,GAmBjDL,EAAOC,QAhBP,SAAqBK,EAAKC,GACxB,IAAIJ,EAAII,GAAU,EACdC,EAAMN,EAEV,MAAO,CACLM,EAAIF,EAAIH,MAAOK,EAAIF,EAAIH,MACvBK,EAAIF,EAAIH,MAAOK,EAAIF,EAAIH,MAAO,IAC9BK,EAAIF,EAAIH,MAAOK,EAAIF,EAAIH,MAAO,IAC9BK,EAAIF,EAAIH,MAAOK,EAAIF,EAAIH,MAAO,IAC9BK,EAAIF,EAAIH,MAAOK,EAAIF,EAAIH,MAAO,IAC9BK,EAAIF,EAAIH,MAAOK,EAAIF,EAAIH,MACvBK,EAAIF,EAAIH,MAAOK,EAAIF,EAAIH,MACvBK,EAAIF,EAAIH,MAAOK,EAAIF,EAAIH,OACtBM,KAAK,M,QCfV,IAAIC,EAAqC,oBAAZ,QAA2BC,OAAOD,iBAAmBC,OAAOD,gBAAgBE,KAAKD,SACnE,oBAAd,UAAuE,mBAAnCE,OAAOC,SAASJ,iBAAiCI,SAASJ,gBAAgBE,KAAKE,UAEhJ,GAAIJ,EAAiB,CAEnB,IAAIK,EAAQ,IAAIC,WAAW,IAE3BhB,EAAOC,QAAU,WAEf,OADAS,EAAgBK,GACTA,OAEJ,CAKL,IAAIE,EAAO,IAAIC,MAAM,IAErBlB,EAAOC,QAAU,WACf,IAAK,IAAWkB,EAAPhB,EAAI,EAAMA,EAAI,GAAIA,IACN,IAAV,EAAJA,KAAiBgB,EAAoB,WAAhBC,KAAKC,UAC/BJ,EAAKd,GAAKgB,MAAY,EAAJhB,IAAa,GAAK,IAGtC,OAAOc,K,cC/BX,IAQIK,EACAC,EATAC,EAAM,EAAQ,KACdC,EAAc,EAAQ,KAWtBC,EAAa,EACbC,EAAa,EA+FjB3B,EAAOC,QA5FP,SAAY2B,EAAStB,EAAKC,GACxB,IAAIJ,EAAIG,GAAOC,GAAU,EACrBsB,EAAIvB,GAAO,GAGXwB,GADJF,EAAUA,GAAW,IACFE,MAAQR,EACvBS,OAAgCC,IAArBJ,EAAQG,SAAyBH,EAAQG,SAAWR,EAKnE,GAAY,MAARO,GAA4B,MAAZC,EAAkB,CACpC,IAAIE,EAAYT,IACJ,MAARM,IAEFA,EAAOR,EAAU,CACA,EAAfW,EAAU,GACVA,EAAU,GAAIA,EAAU,GAAIA,EAAU,GAAIA,EAAU,GAAIA,EAAU,KAGtD,MAAZF,IAEFA,EAAWR,EAAiD,OAApCU,EAAU,IAAM,EAAIA,EAAU,KAQ1D,IAAIC,OAA0BF,IAAlBJ,EAAQM,MAAsBN,EAAQM,OAAQ,IAAIC,MAAOC,UAIjEC,OAA0BL,IAAlBJ,EAAQS,MAAsBT,EAAQS,MAAQV,EAAa,EAGnEW,EAAMJ,EAAQR,GAAeW,EAAQV,GAAY,IAcrD,GAXIW,EAAK,QAA0BN,IAArBJ,EAAQG,WACpBA,EAAWA,EAAW,EAAI,QAKvBO,EAAK,GAAKJ,EAAQR,SAAiCM,IAAlBJ,EAAQS,QAC5CA,EAAQ,GAINA,GAAS,IACX,MAAM,IAAIE,MAAM,mDAGlBb,EAAaQ,EACbP,EAAaU,EACbd,EAAYQ,EAMZ,IAAIS,GAA4B,KAAb,WAHnBN,GAAS,cAG+BG,GAAS,WACjDR,EAAE1B,KAAOqC,IAAO,GAAK,IACrBX,EAAE1B,KAAOqC,IAAO,GAAK,IACrBX,EAAE1B,KAAOqC,IAAO,EAAI,IACpBX,EAAE1B,KAAY,IAALqC,EAGT,IAAIC,EAAOP,EAAQ,WAAc,IAAS,UAC1CL,EAAE1B,KAAOsC,IAAQ,EAAI,IACrBZ,EAAE1B,KAAa,IAANsC,EAGTZ,EAAE1B,KAAOsC,IAAQ,GAAK,GAAM,GAC5BZ,EAAE1B,KAAOsC,IAAQ,GAAK,IAGtBZ,EAAE1B,KAAO4B,IAAa,EAAI,IAG1BF,EAAE1B,KAAkB,IAAX4B,EAGT,IAAK,IAAIW,EAAI,EAAGA,EAAI,IAAKA,EACvBb,EAAE1B,EAAIuC,GAAKZ,EAAKY,GAGlB,OAAOpC,GAAYmB,EAAYI,K,cCzGjC,IAAIL,EAAM,EAAQ,KACdC,EAAc,EAAQ,KA2B1BzB,EAAOC,QAzBP,SAAY2B,EAAStB,EAAKC,GACxB,IAAIJ,EAAIG,GAAOC,GAAU,EAEF,iBAAb,IACRD,EAAkB,WAAZsB,EAAuB,IAAIV,MAAM,IAAM,KAC7CU,EAAU,MAIZ,IAAIX,GAFJW,EAAUA,GAAW,IAEFP,SAAWO,EAAQJ,KAAOA,KAO7C,GAJAP,EAAK,GAAgB,GAAVA,EAAK,GAAa,GAC7BA,EAAK,GAAgB,GAAVA,EAAK,GAAa,IAGzBX,EACF,IAAK,IAAIqC,EAAK,EAAGA,EAAK,KAAMA,EAC1BrC,EAAIH,EAAIwC,GAAM1B,EAAK0B,GAIvB,OAAOrC,GAAOmB,EAAYR,MCxBxB2B,EAA2B,GAG/B,SAASC,EAAoBC,GAE5B,IAAIC,EAAeH,EAAyBE,GAC5C,QAAqBd,IAAjBe,EACH,OAAOA,EAAa9C,QAGrB,IAAID,EAAS4C,EAAyBE,GAAY,CAGjD7C,QAAS,IAOV,OAHA+C,EAAoBF,GAAU9C,EAAQA,EAAOC,QAAS4C,GAG/C7C,EAAOC,QCpBf4C,EAAoBH,EAAK1C,IACxB,IAAIiD,EAASjD,GAAUA,EAAOkD,WAC7B,IAAOlD,EAAiB,QACxB,IAAM,EAEP,OADA6C,EAAoBM,EAAEF,EAAQ,CAAEG,EAAGH,IAC5BA,GCLRJ,EAAoBM,EAAI,CAAClD,EAASoD,KACjC,IAAI,IAAIC,KAAOD,EACXR,EAAoBU,EAAEF,EAAYC,KAAST,EAAoBU,EAAEtD,EAASqD,IAC5EE,OAAOC,eAAexD,EAASqD,EAAK,CAAEI,YAAY,EAAMC,IAAKN,EAAWC,MCJ3ET,EAAoBU,EAAI,CAACK,EAAKC,IAAUL,OAAOM,UAAUC,eAAeC,KAAKJ,EAAKC,GCClFhB,EAAoB1B,EAAKlB,IACH,oBAAXgE,QAA0BA,OAAOC,aAC1CV,OAAOC,eAAexD,EAASgE,OAAOC,YAAa,CAAEC,MAAO,WAE7DX,OAAOC,eAAexD,EAAS,aAAc,CAAEkE,OAAO,K,ySCLvD,MAAM,EAA+BC,QAAQ,a,aCA7C,MAAM,EAA+BA,QAAQ,W,q0DCUtC,IAAMC,EAAb,a,qRAAA,U,UAAA,G,EAAA,E,mJASI,WAAYC,EAAiBC,GAAc,M,MAAA,O,4FAAA,SACvC,cAAMD,G,EADiC,K,OAAA,G,EAAA,U,wFAEvC,EAAKE,KAAO,WACZ,EAAKD,KAAOA,EAH2B,EAT/C,O,EAAA,E,EAAA,uBAoBI,SAAgBE,GACZ,IAAMC,GAAMC,EAAAA,EAAAA,WAAUF,GACtB,OAAO,IAAIJ,EAASK,EAAIE,KAAK,WAAWC,OAAQH,EAAIE,KAAK,QAAQC,Y,EAtBzE,O,8EAAA,KAA8BtC,Q,6kFCiBvB,SAASuC,EACZC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,GAEA,IAAMC,EAgFH,SACHC,EACAC,EACAC,EACAL,GAEA,IAAMM,EAAUH,EACVI,EAAOC,EAAOJ,GAIdK,GAAaC,EAAAA,EAAAA,MAAK,SAAU,OAASJ,EAASC,EAAM,UACpDI,GAAeD,EAAAA,EAAAA,MAAK,SAAUD,EAAOJ,EAAQ,UAC7CO,GAAgBF,EAAAA,EAAAA,MAAK,SAAUC,EAASX,EAAS,UAGvD,OAFsBU,EAAAA,EAAAA,MAAK,SAAUE,EAAU,eAAgB,UA9FrCC,CACtBd,EAAUI,gBACVT,EACAK,EAAUM,OACVL,GAGEc,EAqLH,SACHnB,EACAoB,EACAC,EACAvB,EACAwB,EACAhB,GAEA,IAAMiB,EAAoBvB,EAAOwB,cAC3BC,EA4BH,SAA4BL,EAAad,GAC5C,GAAW,KAAPc,EACA,OAAOA,EAGX,IAAIK,EAAeL,EACQ,KAAvBA,EAAIA,EAAIM,OAAS,IAAsD,KAAzCD,EAAaA,EAAaC,OAAS,KACjED,GAAgB,KAKpB,OAFAA,EAAeE,EAAUF,EAAcnB,EAAkBL,MAElDK,EAAiB,OAAUqB,EAAUF,EAAcnB,EAAkBL,MAAQwB,EAxC/DG,CAAmBR,EAAKd,GACvCuB,EAmDH,SAAoCC,GACvC,GAAW,KAAPA,EACA,MAAO,GAoBX,OA8MG,SAA0BA,GAC7B,GAAkB,IAAdA,EAAGJ,OACH,MAAO,GAGX,OAAOI,EACFC,MAAM,KACNC,QAAO,SAACC,GAAD,OAAOA,KACdC,KAAI,SAACC,GACF,IAAMC,EAAQD,EAAEJ,MAAM,IAAK,GAC3B,MAAO,CAACM,mBAAmBD,EAAM,IAAKC,mBAAmBD,EAAM,QAElEE,MAAK,SAACnE,EAAqBvB,GACxB,OAAOuB,EAAE,GAAGoE,cAAc3F,EAAE,OA3N7B4F,CAAiBV,GACnBI,KAAI,YAA4C,aAA1C7D,EAA0C,KAArCa,EAAqC,KAC7C,OAAOuD,mBAAmBpE,GAAO,IAAMoE,mBAAmBvD,MAE7D1D,KAAK,KA7EmBkH,CAA2BrB,GAClDsB,EA4FH,SAAgC7C,GACnC,GAAIA,EAAQ8C,cAAgBrE,QAA6C,IAAnCA,OAAOsE,QAAQ/C,GAAS4B,OAC1D,MAAO,GAqBX,OAlByBnD,OAAOsE,QAAQ/C,GACnCoC,KAAI,YAAoB,aAAlB3C,EAAkB,KAAZuD,EAAY,KAYrB,OAXsBvD,EAAKwD,cAAcC,OAWlB,KAVE/G,MAAMgH,QAAQH,GAAUA,EAAS,CAACA,IAItDZ,KAAI,SAACC,GAEF,OAAOA,EAAEe,QAAQ,OAAQ,KAAKA,QAAQ,aAAc,OAEvD1H,KAAK,KAEqC,QAElD8G,OACA9G,KAAK,IAjHe2H,CAAuBrD,GAC1CsD,EAAgBC,EAAoBvD,GACpCwD,EAsKH,SAAgChC,GACnC,GAAIA,IAAYiC,EACZ,OAAOjC,EAMX,OAAO5F,IAAAA,OAAc4F,GAAW,GAAI,OAAOyB,cA9KpBS,CAAuBlC,GAW9C,MATyB,CACrBC,EACAE,EACAI,EACAc,EACAS,EACAE,GACF9H,KAAK,MA3MkBiI,CACrBzD,EACAC,EACAC,EACAJ,EACAK,EACAG,GAGEoD,EA2GH,SACH3D,EACAW,EACAL,EACAsD,GAGA,IAAMC,EAAkBC,EAAO9D,GAKzB+D,EAAkBC,EAAsBhE,EAAkBW,EAAQL,GAgBxE,MAdqB,CAEjB2D,EAGAJ,EAGAE,EAGAH,GACFnI,KAAK,MArIcyI,CACjBlE,EACAK,EAAUM,OACVL,GACA6D,EAAAA,EAAAA,QAAO/C,EAAkB,QAGvB2C,EAAkBC,EAAsBhE,EAAkBK,EAAUM,OAAQL,GAC5E+C,EAAgBC,EAAoBvD,GACpCqE,EAmCH,SAA4B5D,EAAgCmD,GAC/D,OAAO3C,EAAAA,EAAAA,MAAK,SAAUR,EAAmBmD,EAAc,OApCrCU,CAAmB7D,EAAmBmD,GAClDW,EAAsB,GAAH,OAAML,EAAN,uBAAqC5D,EAAUkE,YAA/C,YAA8DR,EAA9D,2BAAgGV,EAAhG,uBAA4He,GAIrJ,OAFArE,EAAO,cAAoBuE,EAEpBvE,EAWJ,IAAMyE,EAAb,a,qRAAA,iBAMI,WAAYlF,EAAiBC,GAAc,wBACvC,cAAMD,EAASC,IACVC,KAAO,wBAF2B,EAN/C,aAA2CH,GA2DpC,IAAM4E,EAAmB,mBAOnBT,EAAkB,mBA6DxB,SAASQ,EACZhE,EACAW,EACAL,GAEA,MAAO,CAACQ,EAAOd,GAAmBW,EAAQL,EAAS,gBAAgB7E,KAAK,KAgKrE,SAAS6H,EAAoBvD,GAChC,GAAIA,EAAQ8C,cAAgBrE,OACxB,MAAM,IAAIiG,UAAU,+BAGxB,GAAuC,IAAnCjG,OAAOsE,QAAQ/C,GAAS4B,OACxB,KAAM,8FAYV,OALenD,OAAOkG,KAAK3E,GACtBoC,KAAI,SAAC3C,GAAD,OAAUA,EAAKwD,cAAcC,UACjCV,OACA9G,KAAK,KAqDP,SAASmG,EAAUP,EAAanB,GACnC,MAAW,IAAPmB,EACOA,EAGJA,EACFW,MAAM,IACNG,KAAI,SAACwC,GACF,OAoFKC,EApFOD,IAqFP,KAAOC,GAAK,KAASA,GAAK,KAAOA,GAAK,KAGvD,SAAmBA,GACf,OAAOA,GAAK,KAAOA,GAAK,IAzFOC,CAAUF,IAAW,OAAOG,SAASH,GACjDA,EAIG,KAAVA,EACO,MAKG,KAAVA,GAAiBzE,EACV,IAGJ,IAAMyE,EAAOI,WAAW,GAAG3J,SAAS,IAAIqG,cAqE3D,IAAiBmD,KAnERnJ,KAAK,IAMP,IAAMuJ,EAAb,GAUI,WAAYC,EAAiB/E,GAAe,wDACxCgF,KAAA,OAAcD,EACdC,KAAKhF,KAAOA,KAWb,SAAS4D,EAAOqB,GACnB,OAAO,IAAIhI,KAAKgI,GAAWC,cAAcjC,QAAQ,iBAAkB,IAQhE,SAASrC,EAAOqE,GACnB,OAAOrB,EAAOqB,GAAWE,UAAU,EAAG,G,ooECvfnC,IAAMC,EAAb,GAaI,WAAY3E,EAAgB4D,EAAqB9D,GAC7C,GADsE,gGAChD,iBAAXE,GAAkC,KAAXA,EAC9B,MAAM,IAAI4E,EACN,4DAIR,GAA2B,iBAAhBhB,GAA4C,KAAhBA,EACnC,MAAM,IAAIgB,EACN,mEAIR,GAA+B,iBAApB9E,GAAoD,KAApBA,EACvC,MAAM,IAAI8E,EACN,uEAIRL,KAAKvE,OAASA,EACduE,KAAKX,YAAcA,EACnBW,KAAKzE,gBAAkBA,KAKlB8E,EAAb,a,qRAAA,U,IAAA,G,EAAA,E,mJACI,WAAYjG,GAAiB,6BACnBA,GAFd,eAA2C/B,QCxC3C,MAAM,EAA+B6B,QAAQ,W,2SCWtC,IAAMoG,EAAb,WAUI,WAAYnF,EAAsBoF,EAAqBlF,I,4FAAsC,oGACzF2E,KAAK7E,UAAYA,EACjB6E,KAAKO,YAAcA,EACnBP,KAAK3E,kBAAoBA,E,UAbjC,O,EAAA,G,EAAA,2BAgBI,SACIN,EACAyF,EACAxF,EACAC,EACAC,EACAL,GAEA,IAAMC,EAA2B7C,KAAKwI,MAChC9E,EAAeiD,EAAO9D,GAE5BD,EAAO,KAAW2F,EAClB3F,EAAQ,cAAgBc,EAExBd,EAAUD,EAENC,EAGAC,EAGAC,EAGAC,EAGAC,EAGAC,EAGA8E,KAAK7E,UAGL6E,KAAKO,YAKLP,KAAK3E,mBAITL,EAAgB,KAATA,EAAcA,EAAO,IAC5B,IAAI0F,EAAM,WAAH,OAAcF,GAAd,OAAqBxF,GAK5B,MAJoB,KAAhBC,IACAyF,GAAO,IAAJ,OAAQzF,IAGR,CAAEyF,IAAKA,EAAK7F,QAASA,Q,8EApEpC,K,6vECAO,IAAM8F,GAAb,gCAMI,WAAYxF,GAAsB,WAC9B,IAAME,EAAoB,IAAIyE,GAAkB,GAAO,GADzB,mBAExB3E,EAAW,KAAME,GAR/B,sCAoBI,WAEI,IACMmF,EAAO,GAAH,OAAMR,KAAKO,YAAX,YAA0BP,KAAK7E,UAAUM,OAAzC,kBAEJmF,EAA4B,GAAH,+CAHhB,MAG8CJ,EAAM,IAAK,GAD3D,GACqE,CAC9E,wBAAwBvB,EAAAA,EAAAA,QAFf,GAE4B,SAGnC4B,EAAMC,IAAAA,QAPG,MAOkBF,EAAcF,IALlC,GAK6C,CACtD7F,QAAS+F,EAAc/F,UAE3BmF,KAAKe,cAAcF,EAAIG,WAAYH,EAAII,MAAOJ,EAAI3F,MAElD,IAAIgG,EAA2B,GAwB/B,OAtBYzG,EAAAA,EAAAA,WAAUoG,EAAI3F,MAEtBR,KAAK,WACJyG,WACAC,MAAK,SAACC,EAAGC,GACN,IAAIC,EAAS,GAEbD,EAAiBH,WAAWK,SAAQ,SAACC,GACjC,OAAQA,EAAMC,YACV,IAAK,OACDpI,OAAOqI,OAAOJ,EAAQ,CAAEjH,KAAMmH,EAAMG,gBACpC,MACJ,IAAK,eACDtI,OAAOqI,OAAOJ,EAAQ,CAClBM,aAAc5J,KAAK6J,MAAML,EAAMG,qBAK/CV,EAAQa,KAAKR,MAGdL,IA1Df,yBAuEI,SAAYc,EAAoBC,GAE5B,IACMzB,EAAO,GAAH,OAAMwB,EAAN,YAAoBhC,KAAKO,YAAzB,YAAwCP,KAAK7E,UAAUM,OAAvD,kBAEJyG,EAAc,sBAAH,OAAyBD,GACpCrB,EAA4B,GAAH,+CAJhB,MAI8CJ,EAAM,IAAK0B,EAF3D,GAE8E,CACvF,wBAAwBjD,EAAAA,EAAAA,QAHf,GAG4B,OACrCkD,OAAQF,MAAAA,EAAAA,EAAU,KAGhBpB,EAAMC,IAAAA,QATG,MASkBF,EAAcF,IAPlC,GAO6C,CACtD7F,QAAS+F,EAAc/F,UAE3BmF,KAAKe,cAAcF,EAAIG,WAAYH,EAAII,MAAOJ,EAAI3F,MAElD,IAAIkH,EAA2B,GA+B/B,OA3BA3H,EAAAA,EAAAA,WAAUoG,EAAI3F,MACTR,KAAK,YACL0G,MAAK,SAACC,EAAGgB,GACN,IAAI3I,EAAM,GAEV2I,EAAiBlB,WAAWK,SAAQ,SAACC,GACjC,OAAQA,EAAMC,YACV,IAAK,MACDpI,OAAOqI,OAAOjI,EAAK,CAAEN,IAAKqI,EAAMG,gBAChC,MACJ,IAAK,eACDtI,OAAOqI,OAAOjI,EAAK,CAAE4I,aAAcrK,KAAK6J,MAAML,EAAMG,iBACpD,MACJ,IAAK,OACDtI,OAAOqI,OAAOjI,EAAK,CAAE6I,KAAMd,EAAMG,gBACjC,MACJ,IAAK,OACDtI,OAAOqI,OAAOjI,EAAK,CAAE8I,KAAMC,SAAShB,EAAMG,iBAC1C,MACJ,IAAK,eACDtI,OAAOqI,OAAOjI,EAAK,CAAEgJ,aAAcjB,EAAMG,oBAIrDQ,EAAQL,KAAKrI,MAGd0I,IAtHf,uBAmII,SAAUJ,EAAoBW,GAA6B,MAGjDnC,EAAO,GAAH,OAAMwB,EAAN,YAAoBhC,KAAKO,YAAzB,YAAwCP,KAAK7E,UAAUM,OAAvD,kBACJT,EAAO,IAAH,OAAO2H,GAEX/B,EAA4B,GAAH,+CAJhB,MAI8CJ,EAAMxF,EAAM,GAD5D,GACsE,CAC/E,wBAAwBiE,EAAAA,EAAAA,QAFf,GAE4B,SAGnC4B,EAAMC,IAAAA,QARG,MAQkBF,EAAcF,IALlC,GAK6C,CACtD7F,QAAS+F,EAAc/F,UAM3B,OAJAmF,KAAKe,cAAcF,EAAIG,WAAYH,EAAII,MAAOJ,EAAI3F,MAElD0H,QAAQC,IAAR,uCAA4CC,KAAKC,UAAUlC,EAAIhG,QAAS,KAAM,QAEvE,IAAImI,GACPL,EACA1K,KAAK6J,MAAMjB,EAAIhG,QAAQ,kBACvBgG,EAAIhG,QAAJ,KACA4H,SAAS5B,EAAIhG,QAAQ,mBAJlB,UAKFgG,EAAIhG,QAAQ,8BALV,QAKoC,WACvCgG,EAAI3F,QA1JhB,uBAwKI,SAAU8G,EAAoBW,EAAmBM,GAE7C,IACMzC,EAAO,GAAH,OAAMwB,EAAN,YAAoBhC,KAAKO,YAAzB,YAAwCP,KAAK7E,UAAUM,OAAvD,kBACJT,EAAO,IAAH,OAAO2H,GAEXzH,EAAO+H,EACPrC,EAA4B,GAAH,+CALhB,MAOXJ,EACAxF,EALgB,GAOhBE,EACA,CACI,wBAAwB+D,EAAAA,EAAAA,QAAO/D,EAAM,SAIvC2F,EAAMC,IAAAA,QAhBG,MAgBkBF,EAAcF,IAAKxF,EAAM,CACtDL,QAAS+F,EAAc/F,UAE3BmF,KAAKe,cAAcF,EAAIG,WAAYH,EAAII,MAAOJ,EAAI3F,QA7L1D,0BAyMI,SAAa8G,EAAoBW,GAE7B,IAAM5H,EAAS,SACTyF,EAAO,GAAH,OAAMwB,EAAN,YAAoBhC,KAAKO,YAAzB,YAAwCP,KAAK7E,UAAUM,OAAvD,kBACJT,EAAO,IAAH,OAAO2H,GAGX/B,EAA4B,GAAH,+CAC3B7F,EACAyF,EACAxF,EALgB,GACP,GAOT,CACI,wBAAwBiE,EAAAA,EAAAA,QARnB,GAQgC,SAIvC4B,EAAMC,IAAAA,QAAa/F,EAAQ6F,EAAcF,IAZlC,GAY6C,CACtD7F,QAAS+F,EAAc/F,UAE3BmF,KAAKe,cAAcF,EAAIG,WAAYH,EAAII,MAAOJ,EAAI3F,QA9N1D,2BAmOI,SAAc8F,EAAoBkC,EAAuBC,GACrD,GAAqB,IAAjBD,GAAsC,IAAflC,EAA3B,CAOA,GAAIkC,GAAiBA,EAAcE,WAAW,OAE1C,MAAM,IAAIC,GAAe,qBAAsB,mBAAoB,aAGvE,IAAMC,EAAWnJ,EAASoJ,SAASJ,GACnC,GACS,iCADDG,EAASjJ,KAET,MAAM,IAAIiF,EAAsBgE,EAASlJ,QAASkJ,EAASjJ,MAE3D,MAAM,IAAIgJ,GAAeC,EAASlJ,QAASkJ,EAASjJ,KAAM,oBArP1E,GAA8BiG,GA4PjBkD,GAAb,IAUI,WAAYlJ,EAAcuH,GAAoB,iEAC1C7B,KAAK1F,KAAOA,EACZ0F,KAAK6B,aAAeA,KAMfmB,GAAb,IAkBI,WACI5J,EACAkJ,EACAC,EACAC,EACAE,EACAO,GACF,oKACEjD,KAAK5G,IAAMA,EACX4G,KAAKsC,aAAeA,EACpBtC,KAAKuC,KAAOA,EACZvC,KAAKwC,KAAOA,EACZxC,KAAK0C,aAAeA,EACpB1C,KAAKiD,KAAOA,KAYPI,GAAb,gCAUI,WAAYjJ,EAAiBC,EAAcoJ,GAAmB,8BAC1D,cAAMrJ,EAASC,IAD2C,oBAE1D,EAAKC,KAAO,iBACZ,EAAKmJ,UAAYA,EAHyC,EAVlE,cAAoCtJ,G,20FCvT7B,IAAMuJ,GAAb,gCAQI,WAAYvI,GAAsB,iBAC9B,IAAME,EAAoB,IAAIyE,GAAkB,GAAM,GADxB,aAE9B,cAAM3E,EAAW,iBAAkBE,IAFL,kDAQ9B,EAAKN,OAAS,OAEd,EAAK4I,cAAgB,CACjB,kBAAmB,WACnB,eAAgB,8BAZU,EARtC,sCAgCI,WACI,IAAMzI,EAAO4H,KAAKC,UAAU,IAItBnC,EAA4B,kDAC9BZ,KAAKjF,OACLiF,KAAKQ,KACL,IACA,GACAtF,EAL2B,SAOpB8E,KAAK2D,eAPe,IAQvB,yBAAmB3D,KAAKO,YAAxB,mBAIFM,EAAMC,IAAAA,QAAad,KAAKjF,OAAQ6F,EAAcF,IAAKxF,EAAM,CAC3DL,QAAS+F,EAAc/F,UAK3B,OAHAmF,KAAKe,cAAc,cAAeF,GACVA,EAAI+C,KAAK,cAErB3G,KAAI,SAAC4G,GAAD,OAAOC,GAAOC,SAASF,QAvD/C,uBAkEI,SAAUG,GACN,IAAM9I,EAAO4H,KAAKC,UAAU,CAAEkB,SAAUD,IAIlCpD,EAA4B,kDAC9BZ,KAAKjF,OACLiF,KAAKQ,KACL,IACA,GACAtF,EAL2B,SAOpB8E,KAAK2D,eAPe,IAQvB,yBAAmB3D,KAAKO,YAAxB,sBAIFM,EAAMC,IAAAA,QAAad,KAAKjF,OAAQ6F,EAAcF,IAAKxF,EAAM,CAC3DL,QAAS+F,EAAc/F,UAI3B,OAFAmF,KAAKe,cAAc,iBAAkBF,GAE9BiD,GAAOC,SAASlD,EAAI+C,UAxFnC,0BA6GI,SACItJ,EACA4J,EACAC,EACAC,EACAC,GAEAD,EAAYA,IAAaE,EAAAA,GAAAA,MAEzB,IAAMpJ,EAAO4H,KAAKC,UAAU,CACxBwB,KAAMjK,EACNkK,YAAaL,EACbM,aAAcP,EACdQ,mBAAoBN,EACpBO,KAAMN,IAGJzD,EAA4B,kDAC9BZ,KAAKjF,OACLiF,KAAKQ,KACL,IACA,GACAtF,EAL2B,SAOpB8E,KAAK2D,eAPe,IAQvB,yBAAmB3D,KAAKO,YAAxB,oBAQFM,EAAMC,IAAAA,QAAad,KAAKjF,OAAQ6F,EAAcF,IAAKxF,EAAM,CAC3DL,QAAS+F,EAAc/F,UAI3B,OAFAmF,KAAKe,cAAc,eAAgBF,GAE5BiD,GAAOC,SAASlD,EAAI+C,UAnJnC,4BAiKI,SAAeI,EAAkBE,EAAsBE,GACnDA,EAAYA,IAAaE,EAAAA,GAAAA,MAEzB,IAAMpJ,EAAO4H,KAAKC,UAAU,CACxBkB,SAAUD,EACVS,aAAcP,EACdQ,mBAAoBN,IAKlBxD,EAA4B,kDAC9BZ,KAAKjF,OACLiF,KAAKQ,KACL,IACA,GACAtF,EAL2B,SAOpB8E,KAAK2D,eAPe,IAQvB,yBAAmB3D,KAAKO,YAAxB,sBAIFM,EAAMC,IAAAA,QAAad,KAAKjF,OAAQ6F,EAAcF,IAAKxF,EAAM,CAC3DL,QAAS+F,EAAc/F,UAI3B,OAFAmF,KAAKe,cAAc,iBAAkBF,GAE9BiD,GAAOC,SAASlD,EAAI+C,UA7LnC,0BA4MI,SACII,EADJ,GAGE,QADIY,eAAAA,OACJ,MADqB,GACrB,MADyBC,WAEjBxI,EAAwD,CAC1D4H,SAAUD,IAIK,UANrB,UAOM3H,EAAO,4BAAiC,EAExCA,EAAO,qBAA2BuI,EAGtC,IAAM1J,EAAO4H,KAAKC,UAAU1G,GAItBuE,EAA4B,kDAC9BZ,KAAKjF,OACLiF,KAAKQ,KACL,IACA,GACAtF,EAL2B,SAOpB8E,KAAK2D,eAPe,IAQvB,yBAAmB3D,KAAKO,YAAxB,oBAIFM,EAAMC,IAAAA,QAAad,KAAKjF,OAAQ6F,EAAcF,IAAKxF,EAAM,CAC3DL,QAAS+F,EAAc/F,UAE3BmF,KAAKe,cAAc,eAAgBF,KA9O3C,gBAiPI,WACI,gBAAUb,KAAKO,YAAf,YAA8BP,KAAK7E,UAAUM,OAA7C,oBAlPR,2BAsPI,SAAcgI,EAAmBqB,GAC7B,IAAMC,EAAYD,EAAS9D,WAC3B,GAAkB,IAAd+D,EAAJ,CAIA,IAAM9D,EAAQ6D,EAASlB,OACvB,GAAImB,GAAa,MAAQA,GAAa,KAAM,CAGxC,IAAMC,EACD/D,EAAMgE,SAAuBhE,EAAM7G,SAAuB6G,EAAMiE,OAGrE,GAAqB,8BAAjBjE,EAAMiE,OACN,MAAM,IAAI5F,EAAsB0F,EAAc/D,EAAMiE,QAIxD,MAAM,IAAIC,GAAoBH,EAAc/D,EAAMiE,OAAkBzB,GAGxE,GAAkB,OAAdsB,EACA,MAAM,IAAII,GACN,sCACA,uBACA1B,QAhRhB,GAA0CnD,GA2R7BwD,GAAb,WAoBI,WACIxJ,EACA8K,EACAlB,EACAmB,EACAC,EACAC,GAEF,IADElB,EACF,uDAD2C,GAC3C,2MACErE,KAAK1F,KAAOA,EACZ0F,KAAKoF,IAAMA,EACXpF,KAAKwF,OAAStB,EACdlE,KAAKqF,YAAcA,EACnBrF,KAAKsF,iBAAmBA,EACxBtF,KAAKuF,gBAAkBA,EACvBvF,KAAKqE,KAAOA,EAnCpB,wCA8CI,SAAgBT,GACZ,OAAO,IAAIE,EACPF,EAAKW,KACLX,EAAK6B,IACL7B,EAAKa,aACLb,EAAK8B,YACL9B,EAAK+B,iBACL/B,EAAKgC,gBACLhC,EAAKe,UAtDjB,KA2DaQ,GAAb,gCAUI,WAAY/K,EAAiBC,EAAcoJ,GAAmB,8BAC1D,cAAMrJ,EAASC,IAD2C,oBAE1D,EAAKC,KAAO,6BACZ,EAAKmJ,UAAYA,EAHyC,EAVlE,cAAyCtJ,I","sources":["webpack://k6-jslib-aws/./node_modules/uuid/index.js","webpack://k6-jslib-aws/./node_modules/uuid/lib/bytesToUuid.js","webpack://k6-jslib-aws/./node_modules/uuid/lib/rng-browser.js","webpack://k6-jslib-aws/./node_modules/uuid/v1.js","webpack://k6-jslib-aws/./node_modules/uuid/v4.js","webpack://k6-jslib-aws/webpack/bootstrap","webpack://k6-jslib-aws/webpack/runtime/compat get default export","webpack://k6-jslib-aws/webpack/runtime/define property getters","webpack://k6-jslib-aws/webpack/runtime/hasOwnProperty shorthand","webpack://k6-jslib-aws/webpack/runtime/make namespace object","webpack://k6-jslib-aws/external commonjs \"k6/crypto\"","webpack://k6-jslib-aws/external commonjs \"k6/html\"","webpack://k6-jslib-aws/./src/internal/error.ts","webpack://k6-jslib-aws/./src/internal/signature.ts","webpack://k6-jslib-aws/./src/internal/config.ts","webpack://k6-jslib-aws/external commonjs \"k6/http\"","webpack://k6-jslib-aws/./src/internal/client.ts","webpack://k6-jslib-aws/./src/internal/s3.ts","webpack://k6-jslib-aws/./src/internal/secrets-manager.ts"],"sourcesContent":["var v1 = require('./v1');\nvar v4 = require('./v4');\n\nvar uuid = v4;\nuuid.v1 = v1;\nuuid.v4 = v4;\n\nmodule.exports = uuid;\n","/**\n * Convert array of 16 byte values to UUID string format of the form:\n * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n */\nvar byteToHex = [];\nfor (var i = 0; i < 256; ++i) {\n byteToHex[i] = (i + 0x100).toString(16).substr(1);\n}\n\nfunction bytesToUuid(buf, offset) {\n var i = offset || 0;\n var bth = byteToHex;\n // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4\n return ([\n bth[buf[i++]], bth[buf[i++]],\n bth[buf[i++]], bth[buf[i++]], '-',\n bth[buf[i++]], bth[buf[i++]], '-',\n bth[buf[i++]], bth[buf[i++]], '-',\n bth[buf[i++]], bth[buf[i++]], '-',\n bth[buf[i++]], bth[buf[i++]],\n bth[buf[i++]], bth[buf[i++]],\n bth[buf[i++]], bth[buf[i++]]\n ]).join('');\n}\n\nmodule.exports = bytesToUuid;\n","// Unique ID creation requires a high quality random # generator. In the\n// browser this is a little complicated due to unknown quality of Math.random()\n// and inconsistent support for the `crypto` API. We do the best we can via\n// feature-detection\n\n// getRandomValues needs to be invoked in a context where \"this\" is a Crypto\n// implementation. Also, find the complete implementation of crypto on IE11.\nvar getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||\n (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));\n\nif (getRandomValues) {\n // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto\n var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef\n\n module.exports = function whatwgRNG() {\n getRandomValues(rnds8);\n return rnds8;\n };\n} else {\n // Math.random()-based (RNG)\n //\n // If all else fails, use Math.random(). It's fast, but is of unspecified\n // quality.\n var rnds = new Array(16);\n\n module.exports = function mathRNG() {\n for (var i = 0, r; i < 16; i++) {\n if ((i & 0x03) === 0) r = Math.random() * 0x100000000;\n rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;\n }\n\n return rnds;\n };\n}\n","var rng = require('./lib/rng');\nvar bytesToUuid = require('./lib/bytesToUuid');\n\n// **`v1()` - Generate time-based UUID**\n//\n// Inspired by https://github.com/LiosK/UUID.js\n// and http://docs.python.org/library/uuid.html\n\nvar _nodeId;\nvar _clockseq;\n\n// Previous uuid creation time\nvar _lastMSecs = 0;\nvar _lastNSecs = 0;\n\n// See https://github.com/uuidjs/uuid for API details\nfunction v1(options, buf, offset) {\n var i = buf && offset || 0;\n var b = buf || [];\n\n options = options || {};\n var node = options.node || _nodeId;\n var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq;\n\n // node and clockseq need to be initialized to random values if they're not\n // specified. We do this lazily to minimize issues related to insufficient\n // system entropy. See #189\n if (node == null || clockseq == null) {\n var seedBytes = rng();\n if (node == null) {\n // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)\n node = _nodeId = [\n seedBytes[0] | 0x01,\n seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]\n ];\n }\n if (clockseq == null) {\n // Per 4.2.2, randomize (14 bit) clockseq\n clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;\n }\n }\n\n // UUID timestamps are 100 nano-second units since the Gregorian epoch,\n // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so\n // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'\n // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.\n var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime();\n\n // Per 4.2.1.2, use count of uuid's generated during the current clock\n // cycle to simulate higher resolution clock\n var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1;\n\n // Time since last uuid creation (in msecs)\n var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;\n\n // Per 4.2.1.2, Bump clockseq on clock regression\n if (dt < 0 && options.clockseq === undefined) {\n clockseq = clockseq + 1 & 0x3fff;\n }\n\n // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new\n // time interval\n if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {\n nsecs = 0;\n }\n\n // Per 4.2.1.2 Throw error if too many uuids are requested\n if (nsecs >= 10000) {\n throw new Error('uuid.v1(): Can\\'t create more than 10M uuids/sec');\n }\n\n _lastMSecs = msecs;\n _lastNSecs = nsecs;\n _clockseq = clockseq;\n\n // Per 4.1.4 - Convert from unix epoch to Gregorian epoch\n msecs += 12219292800000;\n\n // `time_low`\n var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;\n b[i++] = tl >>> 24 & 0xff;\n b[i++] = tl >>> 16 & 0xff;\n b[i++] = tl >>> 8 & 0xff;\n b[i++] = tl & 0xff;\n\n // `time_mid`\n var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;\n b[i++] = tmh >>> 8 & 0xff;\n b[i++] = tmh & 0xff;\n\n // `time_high_and_version`\n b[i++] = tmh >>> 24 & 0xf | 0x10; // include version\n b[i++] = tmh >>> 16 & 0xff;\n\n // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)\n b[i++] = clockseq >>> 8 | 0x80;\n\n // `clock_seq_low`\n b[i++] = clockseq & 0xff;\n\n // `node`\n for (var n = 0; n < 6; ++n) {\n b[i + n] = node[n];\n }\n\n return buf ? buf : bytesToUuid(b);\n}\n\nmodule.exports = v1;\n","var rng = require('./lib/rng');\nvar bytesToUuid = require('./lib/bytesToUuid');\n\nfunction v4(options, buf, offset) {\n var i = buf && offset || 0;\n\n if (typeof(options) == 'string') {\n buf = options === 'binary' ? new Array(16) : null;\n options = null;\n }\n options = options || {};\n\n var rnds = options.random || (options.rng || rng)();\n\n // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n rnds[6] = (rnds[6] & 0x0f) | 0x40;\n rnds[8] = (rnds[8] & 0x3f) | 0x80;\n\n // Copy bytes to buffer, if provided\n if (buf) {\n for (var ii = 0; ii < 16; ++ii) {\n buf[i + ii] = rnds[ii];\n }\n }\n\n return buf || bytesToUuid(rnds);\n}\n\nmodule.exports = v4;\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/crypto\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/html\");","import { parseHTML } from 'k6/html'\n\n/**\n * Base class to derive errors from\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class AWSError extends Error {\n code: string\n\n /**\n * Create an AWSError\n *\n * @param {string} message - A longer human readable error message.\n * @param {string} code - A unique short code representing the error that was emitted\n */\n constructor(message: string, code: string) {\n super(message)\n this.name = 'AWSError'\n this.code = code\n }\n\n /**\n * Parse an AWSError from an XML document\n *\n * @param {string} xmlDocument - Serialized XML document to parse the error from\n */\n static parseXML(xmlDocument: string): AWSError {\n const doc = parseHTML(xmlDocument)\n return new AWSError(doc.find('Message').text(), doc.find('Code').text())\n }\n}\n","import crypto, { hmac, sha256 } from 'k6/crypto'\nimport { HTTPMethod, HTTPHeaders } from './http'\nimport { AWSConfig } from './config'\nimport { AWSError } from './error'\n\n/**\n * Includes AWS v4 signing information to the provided HTTP headers object.\n *\n * This function will compute the `Authorization` header signature for the\n * provided request components, and add it to `header`. It will do so by following\n * the procedure detailled AWS' API docs: https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html\n *\n * The resulting `Authorization` header value is computed for the provided\n * headers object. Thus, any modification of the headers past a call to `signHeaders`\n * would effectively invalidate their signature, and the function should be\n * called again to recompute it.\n *\n * @param {object} headers - HTTP headers request to sign.\n * @param {number} requestTimestamp - Timestamp of the request\n * @param {string} method - HTTP method used\n * @param {string} path - HTTP request URL's path\n * @param {string} queryString - HTTP request URL's querystring\n * @param {string | ArrayBuffer} body - HTTP request's payload\n * @param {AWSConfig} - AWS configuration\n * @param {string} service - AWS service name\n * @param {URIEncodingConfig} - URI encoding configuration\n */\nexport function signHeaders(\n headers: HTTPHeaders,\n requestTimestamp: number,\n method: HTTPMethod,\n path: string,\n queryString: string,\n body: string | ArrayBuffer,\n awsConfig: AWSConfig,\n service: string,\n URIencodingConfig: URIEncodingConfig\n): HTTPHeaders {\n const derivedSigningKey = deriveSigningKey(\n awsConfig.secretAccessKey,\n requestTimestamp,\n awsConfig.region,\n service\n )\n\n const canonicalRequest = createCanonicalRequest(\n method,\n path,\n queryString,\n headers,\n body,\n URIencodingConfig\n )\n\n const stringToSign = createStringToSign(\n requestTimestamp,\n awsConfig.region,\n service,\n sha256(canonicalRequest, 'hex')\n )\n\n const credentialScope = createCredentialScope(requestTimestamp, awsConfig.region, service)\n const signedHeaders = createSignedHeaders(headers)\n const signature = calculateSignature(derivedSigningKey, stringToSign)\n const authorizationHeader = `${HashingAlgorithm} Credential=${awsConfig.accessKeyID}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`\n\n headers['Authorization'] = authorizationHeader\n\n return headers\n}\n\n/**\n * Error indicating an Invalid signature has been sent to AWS services\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class InvalidSignatureError extends AWSError {\n /**\n * Constructs an InvalidSignatureError\n *\n * @param {string} message - human readable error message\n */\n constructor(message: string, code: string) {\n super(message, code)\n this.name = 'InvalidSignatureError'\n }\n}\n\n/**\n * Calculte the signature for AWS signature version 4\n *\n * @param {string} derivedSigningKey - dervied signing key as computed by `deriveSigningKey`\n * @param {string} stringToSign - String to sign as computed by `createStringToSign`\n * @return {string}\n */\nexport function calculateSignature(derivedSigningKey: ArrayBuffer, stringToSign: string): string {\n return hmac('sha256', derivedSigningKey, stringToSign, 'hex')\n}\n/**\n * Derives the signing key for authenticating requests signed with\n * the Signature version 4 authentication protocol.\n *\n * deriveSigningKey produces a signing key by creating a series of\n * hash-based message authentication codes (HMACs) represented in\n * a binary format.\n *\n * The derived signing key is specific to the date it's made at, as well as\n * the service and region it targets.\n *\n * @param {string} secretAccessKey - the AWS secret access key to derive the signing key for\n * @param {number} time - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service. MUST be UTF-8 encoded.\n * @return {string}\n */\nexport function deriveSigningKey(\n secretAccessKey: string,\n time: number,\n region: string,\n service: string\n): ArrayBuffer {\n const kSecret = secretAccessKey\n const date = toDate(time)\n\n // FIXME: hmac takes ArrayBuffer as input, but returns bytes (number[]).\n // How does one convert from one to the other?\n const kDate: any = hmac('sha256', 'AWS4' + kSecret, date, 'binary')\n const kRegion: any = hmac('sha256', kDate, region, 'binary')\n const kService: any = hmac('sha256', kRegion, service, 'binary')\n const kSigning: any = hmac('sha256', kService, 'aws4_request', 'binary')\n\n return kSigning\n}\n\n// Hashing Algorithm to use in the signature process\nexport const HashingAlgorithm = 'AWS4-HMAC-SHA256'\n\n/**\n * Certain services, such as S3, allow for unsigned payloads. If\n * producing a signed canonical request for such service, pass\n * the `UnsignedPayload` constant value as the payload parameter.\n */\nexport const UnsignedPayload = 'UNSIGNED-PAYLOAD'\n\n/**\n * Create the \"string to sign\" part of the signature Version 4 protocol.\n *\n * The \"string to sign\" includes meta information about your request and\n * about the canonical request that you created with `createCanonicalRequest`.\n * It is used hand in hand with the signing key to create the request signature.\n *\n * @param {number} requestTimestamp - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service name. MUST be UTF-8 encoded.\n * @param {string} hashedCanonicalRequest - canonical request as produced by calling the createCanonicalRequest function,\n * hashed using the SHA256 algorithm (encoded in hexadecimal format).\n * @return {string}\n */\nexport function createStringToSign(\n requestTimestamp: number,\n region: string,\n service: string,\n hashedCanonicalRequest: string\n): string {\n // the request date specified in ISO8601 format: YYYYMMDD'T'HHMMSS'Z'\n const requestDateTime = toTime(requestTimestamp)\n\n // The credential scope value, consisting of the date in YYYYMMDD format,\n // the targeted region, the targeted service, and a termination string.\n // Note that the region and service MUST be UTF-8 encoded.\n const credentialScope = createCredentialScope(requestTimestamp, region, service)\n\n const stringToSign = [\n // Algorithm\n HashingAlgorithm,\n\n // RequestDateTime\n requestDateTime,\n\n // CredentialScope\n credentialScope,\n\n // HashedCanonicalRequest\n hashedCanonicalRequest,\n ].join('\\n')\n\n return stringToSign\n}\n\n/**\n *\n * Helper function creating a credential scope string to use in the signature\n * version 4 process. A credential scope consists of the date of the request\n * in YYYYMMDD format, the targeted region, the targeted service, and a\n * termination string.\n *\n * Note that the region and service MUST be UTF-8 encoded.\n *\n * @param {number} requestTimestamp - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service name. MUST be UTF-8 encoded.\n * @return {string}\n */\nexport function createCredentialScope(\n requestTimestamp: number,\n region: string,\n service: string\n): string {\n return [toDate(requestTimestamp), region, service, 'aws4_request'].join('/')\n}\n\n/**\n * Create a string that includes information from your request\n * in a AWS signature v4 standardized (canonical) format.\n *\n * @param {string} method - the HTTP request method\n * @param {string} uri - URI-encoded version of the absolute path component of the URI\n * @param {string} query - request's query string\n * @param {Object} headers - all the HTTP headers that you wish to include with the signed request\n * @param {string | ArrayBuffer} payload - payload to include as the body of the request\n * @param {URIEncodingConfig} URIencodingConfig- URI encoding configuration\n * @return {string}\n */\nexport function createCanonicalRequest(\n method: HTTPMethod,\n uri: string,\n query: string,\n headers: HTTPHeaders,\n payload: string | ArrayBuffer,\n URIencodingConfig: URIEncodingConfig\n): string {\n const httpRequestMethod = method.toUpperCase()\n const canonicalURI = createCanonicalURI(uri, URIencodingConfig)\n const canonicalQueryString = createCanonicalQueryString(query)\n const canonicalHeaders = createCanonicalHeaders(headers)\n const signedHeaders = createSignedHeaders(headers)\n const requestPayload = createCanonicalPayload(payload)\n\n const canonicalRequest = [\n httpRequestMethod,\n canonicalURI,\n canonicalQueryString,\n canonicalHeaders,\n signedHeaders,\n requestPayload,\n ].join('\\n')\n\n return canonicalRequest\n}\n\n/**\n * Creates the (canonical) URI-encoded version of the\n * absolute path component of the URI: everything in the URI\n * from the HTTP host to the question mark character (\"?\")\n * that begins the query string parameters (if any).\n *\n * @param {string} uri - URI to canonize\n * @param {URIEncodingConfig} - URI encoding configuration\n * @return {string} - canonical URL\n */\nexport function createCanonicalURI(uri: string, URIencodingConfig: URIEncodingConfig): string {\n if (uri == '/') {\n return uri\n }\n\n let canonicalURI = uri\n if (uri[uri.length - 1] == '/' && canonicalURI[canonicalURI.length - 1] != '/') {\n canonicalURI += '/'\n }\n\n canonicalURI = URIEncode(canonicalURI, URIencodingConfig.path)\n\n return URIencodingConfig.double ? URIEncode(canonicalURI, URIencodingConfig.path) : canonicalURI\n}\n\n// FIXME: does it work as expected?\n/**\n * Creates the canonical form of the request's query\n * string. If the request does not include a query string,\n * provide an empty string.\n *\n * @param {String | Object} qs - query string to canonize\n * @return {string}\n */\nexport function createCanonicalQueryString(qs: string): string {\n if (qs === '') {\n return ''\n }\n\n // const intermediary: { [key: string]: string } = parseQueryString(qs)\n\n // return Object.keys(intermediary)\n // .sort()\n // .map((key: string) => {\n // // const values: string[] = Array.isArray(intermediary[key])\n // // ? intermediary[key]\n // // : [intermediary[key]]\n // const values = intermediary[key]\n\n // return values\n // .sort()\n // .map((val: string) => encodeURIComponent(key) + '=' + encodeURIComponent(val))\n // .join('&')\n // })\n // .join('&')\n\n return parseQueryString(qs)\n .map(([key, value]: [string, string]): string => {\n return encodeURIComponent(key) + '=' + encodeURIComponent(value)\n })\n .join('&')\n}\n/**\n * Create the canonical form of the request's headers.\n * Canonical headers consist of all the HTTP headers you\n * are including with the signed request.\n *\n * Note that:\n * * for HTTP/1.1 requests, the headers should at least\n * contain the `host` header.\n * * for HTTP/2, the `:authority` header must be used instead\n * of `host`.\n *\n * @param {Object} headers\n * @return {string}\n */\nexport function createCanonicalHeaders(headers: HTTPHeaders) {\n if (headers.constructor !== Object || Object.entries(headers).length === 0) {\n return ''\n }\n\n const canonicalHeaders = Object.entries(headers)\n .map(([name, values]) => {\n const canonicalName = name.toLowerCase().trim()\n const normalizedValues = Array.isArray(values) ? values : [values]\n\n // Note that we do not need to sort values\n const canonicalValues = normalizedValues\n .map((v) => {\n // convert sequential spaces to a single space\n return v.replace(/\\s+/g, ' ').replace(/^\\s+|\\s+$/g, '')\n })\n .join(',') // standard for multiple values in a HTTP header\n\n return canonicalName + ':' + canonicalValues + '\\n'\n })\n .sort()\n .join('')\n\n return canonicalHeaders\n}\n\n/**\n * Create the canonical request's signed headers.\n *\n * The signed headers part of the request contains the\n * list of headers included in the request's signing process.\n *\n * Note that:\n * * for HTTP/1.1 requests, the `host` header must be included.\n * * for HTTP/2 requests, the `:authority` header must be included instead\n * of host.\n * * if used, the `x-amz-date` header must be included.\n *\n * @param {Object} headers\n * @return {string}\n * @throws {TypeError} - on headers not being an Object, or being empty.\n */\nexport function createSignedHeaders(headers: { [key: string]: string }) {\n if (headers.constructor !== Object) {\n throw new TypeError('headers should be an object')\n }\n\n if (Object.entries(headers).length === 0) {\n throw 'headers should at least contain either the Host (HTTP 1.1) or :authority (HTTP 2) parameter'\n }\n\n // To create the signed headers list, convert\n // all header names to lowercase, sort them by\n // character code, and use a semicolon to separate\n // the header names.\n const result = Object.keys(headers)\n .map((name) => name.toLowerCase().trim())\n .sort()\n .join(';')\n\n return result\n}\n\n/**\n * Create the canonical form of the request's payload.\n *\n * The canonical payload consists in a lowercased, hex encoded,\n * SHA256 hash of the requests body/payload.\n *\n * Certain services, such as S3, allow for unsigned payload. If\n * producing a signed canonical request for such service, pass\n * the `UnsignedPayload` constant value as the payload parameter.\n *\n * @param {String | ArrayBuffer} payload\n * @return {string}\n */\nexport function createCanonicalPayload(payload: string | ArrayBuffer) {\n if (payload === UnsignedPayload) {\n return payload\n }\n\n // Note that if the paylaod is null, we convert it\n // to an empty string.\n // TODO: Should switching to empty string if null impact headers?\n return crypto.sha256(payload || '', 'hex').toLowerCase()\n}\n\n/**\n * URIEncodes encodes every bytes of a URI to be URL-safe.\n *\n * This implementation is specific to AWS; who intended to make it as\n * close as possible to the underlying RFC 3946. It:\n * * URI encode every byte except the unreserved characters: 'A'-'Z', 'a'-'z', '0'-'9',\n * '-', '.', '_', and '~'.\n * * considers the space character as a reserved character and must URI encodes\n * encodes it as \"%20\" (and not as \"+\").\n * * URI encodes every byte by prefixing with '%' the two-digit hexadecimal value of the byte.\n * * If the `path` argument is set, forward slashes are not encoded, to fit with\n * S3 requirements.\n *\n * N.B: this implementation differs with ES6' mainly in that it does\n * encode the \"'\" character.\n *\n * Based on AWS implementation: https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-core/src/main/java/com/amazonaws/util/SdkHttpUtils.java#L66\n * Encoding specs: https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html\n *\n * @param {string} uri - uri to encode\n * @param {boolean} path - slash characters should be encoded everywhere,\n * but in paths, set to false when encoding a path\n * @return {string} the URI encoded result\n */\nexport function URIEncode(uri: string, path: boolean): string {\n if (uri == '') {\n return uri\n }\n\n return uri\n .split('') // to be able to map over a string, because... javascript...\n .map((letter: string) => {\n if (isAlpha(letter) || isNumeric(letter) || '-._~'.includes(letter)) {\n return letter\n }\n\n // Space should be explicitly encoded to as %20.\n if (letter == ' ') {\n return '%20'\n }\n\n // If the URI is a path, the forward slash shouldn't\n // be encoded.\n if (letter == '/' && path) {\n return '/'\n }\n\n return '%' + letter.charCodeAt(0).toString(16).toUpperCase()\n })\n .join('')\n}\n\n/**\n * Class holding URI encoding configuration\n */\nexport class URIEncodingConfig {\n double: boolean\n path: boolean\n\n /**\n *\n * @param {boolean} double - should the URI be double encoded?\n * @param {boolean} path - is the URI a path? If so, its forward\n * slashes won't be URIencoded.\n */\n constructor(double: boolean, path: boolean) {\n this.double = double\n this.path = path\n }\n}\n\n/**\n * Compute the request time value as specified by the ISO8601\n * format: YYYYMMDD'T'HHMMSS'Z'\n *\n * @param {number} timestamp\n * @return {string}\n */\nexport function toTime(timestamp: number): string {\n return new Date(timestamp).toISOString().replace(/[:\\-]|\\.\\d{3}/g, '')\n}\n/**\n * Computethe request date value in the format: YYYMMDD\n *\n * @param {number} timestamp\n * @return {string}\n */\nexport function toDate(timestamp: number): string {\n return toTime(timestamp).substring(0, 8)\n}\n\n// FIXME: does it work as expected?\n/**\n * Parse a HTTP request URL's querystring into an object\n * containing its `key=value` pairs.\n *\n * @param {string} qs\n * @return {object}\n */\nexport function parseQueryString(qs: string): Array<[string, string]> {\n if (qs.length === 0) {\n return []\n }\n\n return qs\n .split('&')\n .filter((e) => e)\n .map((v: string): [string, string] => {\n const parts = v.split('=', 2) as [string, string]\n return [decodeURIComponent(parts[0]), decodeURIComponent(parts[1])]\n })\n .sort((a: [string, string], b: [string, string]) => {\n return a[0].localeCompare(b[0])\n })\n}\n\nfunction isAlpha(c: string): boolean {\n return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')\n}\n\nfunction isNumeric(c: string): boolean {\n return c >= '0' && c <= '9'\n}\n\n// FIXME: finish implementation when needed\n// See the following for more details:\n// * https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html\n// * https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html\n// export function signQueryString(\n// queryString,\n// requestTimestamp,\n// accessKeyID,\n// secretAccessKey,\n// region,\n// service,\n// ttl, // in seconds\n// headers,\n// doubleURIEncoding = true\n// ) {\n// const credential = [accessKeyID, toDate(requestTimestamp), region, service].join('/')\n//\n// const canonicalRequest = createCanonicalRequest(\n// method,\n// path,\n// queryString,\n// headers,\n// body,\n// doubleURIEncoding\n// )\n//\n// const derivedSigningKey = deriveSigningKey(secretAccessKey, requestTimestamp, region, service)\n//\n// const stringToSign = createStringToSign(\n// requestTimestamp,\n// region,\n// service,\n// sha256(canonicalRequest, 'hex')\n// )\n//\n// const signedHeaders = createSignedHeaders(headers)\n// const signature = calculateSignature(derivedSigningKey, stringToSign)\n//\n// return [\n// `X-Amz-Algorithm=${HashingAlgorithm}`,\n// `X-Amz-Credential=${crediental}`,\n// `X-Amz-Date=${toTime(requestTimestamp)}`,\n// `X-Amz-Expires=${ttl}`,\n// `X-Amz-SignedHeaders=${signedHeaders}`,\n// `X-Amz-Signature=${signature}`,\n//`X-Amz-Security-Token=`, // TODO: optional\n// ].join('&')\n// }\n","/** Class holding an AWS connection information */\nexport class AWSConfig {\n region: string\n accessKeyID: string\n secretAccessKey: string\n\n /**\n * Create an AWSConfig.\n *\n * @param {string} region - the AWS region to connect to, as listed: https://docs.aws.amazon.com/general/latest/gr/rande.html\n * @param {string} accessKeyID - Your user's AWS access key id credential\n * @param {string} secretAccessKey - Your user's AWS secret access key credential\n * @throws {InvalidArgumentException}\n */\n constructor(region: string, accessKeyID: string, secretAccessKey: string) {\n if (typeof region !== 'string' || region === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS region; reason: should be a non empty string'\n )\n }\n\n if (typeof accessKeyID !== 'string' || accessKeyID === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS access key ID; reason: should be a non empty string'\n )\n }\n\n if (typeof secretAccessKey !== 'string' || secretAccessKey === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS secret access key; reason: should be a non empty string'\n )\n }\n\n this.region = region\n this.accessKeyID = accessKeyID\n this.secretAccessKey = secretAccessKey\n }\n}\n\n/** Class representing an invalid AWS configuration */\nexport class InvalidAWSConfigError extends Error {\n constructor(message: string) {\n super(message)\n }\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/http\");","import { HTTPMethod, HTTPHeaders } from './http'\nimport { AWSConfig } from './config'\nimport { signHeaders, URIEncodingConfig, toTime } from './signature'\n\n/**\n * Class allowing to build requests targeting AWS APIs\n *\n * This class is meant to be used as a base class for specific\n * services clients. See S3Client or SecretsManagerClient for\n * usage examples.\n */\nexport class AWSClient {\n awsConfig: AWSConfig\n serviceName: string\n URIencodingConfig: URIEncodingConfig\n\n /**\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n * @param {string} serviceName - name of the service to target.\n * @param {URIEncodingConfig} URIencodingConfig - configures how requests URIs should be encoded.\n */\n constructor(awsConfig: AWSConfig, serviceName: string, URIencodingConfig: URIEncodingConfig) {\n this.awsConfig = awsConfig\n this.serviceName = serviceName\n this.URIencodingConfig = URIencodingConfig\n }\n\n buildRequest(\n method: HTTPMethod,\n host: string,\n path: string,\n queryString: string,\n body: string | ArrayBuffer,\n headers: HTTPHeaders\n ): AWSRequest {\n const requestTimestamp: number = Date.now()\n const date: string = toTime(requestTimestamp)\n\n headers['Host'] = host\n headers['X-Amz-Date'] = date\n\n headers = signHeaders(\n // headers\n headers,\n\n // requestTimestamp\n requestTimestamp,\n\n // method\n method,\n\n // path\n path,\n\n // querystring\n queryString,\n\n // body\n body,\n\n // AWS configuration\n this.awsConfig,\n\n // AwS target service name\n this.serviceName,\n\n // doubleEncoding: S3 does single-encoding of the uri component\n // pathURIEncoding: S3 manipulates object keys, and forward slashes\n // shouldn't be URI encoded\n this.URIencodingConfig\n )\n\n // '?' should not be part of the querystring when we sign the headers\n path = path !== '' ? path : '/'\n let url = `https://${host}${path}`\n if (queryString !== '') {\n url += `?${queryString}`\n }\n\n return { url: url, headers: headers }\n }\n}\n\n/**\n * Type alias representing the result of an AWSClient.buildRequest call\n */\nexport interface AWSRequest {\n url: string\n headers: HTTPHeaders\n}\n","import { bytes } from 'k6'\nimport http from 'k6/http'\nimport { parseHTML } from 'k6/html'\nimport { sha256 } from 'k6/crypto'\n\nimport { InvalidSignatureError, URIEncodingConfig } from './signature'\nimport { AWSClient, AWSRequest } from './client'\nimport { AWSError } from './error'\nimport { AWSConfig } from './config'\n\n/** Class allowing to interact with Amazon AWS's S3 service */\nexport class S3Client extends AWSClient {\n /**\n * Create a S3Client\n *\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n */\n constructor(awsConfig: AWSConfig) {\n const URIencodingConfig = new URIEncodingConfig(false, true)\n super(awsConfig, 's3', URIencodingConfig)\n }\n\n /**\n * Returns a list of all buckets owned by the authenticated sender of the request.\n * To use this operation, you must have the s3:ListAllMyBuckets permission.\n *\n * @return {Array.} buckets - An array of objects describing S3 buckets\n * with the following fields: name, and creationDate.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n listBuckets(): Array {\n // Prepare request\n const method = 'GET'\n const host = `${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(method, host, '/', '', body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n let buckets: Array = []\n\n const doc = parseHTML(res.body as string)\n\n doc.find('Buckets')\n .children()\n .each((_, bucketDefinition) => {\n let bucket = {}\n\n bucketDefinition.children().forEach((child) => {\n switch (child.nodeName()) {\n case 'name':\n Object.assign(bucket, { name: child.textContent() })\n break\n case 'creationdate':\n Object.assign(bucket, {\n creationDate: Date.parse(child.textContent()),\n })\n }\n })\n\n buckets.push(bucket as S3Bucket)\n })\n\n return buckets\n }\n\n /**\n * Returns some or all (up to 1,000) of the objects in a bucket.\n *\n * @param {string} bucketName - Bucket name to list.\n * @param {string?} prefix='' - Limits the response to keys that begin with the specified prefix.\n * @return {Array.} - returns an array of objects describing S3 objects\n * with the following fields: key, lastModified, etag, size and storageClass.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n listObjects(bucketName: string, prefix?: string): Array {\n // Prepare request\n const method = 'GET'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const body = ''\n const querystring = `list-type=2&prefix=${prefix}`\n const signedRequest: AWSRequest = super.buildRequest(method, host, '/', querystring, body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n Prefix: prefix ?? '',\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n let objects: Array = []\n\n // Extract the objects definition from\n // the XML response\n parseHTML(res.body as string)\n .find('Contents')\n .each((_, objectDefinition) => {\n let obj = {}\n\n objectDefinition.children().forEach((child) => {\n switch (child.nodeName()) {\n case 'key':\n Object.assign(obj, { key: child.textContent() })\n break\n case 'lastmodified':\n Object.assign(obj, { lastModified: Date.parse(child.textContent()) })\n break\n case 'etag':\n Object.assign(obj, { etag: child.textContent() })\n break\n case 'size':\n Object.assign(obj, { size: parseInt(child.textContent()) })\n break\n case 'storageclass':\n Object.assign(obj, { storageClass: child.textContent() })\n }\n })\n\n objects.push(obj as S3Object)\n })\n\n return objects\n }\n /**\n * Retrieves an Object from Amazon S3.\n *\n * To use getObject, you must have `READ` access to the object.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to get.\n * @return {S3Object} - returns the content of the fetched S3 Object.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n getObject(bucketName: string, objectKey: string): S3Object {\n // Prepare request\n const method = 'GET'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(method, host, path, '', body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n console.log(`s3 objects response headers: ${JSON.stringify(res.headers, null, ' ')}`)\n\n return new S3Object(\n objectKey,\n Date.parse(res.headers['Last-Modified']),\n res.headers['ETag'],\n parseInt(res.headers['Content-Length']),\n (res.headers['X-Amz-Storage-Class'] ?? 'STANDARD') as StorageClass, // FIXME: GetObject response doesn't contain the storage class\n res.body\n )\n }\n /**\n * Adds an object to a bucket.\n *\n * You must have WRITE permissions on a bucket to add an object to it.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to put.\n * @param {string | ArrayBuffer} data - the content of the S3 Object to upload.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n putObject(bucketName: string, objectKey: string, data: string | ArrayBuffer) {\n // Prepare request\n const method = 'PUT'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const queryString = ''\n const body = data\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n path,\n queryString,\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n }\n\n /**\n * Removes the null version (if there is one) of an object and inserts a delete marker,\n * which becomes the latest version of the object.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to delete.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n deleteObject(bucketName: string, objectKey: string): void {\n // Prepare request\n const method = 'DELETE'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const queryString = ''\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n path,\n queryString,\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n }\n\n // FIXME: remove dependency to `error_message`\n // FIXME: just pass it the response?\n _handle_error(error_code: number, error_message: string, error_body: string) {\n if (error_message == '' || error_code === 0) {\n return\n }\n\n // FIXME: should be error_code === 1301 instead\n // See: https://github.com/grafana/k6/issues/2474\n // See: https://github.com/golang/go/issues/49281\n if (error_message && error_message.startsWith('301')) {\n // Bucket not found\n throw new S3ServiceError('Resource not found', 'ResourceNotFound', 'getObject')\n }\n\n const awsError = AWSError.parseXML(error_body)\n switch (awsError.code) {\n case 'AuthorizationHeaderMalformed':\n throw new InvalidSignatureError(awsError.message, awsError.code)\n default:\n throw new S3ServiceError(awsError.message, awsError.code, 'listObjects')\n }\n }\n}\n\n// TODO: use interface instead?\n/** Class representing a S3 Bucket */\nexport class S3Bucket {\n name: string\n creationDate: Date\n\n /**\n * Create an S3 Bucket\n *\n * @param {string} name - S3 bucket's name\n * @param {Date} creationDate - S3 bucket's creation date\n */\n constructor(name: string, creationDate: Date) {\n this.name = name\n this.creationDate = creationDate\n }\n}\n\n// TODO: use interface instead?\n/** Class representing an S3 Object */\nexport class S3Object {\n key: string\n lastModified: number\n etag: string\n size: number\n storageClass: StorageClass\n data?: string | bytes | null\n\n /**\n * Create an S3 Object\n *\n * @param {string} key - S3 object's key\n * @param {Date} lastModified - S3 object last modification date\n * @param {string} etag - S3 object's etag\n * @param {number} size - S3 object's size\n * @param {StorageClass} storageClass - S3 object's storage class\n * @param {string | bytes | null} data=null - S3 Object's data\n */\n constructor(\n key: string,\n lastModified: number,\n etag: string,\n size: number,\n storageClass: StorageClass,\n data?: string | bytes | null\n ) {\n this.key = key\n this.lastModified = lastModified\n this.etag = etag\n this.size = size\n this.storageClass = storageClass\n this.data = data\n }\n}\n\n/**\n * Error indicating a S3 operation failed\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class S3ServiceError extends AWSError {\n operation: string\n\n /**\n * Constructs a S3ServiceError\n *\n * @param {string} message - human readable error message\n * @param {string} code - A unique short code representing the error that was emitted\n * @param {string} operation - Name of the failed Operation\n */\n constructor(message: string, code: string, operation: string) {\n super(message, code)\n this.name = 'S3ServiceError'\n this.operation = operation\n }\n}\n\n/**\n * Describes the class of storage used to store a S3 object.\n */\ntype StorageClass =\n | 'STANDARD'\n | 'REDUCED_REDUNDANCY'\n | 'GLACIER'\n | 'STANDARD_IA'\n | 'INTELLIGENT_TIERING'\n | 'DEEP_ARCHIVE'\n | 'OUTPOSTS'\n | 'GLACIER_IR'\n | undefined\n","import { JSONArray, JSONObject } from 'k6'\nimport http, { RefinedResponse, ResponseType } from 'k6/http'\n\nimport { AWSClient, AWSRequest } from './client'\nimport { AWSError } from './error'\nimport { AWSConfig } from './config'\nimport { InvalidSignatureError, URIEncodingConfig } from './signature'\nimport { v4 as uuidv4 } from 'uuid'\nimport { HTTPMethod, HTTPHeaders } from './http'\n\n/**\n * Class allowing to interact with Amazon AWS's SecretsManager service\n */\nexport class SecretsManagerClient extends AWSClient {\n method: HTTPMethod\n commonHeaders: HTTPHeaders\n\n /**\n * Create a SecretsManagerClient\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n */\n constructor(awsConfig: AWSConfig) {\n const URIencodingConfig = new URIEncodingConfig(true, false)\n super(awsConfig, 'secretsmanager', URIencodingConfig)\n\n // this.serviceName = 'secretsmanager'\n\n // All interactions with the Secrets Manager service\n // are made via the GET or POST method.\n this.method = 'POST'\n\n this.commonHeaders = {\n 'Accept-Encoding': 'identity',\n 'Content-Type': 'application/x-amz-json-1.1',\n }\n }\n\n /**\n * Returns a list of all secrets owned by the authenticated sender of the request.\n * To use this operation, you must have the secretsmanager:ListSecrets permission.\n *\n * @return {Array.} secrets - An array of objects describing Secret Manager's secrets\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n listSecrets(): Array {\n const body = JSON.stringify({})\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.ListSecrets`,\n }\n )\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('ListSecrets', res)\n const json: JSONArray = res.json('SecretList') as JSONArray\n\n return json.map((s) => Secret.fromJSON(s as JSONObject))\n }\n\n /**\n * Retrieves a secret from Amazon Sercets Manager\n *\n * @param {string} secretID - The ARN or name of the secret to retrieve.\n * @returns {Secret} - returns the content of the fetched Secret object.\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n getSecret(secretID: string): Secret | undefined {\n const body = JSON.stringify({ SecretId: secretID })\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.GetSecretValue`,\n }\n )\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('GetSecretValue', res)\n\n return Secret.fromJSON(res.json() as JSONObject)\n }\n\n /**\n * Creates a new secret\n *\n * Note that this method only supports string-based values at the moment.\n *\n * @param {string} name - The name of the new secret.\n * The secret name can contain ASCII letters, numbers, and the following characters: /_+=.@\n * @param {string} secretString - The text data to encrypt and store in this new version of the secret.\n * @param {string} description - The description of the secret.\n * @param {string} versionID=null - Version of the secret. This value helps ensure idempotency.\n * As a default, if no versionID is provided, one will be created for you using the UUID v4\n * algorithm.\n * @param {Array.} tags=[] - A list of tags to attach to the secret. Each tag is a key and\n * value pair of strings in a JSON text string. Note that tag key names are case sensitive.\n * @returns {Secret} - returns the created secret\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n createSecret(\n name: string,\n secretString: string,\n description: string,\n versionID?: string,\n tags?: Array\n ): Secret {\n versionID = versionID || uuidv4()\n\n const body = JSON.stringify({\n Name: name,\n Description: description,\n SecretString: secretString,\n ClientRequestToken: versionID,\n Tags: tags,\n })\n\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.CreateSecret`,\n }\n )\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n // headers['X-Amz-Target'] = `${this.serviceName}.CreateSecret`\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('CreateSecret', res)\n\n return Secret.fromJSON(res.json() as JSONObject)\n }\n /**\n * Update a secret's value.\n *\n * Note that this method only support string-based values at the moment.\n *\n * @param {string} secretID - The ARN or name of the secret to update.\n * @param {string} secretString - The text data to encrypt and store in this new version of the secret.\n * @param {} versionID=null - A unique identifier for the new version of the secret. This value helps ensure idempotency.\n * As a default, if no versionID is provided, one will be created for you using the UUID v4\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n putSecretValue(secretID: string, secretString: string, versionID?: string): Secret {\n versionID = versionID || uuidv4()\n\n const body = JSON.stringify({\n SecretId: secretID,\n SecretString: secretString,\n ClientRequestToken: versionID,\n })\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.PutSecretValue`,\n }\n )\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('PutSecretValue', res)\n\n return Secret.fromJSON(res.json() as JSONObject)\n }\n\n /**\n * Deletes a secret and all of its versions.\n *\n * You can specify a recovery window during which you can restore the secret.\n * The minimum recovery window is 7 days. The default recovery window is 30 days.\n *\n * @param {string} secretID - The ARN or name of the secret to delete.\n * @param {number} recoveryWindow - The number of days from 7 to 30 that Secrets Manager\n * waits before permanently deleting the secret.\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n deleteSecret(\n secretID: string,\n { recoveryWindow = 30, noRecovery = false }: { recoveryWindow: number; noRecovery: boolean }\n ) {\n const payload: { [key: string]: string | boolean | number } = {\n SecretId: secretID,\n }\n\n // noRecovery and recoveryWindow are exclusive parameters\n if (noRecovery === true) {\n payload['ForceDeleteWithoutRecovery'] = true\n } else {\n payload['RecoveryWindowInDays'] = recoveryWindow\n }\n\n const body = JSON.stringify(payload)\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.DeleteSecret`,\n }\n )\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('DeleteSecret', res)\n }\n\n get host() {\n return `${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n }\n\n // TODO: operation should be an enum\n _handle_error(operation: string, response: RefinedResponse) {\n const errorCode = response.error_code\n if (errorCode === 0) {\n return\n }\n\n const error = response.json() as JSONObject\n if (errorCode >= 1400 && errorCode <= 1499) {\n // In the event of certain errors, the message is not set.\n // Also, note the inconsistency in casing...\n const errorMessage: string =\n (error.Message as string) || (error.message as string) || (error.__type as string)\n\n // Handle specifically the case of an invalid signature\n if (error.__type === 'InvalidSignatureException') {\n throw new InvalidSignatureError(errorMessage, error.__type)\n }\n\n // Otherwise throw a standard service error\n throw new SecretsManagerError(errorMessage, error.__type as string, operation)\n }\n\n if (errorCode === 1500) {\n throw new SecretsManagerError(\n 'An error occured on the server side',\n 'InternalServiceError',\n operation\n )\n }\n }\n}\n\n// TODO: create a Tags type\n\n/**\n * Class representing a Secret Manager's secret\n */\nexport class Secret {\n name: string\n arn: string\n secret: string\n createdDate: number\n lastAccessedDate: number\n lastChangedDate: number\n tags: Array<{ [key: string]: string }>\n\n /**\n * Constructs a Secret Manager's Secret\n *\n * @param {string} name - The friendly name of the secret.\n * @param {string} arn - The ARN of the secret.\n * @param {number} createdDate - The date and time that this version of the secret was created.\n * @param {number} lastAccessedDate - The last date that this secret was accessed. This value is\n * truncated to midnight of the date and therefore shows only the date, not the time.\n * @param {number} lastChangedDate - The last date and time that this secret was modified in any way.\n * @param {Array.} tags - The list of user-defined tags associated with the secret.\n */\n constructor(\n name: string,\n arn: string,\n secretString: string,\n createdDate: number,\n lastAccessedDate: number,\n lastChangedDate: number,\n tags: Array<{ [key: string]: string }> = []\n ) {\n this.name = name\n this.arn = arn\n this.secret = secretString\n this.createdDate = createdDate\n this.lastAccessedDate = lastAccessedDate\n this.lastChangedDate = lastChangedDate\n this.tags = tags\n }\n\n /**\n * Parses and constructs a Secret Manager's Secret from the content\n * of a JSON response returned by the AWS service\n *\n * @param {Object} json - JSON object as returned and parsed from\n * the AWS service's API call.\n * @returns {Secret}\n */\n static fromJSON(json: JSONObject) {\n return new Secret(\n json.Name as string,\n json.ARN as string,\n json.SecretString as string,\n json.CreatedDate as number,\n json.LastAccessedDate as number,\n json.LastChangedDate as number,\n json.Tags as Array<{ [key: string]: string }>\n )\n }\n}\n\nexport class SecretsManagerError extends AWSError {\n operation: string\n\n /**\n * Constructs a SecretsManagerError\n *\n * @param {string} message - human readable error message\n * @param {string} code - A unique short code representing the error that was emitted\n * @param {string} operation - Name of the failed Operation\n */\n constructor(message: string, code: string, operation: string) {\n super(message, code)\n this.name = 'SecretsManagerServiceError'\n this.operation = operation\n }\n}\n"],"names":["v1","v4","uuid","module","exports","byteToHex","i","toString","substr","buf","offset","bth","join","getRandomValues","crypto","bind","window","msCrypto","rnds8","Uint8Array","rnds","Array","r","Math","random","_nodeId","_clockseq","rng","bytesToUuid","_lastMSecs","_lastNSecs","options","b","node","clockseq","undefined","seedBytes","msecs","Date","getTime","nsecs","dt","Error","tl","tmh","n","ii","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","__webpack_modules__","getter","__esModule","d","a","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","require","AWSError","message","code","name","xmlDocument","doc","parseHTML","find","text","signHeaders","headers","requestTimestamp","method","path","queryString","body","awsConfig","service","URIencodingConfig","derivedSigningKey","secretAccessKey","time","region","kSecret","date","toDate","kDate","hmac","kRegion","kService","deriveSigningKey","canonicalRequest","uri","query","payload","httpRequestMethod","toUpperCase","canonicalURI","length","URIEncode","createCanonicalURI","canonicalQueryString","qs","split","filter","e","map","v","parts","decodeURIComponent","sort","localeCompare","parseQueryString","encodeURIComponent","createCanonicalQueryString","canonicalHeaders","constructor","entries","values","toLowerCase","trim","isArray","replace","createCanonicalHeaders","signedHeaders","createSignedHeaders","requestPayload","UnsignedPayload","createCanonicalPayload","createCanonicalRequest","stringToSign","hashedCanonicalRequest","requestDateTime","toTime","credentialScope","createCredentialScope","HashingAlgorithm","createStringToSign","sha256","signature","calculateSignature","authorizationHeader","accessKeyID","InvalidSignatureError","TypeError","keys","letter","c","isNumeric","includes","charCodeAt","URIEncodingConfig","double","this","timestamp","toISOString","substring","AWSConfig","InvalidAWSConfigError","AWSClient","serviceName","host","now","url","S3Client","signedRequest","res","http","_handle_error","error_code","error","buckets","children","each","_","bucketDefinition","bucket","forEach","child","nodeName","assign","textContent","creationDate","parse","push","bucketName","prefix","querystring","Prefix","objects","objectDefinition","lastModified","etag","size","parseInt","storageClass","objectKey","console","log","JSON","stringify","S3Object","data","error_message","error_body","startsWith","S3ServiceError","awsError","parseXML","S3Bucket","operation","SecretsManagerClient","commonHeaders","json","s","Secret","fromJSON","secretID","SecretId","secretString","description","versionID","tags","uuidv4","Name","Description","SecretString","ClientRequestToken","Tags","recoveryWindow","noRecovery","response","errorCode","errorMessage","Message","__type","SecretsManagerError","arn","createdDate","lastAccessedDate","lastChangedDate","secret","ARN","CreatedDate","LastAccessedDate","LastChangedDate"],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"aws.min.js","mappings":"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","sources":["webpack://k6-jslib-aws/./node_modules/uuid/index.js","webpack://k6-jslib-aws/./node_modules/uuid/lib/bytesToUuid.js","webpack://k6-jslib-aws/./node_modules/uuid/lib/rng-browser.js","webpack://k6-jslib-aws/./node_modules/uuid/v1.js","webpack://k6-jslib-aws/./node_modules/uuid/v4.js","webpack://k6-jslib-aws/webpack/bootstrap","webpack://k6-jslib-aws/webpack/runtime/compat get default export","webpack://k6-jslib-aws/webpack/runtime/define property getters","webpack://k6-jslib-aws/webpack/runtime/hasOwnProperty shorthand","webpack://k6-jslib-aws/webpack/runtime/make namespace object","webpack://k6-jslib-aws/external commonjs \"k6/crypto\"","webpack://k6-jslib-aws/external commonjs \"k6/html\"","webpack://k6-jslib-aws/./src/internal/error.ts","webpack://k6-jslib-aws/./src/internal/signature.ts","webpack://k6-jslib-aws/./src/internal/config.ts","webpack://k6-jslib-aws/external commonjs \"k6/http\"","webpack://k6-jslib-aws/./src/internal/client.ts","webpack://k6-jslib-aws/./src/internal/s3.ts","webpack://k6-jslib-aws/./src/internal/secrets-manager.ts"],"sourcesContent":["var v1 = require('./v1');\nvar v4 = require('./v4');\n\nvar uuid = v4;\nuuid.v1 = v1;\nuuid.v4 = v4;\n\nmodule.exports = uuid;\n","/**\n * Convert array of 16 byte values to UUID string format of the form:\n * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n */\nvar byteToHex = [];\nfor (var i = 0; i < 256; ++i) {\n byteToHex[i] = (i + 0x100).toString(16).substr(1);\n}\n\nfunction bytesToUuid(buf, offset) {\n var i = offset || 0;\n var bth = byteToHex;\n // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4\n return ([\n bth[buf[i++]], bth[buf[i++]],\n bth[buf[i++]], bth[buf[i++]], '-',\n bth[buf[i++]], bth[buf[i++]], '-',\n bth[buf[i++]], bth[buf[i++]], '-',\n bth[buf[i++]], bth[buf[i++]], '-',\n bth[buf[i++]], bth[buf[i++]],\n bth[buf[i++]], bth[buf[i++]],\n bth[buf[i++]], bth[buf[i++]]\n ]).join('');\n}\n\nmodule.exports = bytesToUuid;\n","// Unique ID creation requires a high quality random # generator. In the\n// browser this is a little complicated due to unknown quality of Math.random()\n// and inconsistent support for the `crypto` API. We do the best we can via\n// feature-detection\n\n// getRandomValues needs to be invoked in a context where \"this\" is a Crypto\n// implementation. Also, find the complete implementation of crypto on IE11.\nvar getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||\n (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));\n\nif (getRandomValues) {\n // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto\n var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef\n\n module.exports = function whatwgRNG() {\n getRandomValues(rnds8);\n return rnds8;\n };\n} else {\n // Math.random()-based (RNG)\n //\n // If all else fails, use Math.random(). It's fast, but is of unspecified\n // quality.\n var rnds = new Array(16);\n\n module.exports = function mathRNG() {\n for (var i = 0, r; i < 16; i++) {\n if ((i & 0x03) === 0) r = Math.random() * 0x100000000;\n rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;\n }\n\n return rnds;\n };\n}\n","var rng = require('./lib/rng');\nvar bytesToUuid = require('./lib/bytesToUuid');\n\n// **`v1()` - Generate time-based UUID**\n//\n// Inspired by https://github.com/LiosK/UUID.js\n// and http://docs.python.org/library/uuid.html\n\nvar _nodeId;\nvar _clockseq;\n\n// Previous uuid creation time\nvar _lastMSecs = 0;\nvar _lastNSecs = 0;\n\n// See https://github.com/uuidjs/uuid for API details\nfunction v1(options, buf, offset) {\n var i = buf && offset || 0;\n var b = buf || [];\n\n options = options || {};\n var node = options.node || _nodeId;\n var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq;\n\n // node and clockseq need to be initialized to random values if they're not\n // specified. We do this lazily to minimize issues related to insufficient\n // system entropy. See #189\n if (node == null || clockseq == null) {\n var seedBytes = rng();\n if (node == null) {\n // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)\n node = _nodeId = [\n seedBytes[0] | 0x01,\n seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]\n ];\n }\n if (clockseq == null) {\n // Per 4.2.2, randomize (14 bit) clockseq\n clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;\n }\n }\n\n // UUID timestamps are 100 nano-second units since the Gregorian epoch,\n // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so\n // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'\n // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.\n var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime();\n\n // Per 4.2.1.2, use count of uuid's generated during the current clock\n // cycle to simulate higher resolution clock\n var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1;\n\n // Time since last uuid creation (in msecs)\n var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;\n\n // Per 4.2.1.2, Bump clockseq on clock regression\n if (dt < 0 && options.clockseq === undefined) {\n clockseq = clockseq + 1 & 0x3fff;\n }\n\n // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new\n // time interval\n if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {\n nsecs = 0;\n }\n\n // Per 4.2.1.2 Throw error if too many uuids are requested\n if (nsecs >= 10000) {\n throw new Error('uuid.v1(): Can\\'t create more than 10M uuids/sec');\n }\n\n _lastMSecs = msecs;\n _lastNSecs = nsecs;\n _clockseq = clockseq;\n\n // Per 4.1.4 - Convert from unix epoch to Gregorian epoch\n msecs += 12219292800000;\n\n // `time_low`\n var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;\n b[i++] = tl >>> 24 & 0xff;\n b[i++] = tl >>> 16 & 0xff;\n b[i++] = tl >>> 8 & 0xff;\n b[i++] = tl & 0xff;\n\n // `time_mid`\n var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;\n b[i++] = tmh >>> 8 & 0xff;\n b[i++] = tmh & 0xff;\n\n // `time_high_and_version`\n b[i++] = tmh >>> 24 & 0xf | 0x10; // include version\n b[i++] = tmh >>> 16 & 0xff;\n\n // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)\n b[i++] = clockseq >>> 8 | 0x80;\n\n // `clock_seq_low`\n b[i++] = clockseq & 0xff;\n\n // `node`\n for (var n = 0; n < 6; ++n) {\n b[i + n] = node[n];\n }\n\n return buf ? buf : bytesToUuid(b);\n}\n\nmodule.exports = v1;\n","var rng = require('./lib/rng');\nvar bytesToUuid = require('./lib/bytesToUuid');\n\nfunction v4(options, buf, offset) {\n var i = buf && offset || 0;\n\n if (typeof(options) == 'string') {\n buf = options === 'binary' ? new Array(16) : null;\n options = null;\n }\n options = options || {};\n\n var rnds = options.random || (options.rng || rng)();\n\n // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n rnds[6] = (rnds[6] & 0x0f) | 0x40;\n rnds[8] = (rnds[8] & 0x3f) | 0x80;\n\n // Copy bytes to buffer, if provided\n if (buf) {\n for (var ii = 0; ii < 16; ++ii) {\n buf[i + ii] = rnds[ii];\n }\n }\n\n return buf || bytesToUuid(rnds);\n}\n\nmodule.exports = v4;\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/crypto\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/html\");","import { parseHTML } from 'k6/html'\n\n/**\n * Base class to derive errors from\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class AWSError extends Error {\n code: string\n\n /**\n * Create an AWSError\n *\n * @param {string} message - A longer human readable error message.\n * @param {string} code - A unique short code representing the error that was emitted\n */\n constructor(message: string, code: string) {\n super(message)\n this.name = 'AWSError'\n this.code = code\n }\n\n /**\n * Parse an AWSError from an XML document\n *\n * @param {string} xmlDocument - Serialized XML document to parse the error from\n */\n static parseXML(xmlDocument: string): AWSError {\n const doc = parseHTML(xmlDocument)\n return new AWSError(doc.find('Message').text(), doc.find('Code').text())\n }\n}\n","import crypto, { hmac, sha256 } from 'k6/crypto'\nimport { HTTPMethod, HTTPHeaders } from './http'\nimport { AWSConfig } from './config'\nimport { AWSError } from './error'\n\n/**\n * Includes AWS v4 signing information to the provided HTTP headers object.\n *\n * This function will compute the `Authorization` header signature for the\n * provided request components, and add it to `header`. It will do so by following\n * the procedure detailled AWS' API docs: https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html\n *\n * The resulting `Authorization` header value is computed for the provided\n * headers object. Thus, any modification of the headers past a call to `signHeaders`\n * would effectively invalidate their signature, and the function should be\n * called again to recompute it.\n *\n * @param {object} headers - HTTP headers request to sign.\n * @param {number} requestTimestamp - Timestamp of the request\n * @param {string} method - HTTP method used\n * @param {string} path - HTTP request URL's path\n * @param {string} queryString - HTTP request URL's querystring\n * @param {string | ArrayBuffer} body - HTTP request's payload\n * @param {AWSConfig} - AWS configuration\n * @param {string} service - AWS service name\n * @param {URIEncodingConfig} - URI encoding configuration\n */\nexport function signHeaders(\n headers: HTTPHeaders,\n requestTimestamp: number,\n method: HTTPMethod,\n path: string,\n queryString: string,\n body: string | ArrayBuffer,\n awsConfig: AWSConfig,\n service: string,\n URIencodingConfig: URIEncodingConfig\n): HTTPHeaders {\n const derivedSigningKey = deriveSigningKey(\n awsConfig.secretAccessKey,\n requestTimestamp,\n awsConfig.region,\n service\n )\n\n const canonicalRequest = createCanonicalRequest(\n method,\n path,\n queryString,\n headers,\n body,\n URIencodingConfig\n )\n\n const stringToSign = createStringToSign(\n requestTimestamp,\n awsConfig.region,\n service,\n sha256(canonicalRequest, 'hex')\n )\n\n const credentialScope = createCredentialScope(requestTimestamp, awsConfig.region, service)\n const signedHeaders = createSignedHeaders(headers)\n const signature = calculateSignature(derivedSigningKey, stringToSign)\n const authorizationHeader = `${HashingAlgorithm} Credential=${awsConfig.accessKeyID}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`\n\n headers['Authorization'] = authorizationHeader\n\n return headers\n}\n\n/**\n * Error indicating an Invalid signature has been sent to AWS services\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class InvalidSignatureError extends AWSError {\n /**\n * Constructs an InvalidSignatureError\n *\n * @param {string} message - human readable error message\n */\n constructor(message: string, code: string) {\n super(message, code)\n this.name = 'InvalidSignatureError'\n }\n}\n\n/**\n * Calculte the signature for AWS signature version 4\n *\n * @param {string} derivedSigningKey - dervied signing key as computed by `deriveSigningKey`\n * @param {string} stringToSign - String to sign as computed by `createStringToSign`\n * @return {string}\n */\nexport function calculateSignature(derivedSigningKey: ArrayBuffer, stringToSign: string): string {\n return hmac('sha256', derivedSigningKey, stringToSign, 'hex')\n}\n/**\n * Derives the signing key for authenticating requests signed with\n * the Signature version 4 authentication protocol.\n *\n * deriveSigningKey produces a signing key by creating a series of\n * hash-based message authentication codes (HMACs) represented in\n * a binary format.\n *\n * The derived signing key is specific to the date it's made at, as well as\n * the service and region it targets.\n *\n * @param {string} secretAccessKey - the AWS secret access key to derive the signing key for\n * @param {number} time - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service. MUST be UTF-8 encoded.\n * @return {string}\n */\nexport function deriveSigningKey(\n secretAccessKey: string,\n time: number,\n region: string,\n service: string\n): ArrayBuffer {\n const kSecret = secretAccessKey\n const date = toDate(time)\n\n // FIXME: hmac takes ArrayBuffer as input, but returns bytes (number[]).\n // How does one convert from one to the other?\n const kDate: any = hmac('sha256', 'AWS4' + kSecret, date, 'binary')\n const kRegion: any = hmac('sha256', kDate, region, 'binary')\n const kService: any = hmac('sha256', kRegion, service, 'binary')\n const kSigning: any = hmac('sha256', kService, 'aws4_request', 'binary')\n\n return kSigning\n}\n\n// Hashing Algorithm to use in the signature process\nexport const HashingAlgorithm = 'AWS4-HMAC-SHA256'\n\n/**\n * Certain services, such as S3, allow for unsigned payloads. If\n * producing a signed canonical request for such service, pass\n * the `UnsignedPayload` constant value as the payload parameter.\n */\nexport const UnsignedPayload = 'UNSIGNED-PAYLOAD'\n\n/**\n * Create the \"string to sign\" part of the signature Version 4 protocol.\n *\n * The \"string to sign\" includes meta information about your request and\n * about the canonical request that you created with `createCanonicalRequest`.\n * It is used hand in hand with the signing key to create the request signature.\n *\n * @param {number} requestTimestamp - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service name. MUST be UTF-8 encoded.\n * @param {string} hashedCanonicalRequest - canonical request as produced by calling the createCanonicalRequest function,\n * hashed using the SHA256 algorithm (encoded in hexadecimal format).\n * @return {string}\n */\nexport function createStringToSign(\n requestTimestamp: number,\n region: string,\n service: string,\n hashedCanonicalRequest: string\n): string {\n // the request date specified in ISO8601 format: YYYYMMDD'T'HHMMSS'Z'\n const requestDateTime = toTime(requestTimestamp)\n\n // The credential scope value, consisting of the date in YYYYMMDD format,\n // the targeted region, the targeted service, and a termination string.\n // Note that the region and service MUST be UTF-8 encoded.\n const credentialScope = createCredentialScope(requestTimestamp, region, service)\n\n const stringToSign = [\n // Algorithm\n HashingAlgorithm,\n\n // RequestDateTime\n requestDateTime,\n\n // CredentialScope\n credentialScope,\n\n // HashedCanonicalRequest\n hashedCanonicalRequest,\n ].join('\\n')\n\n return stringToSign\n}\n\n/**\n *\n * Helper function creating a credential scope string to use in the signature\n * version 4 process. A credential scope consists of the date of the request\n * in YYYYMMDD format, the targeted region, the targeted service, and a\n * termination string.\n *\n * Note that the region and service MUST be UTF-8 encoded.\n *\n * @param {number} requestTimestamp - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service name. MUST be UTF-8 encoded.\n * @return {string}\n */\nexport function createCredentialScope(\n requestTimestamp: number,\n region: string,\n service: string\n): string {\n return [toDate(requestTimestamp), region, service, 'aws4_request'].join('/')\n}\n\n/**\n * Create a string that includes information from your request\n * in a AWS signature v4 standardized (canonical) format.\n *\n * @param {string} method - the HTTP request method\n * @param {string} uri - URI-encoded version of the absolute path component of the URI\n * @param {string} query - request's query string\n * @param {Object} headers - all the HTTP headers that you wish to include with the signed request\n * @param {string | ArrayBuffer} payload - payload to include as the body of the request\n * @param {URIEncodingConfig} URIencodingConfig- URI encoding configuration\n * @return {string}\n */\nexport function createCanonicalRequest(\n method: HTTPMethod,\n uri: string,\n query: string,\n headers: HTTPHeaders,\n payload: string | ArrayBuffer,\n URIencodingConfig: URIEncodingConfig\n): string {\n const httpRequestMethod = method.toUpperCase()\n const canonicalURI = createCanonicalURI(uri, URIencodingConfig)\n const canonicalQueryString = createCanonicalQueryString(query)\n const canonicalHeaders = createCanonicalHeaders(headers)\n const signedHeaders = createSignedHeaders(headers)\n const requestPayload = createCanonicalPayload(payload)\n\n const canonicalRequest = [\n httpRequestMethod,\n canonicalURI,\n canonicalQueryString,\n canonicalHeaders,\n signedHeaders,\n requestPayload,\n ].join('\\n')\n\n return canonicalRequest\n}\n\n/**\n * Creates the (canonical) URI-encoded version of the\n * absolute path component of the URI: everything in the URI\n * from the HTTP host to the question mark character (\"?\")\n * that begins the query string parameters (if any).\n *\n * @param {string} uri - URI to canonize\n * @param {URIEncodingConfig} - URI encoding configuration\n * @return {string} - canonical URL\n */\nexport function createCanonicalURI(uri: string, URIencodingConfig: URIEncodingConfig): string {\n if (uri == '/') {\n return uri\n }\n\n let canonicalURI = uri\n if (uri[uri.length - 1] == '/' && canonicalURI[canonicalURI.length - 1] != '/') {\n canonicalURI += '/'\n }\n\n canonicalURI = URIEncode(canonicalURI, URIencodingConfig.path)\n\n return URIencodingConfig.double ? URIEncode(canonicalURI, URIencodingConfig.path) : canonicalURI\n}\n\n// FIXME: does it work as expected?\n/**\n * Creates the canonical form of the request's query\n * string. If the request does not include a query string,\n * provide an empty string.\n *\n * @param {String | Object} qs - query string to canonize\n * @return {string}\n */\nexport function createCanonicalQueryString(qs: string): string {\n if (qs === '') {\n return ''\n }\n\n // const intermediary: { [key: string]: string } = parseQueryString(qs)\n\n // return Object.keys(intermediary)\n // .sort()\n // .map((key: string) => {\n // // const values: string[] = Array.isArray(intermediary[key])\n // // ? intermediary[key]\n // // : [intermediary[key]]\n // const values = intermediary[key]\n\n // return values\n // .sort()\n // .map((val: string) => encodeURIComponent(key) + '=' + encodeURIComponent(val))\n // .join('&')\n // })\n // .join('&')\n\n return parseQueryString(qs)\n .map(([key, value]: [string, string]): string => {\n return encodeURIComponent(key) + '=' + encodeURIComponent(value)\n })\n .join('&')\n}\n/**\n * Create the canonical form of the request's headers.\n * Canonical headers consist of all the HTTP headers you\n * are including with the signed request.\n *\n * Note that:\n * * for HTTP/1.1 requests, the headers should at least\n * contain the `host` header.\n * * for HTTP/2, the `:authority` header must be used instead\n * of `host`.\n *\n * @param {Object} headers\n * @return {string}\n */\nexport function createCanonicalHeaders(headers: HTTPHeaders) {\n if (headers.constructor !== Object || Object.entries(headers).length === 0) {\n return ''\n }\n\n const canonicalHeaders = Object.entries(headers)\n .map(([name, values]) => {\n const canonicalName = name.toLowerCase().trim()\n const normalizedValues = Array.isArray(values) ? values : [values]\n\n // Note that we do not need to sort values\n const canonicalValues = normalizedValues\n .map((v) => {\n // convert sequential spaces to a single space\n return v.replace(/\\s+/g, ' ').replace(/^\\s+|\\s+$/g, '')\n })\n .join(',') // standard for multiple values in a HTTP header\n\n return canonicalName + ':' + canonicalValues + '\\n'\n })\n .sort()\n .join('')\n\n return canonicalHeaders\n}\n\n/**\n * Create the canonical request's signed headers.\n *\n * The signed headers part of the request contains the\n * list of headers included in the request's signing process.\n *\n * Note that:\n * * for HTTP/1.1 requests, the `host` header must be included.\n * * for HTTP/2 requests, the `:authority` header must be included instead\n * of host.\n * * if used, the `x-amz-date` header must be included.\n *\n * @param {Object} headers\n * @return {string}\n * @throws {TypeError} - on headers not being an Object, or being empty.\n */\nexport function createSignedHeaders(headers: { [key: string]: string }) {\n if (headers.constructor !== Object) {\n throw new TypeError('headers should be an object')\n }\n\n if (Object.entries(headers).length === 0) {\n throw 'headers should at least contain either the Host (HTTP 1.1) or :authority (HTTP 2) parameter'\n }\n\n // To create the signed headers list, convert\n // all header names to lowercase, sort them by\n // character code, and use a semicolon to separate\n // the header names.\n const result = Object.keys(headers)\n .map((name) => name.toLowerCase().trim())\n .sort()\n .join(';')\n\n return result\n}\n\n/**\n * Create the canonical form of the request's payload.\n *\n * The canonical payload consists in a lowercased, hex encoded,\n * SHA256 hash of the requests body/payload.\n *\n * Certain services, such as S3, allow for unsigned payload. If\n * producing a signed canonical request for such service, pass\n * the `UnsignedPayload` constant value as the payload parameter.\n *\n * @param {String | ArrayBuffer} payload\n * @return {string}\n */\nexport function createCanonicalPayload(payload: string | ArrayBuffer) {\n if (payload === UnsignedPayload) {\n return payload\n }\n\n // Note that if the paylaod is null, we convert it\n // to an empty string.\n // TODO: Should switching to empty string if null impact headers?\n return crypto.sha256(payload || '', 'hex').toLowerCase()\n}\n\n/**\n * URIEncodes encodes every bytes of a URI to be URL-safe.\n *\n * This implementation is specific to AWS; who intended to make it as\n * close as possible to the underlying RFC 3946. It:\n * * URI encode every byte except the unreserved characters: 'A'-'Z', 'a'-'z', '0'-'9',\n * '-', '.', '_', and '~'.\n * * considers the space character as a reserved character and must URI encodes\n * encodes it as \"%20\" (and not as \"+\").\n * * URI encodes every byte by prefixing with '%' the two-digit hexadecimal value of the byte.\n * * If the `path` argument is set, forward slashes are not encoded, to fit with\n * S3 requirements.\n *\n * N.B: this implementation differs with ES6' mainly in that it does\n * encode the \"'\" character.\n *\n * Based on AWS implementation: https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-core/src/main/java/com/amazonaws/util/SdkHttpUtils.java#L66\n * Encoding specs: https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html\n *\n * @param {string} uri - uri to encode\n * @param {boolean} path - slash characters should be encoded everywhere,\n * but in paths, set to false when encoding a path\n * @return {string} the URI encoded result\n */\nexport function URIEncode(uri: string, path: boolean): string {\n if (uri == '') {\n return uri\n }\n\n return uri\n .split('') // to be able to map over a string, because... javascript...\n .map((letter: string) => {\n if (isAlpha(letter) || isNumeric(letter) || '-._~'.includes(letter)) {\n return letter\n }\n\n // Space should be explicitly encoded to as %20.\n if (letter == ' ') {\n return '%20'\n }\n\n // If the URI is a path, the forward slash shouldn't\n // be encoded.\n if (letter == '/' && path) {\n return '/'\n }\n\n return '%' + letter.charCodeAt(0).toString(16).toUpperCase()\n })\n .join('')\n}\n\n/**\n * Class holding URI encoding configuration\n */\nexport class URIEncodingConfig {\n double: boolean\n path: boolean\n\n /**\n *\n * @param {boolean} double - should the URI be double encoded?\n * @param {boolean} path - is the URI a path? If so, its forward\n * slashes won't be URIencoded.\n */\n constructor(double: boolean, path: boolean) {\n this.double = double\n this.path = path\n }\n}\n\n/**\n * Compute the request time value as specified by the ISO8601\n * format: YYYYMMDD'T'HHMMSS'Z'\n *\n * @param {number} timestamp\n * @return {string}\n */\nexport function toTime(timestamp: number): string {\n return new Date(timestamp).toISOString().replace(/[:\\-]|\\.\\d{3}/g, '')\n}\n/**\n * Computethe request date value in the format: YYYMMDD\n *\n * @param {number} timestamp\n * @return {string}\n */\nexport function toDate(timestamp: number): string {\n return toTime(timestamp).substring(0, 8)\n}\n\n// FIXME: does it work as expected?\n/**\n * Parse a HTTP request URL's querystring into an object\n * containing its `key=value` pairs.\n *\n * @param {string} qs\n * @return {object}\n */\nexport function parseQueryString(qs: string): Array<[string, string]> {\n if (qs.length === 0) {\n return []\n }\n\n return qs\n .split('&')\n .filter((e) => e)\n .map((v: string): [string, string] => {\n const parts = v.split('=', 2) as [string, string]\n return [decodeURIComponent(parts[0]), decodeURIComponent(parts[1])]\n })\n .sort((a: [string, string], b: [string, string]) => {\n return a[0].localeCompare(b[0])\n })\n}\n\nfunction isAlpha(c: string): boolean {\n return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')\n}\n\nfunction isNumeric(c: string): boolean {\n return c >= '0' && c <= '9'\n}\n\n// FIXME: finish implementation when needed\n// See the following for more details:\n// * https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html\n// * https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html\n// export function signQueryString(\n// queryString,\n// requestTimestamp,\n// accessKeyID,\n// secretAccessKey,\n// region,\n// service,\n// ttl, // in seconds\n// headers,\n// doubleURIEncoding = true\n// ) {\n// const credential = [accessKeyID, toDate(requestTimestamp), region, service].join('/')\n//\n// const canonicalRequest = createCanonicalRequest(\n// method,\n// path,\n// queryString,\n// headers,\n// body,\n// doubleURIEncoding\n// )\n//\n// const derivedSigningKey = deriveSigningKey(secretAccessKey, requestTimestamp, region, service)\n//\n// const stringToSign = createStringToSign(\n// requestTimestamp,\n// region,\n// service,\n// sha256(canonicalRequest, 'hex')\n// )\n//\n// const signedHeaders = createSignedHeaders(headers)\n// const signature = calculateSignature(derivedSigningKey, stringToSign)\n//\n// return [\n// `X-Amz-Algorithm=${HashingAlgorithm}`,\n// `X-Amz-Credential=${crediental}`,\n// `X-Amz-Date=${toTime(requestTimestamp)}`,\n// `X-Amz-Expires=${ttl}`,\n// `X-Amz-SignedHeaders=${signedHeaders}`,\n// `X-Amz-Signature=${signature}`,\n//`X-Amz-Security-Token=`, // TODO: optional\n// ].join('&')\n// }\n","/** Class holding an AWS connection information */\nexport class AWSConfig {\n region: string\n accessKeyID: string\n secretAccessKey: string\n\n /**\n * Create an AWSConfig.\n *\n * @param {string} region - the AWS region to connect to, as listed: https://docs.aws.amazon.com/general/latest/gr/rande.html\n * @param {string} accessKeyID - Your user's AWS access key id credential\n * @param {string} secretAccessKey - Your user's AWS secret access key credential\n * @throws {InvalidArgumentException}\n */\n constructor(region: string, accessKeyID: string, secretAccessKey: string) {\n if (typeof region !== 'string' || region === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS region; reason: should be a non empty string'\n )\n }\n\n if (typeof accessKeyID !== 'string' || accessKeyID === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS access key ID; reason: should be a non empty string'\n )\n }\n\n if (typeof secretAccessKey !== 'string' || secretAccessKey === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS secret access key; reason: should be a non empty string'\n )\n }\n\n this.region = region\n this.accessKeyID = accessKeyID\n this.secretAccessKey = secretAccessKey\n }\n}\n\n/** Class representing an invalid AWS configuration */\nexport class InvalidAWSConfigError extends Error {\n constructor(message: string) {\n super(message)\n }\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/http\");","import { HTTPMethod, HTTPHeaders } from './http'\nimport { AWSConfig } from './config'\nimport { signHeaders, URIEncodingConfig, toTime } from './signature'\n\n/**\n * Class allowing to build requests targeting AWS APIs\n *\n * This class is meant to be used as a base class for specific\n * services clients. See S3Client or SecretsManagerClient for\n * usage examples.\n */\nexport class AWSClient {\n awsConfig: AWSConfig\n serviceName: string\n URIencodingConfig: URIEncodingConfig\n\n /**\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n * @param {string} serviceName - name of the service to target.\n * @param {URIEncodingConfig} URIencodingConfig - configures how requests URIs should be encoded.\n */\n constructor(awsConfig: AWSConfig, serviceName: string, URIencodingConfig: URIEncodingConfig) {\n this.awsConfig = awsConfig\n this.serviceName = serviceName\n this.URIencodingConfig = URIencodingConfig\n }\n\n buildRequest(\n method: HTTPMethod,\n host: string,\n path: string,\n queryString: string,\n body: string | ArrayBuffer,\n headers: HTTPHeaders\n ): AWSRequest {\n const requestTimestamp: number = Date.now()\n const date: string = toTime(requestTimestamp)\n\n headers['Host'] = host\n headers['X-Amz-Date'] = date\n\n headers = signHeaders(\n // headers\n headers,\n\n // requestTimestamp\n requestTimestamp,\n\n // method\n method,\n\n // path\n path,\n\n // querystring\n queryString,\n\n // body\n body,\n\n // AWS configuration\n this.awsConfig,\n\n // AwS target service name\n this.serviceName,\n\n // doubleEncoding: S3 does single-encoding of the uri component\n // pathURIEncoding: S3 manipulates object keys, and forward slashes\n // shouldn't be URI encoded\n this.URIencodingConfig\n )\n\n // '?' should not be part of the querystring when we sign the headers\n path = path !== '' ? path : '/'\n let url = `https://${host}${path}`\n if (queryString !== '') {\n url += `?${queryString}`\n }\n\n return { url: url, headers: headers }\n }\n}\n\n/**\n * Type alias representing the result of an AWSClient.buildRequest call\n */\nexport interface AWSRequest {\n url: string\n headers: HTTPHeaders\n}\n","import { bytes } from 'k6'\nimport http, { RefinedResponse, ResponseType } from 'k6/http'\nimport { parseHTML } from 'k6/html'\nimport { sha256 } from 'k6/crypto'\n\nimport { InvalidSignatureError, URIEncodingConfig } from './signature'\nimport { AWSClient, AWSRequest } from './client'\nimport { AWSError } from './error'\nimport { AWSConfig } from './config'\n\n/** Class allowing to interact with Amazon AWS's S3 service */\nexport class S3Client extends AWSClient {\n /**\n * Create a S3Client\n *\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n */\n constructor(awsConfig: AWSConfig) {\n const URIencodingConfig = new URIEncodingConfig(false, true)\n super(awsConfig, 's3', URIencodingConfig)\n }\n\n /**\n * Returns a list of all buckets owned by the authenticated sender of the request.\n * To use this operation, you must have the s3:ListAllMyBuckets permission.\n *\n * @return {Array.} buckets - An array of objects describing S3 buckets\n * with the following fields: name, and creationDate.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n listBuckets(): Array {\n // Prepare request\n const method = 'GET'\n const host = `${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(method, host, '/', '', body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('ListBuckets', res)\n\n let buckets: Array = []\n\n const doc = parseHTML(res.body as string)\n\n doc.find('Buckets')\n .children()\n .each((_, bucketDefinition) => {\n let bucket = {}\n\n bucketDefinition.children().forEach((child) => {\n switch (child.nodeName()) {\n case 'name':\n Object.assign(bucket, { name: child.textContent() })\n break\n case 'creationdate':\n Object.assign(bucket, {\n creationDate: Date.parse(child.textContent()),\n })\n }\n })\n\n buckets.push(bucket as S3Bucket)\n })\n\n return buckets\n }\n\n /**\n * Returns some or all (up to 1,000) of the objects in a bucket.\n *\n * @param {string} bucketName - Bucket name to list.\n * @param {string?} prefix='' - Limits the response to keys that begin with the specified prefix.\n * @return {Array.} - returns an array of objects describing S3 objects\n * with the following fields: key, lastModified, etag, size and storageClass.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n listObjects(bucketName: string, prefix?: string): Array {\n // Prepare request\n const method = 'GET'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const body = ''\n const querystring = `list-type=2&prefix=${prefix}`\n const signedRequest: AWSRequest = super.buildRequest(method, host, '/', querystring, body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n Prefix: prefix ?? '',\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('ListObjectsV2', res)\n\n let objects: Array = []\n\n // Extract the objects definition from\n // the XML response\n parseHTML(res.body as string)\n .find('Contents')\n .each((_, objectDefinition) => {\n let obj = {}\n\n objectDefinition.children().forEach((child) => {\n switch (child.nodeName()) {\n case 'key':\n Object.assign(obj, { key: child.textContent() })\n break\n case 'lastmodified':\n Object.assign(obj, { lastModified: Date.parse(child.textContent()) })\n break\n case 'etag':\n Object.assign(obj, { etag: child.textContent() })\n break\n case 'size':\n Object.assign(obj, { size: parseInt(child.textContent()) })\n break\n case 'storageclass':\n Object.assign(obj, { storageClass: child.textContent() })\n }\n })\n\n objects.push(obj as S3Object)\n })\n\n return objects\n }\n /**\n * Retrieves an Object from Amazon S3.\n *\n * To use getObject, you must have `READ` access to the object.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to get.\n * @return {S3Object} - returns the content of the fetched S3 Object.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n getObject(bucketName: string, objectKey: string): S3Object {\n // Prepare request\n const method = 'GET'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(method, host, path, '', body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('GetObject', res)\n\n return new S3Object(\n objectKey,\n Date.parse(res.headers['Last-Modified']),\n res.headers['ETag'],\n parseInt(res.headers['Content-Length']),\n\n // The X-Amz-Storage-Class header is only set if the storage class is\n // not the default 'STANDARD' one.\n (res.headers['X-Amz-Storage-Class'] ?? 'STANDARD') as StorageClass,\n\n res.body\n )\n }\n /**\n * Adds an object to a bucket.\n *\n * You must have WRITE permissions on a bucket to add an object to it.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to put.\n * @param {string | ArrayBuffer} data - the content of the S3 Object to upload.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n putObject(bucketName: string, objectKey: string, data: string | ArrayBuffer) {\n // Prepare request\n const method = 'PUT'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const queryString = ''\n const body = data\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n path,\n queryString,\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('PutObject', res)\n }\n\n /**\n * Removes the null version (if there is one) of an object and inserts a delete marker,\n * which becomes the latest version of the object.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to delete.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n deleteObject(bucketName: string, objectKey: string): void {\n // Prepare request\n const method = 'DELETE'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const queryString = ''\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n path,\n queryString,\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('DeleteObject', res)\n }\n\n _handle_error(operation: S3Operation, response: RefinedResponse) {\n const errorCode: number = response.error_code\n const errorMessage: string = response.error\n\n if (errorMessage == '' || errorCode === 0) {\n return\n }\n\n // FIXME: should be errorCode === 1301 instead\n // See: https://github.com/grafana/k6/issues/2474\n // See: https://github.com/golang/go/issues/49281\n if (errorMessage && errorMessage.startsWith('301')) {\n throw new S3ServiceError('Resource not found', 'ResourceNotFound', operation)\n }\n\n const awsError = AWSError.parseXML(response.body as string)\n switch (awsError.code) {\n case 'AuthorizationHeaderMalformed':\n throw new InvalidSignatureError(awsError.message, awsError.code)\n default:\n throw new S3ServiceError(awsError.message, awsError.code, operation)\n }\n }\n}\n\n/** Class representing a S3 Bucket */\nexport class S3Bucket {\n name: string\n creationDate: Date\n\n /**\n * Create an S3 Bucket\n *\n * @param {string} name - S3 bucket's name\n * @param {Date} creationDate - S3 bucket's creation date\n */\n constructor(name: string, creationDate: Date) {\n this.name = name\n this.creationDate = creationDate\n }\n}\n\n/** Class representing an S3 Object */\nexport class S3Object {\n key: string\n lastModified: number\n etag: string\n size: number\n storageClass: StorageClass\n data?: string | bytes | null\n\n /**\n * Create an S3 Object\n *\n * @param {string} key - S3 object's key\n * @param {Date} lastModified - S3 object last modification date\n * @param {string} etag - S3 object's etag\n * @param {number} size - S3 object's size\n * @param {StorageClass} storageClass - S3 object's storage class\n * @param {string | bytes | null} data=null - S3 Object's data\n */\n constructor(\n key: string,\n lastModified: number,\n etag: string,\n size: number,\n storageClass: StorageClass,\n data?: string | bytes | null\n ) {\n this.key = key\n this.lastModified = lastModified\n this.etag = etag\n this.size = size\n this.storageClass = storageClass\n this.data = data\n }\n}\n\n/**\n * Error indicating a S3 operation failed\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class S3ServiceError extends AWSError {\n operation: string\n\n /**\n * Constructs a S3ServiceError\n *\n * @param {string} message - human readable error message\n * @param {string} code - A unique short code representing the error that was emitted\n * @param {string} operation - Name of the failed Operation\n */\n constructor(message: string, code: string, operation: string) {\n super(message, code)\n this.name = 'S3ServiceError'\n this.operation = operation\n }\n}\n\n/**\n * S3Operation describes possible values for S3 API operations,\n * as defined by AWS APIs.\n */\ntype S3Operation = 'ListBuckets' | 'ListObjectsV2' | 'GetObject' | 'PutObject' | 'DeleteObject'\n\n/**\n * Describes the class of storage used to store a S3 object.\n */\ntype StorageClass =\n | 'STANDARD'\n | 'REDUCED_REDUNDANCY'\n | 'GLACIER'\n | 'STANDARD_IA'\n | 'INTELLIGENT_TIERING'\n | 'DEEP_ARCHIVE'\n | 'OUTPOSTS'\n | 'GLACIER_IR'\n | undefined\n","import { JSONArray, JSONObject } from 'k6'\nimport http, { RefinedResponse, ResponseType } from 'k6/http'\n\nimport { AWSClient, AWSRequest } from './client'\nimport { AWSError } from './error'\nimport { AWSConfig } from './config'\nimport { InvalidSignatureError, URIEncodingConfig } from './signature'\nimport { v4 as uuidv4 } from 'uuid'\nimport { HTTPMethod, HTTPHeaders } from './http'\n\n/**\n * Class allowing to interact with Amazon AWS's SecretsManager service\n */\nexport class SecretsManagerClient extends AWSClient {\n method: HTTPMethod\n commonHeaders: HTTPHeaders\n\n /**\n * Create a SecretsManagerClient\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n */\n constructor(awsConfig: AWSConfig) {\n const URIencodingConfig = new URIEncodingConfig(true, false)\n super(awsConfig, 'secretsmanager', URIencodingConfig)\n\n // this.serviceName = 'secretsmanager'\n\n // All interactions with the Secrets Manager service\n // are made via the GET or POST method.\n this.method = 'POST'\n\n this.commonHeaders = {\n 'Accept-Encoding': 'identity',\n 'Content-Type': 'application/x-amz-json-1.1',\n }\n }\n\n /**\n * Returns a list of all secrets owned by the authenticated sender of the request.\n * To use this operation, you must have the secretsmanager:ListSecrets permission.\n *\n * @return {Array.} secrets - An array of objects describing Secret Manager's secrets\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n listSecrets(): Array {\n const body = JSON.stringify({})\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.ListSecrets`,\n }\n )\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('ListSecrets', res)\n const json: JSONArray = res.json('SecretList') as JSONArray\n\n return json.map((s) => Secret.fromJSON(s as JSONObject))\n }\n\n /**\n * Retrieves a secret from Amazon Sercets Manager\n *\n * @param {string} secretID - The ARN or name of the secret to retrieve.\n * @returns {Secret} - returns the content of the fetched Secret object.\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n getSecret(secretID: string): Secret | undefined {\n const body = JSON.stringify({ SecretId: secretID })\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.GetSecretValue`,\n }\n )\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('GetSecretValue', res)\n\n return Secret.fromJSON(res.json() as JSONObject)\n }\n\n /**\n * Creates a new secret\n *\n * Note that this method only supports string-based values at the moment.\n *\n * @param {string} name - The name of the new secret.\n * The secret name can contain ASCII letters, numbers, and the following characters: /_+=.@\n * @param {string} secretString - The text data to encrypt and store in this new version of the secret.\n * @param {string} description - The description of the secret.\n * @param {string} versionID=null - Version of the secret. This value helps ensure idempotency.\n * As a default, if no versionID is provided, one will be created for you using the UUID v4\n * algorithm.\n * @param {Array.} tags=[] - A list of tags to attach to the secret. Each tag is a key and\n * value pair of strings in a JSON text string. Note that tag key names are case sensitive.\n * @returns {Secret} - returns the created secret\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n createSecret(\n name: string,\n secretString: string,\n description: string,\n versionID?: string,\n tags?: Array\n ): Secret {\n versionID = versionID || uuidv4()\n\n const body = JSON.stringify({\n Name: name,\n Description: description,\n SecretString: secretString,\n ClientRequestToken: versionID,\n Tags: tags,\n })\n\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.CreateSecret`,\n }\n )\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n // headers['X-Amz-Target'] = `${this.serviceName}.CreateSecret`\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('CreateSecret', res)\n\n return Secret.fromJSON(res.json() as JSONObject)\n }\n /**\n * Update a secret's value.\n *\n * Note that this method only support string-based values at the moment.\n *\n * @param {string} secretID - The ARN or name of the secret to update.\n * @param {string} secretString - The text data to encrypt and store in this new version of the secret.\n * @param {} versionID=null - A unique identifier for the new version of the secret. This value helps ensure idempotency.\n * As a default, if no versionID is provided, one will be created for you using the UUID v4\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n putSecretValue(secretID: string, secretString: string, versionID?: string): Secret {\n versionID = versionID || uuidv4()\n\n const body = JSON.stringify({\n SecretId: secretID,\n SecretString: secretString,\n ClientRequestToken: versionID,\n })\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.PutSecretValue`,\n }\n )\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('PutSecretValue', res)\n\n return Secret.fromJSON(res.json() as JSONObject)\n }\n\n /**\n * Deletes a secret and all of its versions.\n *\n * You can specify a recovery window during which you can restore the secret.\n * The minimum recovery window is 7 days. The default recovery window is 30 days.\n *\n * @param {string} secretID - The ARN or name of the secret to delete.\n * @param {number} recoveryWindow - The number of days from 7 to 30 that Secrets Manager\n * waits before permanently deleting the secret.\n * @throws {SecretsManagerServiceError}\n * @throws {InvalidSignatureError}\n */\n deleteSecret(\n secretID: string,\n { recoveryWindow = 30, noRecovery = false }: { recoveryWindow: number; noRecovery: boolean }\n ) {\n const payload: { [key: string]: string | boolean | number } = {\n SecretId: secretID,\n }\n\n // noRecovery and recoveryWindow are exclusive parameters\n if (noRecovery === true) {\n payload['ForceDeleteWithoutRecovery'] = true\n } else {\n payload['RecoveryWindowInDays'] = recoveryWindow\n }\n\n const body = JSON.stringify(payload)\n\n // Ensure to include the desired 'Action' in the X-Amz-Target\n // header field, as documented by the AWS API docs.\n const signedRequest: AWSRequest = super.buildRequest(\n this.method,\n this.host,\n '/',\n '',\n body,\n {\n ...this.commonHeaders,\n 'X-Amz-Target': `${this.serviceName}.DeleteSecret`,\n }\n )\n\n const res = http.request(this.method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('DeleteSecret', res)\n }\n\n get host() {\n return `${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n }\n\n // TODO: operation should be an enum\n _handle_error(operation: string, response: RefinedResponse) {\n const errorCode = response.error_code\n if (errorCode === 0) {\n return\n }\n\n const error = response.json() as JSONObject\n if (errorCode >= 1400 && errorCode <= 1499) {\n // In the event of certain errors, the message is not set.\n // Also, note the inconsistency in casing...\n const errorMessage: string =\n (error.Message as string) || (error.message as string) || (error.__type as string)\n\n // Handle specifically the case of an invalid signature\n if (error.__type === 'InvalidSignatureException') {\n throw new InvalidSignatureError(errorMessage, error.__type)\n }\n\n // Otherwise throw a standard service error\n throw new SecretsManagerError(errorMessage, error.__type as string, operation)\n }\n\n if (errorCode === 1500) {\n throw new SecretsManagerError(\n 'An error occured on the server side',\n 'InternalServiceError',\n operation\n )\n }\n }\n}\n\n// TODO: create a Tags type\n\n/**\n * Class representing a Secret Manager's secret\n */\nexport class Secret {\n name: string\n arn: string\n secret: string\n createdDate: number\n lastAccessedDate: number\n lastChangedDate: number\n tags: Array<{ [key: string]: string }>\n\n /**\n * Constructs a Secret Manager's Secret\n *\n * @param {string} name - The friendly name of the secret.\n * @param {string} arn - The ARN of the secret.\n * @param {number} createdDate - The date and time that this version of the secret was created.\n * @param {number} lastAccessedDate - The last date that this secret was accessed. This value is\n * truncated to midnight of the date and therefore shows only the date, not the time.\n * @param {number} lastChangedDate - The last date and time that this secret was modified in any way.\n * @param {Array.} tags - The list of user-defined tags associated with the secret.\n */\n constructor(\n name: string,\n arn: string,\n secretString: string,\n createdDate: number,\n lastAccessedDate: number,\n lastChangedDate: number,\n tags: Array<{ [key: string]: string }> = []\n ) {\n this.name = name\n this.arn = arn\n this.secret = secretString\n this.createdDate = createdDate\n this.lastAccessedDate = lastAccessedDate\n this.lastChangedDate = lastChangedDate\n this.tags = tags\n }\n\n /**\n * Parses and constructs a Secret Manager's Secret from the content\n * of a JSON response returned by the AWS service\n *\n * @param {Object} json - JSON object as returned and parsed from\n * the AWS service's API call.\n * @returns {Secret}\n */\n static fromJSON(json: JSONObject) {\n return new Secret(\n json.Name as string,\n json.ARN as string,\n json.SecretString as string,\n json.CreatedDate as number,\n json.LastAccessedDate as number,\n json.LastChangedDate as number,\n json.Tags as Array<{ [key: string]: string }>\n )\n }\n}\n\nexport class SecretsManagerError extends AWSError {\n operation: string\n\n /**\n * Constructs a SecretsManagerError\n *\n * @param {string} message - human readable error message\n * @param {string} code - A unique short code representing the error that was emitted\n * @param {string} operation - Name of the failed Operation\n */\n constructor(message: string, code: string, operation: string) {\n super(message, code)\n this.name = 'SecretsManagerServiceError'\n this.operation = operation\n }\n}\n"],"names":["v1","v4","uuid","module","exports","byteToHex","i","toString","substr","buf","offset","bth","join","getRandomValues","crypto","bind","window","msCrypto","rnds8","Uint8Array","rnds","Array","r","Math","random","_nodeId","_clockseq","rng","bytesToUuid","_lastMSecs","_lastNSecs","options","b","node","clockseq","undefined","seedBytes","msecs","Date","getTime","nsecs","dt","Error","tl","tmh","n","ii","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","__webpack_modules__","getter","__esModule","d","a","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","require","AWSError","message","code","name","xmlDocument","doc","parseHTML","find","text","signHeaders","headers","requestTimestamp","method","path","queryString","body","awsConfig","service","URIencodingConfig","derivedSigningKey","secretAccessKey","time","region","kSecret","date","toDate","kDate","hmac","kRegion","kService","deriveSigningKey","canonicalRequest","uri","query","payload","httpRequestMethod","toUpperCase","canonicalURI","length","URIEncode","createCanonicalURI","canonicalQueryString","qs","split","filter","e","map","v","parts","decodeURIComponent","sort","localeCompare","parseQueryString","encodeURIComponent","createCanonicalQueryString","canonicalHeaders","constructor","entries","values","toLowerCase","trim","isArray","replace","createCanonicalHeaders","signedHeaders","createSignedHeaders","requestPayload","UnsignedPayload","createCanonicalPayload","createCanonicalRequest","stringToSign","hashedCanonicalRequest","requestDateTime","toTime","credentialScope","createCredentialScope","HashingAlgorithm","createStringToSign","sha256","signature","calculateSignature","authorizationHeader","accessKeyID","InvalidSignatureError","TypeError","keys","letter","c","isNumeric","includes","charCodeAt","URIEncodingConfig","double","this","timestamp","toISOString","substring","AWSConfig","InvalidAWSConfigError","AWSClient","serviceName","host","now","url","S3Client","signedRequest","res","http","_handle_error","buckets","children","each","_","bucketDefinition","bucket","forEach","child","nodeName","assign","textContent","creationDate","parse","push","bucketName","prefix","querystring","Prefix","objects","objectDefinition","lastModified","etag","size","parseInt","storageClass","objectKey","S3Object","data","operation","response","errorCode","error_code","errorMessage","error","startsWith","S3ServiceError","awsError","parseXML","S3Bucket","SecretsManagerClient","commonHeaders","JSON","stringify","json","s","Secret","fromJSON","secretID","SecretId","secretString","description","versionID","tags","uuidv4","Name","Description","SecretString","ClientRequestToken","Tags","recoveryWindow","noRecovery","Message","__type","SecretsManagerError","arn","createdDate","lastAccessedDate","lastChangedDate","secret","ARN","CreatedDate","LastAccessedDate","LastChangedDate"],"sourceRoot":""} \ No newline at end of file diff --git a/build/s3.min.js b/build/s3.min.js index 5b52dc8..457cdcf 100644 --- a/build/s3.min.js +++ b/build/s3.min.js @@ -1,2 +1,2 @@ -(()=>{"use strict";var e={n:t=>{var r=t&&t.__esModule?()=>t.default:()=>t;return e.d(r,{a:r}),r},d:(t,r)=>{for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{AWSConfig:()=>F,InvalidAWSConfigError:()=>$,InvalidSignatureError:()=>R,S3Bucket:()=>ye,S3Client:()=>pe,S3Object:()=>he,S3ServiceError:()=>be,URIEncodingConfig:()=>D});const r=require("k6/crypto");var n=e.n(r);const o=require("k6/html");function i(e){return i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i(e)}function c(e,t){for(var r=0;re.length)&&(t=e.length);for(var r=0,n=new Array(t);r="A"&&r<="Z"||r>="a"&&r<="z"||function(e){return e>="0"&&e<="9"}(e)||"-._~".includes(e)?e:" "==e?"%20":"/"==e&&t?"/":"%"+e.charCodeAt(0).toString(16).toUpperCase();var r})).join("")}var D=w((function e(t,r){O(this,e),d(this,"double",void 0),d(this,"path",void 0),this.double=t,this.path=r}));function I(e){return new Date(e).toISOString().replace(/[:\-]|\.\d{3}/g,"")}function M(e){return I(e).substring(0,8)}function z(e){return z="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},z(e)}function q(e,t){if(t&&("object"===z(t)||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e)}function H(e){var t="function"==typeof Map?new Map:void 0;return H=function(e){if(null===e||(r=e,-1===Function.toString.call(r).indexOf("[native code]")))return e;var r;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return N(e,arguments,B(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),L(n,e)},H(e)}function N(e,t,r){return N=U()?Reflect.construct:function(e,t,r){var n=[null];n.push.apply(n,t);var o=new(Function.bind.apply(e,n));return r&&L(o,r.prototype),o},N.apply(null,arguments)}function U(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}function L(e,t){return L=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},L(e,t)}function B(e){return B=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},B(e)}function W(e,t){for(var r=0;r{"use strict";var e={n:t=>{var r=t&&t.__esModule?()=>t.default:()=>t;return e.d(r,{a:r}),r},d:(t,r)=>{for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{AWSConfig:()=>F,InvalidAWSConfigError:()=>$,InvalidSignatureError:()=>R,S3Bucket:()=>ye,S3Client:()=>pe,S3Object:()=>he,S3ServiceError:()=>be,URIEncodingConfig:()=>D});const r=require("k6/crypto");var n=e.n(r);const o=require("k6/html");function i(e){return i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i(e)}function c(e,t){for(var r=0;re.length)&&(t=e.length);for(var r=0,n=new Array(t);r="A"&&r<="Z"||r>="a"&&r<="z"||function(e){return e>="0"&&e<="9"}(e)||"-._~".includes(e)?e:" "==e?"%20":"/"==e&&t?"/":"%"+e.charCodeAt(0).toString(16).toUpperCase();var r})).join("")}var D=w((function e(t,r){O(this,e),d(this,"double",void 0),d(this,"path",void 0),this.double=t,this.path=r}));function I(e){return new Date(e).toISOString().replace(/[:\-]|\.\d{3}/g,"")}function M(e){return I(e).substring(0,8)}function z(e){return z="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},z(e)}function q(e,t){if(t&&("object"===z(t)||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e)}function H(e){var t="function"==typeof Map?new Map:void 0;return H=function(e){if(null===e||(r=e,-1===Function.toString.call(r).indexOf("[native code]")))return e;var r;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return L(e,arguments,B(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),U(n,e)},H(e)}function L(e,t,r){return L=N()?Reflect.construct:function(e,t,r){var n=[null];n.push.apply(n,t);var o=new(Function.bind.apply(e,n));return r&&U(o,r.prototype),o},L.apply(null,arguments)}function N(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}function U(e,t){return U=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},U(e,t)}function B(e){return B=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},B(e)}function W(e,t){for(var r=0;r {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/crypto\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/html\");","import { parseHTML } from 'k6/html'\n\n/**\n * Base class to derive errors from\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class AWSError extends Error {\n code: string\n\n /**\n * Create an AWSError\n *\n * @param {string} message - A longer human readable error message.\n * @param {string} code - A unique short code representing the error that was emitted\n */\n constructor(message: string, code: string) {\n super(message)\n this.name = 'AWSError'\n this.code = code\n }\n\n /**\n * Parse an AWSError from an XML document\n *\n * @param {string} xmlDocument - Serialized XML document to parse the error from\n */\n static parseXML(xmlDocument: string): AWSError {\n const doc = parseHTML(xmlDocument)\n return new AWSError(doc.find('Message').text(), doc.find('Code').text())\n }\n}\n","import crypto, { hmac, sha256 } from 'k6/crypto'\nimport { HTTPMethod, HTTPHeaders } from './http'\nimport { AWSConfig } from './config'\nimport { AWSError } from './error'\n\n/**\n * Includes AWS v4 signing information to the provided HTTP headers object.\n *\n * This function will compute the `Authorization` header signature for the\n * provided request components, and add it to `header`. It will do so by following\n * the procedure detailled AWS' API docs: https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html\n *\n * The resulting `Authorization` header value is computed for the provided\n * headers object. Thus, any modification of the headers past a call to `signHeaders`\n * would effectively invalidate their signature, and the function should be\n * called again to recompute it.\n *\n * @param {object} headers - HTTP headers request to sign.\n * @param {number} requestTimestamp - Timestamp of the request\n * @param {string} method - HTTP method used\n * @param {string} path - HTTP request URL's path\n * @param {string} queryString - HTTP request URL's querystring\n * @param {string | ArrayBuffer} body - HTTP request's payload\n * @param {AWSConfig} - AWS configuration\n * @param {string} service - AWS service name\n * @param {URIEncodingConfig} - URI encoding configuration\n */\nexport function signHeaders(\n headers: HTTPHeaders,\n requestTimestamp: number,\n method: HTTPMethod,\n path: string,\n queryString: string,\n body: string | ArrayBuffer,\n awsConfig: AWSConfig,\n service: string,\n URIencodingConfig: URIEncodingConfig\n): HTTPHeaders {\n const derivedSigningKey = deriveSigningKey(\n awsConfig.secretAccessKey,\n requestTimestamp,\n awsConfig.region,\n service\n )\n\n const canonicalRequest = createCanonicalRequest(\n method,\n path,\n queryString,\n headers,\n body,\n URIencodingConfig\n )\n\n const stringToSign = createStringToSign(\n requestTimestamp,\n awsConfig.region,\n service,\n sha256(canonicalRequest, 'hex')\n )\n\n const credentialScope = createCredentialScope(requestTimestamp, awsConfig.region, service)\n const signedHeaders = createSignedHeaders(headers)\n const signature = calculateSignature(derivedSigningKey, stringToSign)\n const authorizationHeader = `${HashingAlgorithm} Credential=${awsConfig.accessKeyID}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`\n\n headers['Authorization'] = authorizationHeader\n\n return headers\n}\n\n/**\n * Error indicating an Invalid signature has been sent to AWS services\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class InvalidSignatureError extends AWSError {\n /**\n * Constructs an InvalidSignatureError\n *\n * @param {string} message - human readable error message\n */\n constructor(message: string, code: string) {\n super(message, code)\n this.name = 'InvalidSignatureError'\n }\n}\n\n/**\n * Calculte the signature for AWS signature version 4\n *\n * @param {string} derivedSigningKey - dervied signing key as computed by `deriveSigningKey`\n * @param {string} stringToSign - String to sign as computed by `createStringToSign`\n * @return {string}\n */\nexport function calculateSignature(derivedSigningKey: ArrayBuffer, stringToSign: string): string {\n return hmac('sha256', derivedSigningKey, stringToSign, 'hex')\n}\n/**\n * Derives the signing key for authenticating requests signed with\n * the Signature version 4 authentication protocol.\n *\n * deriveSigningKey produces a signing key by creating a series of\n * hash-based message authentication codes (HMACs) represented in\n * a binary format.\n *\n * The derived signing key is specific to the date it's made at, as well as\n * the service and region it targets.\n *\n * @param {string} secretAccessKey - the AWS secret access key to derive the signing key for\n * @param {number} time - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service. MUST be UTF-8 encoded.\n * @return {string}\n */\nexport function deriveSigningKey(\n secretAccessKey: string,\n time: number,\n region: string,\n service: string\n): ArrayBuffer {\n const kSecret = secretAccessKey\n const date = toDate(time)\n\n // FIXME: hmac takes ArrayBuffer as input, but returns bytes (number[]).\n // How does one convert from one to the other?\n const kDate: any = hmac('sha256', 'AWS4' + kSecret, date, 'binary')\n const kRegion: any = hmac('sha256', kDate, region, 'binary')\n const kService: any = hmac('sha256', kRegion, service, 'binary')\n const kSigning: any = hmac('sha256', kService, 'aws4_request', 'binary')\n\n return kSigning\n}\n\n// Hashing Algorithm to use in the signature process\nexport const HashingAlgorithm = 'AWS4-HMAC-SHA256'\n\n/**\n * Certain services, such as S3, allow for unsigned payloads. If\n * producing a signed canonical request for such service, pass\n * the `UnsignedPayload` constant value as the payload parameter.\n */\nexport const UnsignedPayload = 'UNSIGNED-PAYLOAD'\n\n/**\n * Create the \"string to sign\" part of the signature Version 4 protocol.\n *\n * The \"string to sign\" includes meta information about your request and\n * about the canonical request that you created with `createCanonicalRequest`.\n * It is used hand in hand with the signing key to create the request signature.\n *\n * @param {number} requestTimestamp - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service name. MUST be UTF-8 encoded.\n * @param {string} hashedCanonicalRequest - canonical request as produced by calling the createCanonicalRequest function,\n * hashed using the SHA256 algorithm (encoded in hexadecimal format).\n * @return {string}\n */\nexport function createStringToSign(\n requestTimestamp: number,\n region: string,\n service: string,\n hashedCanonicalRequest: string\n): string {\n // the request date specified in ISO8601 format: YYYYMMDD'T'HHMMSS'Z'\n const requestDateTime = toTime(requestTimestamp)\n\n // The credential scope value, consisting of the date in YYYYMMDD format,\n // the targeted region, the targeted service, and a termination string.\n // Note that the region and service MUST be UTF-8 encoded.\n const credentialScope = createCredentialScope(requestTimestamp, region, service)\n\n const stringToSign = [\n // Algorithm\n HashingAlgorithm,\n\n // RequestDateTime\n requestDateTime,\n\n // CredentialScope\n credentialScope,\n\n // HashedCanonicalRequest\n hashedCanonicalRequest,\n ].join('\\n')\n\n return stringToSign\n}\n\n/**\n *\n * Helper function creating a credential scope string to use in the signature\n * version 4 process. A credential scope consists of the date of the request\n * in YYYYMMDD format, the targeted region, the targeted service, and a\n * termination string.\n *\n * Note that the region and service MUST be UTF-8 encoded.\n *\n * @param {number} requestTimestamp - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service name. MUST be UTF-8 encoded.\n * @return {string}\n */\nexport function createCredentialScope(\n requestTimestamp: number,\n region: string,\n service: string\n): string {\n return [toDate(requestTimestamp), region, service, 'aws4_request'].join('/')\n}\n\n/**\n * Create a string that includes information from your request\n * in a AWS signature v4 standardized (canonical) format.\n *\n * @param {string} method - the HTTP request method\n * @param {string} uri - URI-encoded version of the absolute path component of the URI\n * @param {string} query - request's query string\n * @param {Object} headers - all the HTTP headers that you wish to include with the signed request\n * @param {string | ArrayBuffer} payload - payload to include as the body of the request\n * @param {URIEncodingConfig} URIencodingConfig- URI encoding configuration\n * @return {string}\n */\nexport function createCanonicalRequest(\n method: HTTPMethod,\n uri: string,\n query: string,\n headers: HTTPHeaders,\n payload: string | ArrayBuffer,\n URIencodingConfig: URIEncodingConfig\n): string {\n const httpRequestMethod = method.toUpperCase()\n const canonicalURI = createCanonicalURI(uri, URIencodingConfig)\n const canonicalQueryString = createCanonicalQueryString(query)\n const canonicalHeaders = createCanonicalHeaders(headers)\n const signedHeaders = createSignedHeaders(headers)\n const requestPayload = createCanonicalPayload(payload)\n\n const canonicalRequest = [\n httpRequestMethod,\n canonicalURI,\n canonicalQueryString,\n canonicalHeaders,\n signedHeaders,\n requestPayload,\n ].join('\\n')\n\n return canonicalRequest\n}\n\n/**\n * Creates the (canonical) URI-encoded version of the\n * absolute path component of the URI: everything in the URI\n * from the HTTP host to the question mark character (\"?\")\n * that begins the query string parameters (if any).\n *\n * @param {string} uri - URI to canonize\n * @param {URIEncodingConfig} - URI encoding configuration\n * @return {string} - canonical URL\n */\nexport function createCanonicalURI(uri: string, URIencodingConfig: URIEncodingConfig): string {\n if (uri == '/') {\n return uri\n }\n\n let canonicalURI = uri\n if (uri[uri.length - 1] == '/' && canonicalURI[canonicalURI.length - 1] != '/') {\n canonicalURI += '/'\n }\n\n canonicalURI = URIEncode(canonicalURI, URIencodingConfig.path)\n\n return URIencodingConfig.double ? URIEncode(canonicalURI, URIencodingConfig.path) : canonicalURI\n}\n\n// FIXME: does it work as expected?\n/**\n * Creates the canonical form of the request's query\n * string. If the request does not include a query string,\n * provide an empty string.\n *\n * @param {String | Object} qs - query string to canonize\n * @return {string}\n */\nexport function createCanonicalQueryString(qs: string): string {\n if (qs === '') {\n return ''\n }\n\n // const intermediary: { [key: string]: string } = parseQueryString(qs)\n\n // return Object.keys(intermediary)\n // .sort()\n // .map((key: string) => {\n // // const values: string[] = Array.isArray(intermediary[key])\n // // ? intermediary[key]\n // // : [intermediary[key]]\n // const values = intermediary[key]\n\n // return values\n // .sort()\n // .map((val: string) => encodeURIComponent(key) + '=' + encodeURIComponent(val))\n // .join('&')\n // })\n // .join('&')\n\n return parseQueryString(qs)\n .map(([key, value]: [string, string]): string => {\n return encodeURIComponent(key) + '=' + encodeURIComponent(value)\n })\n .join('&')\n}\n/**\n * Create the canonical form of the request's headers.\n * Canonical headers consist of all the HTTP headers you\n * are including with the signed request.\n *\n * Note that:\n * * for HTTP/1.1 requests, the headers should at least\n * contain the `host` header.\n * * for HTTP/2, the `:authority` header must be used instead\n * of `host`.\n *\n * @param {Object} headers\n * @return {string}\n */\nexport function createCanonicalHeaders(headers: HTTPHeaders) {\n if (headers.constructor !== Object || Object.entries(headers).length === 0) {\n return ''\n }\n\n const canonicalHeaders = Object.entries(headers)\n .map(([name, values]) => {\n const canonicalName = name.toLowerCase().trim()\n const normalizedValues = Array.isArray(values) ? values : [values]\n\n // Note that we do not need to sort values\n const canonicalValues = normalizedValues\n .map((v) => {\n // convert sequential spaces to a single space\n return v.replace(/\\s+/g, ' ').replace(/^\\s+|\\s+$/g, '')\n })\n .join(',') // standard for multiple values in a HTTP header\n\n return canonicalName + ':' + canonicalValues + '\\n'\n })\n .sort()\n .join('')\n\n return canonicalHeaders\n}\n\n/**\n * Create the canonical request's signed headers.\n *\n * The signed headers part of the request contains the\n * list of headers included in the request's signing process.\n *\n * Note that:\n * * for HTTP/1.1 requests, the `host` header must be included.\n * * for HTTP/2 requests, the `:authority` header must be included instead\n * of host.\n * * if used, the `x-amz-date` header must be included.\n *\n * @param {Object} headers\n * @return {string}\n * @throws {TypeError} - on headers not being an Object, or being empty.\n */\nexport function createSignedHeaders(headers: { [key: string]: string }) {\n if (headers.constructor !== Object) {\n throw new TypeError('headers should be an object')\n }\n\n if (Object.entries(headers).length === 0) {\n throw 'headers should at least contain either the Host (HTTP 1.1) or :authority (HTTP 2) parameter'\n }\n\n // To create the signed headers list, convert\n // all header names to lowercase, sort them by\n // character code, and use a semicolon to separate\n // the header names.\n const result = Object.keys(headers)\n .map((name) => name.toLowerCase().trim())\n .sort()\n .join(';')\n\n return result\n}\n\n/**\n * Create the canonical form of the request's payload.\n *\n * The canonical payload consists in a lowercased, hex encoded,\n * SHA256 hash of the requests body/payload.\n *\n * Certain services, such as S3, allow for unsigned payload. If\n * producing a signed canonical request for such service, pass\n * the `UnsignedPayload` constant value as the payload parameter.\n *\n * @param {String | ArrayBuffer} payload\n * @return {string}\n */\nexport function createCanonicalPayload(payload: string | ArrayBuffer) {\n if (payload === UnsignedPayload) {\n return payload\n }\n\n // Note that if the paylaod is null, we convert it\n // to an empty string.\n // TODO: Should switching to empty string if null impact headers?\n return crypto.sha256(payload || '', 'hex').toLowerCase()\n}\n\n/**\n * URIEncodes encodes every bytes of a URI to be URL-safe.\n *\n * This implementation is specific to AWS; who intended to make it as\n * close as possible to the underlying RFC 3946. It:\n * * URI encode every byte except the unreserved characters: 'A'-'Z', 'a'-'z', '0'-'9',\n * '-', '.', '_', and '~'.\n * * considers the space character as a reserved character and must URI encodes\n * encodes it as \"%20\" (and not as \"+\").\n * * URI encodes every byte by prefixing with '%' the two-digit hexadecimal value of the byte.\n * * If the `path` argument is set, forward slashes are not encoded, to fit with\n * S3 requirements.\n *\n * N.B: this implementation differs with ES6' mainly in that it does\n * encode the \"'\" character.\n *\n * Based on AWS implementation: https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-core/src/main/java/com/amazonaws/util/SdkHttpUtils.java#L66\n * Encoding specs: https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html\n *\n * @param {string} uri - uri to encode\n * @param {boolean} path - slash characters should be encoded everywhere,\n * but in paths, set to false when encoding a path\n * @return {string} the URI encoded result\n */\nexport function URIEncode(uri: string, path: boolean): string {\n if (uri == '') {\n return uri\n }\n\n return uri\n .split('') // to be able to map over a string, because... javascript...\n .map((letter: string) => {\n if (isAlpha(letter) || isNumeric(letter) || '-._~'.includes(letter)) {\n return letter\n }\n\n // Space should be explicitly encoded to as %20.\n if (letter == ' ') {\n return '%20'\n }\n\n // If the URI is a path, the forward slash shouldn't\n // be encoded.\n if (letter == '/' && path) {\n return '/'\n }\n\n return '%' + letter.charCodeAt(0).toString(16).toUpperCase()\n })\n .join('')\n}\n\n/**\n * Class holding URI encoding configuration\n */\nexport class URIEncodingConfig {\n double: boolean\n path: boolean\n\n /**\n *\n * @param {boolean} double - should the URI be double encoded?\n * @param {boolean} path - is the URI a path? If so, its forward\n * slashes won't be URIencoded.\n */\n constructor(double: boolean, path: boolean) {\n this.double = double\n this.path = path\n }\n}\n\n/**\n * Compute the request time value as specified by the ISO8601\n * format: YYYYMMDD'T'HHMMSS'Z'\n *\n * @param {number} timestamp\n * @return {string}\n */\nexport function toTime(timestamp: number): string {\n return new Date(timestamp).toISOString().replace(/[:\\-]|\\.\\d{3}/g, '')\n}\n/**\n * Computethe request date value in the format: YYYMMDD\n *\n * @param {number} timestamp\n * @return {string}\n */\nexport function toDate(timestamp: number): string {\n return toTime(timestamp).substring(0, 8)\n}\n\n// FIXME: does it work as expected?\n/**\n * Parse a HTTP request URL's querystring into an object\n * containing its `key=value` pairs.\n *\n * @param {string} qs\n * @return {object}\n */\nexport function parseQueryString(qs: string): Array<[string, string]> {\n if (qs.length === 0) {\n return []\n }\n\n return qs\n .split('&')\n .filter((e) => e)\n .map((v: string): [string, string] => {\n const parts = v.split('=', 2) as [string, string]\n return [decodeURIComponent(parts[0]), decodeURIComponent(parts[1])]\n })\n .sort((a: [string, string], b: [string, string]) => {\n return a[0].localeCompare(b[0])\n })\n}\n\nfunction isAlpha(c: string): boolean {\n return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')\n}\n\nfunction isNumeric(c: string): boolean {\n return c >= '0' && c <= '9'\n}\n\n// FIXME: finish implementation when needed\n// See the following for more details:\n// * https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html\n// * https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html\n// export function signQueryString(\n// queryString,\n// requestTimestamp,\n// accessKeyID,\n// secretAccessKey,\n// region,\n// service,\n// ttl, // in seconds\n// headers,\n// doubleURIEncoding = true\n// ) {\n// const credential = [accessKeyID, toDate(requestTimestamp), region, service].join('/')\n//\n// const canonicalRequest = createCanonicalRequest(\n// method,\n// path,\n// queryString,\n// headers,\n// body,\n// doubleURIEncoding\n// )\n//\n// const derivedSigningKey = deriveSigningKey(secretAccessKey, requestTimestamp, region, service)\n//\n// const stringToSign = createStringToSign(\n// requestTimestamp,\n// region,\n// service,\n// sha256(canonicalRequest, 'hex')\n// )\n//\n// const signedHeaders = createSignedHeaders(headers)\n// const signature = calculateSignature(derivedSigningKey, stringToSign)\n//\n// return [\n// `X-Amz-Algorithm=${HashingAlgorithm}`,\n// `X-Amz-Credential=${crediental}`,\n// `X-Amz-Date=${toTime(requestTimestamp)}`,\n// `X-Amz-Expires=${ttl}`,\n// `X-Amz-SignedHeaders=${signedHeaders}`,\n// `X-Amz-Signature=${signature}`,\n//`X-Amz-Security-Token=`, // TODO: optional\n// ].join('&')\n// }\n","/** Class holding an AWS connection information */\nexport class AWSConfig {\n region: string\n accessKeyID: string\n secretAccessKey: string\n\n /**\n * Create an AWSConfig.\n *\n * @param {string} region - the AWS region to connect to, as listed: https://docs.aws.amazon.com/general/latest/gr/rande.html\n * @param {string} accessKeyID - Your user's AWS access key id credential\n * @param {string} secretAccessKey - Your user's AWS secret access key credential\n * @throws {InvalidArgumentException}\n */\n constructor(region: string, accessKeyID: string, secretAccessKey: string) {\n if (typeof region !== 'string' || region === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS region; reason: should be a non empty string'\n )\n }\n\n if (typeof accessKeyID !== 'string' || accessKeyID === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS access key ID; reason: should be a non empty string'\n )\n }\n\n if (typeof secretAccessKey !== 'string' || secretAccessKey === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS secret access key; reason: should be a non empty string'\n )\n }\n\n this.region = region\n this.accessKeyID = accessKeyID\n this.secretAccessKey = secretAccessKey\n }\n}\n\n/** Class representing an invalid AWS configuration */\nexport class InvalidAWSConfigError extends Error {\n constructor(message: string) {\n super(message)\n }\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/http\");","import { bytes } from 'k6'\nimport http from 'k6/http'\nimport { parseHTML } from 'k6/html'\nimport { sha256 } from 'k6/crypto'\n\nimport { InvalidSignatureError, URIEncodingConfig } from './signature'\nimport { AWSClient, AWSRequest } from './client'\nimport { AWSError } from './error'\nimport { AWSConfig } from './config'\n\n/** Class allowing to interact with Amazon AWS's S3 service */\nexport class S3Client extends AWSClient {\n /**\n * Create a S3Client\n *\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n */\n constructor(awsConfig: AWSConfig) {\n const URIencodingConfig = new URIEncodingConfig(false, true)\n super(awsConfig, 's3', URIencodingConfig)\n }\n\n /**\n * Returns a list of all buckets owned by the authenticated sender of the request.\n * To use this operation, you must have the s3:ListAllMyBuckets permission.\n *\n * @return {Array.} buckets - An array of objects describing S3 buckets\n * with the following fields: name, and creationDate.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n listBuckets(): Array {\n // Prepare request\n const method = 'GET'\n const host = `${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(method, host, '/', '', body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n let buckets: Array = []\n\n const doc = parseHTML(res.body as string)\n\n doc.find('Buckets')\n .children()\n .each((_, bucketDefinition) => {\n let bucket = {}\n\n bucketDefinition.children().forEach((child) => {\n switch (child.nodeName()) {\n case 'name':\n Object.assign(bucket, { name: child.textContent() })\n break\n case 'creationdate':\n Object.assign(bucket, {\n creationDate: Date.parse(child.textContent()),\n })\n }\n })\n\n buckets.push(bucket as S3Bucket)\n })\n\n return buckets\n }\n\n /**\n * Returns some or all (up to 1,000) of the objects in a bucket.\n *\n * @param {string} bucketName - Bucket name to list.\n * @param {string?} prefix='' - Limits the response to keys that begin with the specified prefix.\n * @return {Array.} - returns an array of objects describing S3 objects\n * with the following fields: key, lastModified, etag, size and storageClass.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n listObjects(bucketName: string, prefix?: string): Array {\n // Prepare request\n const method = 'GET'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const body = ''\n const querystring = `list-type=2&prefix=${prefix}`\n const signedRequest: AWSRequest = super.buildRequest(method, host, '/', querystring, body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n Prefix: prefix ?? '',\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n let objects: Array = []\n\n // Extract the objects definition from\n // the XML response\n parseHTML(res.body as string)\n .find('Contents')\n .each((_, objectDefinition) => {\n let obj = {}\n\n objectDefinition.children().forEach((child) => {\n switch (child.nodeName()) {\n case 'key':\n Object.assign(obj, { key: child.textContent() })\n break\n case 'lastmodified':\n Object.assign(obj, { lastModified: Date.parse(child.textContent()) })\n break\n case 'etag':\n Object.assign(obj, { etag: child.textContent() })\n break\n case 'size':\n Object.assign(obj, { size: parseInt(child.textContent()) })\n break\n case 'storageclass':\n Object.assign(obj, { storageClass: child.textContent() })\n }\n })\n\n objects.push(obj as S3Object)\n })\n\n return objects\n }\n /**\n * Retrieves an Object from Amazon S3.\n *\n * To use getObject, you must have `READ` access to the object.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to get.\n * @return {S3Object} - returns the content of the fetched S3 Object.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n getObject(bucketName: string, objectKey: string): S3Object {\n // Prepare request\n const method = 'GET'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(method, host, path, '', body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n\n console.log(`s3 objects response headers: ${JSON.stringify(res.headers, null, ' ')}`)\n\n return new S3Object(\n objectKey,\n Date.parse(res.headers['Last-Modified']),\n res.headers['ETag'],\n parseInt(res.headers['Content-Length']),\n (res.headers['X-Amz-Storage-Class'] ?? 'STANDARD') as StorageClass, // FIXME: GetObject response doesn't contain the storage class\n res.body\n )\n }\n /**\n * Adds an object to a bucket.\n *\n * You must have WRITE permissions on a bucket to add an object to it.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to put.\n * @param {string | ArrayBuffer} data - the content of the S3 Object to upload.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n putObject(bucketName: string, objectKey: string, data: string | ArrayBuffer) {\n // Prepare request\n const method = 'PUT'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const queryString = ''\n const body = data\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n path,\n queryString,\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n }\n\n /**\n * Removes the null version (if there is one) of an object and inserts a delete marker,\n * which becomes the latest version of the object.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to delete.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n deleteObject(bucketName: string, objectKey: string): void {\n // Prepare request\n const method = 'DELETE'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const queryString = ''\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n path,\n queryString,\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error(res.error_code, res.error, res.body as string)\n }\n\n // FIXME: remove dependency to `error_message`\n // FIXME: just pass it the response?\n _handle_error(error_code: number, error_message: string, error_body: string) {\n if (error_message == '' || error_code === 0) {\n return\n }\n\n // FIXME: should be error_code === 1301 instead\n // See: https://github.com/grafana/k6/issues/2474\n // See: https://github.com/golang/go/issues/49281\n if (error_message && error_message.startsWith('301')) {\n // Bucket not found\n throw new S3ServiceError('Resource not found', 'ResourceNotFound', 'getObject')\n }\n\n const awsError = AWSError.parseXML(error_body)\n switch (awsError.code) {\n case 'AuthorizationHeaderMalformed':\n throw new InvalidSignatureError(awsError.message, awsError.code)\n default:\n throw new S3ServiceError(awsError.message, awsError.code, 'listObjects')\n }\n }\n}\n\n// TODO: use interface instead?\n/** Class representing a S3 Bucket */\nexport class S3Bucket {\n name: string\n creationDate: Date\n\n /**\n * Create an S3 Bucket\n *\n * @param {string} name - S3 bucket's name\n * @param {Date} creationDate - S3 bucket's creation date\n */\n constructor(name: string, creationDate: Date) {\n this.name = name\n this.creationDate = creationDate\n }\n}\n\n// TODO: use interface instead?\n/** Class representing an S3 Object */\nexport class S3Object {\n key: string\n lastModified: number\n etag: string\n size: number\n storageClass: StorageClass\n data?: string | bytes | null\n\n /**\n * Create an S3 Object\n *\n * @param {string} key - S3 object's key\n * @param {Date} lastModified - S3 object last modification date\n * @param {string} etag - S3 object's etag\n * @param {number} size - S3 object's size\n * @param {StorageClass} storageClass - S3 object's storage class\n * @param {string | bytes | null} data=null - S3 Object's data\n */\n constructor(\n key: string,\n lastModified: number,\n etag: string,\n size: number,\n storageClass: StorageClass,\n data?: string | bytes | null\n ) {\n this.key = key\n this.lastModified = lastModified\n this.etag = etag\n this.size = size\n this.storageClass = storageClass\n this.data = data\n }\n}\n\n/**\n * Error indicating a S3 operation failed\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class S3ServiceError extends AWSError {\n operation: string\n\n /**\n * Constructs a S3ServiceError\n *\n * @param {string} message - human readable error message\n * @param {string} code - A unique short code representing the error that was emitted\n * @param {string} operation - Name of the failed Operation\n */\n constructor(message: string, code: string, operation: string) {\n super(message, code)\n this.name = 'S3ServiceError'\n this.operation = operation\n }\n}\n\n/**\n * Describes the class of storage used to store a S3 object.\n */\ntype StorageClass =\n | 'STANDARD'\n | 'REDUCED_REDUNDANCY'\n | 'GLACIER'\n | 'STANDARD_IA'\n | 'INTELLIGENT_TIERING'\n | 'DEEP_ARCHIVE'\n | 'OUTPOSTS'\n | 'GLACIER_IR'\n | undefined\n","import { HTTPMethod, HTTPHeaders } from './http'\nimport { AWSConfig } from './config'\nimport { signHeaders, URIEncodingConfig, toTime } from './signature'\n\n/**\n * Class allowing to build requests targeting AWS APIs\n *\n * This class is meant to be used as a base class for specific\n * services clients. See S3Client or SecretsManagerClient for\n * usage examples.\n */\nexport class AWSClient {\n awsConfig: AWSConfig\n serviceName: string\n URIencodingConfig: URIEncodingConfig\n\n /**\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n * @param {string} serviceName - name of the service to target.\n * @param {URIEncodingConfig} URIencodingConfig - configures how requests URIs should be encoded.\n */\n constructor(awsConfig: AWSConfig, serviceName: string, URIencodingConfig: URIEncodingConfig) {\n this.awsConfig = awsConfig\n this.serviceName = serviceName\n this.URIencodingConfig = URIencodingConfig\n }\n\n buildRequest(\n method: HTTPMethod,\n host: string,\n path: string,\n queryString: string,\n body: string | ArrayBuffer,\n headers: HTTPHeaders\n ): AWSRequest {\n const requestTimestamp: number = Date.now()\n const date: string = toTime(requestTimestamp)\n\n headers['Host'] = host\n headers['X-Amz-Date'] = date\n\n headers = signHeaders(\n // headers\n headers,\n\n // requestTimestamp\n requestTimestamp,\n\n // method\n method,\n\n // path\n path,\n\n // querystring\n queryString,\n\n // body\n body,\n\n // AWS configuration\n this.awsConfig,\n\n // AwS target service name\n this.serviceName,\n\n // doubleEncoding: S3 does single-encoding of the uri component\n // pathURIEncoding: S3 manipulates object keys, and forward slashes\n // shouldn't be URI encoded\n this.URIencodingConfig\n )\n\n // '?' should not be part of the querystring when we sign the headers\n path = path !== '' ? path : '/'\n let url = `https://${host}${path}`\n if (queryString !== '') {\n url += `?${queryString}`\n }\n\n return { url: url, headers: headers }\n }\n}\n\n/**\n * Type alias representing the result of an AWSClient.buildRequest call\n */\nexport interface AWSRequest {\n url: string\n headers: HTTPHeaders\n}\n"],"names":["__webpack_require__","module","getter","__esModule","d","a","exports","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","require","AWSError","message","code","name","xmlDocument","doc","parseHTML","find","text","Error","signHeaders","headers","requestTimestamp","method","path","queryString","body","awsConfig","service","URIencodingConfig","derivedSigningKey","secretAccessKey","time","region","kSecret","date","toDate","kDate","hmac","kRegion","kService","deriveSigningKey","canonicalRequest","uri","query","payload","httpRequestMethod","toUpperCase","canonicalURI","length","URIEncode","createCanonicalURI","canonicalQueryString","qs","split","filter","e","map","v","parts","decodeURIComponent","sort","b","localeCompare","parseQueryString","encodeURIComponent","join","createCanonicalQueryString","canonicalHeaders","constructor","entries","values","toLowerCase","trim","Array","isArray","replace","createCanonicalHeaders","signedHeaders","createSignedHeaders","requestPayload","UnsignedPayload","crypto","createCanonicalPayload","createCanonicalRequest","stringToSign","hashedCanonicalRequest","requestDateTime","toTime","credentialScope","createCredentialScope","HashingAlgorithm","createStringToSign","sha256","signature","calculateSignature","authorizationHeader","accessKeyID","InvalidSignatureError","TypeError","keys","letter","c","isNumeric","includes","charCodeAt","toString","URIEncodingConfig","double","this","timestamp","Date","toISOString","substring","AWSConfig","InvalidAWSConfigError","S3Client","host","serviceName","signedRequest","res","http","url","_handle_error","error_code","error","buckets","children","each","_","bucketDefinition","bucket","forEach","child","nodeName","assign","textContent","creationDate","parse","push","bucketName","prefix","querystring","Prefix","objects","objectDefinition","lastModified","etag","size","parseInt","storageClass","objectKey","console","log","JSON","stringify","S3Object","data","error_message","error_body","startsWith","S3ServiceError","awsError","parseXML","now","S3Bucket","operation"],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"s3.min.js","mappings":"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","sources":["webpack://k6-jslib-aws/webpack/bootstrap","webpack://k6-jslib-aws/webpack/runtime/compat get default export","webpack://k6-jslib-aws/webpack/runtime/define property getters","webpack://k6-jslib-aws/webpack/runtime/hasOwnProperty shorthand","webpack://k6-jslib-aws/webpack/runtime/make namespace object","webpack://k6-jslib-aws/external commonjs \"k6/crypto\"","webpack://k6-jslib-aws/external commonjs \"k6/html\"","webpack://k6-jslib-aws/./src/internal/error.ts","webpack://k6-jslib-aws/./src/internal/signature.ts","webpack://k6-jslib-aws/./src/internal/config.ts","webpack://k6-jslib-aws/external commonjs \"k6/http\"","webpack://k6-jslib-aws/./src/internal/s3.ts","webpack://k6-jslib-aws/./src/internal/client.ts"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/crypto\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/html\");","import { parseHTML } from 'k6/html'\n\n/**\n * Base class to derive errors from\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class AWSError extends Error {\n code: string\n\n /**\n * Create an AWSError\n *\n * @param {string} message - A longer human readable error message.\n * @param {string} code - A unique short code representing the error that was emitted\n */\n constructor(message: string, code: string) {\n super(message)\n this.name = 'AWSError'\n this.code = code\n }\n\n /**\n * Parse an AWSError from an XML document\n *\n * @param {string} xmlDocument - Serialized XML document to parse the error from\n */\n static parseXML(xmlDocument: string): AWSError {\n const doc = parseHTML(xmlDocument)\n return new AWSError(doc.find('Message').text(), doc.find('Code').text())\n }\n}\n","import crypto, { hmac, sha256 } from 'k6/crypto'\nimport { HTTPMethod, HTTPHeaders } from './http'\nimport { AWSConfig } from './config'\nimport { AWSError } from './error'\n\n/**\n * Includes AWS v4 signing information to the provided HTTP headers object.\n *\n * This function will compute the `Authorization` header signature for the\n * provided request components, and add it to `header`. It will do so by following\n * the procedure detailled AWS' API docs: https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html\n *\n * The resulting `Authorization` header value is computed for the provided\n * headers object. Thus, any modification of the headers past a call to `signHeaders`\n * would effectively invalidate their signature, and the function should be\n * called again to recompute it.\n *\n * @param {object} headers - HTTP headers request to sign.\n * @param {number} requestTimestamp - Timestamp of the request\n * @param {string} method - HTTP method used\n * @param {string} path - HTTP request URL's path\n * @param {string} queryString - HTTP request URL's querystring\n * @param {string | ArrayBuffer} body - HTTP request's payload\n * @param {AWSConfig} - AWS configuration\n * @param {string} service - AWS service name\n * @param {URIEncodingConfig} - URI encoding configuration\n */\nexport function signHeaders(\n headers: HTTPHeaders,\n requestTimestamp: number,\n method: HTTPMethod,\n path: string,\n queryString: string,\n body: string | ArrayBuffer,\n awsConfig: AWSConfig,\n service: string,\n URIencodingConfig: URIEncodingConfig\n): HTTPHeaders {\n const derivedSigningKey = deriveSigningKey(\n awsConfig.secretAccessKey,\n requestTimestamp,\n awsConfig.region,\n service\n )\n\n const canonicalRequest = createCanonicalRequest(\n method,\n path,\n queryString,\n headers,\n body,\n URIencodingConfig\n )\n\n const stringToSign = createStringToSign(\n requestTimestamp,\n awsConfig.region,\n service,\n sha256(canonicalRequest, 'hex')\n )\n\n const credentialScope = createCredentialScope(requestTimestamp, awsConfig.region, service)\n const signedHeaders = createSignedHeaders(headers)\n const signature = calculateSignature(derivedSigningKey, stringToSign)\n const authorizationHeader = `${HashingAlgorithm} Credential=${awsConfig.accessKeyID}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`\n\n headers['Authorization'] = authorizationHeader\n\n return headers\n}\n\n/**\n * Error indicating an Invalid signature has been sent to AWS services\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class InvalidSignatureError extends AWSError {\n /**\n * Constructs an InvalidSignatureError\n *\n * @param {string} message - human readable error message\n */\n constructor(message: string, code: string) {\n super(message, code)\n this.name = 'InvalidSignatureError'\n }\n}\n\n/**\n * Calculte the signature for AWS signature version 4\n *\n * @param {string} derivedSigningKey - dervied signing key as computed by `deriveSigningKey`\n * @param {string} stringToSign - String to sign as computed by `createStringToSign`\n * @return {string}\n */\nexport function calculateSignature(derivedSigningKey: ArrayBuffer, stringToSign: string): string {\n return hmac('sha256', derivedSigningKey, stringToSign, 'hex')\n}\n/**\n * Derives the signing key for authenticating requests signed with\n * the Signature version 4 authentication protocol.\n *\n * deriveSigningKey produces a signing key by creating a series of\n * hash-based message authentication codes (HMACs) represented in\n * a binary format.\n *\n * The derived signing key is specific to the date it's made at, as well as\n * the service and region it targets.\n *\n * @param {string} secretAccessKey - the AWS secret access key to derive the signing key for\n * @param {number} time - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service. MUST be UTF-8 encoded.\n * @return {string}\n */\nexport function deriveSigningKey(\n secretAccessKey: string,\n time: number,\n region: string,\n service: string\n): ArrayBuffer {\n const kSecret = secretAccessKey\n const date = toDate(time)\n\n // FIXME: hmac takes ArrayBuffer as input, but returns bytes (number[]).\n // How does one convert from one to the other?\n const kDate: any = hmac('sha256', 'AWS4' + kSecret, date, 'binary')\n const kRegion: any = hmac('sha256', kDate, region, 'binary')\n const kService: any = hmac('sha256', kRegion, service, 'binary')\n const kSigning: any = hmac('sha256', kService, 'aws4_request', 'binary')\n\n return kSigning\n}\n\n// Hashing Algorithm to use in the signature process\nexport const HashingAlgorithm = 'AWS4-HMAC-SHA256'\n\n/**\n * Certain services, such as S3, allow for unsigned payloads. If\n * producing a signed canonical request for such service, pass\n * the `UnsignedPayload` constant value as the payload parameter.\n */\nexport const UnsignedPayload = 'UNSIGNED-PAYLOAD'\n\n/**\n * Create the \"string to sign\" part of the signature Version 4 protocol.\n *\n * The \"string to sign\" includes meta information about your request and\n * about the canonical request that you created with `createCanonicalRequest`.\n * It is used hand in hand with the signing key to create the request signature.\n *\n * @param {number} requestTimestamp - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service name. MUST be UTF-8 encoded.\n * @param {string} hashedCanonicalRequest - canonical request as produced by calling the createCanonicalRequest function,\n * hashed using the SHA256 algorithm (encoded in hexadecimal format).\n * @return {string}\n */\nexport function createStringToSign(\n requestTimestamp: number,\n region: string,\n service: string,\n hashedCanonicalRequest: string\n): string {\n // the request date specified in ISO8601 format: YYYYMMDD'T'HHMMSS'Z'\n const requestDateTime = toTime(requestTimestamp)\n\n // The credential scope value, consisting of the date in YYYYMMDD format,\n // the targeted region, the targeted service, and a termination string.\n // Note that the region and service MUST be UTF-8 encoded.\n const credentialScope = createCredentialScope(requestTimestamp, region, service)\n\n const stringToSign = [\n // Algorithm\n HashingAlgorithm,\n\n // RequestDateTime\n requestDateTime,\n\n // CredentialScope\n credentialScope,\n\n // HashedCanonicalRequest\n hashedCanonicalRequest,\n ].join('\\n')\n\n return stringToSign\n}\n\n/**\n *\n * Helper function creating a credential scope string to use in the signature\n * version 4 process. A credential scope consists of the date of the request\n * in YYYYMMDD format, the targeted region, the targeted service, and a\n * termination string.\n *\n * Note that the region and service MUST be UTF-8 encoded.\n *\n * @param {number} requestTimestamp - timestamp of the request\n * @param {string} region - targeted AWS region. MUST be UTF-8 encoded.\n * @param {string} service - targeted AWS service name. MUST be UTF-8 encoded.\n * @return {string}\n */\nexport function createCredentialScope(\n requestTimestamp: number,\n region: string,\n service: string\n): string {\n return [toDate(requestTimestamp), region, service, 'aws4_request'].join('/')\n}\n\n/**\n * Create a string that includes information from your request\n * in a AWS signature v4 standardized (canonical) format.\n *\n * @param {string} method - the HTTP request method\n * @param {string} uri - URI-encoded version of the absolute path component of the URI\n * @param {string} query - request's query string\n * @param {Object} headers - all the HTTP headers that you wish to include with the signed request\n * @param {string | ArrayBuffer} payload - payload to include as the body of the request\n * @param {URIEncodingConfig} URIencodingConfig- URI encoding configuration\n * @return {string}\n */\nexport function createCanonicalRequest(\n method: HTTPMethod,\n uri: string,\n query: string,\n headers: HTTPHeaders,\n payload: string | ArrayBuffer,\n URIencodingConfig: URIEncodingConfig\n): string {\n const httpRequestMethod = method.toUpperCase()\n const canonicalURI = createCanonicalURI(uri, URIencodingConfig)\n const canonicalQueryString = createCanonicalQueryString(query)\n const canonicalHeaders = createCanonicalHeaders(headers)\n const signedHeaders = createSignedHeaders(headers)\n const requestPayload = createCanonicalPayload(payload)\n\n const canonicalRequest = [\n httpRequestMethod,\n canonicalURI,\n canonicalQueryString,\n canonicalHeaders,\n signedHeaders,\n requestPayload,\n ].join('\\n')\n\n return canonicalRequest\n}\n\n/**\n * Creates the (canonical) URI-encoded version of the\n * absolute path component of the URI: everything in the URI\n * from the HTTP host to the question mark character (\"?\")\n * that begins the query string parameters (if any).\n *\n * @param {string} uri - URI to canonize\n * @param {URIEncodingConfig} - URI encoding configuration\n * @return {string} - canonical URL\n */\nexport function createCanonicalURI(uri: string, URIencodingConfig: URIEncodingConfig): string {\n if (uri == '/') {\n return uri\n }\n\n let canonicalURI = uri\n if (uri[uri.length - 1] == '/' && canonicalURI[canonicalURI.length - 1] != '/') {\n canonicalURI += '/'\n }\n\n canonicalURI = URIEncode(canonicalURI, URIencodingConfig.path)\n\n return URIencodingConfig.double ? URIEncode(canonicalURI, URIencodingConfig.path) : canonicalURI\n}\n\n// FIXME: does it work as expected?\n/**\n * Creates the canonical form of the request's query\n * string. If the request does not include a query string,\n * provide an empty string.\n *\n * @param {String | Object} qs - query string to canonize\n * @return {string}\n */\nexport function createCanonicalQueryString(qs: string): string {\n if (qs === '') {\n return ''\n }\n\n // const intermediary: { [key: string]: string } = parseQueryString(qs)\n\n // return Object.keys(intermediary)\n // .sort()\n // .map((key: string) => {\n // // const values: string[] = Array.isArray(intermediary[key])\n // // ? intermediary[key]\n // // : [intermediary[key]]\n // const values = intermediary[key]\n\n // return values\n // .sort()\n // .map((val: string) => encodeURIComponent(key) + '=' + encodeURIComponent(val))\n // .join('&')\n // })\n // .join('&')\n\n return parseQueryString(qs)\n .map(([key, value]: [string, string]): string => {\n return encodeURIComponent(key) + '=' + encodeURIComponent(value)\n })\n .join('&')\n}\n/**\n * Create the canonical form of the request's headers.\n * Canonical headers consist of all the HTTP headers you\n * are including with the signed request.\n *\n * Note that:\n * * for HTTP/1.1 requests, the headers should at least\n * contain the `host` header.\n * * for HTTP/2, the `:authority` header must be used instead\n * of `host`.\n *\n * @param {Object} headers\n * @return {string}\n */\nexport function createCanonicalHeaders(headers: HTTPHeaders) {\n if (headers.constructor !== Object || Object.entries(headers).length === 0) {\n return ''\n }\n\n const canonicalHeaders = Object.entries(headers)\n .map(([name, values]) => {\n const canonicalName = name.toLowerCase().trim()\n const normalizedValues = Array.isArray(values) ? values : [values]\n\n // Note that we do not need to sort values\n const canonicalValues = normalizedValues\n .map((v) => {\n // convert sequential spaces to a single space\n return v.replace(/\\s+/g, ' ').replace(/^\\s+|\\s+$/g, '')\n })\n .join(',') // standard for multiple values in a HTTP header\n\n return canonicalName + ':' + canonicalValues + '\\n'\n })\n .sort()\n .join('')\n\n return canonicalHeaders\n}\n\n/**\n * Create the canonical request's signed headers.\n *\n * The signed headers part of the request contains the\n * list of headers included in the request's signing process.\n *\n * Note that:\n * * for HTTP/1.1 requests, the `host` header must be included.\n * * for HTTP/2 requests, the `:authority` header must be included instead\n * of host.\n * * if used, the `x-amz-date` header must be included.\n *\n * @param {Object} headers\n * @return {string}\n * @throws {TypeError} - on headers not being an Object, or being empty.\n */\nexport function createSignedHeaders(headers: { [key: string]: string }) {\n if (headers.constructor !== Object) {\n throw new TypeError('headers should be an object')\n }\n\n if (Object.entries(headers).length === 0) {\n throw 'headers should at least contain either the Host (HTTP 1.1) or :authority (HTTP 2) parameter'\n }\n\n // To create the signed headers list, convert\n // all header names to lowercase, sort them by\n // character code, and use a semicolon to separate\n // the header names.\n const result = Object.keys(headers)\n .map((name) => name.toLowerCase().trim())\n .sort()\n .join(';')\n\n return result\n}\n\n/**\n * Create the canonical form of the request's payload.\n *\n * The canonical payload consists in a lowercased, hex encoded,\n * SHA256 hash of the requests body/payload.\n *\n * Certain services, such as S3, allow for unsigned payload. If\n * producing a signed canonical request for such service, pass\n * the `UnsignedPayload` constant value as the payload parameter.\n *\n * @param {String | ArrayBuffer} payload\n * @return {string}\n */\nexport function createCanonicalPayload(payload: string | ArrayBuffer) {\n if (payload === UnsignedPayload) {\n return payload\n }\n\n // Note that if the paylaod is null, we convert it\n // to an empty string.\n // TODO: Should switching to empty string if null impact headers?\n return crypto.sha256(payload || '', 'hex').toLowerCase()\n}\n\n/**\n * URIEncodes encodes every bytes of a URI to be URL-safe.\n *\n * This implementation is specific to AWS; who intended to make it as\n * close as possible to the underlying RFC 3946. It:\n * * URI encode every byte except the unreserved characters: 'A'-'Z', 'a'-'z', '0'-'9',\n * '-', '.', '_', and '~'.\n * * considers the space character as a reserved character and must URI encodes\n * encodes it as \"%20\" (and not as \"+\").\n * * URI encodes every byte by prefixing with '%' the two-digit hexadecimal value of the byte.\n * * If the `path` argument is set, forward slashes are not encoded, to fit with\n * S3 requirements.\n *\n * N.B: this implementation differs with ES6' mainly in that it does\n * encode the \"'\" character.\n *\n * Based on AWS implementation: https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-core/src/main/java/com/amazonaws/util/SdkHttpUtils.java#L66\n * Encoding specs: https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html\n *\n * @param {string} uri - uri to encode\n * @param {boolean} path - slash characters should be encoded everywhere,\n * but in paths, set to false when encoding a path\n * @return {string} the URI encoded result\n */\nexport function URIEncode(uri: string, path: boolean): string {\n if (uri == '') {\n return uri\n }\n\n return uri\n .split('') // to be able to map over a string, because... javascript...\n .map((letter: string) => {\n if (isAlpha(letter) || isNumeric(letter) || '-._~'.includes(letter)) {\n return letter\n }\n\n // Space should be explicitly encoded to as %20.\n if (letter == ' ') {\n return '%20'\n }\n\n // If the URI is a path, the forward slash shouldn't\n // be encoded.\n if (letter == '/' && path) {\n return '/'\n }\n\n return '%' + letter.charCodeAt(0).toString(16).toUpperCase()\n })\n .join('')\n}\n\n/**\n * Class holding URI encoding configuration\n */\nexport class URIEncodingConfig {\n double: boolean\n path: boolean\n\n /**\n *\n * @param {boolean} double - should the URI be double encoded?\n * @param {boolean} path - is the URI a path? If so, its forward\n * slashes won't be URIencoded.\n */\n constructor(double: boolean, path: boolean) {\n this.double = double\n this.path = path\n }\n}\n\n/**\n * Compute the request time value as specified by the ISO8601\n * format: YYYYMMDD'T'HHMMSS'Z'\n *\n * @param {number} timestamp\n * @return {string}\n */\nexport function toTime(timestamp: number): string {\n return new Date(timestamp).toISOString().replace(/[:\\-]|\\.\\d{3}/g, '')\n}\n/**\n * Computethe request date value in the format: YYYMMDD\n *\n * @param {number} timestamp\n * @return {string}\n */\nexport function toDate(timestamp: number): string {\n return toTime(timestamp).substring(0, 8)\n}\n\n// FIXME: does it work as expected?\n/**\n * Parse a HTTP request URL's querystring into an object\n * containing its `key=value` pairs.\n *\n * @param {string} qs\n * @return {object}\n */\nexport function parseQueryString(qs: string): Array<[string, string]> {\n if (qs.length === 0) {\n return []\n }\n\n return qs\n .split('&')\n .filter((e) => e)\n .map((v: string): [string, string] => {\n const parts = v.split('=', 2) as [string, string]\n return [decodeURIComponent(parts[0]), decodeURIComponent(parts[1])]\n })\n .sort((a: [string, string], b: [string, string]) => {\n return a[0].localeCompare(b[0])\n })\n}\n\nfunction isAlpha(c: string): boolean {\n return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')\n}\n\nfunction isNumeric(c: string): boolean {\n return c >= '0' && c <= '9'\n}\n\n// FIXME: finish implementation when needed\n// See the following for more details:\n// * https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html\n// * https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html\n// export function signQueryString(\n// queryString,\n// requestTimestamp,\n// accessKeyID,\n// secretAccessKey,\n// region,\n// service,\n// ttl, // in seconds\n// headers,\n// doubleURIEncoding = true\n// ) {\n// const credential = [accessKeyID, toDate(requestTimestamp), region, service].join('/')\n//\n// const canonicalRequest = createCanonicalRequest(\n// method,\n// path,\n// queryString,\n// headers,\n// body,\n// doubleURIEncoding\n// )\n//\n// const derivedSigningKey = deriveSigningKey(secretAccessKey, requestTimestamp, region, service)\n//\n// const stringToSign = createStringToSign(\n// requestTimestamp,\n// region,\n// service,\n// sha256(canonicalRequest, 'hex')\n// )\n//\n// const signedHeaders = createSignedHeaders(headers)\n// const signature = calculateSignature(derivedSigningKey, stringToSign)\n//\n// return [\n// `X-Amz-Algorithm=${HashingAlgorithm}`,\n// `X-Amz-Credential=${crediental}`,\n// `X-Amz-Date=${toTime(requestTimestamp)}`,\n// `X-Amz-Expires=${ttl}`,\n// `X-Amz-SignedHeaders=${signedHeaders}`,\n// `X-Amz-Signature=${signature}`,\n//`X-Amz-Security-Token=`, // TODO: optional\n// ].join('&')\n// }\n","/** Class holding an AWS connection information */\nexport class AWSConfig {\n region: string\n accessKeyID: string\n secretAccessKey: string\n\n /**\n * Create an AWSConfig.\n *\n * @param {string} region - the AWS region to connect to, as listed: https://docs.aws.amazon.com/general/latest/gr/rande.html\n * @param {string} accessKeyID - Your user's AWS access key id credential\n * @param {string} secretAccessKey - Your user's AWS secret access key credential\n * @throws {InvalidArgumentException}\n */\n constructor(region: string, accessKeyID: string, secretAccessKey: string) {\n if (typeof region !== 'string' || region === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS region; reason: should be a non empty string'\n )\n }\n\n if (typeof accessKeyID !== 'string' || accessKeyID === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS access key ID; reason: should be a non empty string'\n )\n }\n\n if (typeof secretAccessKey !== 'string' || secretAccessKey === '') {\n throw new InvalidAWSConfigError(\n 'invalid AWS secret access key; reason: should be a non empty string'\n )\n }\n\n this.region = region\n this.accessKeyID = accessKeyID\n this.secretAccessKey = secretAccessKey\n }\n}\n\n/** Class representing an invalid AWS configuration */\nexport class InvalidAWSConfigError extends Error {\n constructor(message: string) {\n super(message)\n }\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"k6/http\");","import { bytes } from 'k6'\nimport http, { RefinedResponse, ResponseType } from 'k6/http'\nimport { parseHTML } from 'k6/html'\nimport { sha256 } from 'k6/crypto'\n\nimport { InvalidSignatureError, URIEncodingConfig } from './signature'\nimport { AWSClient, AWSRequest } from './client'\nimport { AWSError } from './error'\nimport { AWSConfig } from './config'\n\n/** Class allowing to interact with Amazon AWS's S3 service */\nexport class S3Client extends AWSClient {\n /**\n * Create a S3Client\n *\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n */\n constructor(awsConfig: AWSConfig) {\n const URIencodingConfig = new URIEncodingConfig(false, true)\n super(awsConfig, 's3', URIencodingConfig)\n }\n\n /**\n * Returns a list of all buckets owned by the authenticated sender of the request.\n * To use this operation, you must have the s3:ListAllMyBuckets permission.\n *\n * @return {Array.} buckets - An array of objects describing S3 buckets\n * with the following fields: name, and creationDate.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n listBuckets(): Array {\n // Prepare request\n const method = 'GET'\n const host = `${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(method, host, '/', '', body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('ListBuckets', res)\n\n let buckets: Array = []\n\n const doc = parseHTML(res.body as string)\n\n doc.find('Buckets')\n .children()\n .each((_, bucketDefinition) => {\n let bucket = {}\n\n bucketDefinition.children().forEach((child) => {\n switch (child.nodeName()) {\n case 'name':\n Object.assign(bucket, { name: child.textContent() })\n break\n case 'creationdate':\n Object.assign(bucket, {\n creationDate: Date.parse(child.textContent()),\n })\n }\n })\n\n buckets.push(bucket as S3Bucket)\n })\n\n return buckets\n }\n\n /**\n * Returns some or all (up to 1,000) of the objects in a bucket.\n *\n * @param {string} bucketName - Bucket name to list.\n * @param {string?} prefix='' - Limits the response to keys that begin with the specified prefix.\n * @return {Array.} - returns an array of objects describing S3 objects\n * with the following fields: key, lastModified, etag, size and storageClass.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n listObjects(bucketName: string, prefix?: string): Array {\n // Prepare request\n const method = 'GET'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const body = ''\n const querystring = `list-type=2&prefix=${prefix}`\n const signedRequest: AWSRequest = super.buildRequest(method, host, '/', querystring, body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n Prefix: prefix ?? '',\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('ListObjectsV2', res)\n\n let objects: Array = []\n\n // Extract the objects definition from\n // the XML response\n parseHTML(res.body as string)\n .find('Contents')\n .each((_, objectDefinition) => {\n let obj = {}\n\n objectDefinition.children().forEach((child) => {\n switch (child.nodeName()) {\n case 'key':\n Object.assign(obj, { key: child.textContent() })\n break\n case 'lastmodified':\n Object.assign(obj, { lastModified: Date.parse(child.textContent()) })\n break\n case 'etag':\n Object.assign(obj, { etag: child.textContent() })\n break\n case 'size':\n Object.assign(obj, { size: parseInt(child.textContent()) })\n break\n case 'storageclass':\n Object.assign(obj, { storageClass: child.textContent() })\n }\n })\n\n objects.push(obj as S3Object)\n })\n\n return objects\n }\n /**\n * Retrieves an Object from Amazon S3.\n *\n * To use getObject, you must have `READ` access to the object.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to get.\n * @return {S3Object} - returns the content of the fetched S3 Object.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n getObject(bucketName: string, objectKey: string): S3Object {\n // Prepare request\n const method = 'GET'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(method, host, path, '', body, {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n })\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('GetObject', res)\n\n return new S3Object(\n objectKey,\n Date.parse(res.headers['Last-Modified']),\n res.headers['ETag'],\n parseInt(res.headers['Content-Length']),\n\n // The X-Amz-Storage-Class header is only set if the storage class is\n // not the default 'STANDARD' one.\n (res.headers['X-Amz-Storage-Class'] ?? 'STANDARD') as StorageClass,\n\n res.body\n )\n }\n /**\n * Adds an object to a bucket.\n *\n * You must have WRITE permissions on a bucket to add an object to it.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to put.\n * @param {string | ArrayBuffer} data - the content of the S3 Object to upload.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n putObject(bucketName: string, objectKey: string, data: string | ArrayBuffer) {\n // Prepare request\n const method = 'PUT'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const queryString = ''\n const body = data\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n path,\n queryString,\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('PutObject', res)\n }\n\n /**\n * Removes the null version (if there is one) of an object and inserts a delete marker,\n * which becomes the latest version of the object.\n *\n * @param {string} bucketName - The bucket name containing the object.\n * @param {string} objectKey - Key of the object to delete.\n * @throws {S3ServiceError}\n * @throws {InvalidSignatureError}\n */\n deleteObject(bucketName: string, objectKey: string): void {\n // Prepare request\n const method = 'DELETE'\n const host = `${bucketName}.${this.serviceName}.${this.awsConfig.region}.amazonaws.com`\n const path = `/${objectKey}`\n const queryString = ''\n const body = ''\n const signedRequest: AWSRequest = super.buildRequest(\n method,\n host,\n path,\n queryString,\n body,\n {\n 'X-Amz-Content-SHA256': sha256(body, 'hex'),\n }\n )\n\n const res = http.request(method, signedRequest.url, body, {\n headers: signedRequest.headers,\n })\n this._handle_error('DeleteObject', res)\n }\n\n _handle_error(operation: S3Operation, response: RefinedResponse) {\n const errorCode: number = response.error_code\n const errorMessage: string = response.error\n\n if (errorMessage == '' || errorCode === 0) {\n return\n }\n\n // FIXME: should be errorCode === 1301 instead\n // See: https://github.com/grafana/k6/issues/2474\n // See: https://github.com/golang/go/issues/49281\n if (errorMessage && errorMessage.startsWith('301')) {\n throw new S3ServiceError('Resource not found', 'ResourceNotFound', operation)\n }\n\n const awsError = AWSError.parseXML(response.body as string)\n switch (awsError.code) {\n case 'AuthorizationHeaderMalformed':\n throw new InvalidSignatureError(awsError.message, awsError.code)\n default:\n throw new S3ServiceError(awsError.message, awsError.code, operation)\n }\n }\n}\n\n/** Class representing a S3 Bucket */\nexport class S3Bucket {\n name: string\n creationDate: Date\n\n /**\n * Create an S3 Bucket\n *\n * @param {string} name - S3 bucket's name\n * @param {Date} creationDate - S3 bucket's creation date\n */\n constructor(name: string, creationDate: Date) {\n this.name = name\n this.creationDate = creationDate\n }\n}\n\n/** Class representing an S3 Object */\nexport class S3Object {\n key: string\n lastModified: number\n etag: string\n size: number\n storageClass: StorageClass\n data?: string | bytes | null\n\n /**\n * Create an S3 Object\n *\n * @param {string} key - S3 object's key\n * @param {Date} lastModified - S3 object last modification date\n * @param {string} etag - S3 object's etag\n * @param {number} size - S3 object's size\n * @param {StorageClass} storageClass - S3 object's storage class\n * @param {string | bytes | null} data=null - S3 Object's data\n */\n constructor(\n key: string,\n lastModified: number,\n etag: string,\n size: number,\n storageClass: StorageClass,\n data?: string | bytes | null\n ) {\n this.key = key\n this.lastModified = lastModified\n this.etag = etag\n this.size = size\n this.storageClass = storageClass\n this.data = data\n }\n}\n\n/**\n * Error indicating a S3 operation failed\n *\n * Inspired from AWS official error types, as\n * described in:\n * * https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/\n * * https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts\n */\nexport class S3ServiceError extends AWSError {\n operation: string\n\n /**\n * Constructs a S3ServiceError\n *\n * @param {string} message - human readable error message\n * @param {string} code - A unique short code representing the error that was emitted\n * @param {string} operation - Name of the failed Operation\n */\n constructor(message: string, code: string, operation: string) {\n super(message, code)\n this.name = 'S3ServiceError'\n this.operation = operation\n }\n}\n\n/**\n * S3Operation describes possible values for S3 API operations,\n * as defined by AWS APIs.\n */\ntype S3Operation = 'ListBuckets' | 'ListObjectsV2' | 'GetObject' | 'PutObject' | 'DeleteObject'\n\n/**\n * Describes the class of storage used to store a S3 object.\n */\ntype StorageClass =\n | 'STANDARD'\n | 'REDUCED_REDUNDANCY'\n | 'GLACIER'\n | 'STANDARD_IA'\n | 'INTELLIGENT_TIERING'\n | 'DEEP_ARCHIVE'\n | 'OUTPOSTS'\n | 'GLACIER_IR'\n | undefined\n","import { HTTPMethod, HTTPHeaders } from './http'\nimport { AWSConfig } from './config'\nimport { signHeaders, URIEncodingConfig, toTime } from './signature'\n\n/**\n * Class allowing to build requests targeting AWS APIs\n *\n * This class is meant to be used as a base class for specific\n * services clients. See S3Client or SecretsManagerClient for\n * usage examples.\n */\nexport class AWSClient {\n awsConfig: AWSConfig\n serviceName: string\n URIencodingConfig: URIEncodingConfig\n\n /**\n * @param {AWSConfig} awsConfig - configuration attributes to use when interacting with AWS' APIs\n * @param {string} serviceName - name of the service to target.\n * @param {URIEncodingConfig} URIencodingConfig - configures how requests URIs should be encoded.\n */\n constructor(awsConfig: AWSConfig, serviceName: string, URIencodingConfig: URIEncodingConfig) {\n this.awsConfig = awsConfig\n this.serviceName = serviceName\n this.URIencodingConfig = URIencodingConfig\n }\n\n buildRequest(\n method: HTTPMethod,\n host: string,\n path: string,\n queryString: string,\n body: string | ArrayBuffer,\n headers: HTTPHeaders\n ): AWSRequest {\n const requestTimestamp: number = Date.now()\n const date: string = toTime(requestTimestamp)\n\n headers['Host'] = host\n headers['X-Amz-Date'] = date\n\n headers = signHeaders(\n // headers\n headers,\n\n // requestTimestamp\n requestTimestamp,\n\n // method\n method,\n\n // path\n path,\n\n // querystring\n queryString,\n\n // body\n body,\n\n // AWS configuration\n this.awsConfig,\n\n // AwS target service name\n this.serviceName,\n\n // doubleEncoding: S3 does single-encoding of the uri component\n // pathURIEncoding: S3 manipulates object keys, and forward slashes\n // shouldn't be URI encoded\n this.URIencodingConfig\n )\n\n // '?' should not be part of the querystring when we sign the headers\n path = path !== '' ? path : '/'\n let url = `https://${host}${path}`\n if (queryString !== '') {\n url += `?${queryString}`\n }\n\n return { url: url, headers: headers }\n }\n}\n\n/**\n * Type alias representing the result of an AWSClient.buildRequest call\n */\nexport interface AWSRequest {\n url: string\n headers: HTTPHeaders\n}\n"],"names":["__webpack_require__","module","getter","__esModule","d","a","exports","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","require","AWSError","message","code","name","xmlDocument","doc","parseHTML","find","text","Error","signHeaders","headers","requestTimestamp","method","path","queryString","body","awsConfig","service","URIencodingConfig","derivedSigningKey","secretAccessKey","time","region","kSecret","date","toDate","kDate","hmac","kRegion","kService","deriveSigningKey","canonicalRequest","uri","query","payload","httpRequestMethod","toUpperCase","canonicalURI","length","URIEncode","createCanonicalURI","canonicalQueryString","qs","split","filter","e","map","v","parts","decodeURIComponent","sort","b","localeCompare","parseQueryString","encodeURIComponent","join","createCanonicalQueryString","canonicalHeaders","constructor","entries","values","toLowerCase","trim","Array","isArray","replace","createCanonicalHeaders","signedHeaders","createSignedHeaders","requestPayload","UnsignedPayload","crypto","createCanonicalPayload","createCanonicalRequest","stringToSign","hashedCanonicalRequest","requestDateTime","toTime","credentialScope","createCredentialScope","HashingAlgorithm","createStringToSign","sha256","signature","calculateSignature","authorizationHeader","accessKeyID","InvalidSignatureError","TypeError","keys","letter","c","isNumeric","includes","charCodeAt","toString","URIEncodingConfig","double","this","timestamp","Date","toISOString","substring","AWSConfig","InvalidAWSConfigError","S3Client","host","serviceName","signedRequest","res","http","url","_handle_error","buckets","children","each","_","bucketDefinition","bucket","forEach","child","nodeName","assign","textContent","creationDate","parse","push","bucketName","prefix","querystring","Prefix","objects","objectDefinition","lastModified","etag","size","parseInt","storageClass","objectKey","S3Object","data","operation","response","errorCode","error_code","errorMessage","error","startsWith","S3ServiceError","awsError","parseXML","now","S3Bucket"],"sourceRoot":""} \ No newline at end of file diff --git a/src/internal/s3.ts b/src/internal/s3.ts index aa55dba..434bc8a 100644 --- a/src/internal/s3.ts +++ b/src/internal/s3.ts @@ -1,5 +1,5 @@ import { bytes } from 'k6' -import http from 'k6/http' +import http, { RefinedResponse, ResponseType } from 'k6/http' import { parseHTML } from 'k6/html' import { sha256 } from 'k6/crypto' @@ -41,7 +41,7 @@ export class S3Client extends AWSClient { const res = http.request(method, signedRequest.url, body, { headers: signedRequest.headers, }) - this._handle_error(res.error_code, res.error, res.body as string) + this._handle_error('ListBuckets', res) let buckets: Array = [] @@ -94,7 +94,7 @@ export class S3Client extends AWSClient { const res = http.request(method, signedRequest.url, body, { headers: signedRequest.headers, }) - this._handle_error(res.error_code, res.error, res.body as string) + this._handle_error('ListObjectsV2', res) let objects: Array = [] @@ -157,7 +157,7 @@ export class S3Client extends AWSClient { const res = http.request(method, signedRequest.url, body, { headers: signedRequest.headers, }) - this._handle_error(res.error_code, res.error, res.body as string) + this._handle_error('GetObject', res) return new S3Object( objectKey, @@ -204,7 +204,7 @@ export class S3Client extends AWSClient { const res = http.request(method, signedRequest.url, body, { headers: signedRequest.headers, }) - this._handle_error(res.error_code, res.error, res.body as string) + this._handle_error('PutObject', res) } /** @@ -237,35 +237,34 @@ export class S3Client extends AWSClient { const res = http.request(method, signedRequest.url, body, { headers: signedRequest.headers, }) - this._handle_error(res.error_code, res.error, res.body as string) + this._handle_error('DeleteObject', res) } - // FIXME: remove dependency to `error_message` - // FIXME: just pass it the response? - _handle_error(error_code: number, error_message: string, error_body: string) { - if (error_message == '' || error_code === 0) { + _handle_error(operation: S3Operation, response: RefinedResponse) { + const errorCode: number = response.error_code + const errorMessage: string = response.error + + if (errorMessage == '' || errorCode === 0) { return } - // FIXME: should be error_code === 1301 instead + // FIXME: should be errorCode === 1301 instead // See: https://github.com/grafana/k6/issues/2474 // See: https://github.com/golang/go/issues/49281 - if (error_message && error_message.startsWith('301')) { - // Bucket not found - throw new S3ServiceError('Resource not found', 'ResourceNotFound', 'getObject') + if (errorMessage && errorMessage.startsWith('301')) { + throw new S3ServiceError('Resource not found', 'ResourceNotFound', operation) } - const awsError = AWSError.parseXML(error_body) + const awsError = AWSError.parseXML(response.body as string) switch (awsError.code) { case 'AuthorizationHeaderMalformed': throw new InvalidSignatureError(awsError.message, awsError.code) default: - throw new S3ServiceError(awsError.message, awsError.code, 'listObjects') + throw new S3ServiceError(awsError.message, awsError.code, operation) } } } -// TODO: use interface instead? /** Class representing a S3 Bucket */ export class S3Bucket { name: string @@ -283,7 +282,6 @@ export class S3Bucket { } } -// TODO: use interface instead? /** Class representing an S3 Object */ export class S3Object { key: string @@ -345,6 +343,12 @@ export class S3ServiceError extends AWSError { } } +/** + * S3Operation describes possible values for S3 API operations, + * as defined by AWS APIs. + */ +type S3Operation = 'ListBuckets' | 'ListObjectsV2' | 'GetObject' | 'PutObject' | 'DeleteObject' + /** * Describes the class of storage used to store a S3 object. */ From df3a92d483d83639f71366518e4f3f3dda1d5868 Mon Sep 17 00:00:00 2001 From: oleiade Date: Mon, 25 Apr 2022 14:23:12 +0200 Subject: [PATCH 4/7] cleanup! --- src/internal/s3.ts | 4 ---- src/internal/signature.ts | 2 -- 2 files changed, 6 deletions(-) diff --git a/src/internal/s3.ts b/src/internal/s3.ts index 434bc8a..b7bbaf1 100644 --- a/src/internal/s3.ts +++ b/src/internal/s3.ts @@ -111,10 +111,6 @@ export class S3Client extends AWSClient { Object.assign(obj, { key: child.textContent() }) break case 'lastmodified': - // const parsed = Date.parse( - // child.textContent(), - // 'YYYY-MM-ddTHH:mm:ss.sssZ' - // ) Object.assign(obj, { lastModified: Date.parse(child.textContent()) }) break case 'etag': diff --git a/src/internal/signature.ts b/src/internal/signature.ts index 65827e2..14ad6fe 100644 --- a/src/internal/signature.ts +++ b/src/internal/signature.ts @@ -276,7 +276,6 @@ export function createCanonicalURI(uri: string, URIencodingConfig: URIEncodingCo return URIencodingConfig.double ? URIEncode(canonicalURI, URIencodingConfig.path) : canonicalURI } -// FIXME: does it work as expected? /** * Creates the canonical form of the request's query * string. If the request does not include a query string, @@ -505,7 +504,6 @@ export function toDate(timestamp: number): string { return toTime(timestamp).substring(0, 8) } -// FIXME: does it work as expected? /** * Parse a HTTP request URL's querystring into an object * containing its `key=value` pairs. From 0e1ecece5c5155bb2cf6b96dfde43ad86d009dfd Mon Sep 17 00:00:00 2001 From: oleiade Date: Mon, 25 Apr 2022 14:37:39 +0200 Subject: [PATCH 5/7] Rename SecretsManagerError to SecretsManagerServiceError --- src/index.ts | 8 ++++++-- src/internal/secrets-manager.ts | 8 ++++---- src/secrets-manager.ts | 8 ++++++-- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/index.ts b/src/index.ts index 8e98c1f..f0e3187 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,7 +2,11 @@ import { signHeaders, InvalidSignatureError, URIEncodingConfig } from './internal/signature' import { AWSConfig, InvalidAWSConfigError } from './internal/config' import { S3Client, S3Bucket, S3Object, S3ServiceError } from './internal/s3' -import { SecretsManagerClient, Secret, SecretsManagerError } from './internal/secrets-manager' +import { + SecretsManagerClient, + Secret, + SecretsManagerServiceError, +} from './internal/secrets-manager' // Re-Export public symbols export { @@ -21,5 +25,5 @@ export { // SecretsManager SecretsManagerClient, Secret, - SecretsManagerError, + SecretsManagerServiceError, } diff --git a/src/internal/secrets-manager.ts b/src/internal/secrets-manager.ts index b7dbe45..cd2c978 100644 --- a/src/internal/secrets-manager.ts +++ b/src/internal/secrets-manager.ts @@ -276,11 +276,11 @@ export class SecretsManagerClient extends AWSClient { } // Otherwise throw a standard service error - throw new SecretsManagerError(errorMessage, error.__type as string, operation) + throw new SecretsManagerServiceError(errorMessage, error.__type as string, operation) } if (errorCode === 1500) { - throw new SecretsManagerError( + throw new SecretsManagerServiceError( 'An error occured on the server side', 'InternalServiceError', operation @@ -353,11 +353,11 @@ export class Secret { } } -export class SecretsManagerError extends AWSError { +export class SecretsManagerServiceError extends AWSError { operation: string /** - * Constructs a SecretsManagerError + * Constructs a SecretsManagerServiceError * * @param {string} message - human readable error message * @param {string} code - A unique short code representing the error that was emitted diff --git a/src/secrets-manager.ts b/src/secrets-manager.ts index 1db9b9b..04327f9 100644 --- a/src/secrets-manager.ts +++ b/src/secrets-manager.ts @@ -1,7 +1,11 @@ // Import only symbols we wish to re-export publicly import { signHeaders, InvalidSignatureError, URIEncodingConfig } from './internal/signature' import { AWSConfig, InvalidAWSConfigError } from './internal/config' -import { SecretsManagerClient, Secret, SecretsManagerError } from './internal/secrets-manager' +import { + SecretsManagerClient, + Secret, + SecretsManagerServiceError, +} from './internal/secrets-manager' // Re-Export public symbols export { @@ -15,5 +19,5 @@ export { // SecretsManager SecretsManagerClient, Secret, - SecretsManagerError, + SecretsManagerServiceError, } From 37b30c73d57e2945c834555f4e49eb19d08b1146 Mon Sep 17 00:00:00 2001 From: oleiade Date: Mon, 25 Apr 2022 14:38:22 +0200 Subject: [PATCH 6/7] Adjust AWSConfig constructor's to typescript --- src/internal/config.ts | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/internal/config.ts b/src/internal/config.ts index 24d0edd..faf4c48 100644 --- a/src/internal/config.ts +++ b/src/internal/config.ts @@ -13,24 +13,36 @@ export class AWSConfig { * @throws {InvalidArgumentException} */ constructor(region: string, accessKeyID: string, secretAccessKey: string) { - if (typeof region !== 'string' || region === '') { + if (region === '') { throw new InvalidAWSConfigError( 'invalid AWS region; reason: should be a non empty string' ) } - if (typeof accessKeyID !== 'string' || accessKeyID === '') { + if (accessKeyID === '') { throw new InvalidAWSConfigError( 'invalid AWS access key ID; reason: should be a non empty string' ) } - if (typeof secretAccessKey !== 'string' || secretAccessKey === '') { + if (accessKeyID.length < 16 || accessKeyID.length > 128) { + throw new InvalidAWSConfigError( + `invalid AWS access key ID; reason: size should be between 16 and 128 characters, got ${accessKeyID.length}` + ) + } + + if (secretAccessKey === '') { throw new InvalidAWSConfigError( 'invalid AWS secret access key; reason: should be a non empty string' ) } + if (secretAccessKey.length < 16 || secretAccessKey.length > 128) { + throw new InvalidAWSConfigError( + `invalid AWS secret access key; reason: size should be between 16 and 128 characters, got ${secretAccessKey.length}` + ) + } + this.region = region this.accessKeyID = accessKeyID this.secretAccessKey = secretAccessKey From 8ec8155088e29138758e1e354493baadde31129b Mon Sep 17 00:00:00 2001 From: oleiade Date: Mon, 25 Apr 2022 14:44:41 +0200 Subject: [PATCH 7/7] Rename SecretManager's secretID and secretString args to id and secret --- src/internal/secrets-manager.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/internal/secrets-manager.ts b/src/internal/secrets-manager.ts index cd2c978..4ac1b14 100644 --- a/src/internal/secrets-manager.ts +++ b/src/internal/secrets-manager.ts @@ -72,13 +72,13 @@ export class SecretsManagerClient extends AWSClient { /** * Retrieves a secret from Amazon Sercets Manager * - * @param {string} secretID - The ARN or name of the secret to retrieve. + * @param {string} id - The ARN or name of the secret to retrieve. * @returns {Secret} - returns the content of the fetched Secret object. * @throws {SecretsManagerServiceError} * @throws {InvalidSignatureError} */ - getSecret(secretID: string): Secret | undefined { - const body = JSON.stringify({ SecretId: secretID }) + getSecret(id: string): Secret | undefined { + const body = JSON.stringify({ SecretId: id }) // Ensure to include the desired 'Action' in the X-Amz-Target // header field, as documented by the AWS API docs. @@ -109,7 +109,7 @@ export class SecretsManagerClient extends AWSClient { * * @param {string} name - The name of the new secret. * The secret name can contain ASCII letters, numbers, and the following characters: /_+=.@ - * @param {string} secretString - The text data to encrypt and store in this new version of the secret. + * @param {string} secret - The text data to encrypt and store in this new version of the secret. * @param {string} description - The description of the secret. * @param {string} versionID=null - Version of the secret. This value helps ensure idempotency. * As a default, if no versionID is provided, one will be created for you using the UUID v4 @@ -122,7 +122,7 @@ export class SecretsManagerClient extends AWSClient { */ createSecret( name: string, - secretString: string, + secret: string, description: string, versionID?: string, tags?: Array @@ -132,7 +132,7 @@ export class SecretsManagerClient extends AWSClient { const body = JSON.stringify({ Name: name, Description: description, - SecretString: secretString, + SecretString: secret, ClientRequestToken: versionID, Tags: tags, }) @@ -165,19 +165,19 @@ export class SecretsManagerClient extends AWSClient { * * Note that this method only support string-based values at the moment. * - * @param {string} secretID - The ARN or name of the secret to update. - * @param {string} secretString - The text data to encrypt and store in this new version of the secret. + * @param {string} id - The ARN or name of the secret to update. + * @param {string} secret - The text data to encrypt and store in this new version of the secret. * @param {} versionID=null - A unique identifier for the new version of the secret. This value helps ensure idempotency. * As a default, if no versionID is provided, one will be created for you using the UUID v4 * @throws {SecretsManagerServiceError} * @throws {InvalidSignatureError} */ - putSecretValue(secretID: string, secretString: string, versionID?: string): Secret { + putSecretValue(id: string, secret: string, versionID?: string): Secret { versionID = versionID || uuidv4() const body = JSON.stringify({ - SecretId: secretID, - SecretString: secretString, + SecretId: id, + SecretString: secret, ClientRequestToken: versionID, }) @@ -216,11 +216,11 @@ export class SecretsManagerClient extends AWSClient { * @throws {InvalidSignatureError} */ deleteSecret( - secretID: string, + id: string, { recoveryWindow = 30, noRecovery = false }: { recoveryWindow: number; noRecovery: boolean } ) { const payload: { [key: string]: string | boolean | number } = { - SecretId: secretID, + SecretId: id, } // noRecovery and recoveryWindow are exclusive parameters