@sls-next/lambda-at-edge
Version:
Provides handlers that can be used in CloudFront Lambda@Edge to deploy next.js applications to the edge
1,168 lines (1,094 loc) • 1.26 MB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var Stream = require('stream');
var zlib = require('zlib');
var http = require('http');
var Manifest = require('./manifest.json');
var crypto = require('crypto');
var os = require('os');
var path = require('path');
var fs = require('fs');
var Url = require('url');
var buffer = require('buffer');
var https = require('https');
require('http2');
var process$1 = require('process');
var child_process = require('child_process');
var util$1 = require('util');
require('perf_hooks');
var punycode = require('punycode');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var Stream__default = /*#__PURE__*/_interopDefaultLegacy(Stream);
var zlib__default = /*#__PURE__*/_interopDefaultLegacy(zlib);
var http__default = /*#__PURE__*/_interopDefaultLegacy(http);
var Manifest__default = /*#__PURE__*/_interopDefaultLegacy(Manifest);
var crypto__default = /*#__PURE__*/_interopDefaultLegacy(crypto);
var Url__default = /*#__PURE__*/_interopDefaultLegacy(Url);
var punycode__default = /*#__PURE__*/_interopDefaultLegacy(punycode);
const specialNodeHeaders = [
"age",
"authorization",
"content-length",
"content-type",
"etag",
"expires",
"from",
"host",
"if-modified-since",
"if-unmodified-since",
"last-modified",
"location",
"max-forwards",
"proxy-authorization",
"referer",
"retry-after",
"user-agent"
];
const readOnlyCloudFrontHeaders = {
"accept-encoding": true,
"content-length": true,
"if-modified-since": true,
"if-none-match": true,
"if-range": true,
"if-unmodified-since": true,
"transfer-encoding": true,
via: true
};
const HttpStatusCodes = {
202: "Accepted",
502: "Bad Gateway",
400: "Bad Request",
409: "Conflict",
100: "Continue",
201: "Created",
417: "Expectation Failed",
424: "Failed Dependency",
403: "Forbidden",
504: "Gateway Timeout",
410: "Gone",
505: "HTTP Version Not Supported",
418: "I'm a teapot",
419: "Insufficient Space on Resource",
507: "Insufficient Storage",
500: "Server Error",
411: "Length Required",
423: "Locked",
420: "Method Failure",
405: "Method Not Allowed",
301: "Moved Permanently",
302: "Moved Temporarily",
207: "Multi-Status",
300: "Multiple Choices",
511: "Network Authentication Required",
204: "No Content",
203: "Non Authoritative Information",
406: "Not Acceptable",
404: "Not Found",
501: "Not Implemented",
304: "Not Modified",
200: "OK",
206: "Partial Content",
402: "Payment Required",
308: "Permanent Redirect",
412: "Precondition Failed",
428: "Precondition Required",
102: "Processing",
407: "Proxy Authentication Required",
431: "Request Header Fields Too Large",
408: "Request Timeout",
413: "Request Entity Too Large",
414: "Request-URI Too Long",
416: "Requested Range Not Satisfiable",
205: "Reset Content",
303: "See Other",
503: "Service Unavailable",
101: "Switching Protocols",
307: "Temporary Redirect",
429: "Too Many Requests",
401: "Unauthorized",
422: "Unprocessable Entity",
415: "Unsupported Media Type",
305: "Use Proxy"
};
const toCloudFrontHeaders = (headers, headerNames, originalHeaders) => {
const result = {};
Object.entries(originalHeaders).forEach(([headerName, headerValue]) => {
result[headerName.toLowerCase()] = headerValue;
});
Object.entries(headers).forEach(([headerName, headerValue]) => {
const headerKey = headerName.toLowerCase();
headerName = headerNames[headerKey] || headerName;
if (readOnlyCloudFrontHeaders[headerKey]) {
return;
}
result[headerKey] = [];
if (headerValue instanceof Array) {
headerValue.forEach((val) => {
if (val) {
result[headerKey].push({
key: headerName,
value: val.toString()
});
}
});
} else {
if (headerValue) {
result[headerKey].push({
key: headerName,
value: headerValue.toString()
});
}
}
});
return result;
};
const isGzipSupported = (headers) => {
let gz = false;
const ae = headers["accept-encoding"];
if (ae) {
for (let i = 0; i < ae.length; i++) {
const { value } = ae[i];
const bits = value.split(",").map((x) => x.split(";")[0].trim());
if (bits.indexOf("gzip") !== -1) {
gz = true;
}
}
}
return gz;
};
const defaultOptions$3 = {
enableHTTPCompression: false
};
const handler$1 = (
event,
{ enableHTTPCompression, rewrittenUri } = defaultOptions$3
) => {
const { request: cfRequest, response: cfResponse = { headers: {} } } = event;
const response = {
headers: {}
};
const newStream = new Stream__default["default"].Readable();
const req = Object.assign(newStream, http__default["default"].IncomingMessage.prototype);
req.url = rewrittenUri || cfRequest.uri;
req.method = cfRequest.method;
req.rawHeaders = [];
req.headers = {};
req.connection = {};
if (cfRequest.querystring) {
req.url = req.url + `?` + cfRequest.querystring;
}
const headers = cfRequest.headers || {};
for (const lowercaseKey of Object.keys(headers)) {
const headerKeyValPairs = headers[lowercaseKey];
headerKeyValPairs.forEach((keyVal) => {
req.rawHeaders.push(keyVal.key);
req.rawHeaders.push(keyVal.value);
});
req.headers[lowercaseKey] = headerKeyValPairs[0].value;
}
req.getHeader = (name) => {
return req.headers[name.toLowerCase()];
};
req.getHeaders = () => {
return req.headers;
};
if (cfRequest.body && cfRequest.body.data) {
req.push(
cfRequest.body.data,
cfRequest.body.encoding ? "base64" : undefined
);
}
req.push(null);
const res = new Stream__default["default"]();
res.finished = false;
Object.defineProperty(res, "statusCode", {
get() {
return response.status;
},
set(statusCode) {
response.status = statusCode.toString();
response.statusDescription = HttpStatusCodes[statusCode];
}
});
res.headers = {};
const headerNames = {};
res.writeHead = (status, headers) => {
response.status = status.toString();
response.statusDescription = HttpStatusCodes[status];
if (headers) {
res.headers = Object.assign(res.headers, headers);
}
return res;
};
res.write = (chunk) => {
if (!response.body) {
response.body = Buffer.from("");
}
response.body = Buffer.concat([
response.body,
Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)
]);
};
let shouldGzip = enableHTTPCompression && isGzipSupported(headers);
const responsePromise = new Promise((resolve) => {
res.end = (text) => {
if (res.finished === true) {
return;
}
res.finished = true;
if (text) res.write(text);
if (!res.statusCode) {
res.statusCode = 200;
}
if (response.body) {
response.bodyEncoding = "base64";
response.body = shouldGzip
? zlib__default["default"].gzipSync(response.body).toString("base64")
: Buffer.from(response.body).toString("base64");
}
response.headers = toCloudFrontHeaders(
res.headers,
headerNames,
cfResponse.headers
);
if (shouldGzip) {
response.headers["content-encoding"] = [
{ key: "Content-Encoding", value: "gzip" }
];
}
resolve(response);
};
});
res.setHeader = (name, value) => {
res.headers[name.toLowerCase()] = value;
headerNames[name.toLowerCase()] = name;
};
res.removeHeader = (name) => {
delete res.headers[name.toLowerCase()];
};
res.getHeader = (name) => {
return res.headers[name.toLowerCase()];
};
res.getHeaders = () => {
return res.headers;
};
res.hasHeader = (name) => {
return !!res.getHeader(name);
};
return {
req,
res,
responsePromise
};
};
handler$1.SPECIAL_NODE_HEADERS = specialNodeHeaders;
var nextAwsCloudfront = handler$1;
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics$2 = function(d, b) {
extendStatics$2 = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics$2(d, b);
};
function __extends$2(d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics$2(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var __assign$2 = function() {
__assign$2 = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign$2.apply(this, arguments);
};
function __rest$2(s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
}
function __awaiter$2(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
function __generator$2(thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
}
function __values$2(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
}
function __read$2(o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
}
function __spreadArray(to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
}
function __await$2(v) {
return this instanceof __await$2 ? (this.v = v, this) : new __await$2(v);
}
function __asyncGenerator$2(thisArg, _arguments, generator) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var g = generator.apply(thisArg, _arguments || []), i, q = [];
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
function step(r) { r.value instanceof __await$2 ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
function fulfill(value) { resume("next", value); }
function reject(value) { resume("throw", value); }
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
}
function __asyncValues$2(o) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var m = o[Symbol.asyncIterator], i;
return m ? m.call(o) : (o = typeof __values$2 === "function" ? __values$2(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
}
var SelectorType;
(function (SelectorType) {
SelectorType["ENV"] = "env";
SelectorType["CONFIG"] = "shared config entry";
})(SelectorType || (SelectorType = {}));
var booleanSelector = function (obj, key, type) {
if (!(key in obj))
return undefined;
if (obj[key] === "true")
return true;
if (obj[key] === "false")
return false;
throw new Error("Cannot load " + type + " \"" + key + "\". Expected \"true\" or \"false\", got " + obj[key] + ".");
};
var NODE_USE_ARN_REGION_ENV_NAME = "AWS_S3_USE_ARN_REGION";
var NODE_USE_ARN_REGION_INI_NAME = "s3_use_arn_region";
var NODE_USE_ARN_REGION_CONFIG_OPTIONS = {
environmentVariableSelector: function (env) {
return booleanSelector(env, NODE_USE_ARN_REGION_ENV_NAME, SelectorType.ENV);
},
configFileSelector: function (profile) { return booleanSelector(profile, NODE_USE_ARN_REGION_INI_NAME, SelectorType.CONFIG); },
default: false,
};
var HttpRequest = (function () {
function HttpRequest(options) {
this.method = options.method || "GET";
this.hostname = options.hostname || "localhost";
this.port = options.port;
this.query = options.query || {};
this.headers = options.headers || {};
this.body = options.body;
this.protocol = options.protocol
? options.protocol.substr(-1) !== ":"
? options.protocol + ":"
: options.protocol
: "https:";
this.path = options.path ? (options.path.charAt(0) !== "/" ? "/" + options.path : options.path) : "/";
}
HttpRequest.isInstance = function (request) {
if (!request)
return false;
var req = request;
return ("method" in req &&
"protocol" in req &&
"hostname" in req &&
"path" in req &&
typeof req["query"] === "object" &&
typeof req["headers"] === "object");
};
HttpRequest.prototype.clone = function () {
var cloned = new HttpRequest(__assign$2(__assign$2({}, this), { headers: __assign$2({}, this.headers) }));
if (cloned.query)
cloned.query = cloneQuery$1(cloned.query);
return cloned;
};
return HttpRequest;
}());
function cloneQuery$1(query) {
return Object.keys(query).reduce(function (carry, paramName) {
var _a;
var param = query[paramName];
return __assign$2(__assign$2({}, carry), (_a = {}, _a[paramName] = Array.isArray(param) ? __spreadArray([], __read$2(param)) : param, _a));
}, {});
}
var HttpResponse = (function () {
function HttpResponse(options) {
this.statusCode = options.statusCode;
this.headers = options.headers || {};
this.body = options.body;
}
HttpResponse.isInstance = function (response) {
if (!response)
return false;
var resp = response;
return typeof resp.statusCode === "number" && typeof resp.headers === "object";
};
return HttpResponse;
}());
var validate$2 = function (str) {
return typeof str === "string" && str.indexOf("arn:") === 0 && str.split(":").length >= 6;
};
var parse = function (arn) {
var segments = arn.split(":");
if (segments.length < 6 || segments[0] !== "arn")
throw new Error("Malformed ARN");
var _a = __read$2(segments), partition = _a[1], service = _a[2], region = _a[3], accountId = _a[4], resource = _a.slice(5);
return {
partition: partition,
service: service,
region: region,
accountId: accountId,
resource: resource.join(":"),
};
};
var DOMAIN_PATTERN = /^[a-z0-9][a-z0-9\.\-]{1,61}[a-z0-9]$/;
var IP_ADDRESS_PATTERN = /(\d+\.){3}\d+/;
var DOTS_PATTERN = /\.\./;
var DOT_PATTERN = /\./;
var S3_HOSTNAME_PATTERN = /^(.+\.)?s3(-fips)?(\.dualstack)?[.-]([a-z0-9-]+)\./;
var S3_US_EAST_1_ALTNAME_PATTERN = /^s3(-external-1)?\.amazonaws\.com$/;
var AWS_PARTITION_SUFFIX = "amazonaws.com";
var isBucketNameOptions = function (options) { return typeof options.bucketName === "string"; };
var isDnsCompatibleBucketName = function (bucketName) {
return DOMAIN_PATTERN.test(bucketName) && !IP_ADDRESS_PATTERN.test(bucketName) && !DOTS_PATTERN.test(bucketName);
};
var getRegionalSuffix = function (hostname) {
var parts = hostname.match(S3_HOSTNAME_PATTERN);
return [parts[4], hostname.replace(new RegExp("^" + parts[0]), "")];
};
var getSuffix = function (hostname) {
return S3_US_EAST_1_ALTNAME_PATTERN.test(hostname) ? ["us-east-1", AWS_PARTITION_SUFFIX] : getRegionalSuffix(hostname);
};
var getSuffixForArnEndpoint = function (hostname) {
return S3_US_EAST_1_ALTNAME_PATTERN.test(hostname)
? [hostname.replace("." + AWS_PARTITION_SUFFIX, ""), AWS_PARTITION_SUFFIX]
: getRegionalSuffix(hostname);
};
var validateArnEndpointOptions = function (options) {
if (options.pathStyleEndpoint) {
throw new Error("Path-style S3 endpoint is not supported when bucket is an ARN");
}
if (options.accelerateEndpoint) {
throw new Error("Accelerate endpoint is not supported when bucket is an ARN");
}
if (!options.tlsCompatible) {
throw new Error("HTTPS is required when bucket is an ARN");
}
};
var validateService = function (service) {
if (service !== "s3" && service !== "s3-outposts" && service !== "s3-object-lambda") {
throw new Error("Expect 's3' or 's3-outposts' or 's3-object-lambda' in ARN service component");
}
};
var validateS3Service = function (service) {
if (service !== "s3") {
throw new Error("Expect 's3' in Accesspoint ARN service component");
}
};
var validateOutpostService = function (service) {
if (service !== "s3-outposts") {
throw new Error("Expect 's3-posts' in Outpost ARN service component");
}
};
var validatePartition = function (partition, options) {
if (partition !== options.clientPartition) {
throw new Error("Partition in ARN is incompatible, got \"" + partition + "\" but expected \"" + options.clientPartition + "\"");
}
};
var validateRegion = function (region, options) {
if (region === "") {
throw new Error("ARN region is empty");
}
if (options.useFipsEndpoint) {
if (!options.allowFipsRegion) {
throw new Error("FIPS region is not supported");
}
else if (!isEqualRegions(region, options.clientRegion)) {
throw new Error("Client FIPS region " + options.clientRegion + " doesn't match region " + region + " in ARN");
}
}
if (!options.useArnRegion &&
!isEqualRegions(region, options.clientRegion || "") &&
!isEqualRegions(region, options.clientSigningRegion || "")) {
throw new Error("Region in ARN is incompatible, got " + region + " but expected " + options.clientRegion);
}
};
var validateRegionalClient = function (region) {
if (["s3-external-1", "aws-global"].includes(region)) {
throw new Error("Client region " + region + " is not regional");
}
};
var isEqualRegions = function (regionA, regionB) { return regionA === regionB; };
var validateAccountId = function (accountId) {
if (!/[0-9]{12}/.exec(accountId)) {
throw new Error("Access point ARN accountID does not match regex '[0-9]{12}'");
}
};
var validateDNSHostLabel = function (label, options) {
if (options === void 0) { options = { tlsCompatible: true }; }
if (label.length >= 64 ||
!/^[a-z0-9][a-z0-9.-]*[a-z0-9]$/.test(label) ||
/(\d+\.){3}\d+/.test(label) ||
/[.-]{2}/.test(label) ||
((options === null || options === void 0 ? void 0 : options.tlsCompatible) && DOT_PATTERN.test(label))) {
throw new Error("Invalid DNS label " + label);
}
};
var validateCustomEndpoint = function (options) {
if (options.isCustomEndpoint) {
if (options.dualstackEndpoint)
throw new Error("Dualstack endpoint is not supported with custom endpoint");
if (options.accelerateEndpoint)
throw new Error("Accelerate endpoint is not supported with custom endpoint");
}
};
var getArnResources = function (resource) {
var delimiter = resource.includes(":") ? ":" : "/";
var _a = __read$2(resource.split(delimiter)), resourceType = _a[0], rest = _a.slice(1);
if (resourceType === "accesspoint") {
if (rest.length !== 1 || rest[0] === "") {
throw new Error("Access Point ARN should have one resource accesspoint" + delimiter + "{accesspointname}");
}
return { accesspointName: rest[0] };
}
else if (resourceType === "outpost") {
if (!rest[0] || rest[1] !== "accesspoint" || !rest[2] || rest.length !== 3) {
throw new Error("Outpost ARN should have resource outpost" + delimiter + "{outpostId}" + delimiter + "accesspoint" + delimiter + "{accesspointName}");
}
var _b = __read$2(rest, 3), outpostId = _b[0]; _b[1]; var accesspointName = _b[2];
return { outpostId: outpostId, accesspointName: accesspointName };
}
else {
throw new Error("ARN resource should begin with 'accesspoint" + delimiter + "' or 'outpost" + delimiter + "'");
}
};
var validateNoDualstack = function (dualstackEndpoint) {
if (dualstackEndpoint)
throw new Error("Dualstack endpoint is not supported with Outpost or Multi-region Access Point ARN.");
};
var validateNoFIPS = function (useFipsEndpoint) {
if (useFipsEndpoint)
throw new Error("FIPS region is not supported with Outpost.");
};
var validateMrapAlias = function (name) {
try {
name.split(".").forEach(function (label) {
validateDNSHostLabel(label);
});
}
catch (e) {
throw new Error("\"" + name + "\" is not a DNS compatible name.");
}
};
var bucketHostname = function (options) {
validateCustomEndpoint(options);
return isBucketNameOptions(options)
?
getEndpointFromBucketName(options)
:
getEndpointFromArn(options);
};
var getEndpointFromBucketName = function (_a) {
var _b = _a.accelerateEndpoint, accelerateEndpoint = _b === void 0 ? false : _b, region = _a.clientRegion, baseHostname = _a.baseHostname, bucketName = _a.bucketName, _c = _a.dualstackEndpoint, dualstackEndpoint = _c === void 0 ? false : _c; _a.fipsEndpoint; var _e = _a.pathStyleEndpoint, pathStyleEndpoint = _e === void 0 ? false : _e, _f = _a.tlsCompatible, tlsCompatible = _f === void 0 ? true : _f, _g = _a.isCustomEndpoint, isCustomEndpoint = _g === void 0 ? false : _g;
var _h = __read$2(isCustomEndpoint ? [region, baseHostname] : getSuffix(baseHostname), 2), clientRegion = _h[0], hostnameSuffix = _h[1];
if (pathStyleEndpoint || !isDnsCompatibleBucketName(bucketName) || (tlsCompatible && DOT_PATTERN.test(bucketName))) {
return {
bucketEndpoint: false,
hostname: dualstackEndpoint ? "s3.dualstack." + clientRegion + "." + hostnameSuffix : baseHostname,
};
}
if (accelerateEndpoint) {
baseHostname = "s3-accelerate" + (dualstackEndpoint ? ".dualstack" : "") + "." + hostnameSuffix;
}
else if (dualstackEndpoint) {
baseHostname = "s3.dualstack." + clientRegion + "." + hostnameSuffix;
}
return {
bucketEndpoint: true,
hostname: bucketName + "." + baseHostname,
};
};
var getEndpointFromArn = function (options) {
var isCustomEndpoint = options.isCustomEndpoint, baseHostname = options.baseHostname, clientRegion = options.clientRegion;
var hostnameSuffix = isCustomEndpoint ? baseHostname : getSuffixForArnEndpoint(baseHostname)[1];
var pathStyleEndpoint = options.pathStyleEndpoint, _a = options.accelerateEndpoint, accelerateEndpoint = _a === void 0 ? false : _a; options.fipsEndpoint; var _c = options.tlsCompatible, tlsCompatible = _c === void 0 ? true : _c, bucketName = options.bucketName, _d = options.clientPartition, clientPartition = _d === void 0 ? "aws" : _d;
validateArnEndpointOptions({ pathStyleEndpoint: pathStyleEndpoint, accelerateEndpoint: accelerateEndpoint, tlsCompatible: tlsCompatible });
var service = bucketName.service, partition = bucketName.partition, accountId = bucketName.accountId, region = bucketName.region, resource = bucketName.resource;
validateService(service);
validatePartition(partition, { clientPartition: clientPartition });
validateAccountId(accountId);
var _e = getArnResources(resource), accesspointName = _e.accesspointName, outpostId = _e.outpostId;
if (service === "s3-object-lambda") {
return getEndpointFromObjectLambdaArn(__assign$2(__assign$2({}, options), { tlsCompatible: tlsCompatible, bucketName: bucketName, accesspointName: accesspointName, hostnameSuffix: hostnameSuffix }));
}
if (region === "") {
return getEndpointFromMRAPArn(__assign$2(__assign$2({}, options), { clientRegion: clientRegion, mrapAlias: accesspointName, hostnameSuffix: hostnameSuffix }));
}
if (outpostId) {
return getEndpointFromOutpostArn(__assign$2(__assign$2({}, options), { clientRegion: clientRegion, outpostId: outpostId, accesspointName: accesspointName, hostnameSuffix: hostnameSuffix }));
}
return getEndpointFromAccessPointArn(__assign$2(__assign$2({}, options), { clientRegion: clientRegion, accesspointName: accesspointName, hostnameSuffix: hostnameSuffix }));
};
var getEndpointFromObjectLambdaArn = function (_a) {
var _b = _a.dualstackEndpoint, dualstackEndpoint = _b === void 0 ? false : _b, _c = _a.fipsEndpoint, fipsEndpoint = _c === void 0 ? false : _c, _d = _a.tlsCompatible, tlsCompatible = _d === void 0 ? true : _d, useArnRegion = _a.useArnRegion, clientRegion = _a.clientRegion, _e = _a.clientSigningRegion, clientSigningRegion = _e === void 0 ? clientRegion : _e, accesspointName = _a.accesspointName, bucketName = _a.bucketName, hostnameSuffix = _a.hostnameSuffix;
var accountId = bucketName.accountId, region = bucketName.region, service = bucketName.service;
validateRegionalClient(clientRegion);
validateRegion(region, {
useArnRegion: useArnRegion,
clientRegion: clientRegion,
clientSigningRegion: clientSigningRegion,
allowFipsRegion: true,
useFipsEndpoint: fipsEndpoint,
});
validateNoDualstack(dualstackEndpoint);
var DNSHostLabel = accesspointName + "-" + accountId;
validateDNSHostLabel(DNSHostLabel, { tlsCompatible: tlsCompatible });
var endpointRegion = useArnRegion ? region : clientRegion;
var signingRegion = useArnRegion ? region : clientSigningRegion;
return {
bucketEndpoint: true,
hostname: DNSHostLabel + "." + service + (fipsEndpoint ? "-fips" : "") + "." + endpointRegion + "." + hostnameSuffix,
signingRegion: signingRegion,
signingService: service,
};
};
var getEndpointFromMRAPArn = function (_a) {
var disableMultiregionAccessPoints = _a.disableMultiregionAccessPoints, _b = _a.dualstackEndpoint, dualstackEndpoint = _b === void 0 ? false : _b, isCustomEndpoint = _a.isCustomEndpoint, mrapAlias = _a.mrapAlias, hostnameSuffix = _a.hostnameSuffix;
if (disableMultiregionAccessPoints === true) {
throw new Error("SDK is attempting to use a MRAP ARN. Please enable to feature.");
}
validateMrapAlias(mrapAlias);
validateNoDualstack(dualstackEndpoint);
return {
bucketEndpoint: true,
hostname: "" + mrapAlias + (isCustomEndpoint ? "" : ".accesspoint.s3-global") + "." + hostnameSuffix,
signingRegion: "*",
};
};
var getEndpointFromOutpostArn = function (_a) {
var useArnRegion = _a.useArnRegion, clientRegion = _a.clientRegion, _b = _a.clientSigningRegion, clientSigningRegion = _b === void 0 ? clientRegion : _b, bucketName = _a.bucketName, outpostId = _a.outpostId, _c = _a.dualstackEndpoint, dualstackEndpoint = _c === void 0 ? false : _c, _d = _a.fipsEndpoint, fipsEndpoint = _d === void 0 ? false : _d, _e = _a.tlsCompatible, tlsCompatible = _e === void 0 ? true : _e, accesspointName = _a.accesspointName, isCustomEndpoint = _a.isCustomEndpoint, hostnameSuffix = _a.hostnameSuffix;
validateRegionalClient(clientRegion);
validateRegion(bucketName.region, { useArnRegion: useArnRegion, clientRegion: clientRegion, clientSigningRegion: clientSigningRegion, useFipsEndpoint: fipsEndpoint });
var DNSHostLabel = accesspointName + "-" + bucketName.accountId;
validateDNSHostLabel(DNSHostLabel, { tlsCompatible: tlsCompatible });
var endpointRegion = useArnRegion ? bucketName.region : clientRegion;
var signingRegion = useArnRegion ? bucketName.region : clientSigningRegion;
validateOutpostService(bucketName.service);
validateDNSHostLabel(outpostId, { tlsCompatible: tlsCompatible });
validateNoDualstack(dualstackEndpoint);
validateNoFIPS(fipsEndpoint);
var hostnamePrefix = DNSHostLabel + "." + outpostId;
return {
bucketEndpoint: true,
hostname: "" + hostnamePrefix + (isCustomEndpoint ? "" : ".s3-outposts." + endpointRegion) + "." + hostnameSuffix,
signingRegion: signingRegion,
signingService: "s3-outposts",
};
};
var getEndpointFromAccessPointArn = function (_a) {
var useArnRegion = _a.useArnRegion, clientRegion = _a.clientRegion, _b = _a.clientSigningRegion, clientSigningRegion = _b === void 0 ? clientRegion : _b, bucketName = _a.bucketName, _c = _a.dualstackEndpoint, dualstackEndpoint = _c === void 0 ? false : _c, _d = _a.fipsEndpoint, fipsEndpoint = _d === void 0 ? false : _d, _e = _a.tlsCompatible, tlsCompatible = _e === void 0 ? true : _e, accesspointName = _a.accesspointName, isCustomEndpoint = _a.isCustomEndpoint, hostnameSuffix = _a.hostnameSuffix;
validateRegionalClient(clientRegion);
validateRegion(bucketName.region, {
useArnRegion: useArnRegion,
clientRegion: clientRegion,
clientSigningRegion: clientSigningRegion,
allowFipsRegion: true,
useFipsEndpoint: fipsEndpoint,
});
var hostnamePrefix = accesspointName + "-" + bucketName.accountId;
validateDNSHostLabel(hostnamePrefix, { tlsCompatible: tlsCompatible });
var endpointRegion = useArnRegion ? bucketName.region : clientRegion;
var signingRegion = useArnRegion ? bucketName.region : clientSigningRegion;
validateS3Service(bucketName.service);
return {
bucketEndpoint: true,
hostname: "" + hostnamePrefix + (isCustomEndpoint
? ""
: ".s3-accesspoint" + (fipsEndpoint ? "-fips" : "") + (dualstackEndpoint ? ".dualstack" : "") + "." + endpointRegion) + "." + hostnameSuffix,
signingRegion: signingRegion,
};
};
var bucketEndpointMiddleware = function (options) {
return function (next, context) {
return function (args) { return __awaiter$2(void 0, void 0, void 0, function () {
var bucketName, replaceBucketInPath, request, bucketArn, clientRegion, useDualstackEndpoint, useFipsEndpoint, _a, partition, _b, signingRegion, useArnRegion, _c, hostname, bucketEndpoint, modifiedSigningRegion, signingService, _d, clientRegion, dualstackEndpoint, fipsEndpoint, _e, hostname, bucketEndpoint;
var _f;
return __generator$2(this, function (_g) {
switch (_g.label) {
case 0:
bucketName = args.input.Bucket;
replaceBucketInPath = options.bucketEndpoint;
request = args.request;
if (!HttpRequest.isInstance(request)) return [3, 13];
if (!options.bucketEndpoint) return [3, 1];
request.hostname = bucketName;
return [3, 12];
case 1:
if (!validate$2(bucketName)) return [3, 8];
bucketArn = parse(bucketName);
return [4, options.region()];
case 2:
clientRegion = _g.sent();
return [4, options.useDualstackEndpoint()];
case 3:
useDualstackEndpoint = _g.sent();
return [4, options.useFipsEndpoint()];
case 4:
useFipsEndpoint = _g.sent();
return [4, options.regionInfoProvider(clientRegion, { useDualstackEndpoint: useDualstackEndpoint, useFipsEndpoint: useFipsEndpoint })];
case 5:
_a = (_g.sent()) || {}, partition = _a.partition, _b = _a.signingRegion, signingRegion = _b === void 0 ? clientRegion : _b;
return [4, options.useArnRegion()];
case 6:
useArnRegion = _g.sent();
_d = bucketHostname;
_f = {
bucketName: bucketArn,
baseHostname: request.hostname,
accelerateEndpoint: options.useAccelerateEndpoint,
dualstackEndpoint: useDualstackEndpoint,
fipsEndpoint: useFipsEndpoint,
pathStyleEndpoint: options.forcePathStyle,
tlsCompatible: request.protocol === "https:",
useArnRegion: useArnRegion,
clientPartition: partition,
clientSigningRegion: signingRegion,
clientRegion: clientRegion,
isCustomEndpoint: options.isCustomEndpoint
};
return [4, options.disableMultiregionAccessPoints()];
case 7:
_c = _d.apply(void 0, [(_f.disableMultiregionAccessPoints = _g.sent(),
_f)]), hostname = _c.hostname, bucketEndpoint = _c.bucketEndpoint, modifiedSigningRegion = _c.signingRegion, signingService = _c.signingService;
if (modifiedSigningRegion && modifiedSigningRegion !== signingRegion) {
context["signing_region"] = modifiedSigningRegion;
}
if (signingService && signingService !== "s3") {
context["signing_service"] = signingService;
}
request.hostname = hostname;
replaceBucketInPath = bucketEndpoint;
return [3, 12];
case 8: return [4, options.region()];
case 9:
clientRegion = _g.sent();
return [4, options.useDualstackEndpoint()];
case 10:
dualstackEndpoint = _g.sent();
return [4, options.useFipsEndpoint()];
case 11:
fipsEndpoint = _g.sent();
_e = bucketHostname({
bucketName: bucketName,
clientRegion: clientRegion,
baseHostname: request.hostname,
accelerateEndpoint: options.useAccelerateEndpoint,
dualstackEndpoint: dualstackEndpoint,
fipsEndpoint: fipsEndpoint,
pathStyleEndpoint: options.forcePathStyle,
tlsCompatible: request.protocol === "https:",
isCustomEndpoint: options.isCustomEndpoint,
}), hostname = _e.hostname, bucketEndpoint = _e.bucketEndpoint;
request.hostname = hostname;
replaceBucketInPath = bucketEndpoint;
_g.label = 12;
case 12:
if (replaceBucketInPath) {
request.path = request.path.replace(/^(\/)?[^\/]+/, "");
if (request.path === "") {
request.path = "/";
}
}
_g.label = 13;
case 13: return [2, next(__assign$2(__assign$2({}, args), { request: request }))];
}
});
}); };
};
};
var bucketEndpointMiddlewareOptions = {
tags: ["BUCKET_ENDPOINT"],
name: "bucketEndpointMiddleware",
relation: "before",
toMiddleware: "hostHeaderMiddleware",
override: true,
};
var getBucketEndpointPlugin = function (options) { return ({
applyToStack: function (clientStack) {
clientStack.addRelativeTo(bucketEndpointMiddleware(options), bucketEndpointMiddlewareOptions);
},
}); };
function resolveBucketEndpointConfig(input) {
var _a = input.bucketEndpoint, bucketEndpoint = _a === void 0 ? false : _a, _b = input.forcePathStyle, forcePathStyle = _b === void 0 ? false : _b, _c = input.useAccelerateEndpoint, useAccelerateEndpoint = _c === void 0 ? false : _c, _d = input.useArnRegion, useArnRegion = _d === void 0 ? false : _d, _e = input.disableMultiregionAccessPoints, disableMultiregionAccessPoints = _e === void 0 ? false : _e;
return __assign$2(__assign$2({}, input), { bucketEndpoint: bucketEndpoint, forcePathStyle: forcePathStyle, useAccelerateEndpoint: useAccelerateEndpoint, useArnRegion: typeof useArnRegion === "function" ? useArnRegion : function () { return Promise.resolve(useArnRegion); }, disableMultiregionAccessPoints: typeof disableMultiregionAccessPoints === "function"
? disableMultiregionAccessPoints
: function () { return Promise.resolve(disableMultiregionAccessPoints); } });
}
var deserializerMiddleware = function (options, deserializer) {
return function (next, context) {
return function (args) { return __awaiter$2(void 0, void 0, void 0, function () {
var response, parsed, error_1;
return __generator$2(this, function (_a) {
switch (_a.label) {
case 0: return [4, next(args)];
case 1:
response = (_a.sent()).response;
_a.label = 2;
case 2:
_a.trys.push([2, 4, , 5]);
return [4, deserializer(response, options)];
case 3:
parsed = _a.sent();
return [2, {
response: response,
output: parsed,
}];
case 4:
error_1 = _a.sent();
throw Object.assign(error_1, { $response: response });
case 5: return [2];
}
});
}); };
};
};
var serializerMiddleware = function (options, serializer) {
return function (next, context) {
return function (args) { return __awaiter$2(void 0, void 0, void 0, function () {
var request;
return __generator$2(this, function (_a) {
switch (_a.label) {
case 0: return [4, serializer(args.input, options)];
case 1:
request = _a.sent();
return [2, next(__assign$2(__assign$2({}, args), { request: request }))];
}
});
}); };
};
};
var deserializerMiddlewareOption = {
name: "deserializerMiddleware",
step: "deserialize",
tags: ["DESERIALIZER"],
override: true,
};
var serializerMiddlewareOption = {
name: "serializerMiddleware",
step: "serialize",
tags: ["SERIALIZER"],
override: true,
};
function getSerdePlugin(config, serializer, deserializer) {
return {
applyToStack: function (commandStack) {
commandStack.add(deserializerMiddleware(config, deserializer), deserializerMiddlewareOption);
commandStack.add(serializerMiddleware(config, serializer), serializerMiddlewareOption);
},
};
}
var constructStack = function () {
var absoluteEntries = [];
var relativeEntries = [];
var entriesNameSet = new Set();
var sort = function (entries) {
return entries.sort(function (a, b) {
return stepWeights[b.step] - stepWeights[a.step] ||
priorityWeights[b.priority || "normal"] - priorityWeights[a.priority || "normal"];
});
};
var removeByName = function (toRemove) {
var isRemoved = false;
var filterCb = function (entry) {
if (entry.name && entry.name === toRemove) {
isRemoved = true;
entriesNameSet.delete(toRemove);
return false;
}
return true;
};
absoluteEntries = absoluteEntries.filter(filterCb);
relativeEntries = relativeEntries.filter(filterCb);
return isRemoved;
};
var removeByReference = function (toRemove) {
var isRemoved = false;
var filterCb = function (entry) {
if (entry.middleware === toRemove) {
isRemoved = true;
if (entry.name)
entriesNameSet.delete(entry.name);
return false;
}
return true;
};
absoluteEntries = absoluteEntries.filter(filterCb);
relativeEntries = relativeEntries.filter(filterCb);
return isRemoved;
};
var cloneTo = function (toStack) {
absoluteEntries.forEach(function (entry) {
toStack.add(entry.middleware, __assign$2({}, entry));
});
relativeEntries.forEach(function (entry) {
toStack.addRelativeTo(entry.middleware, __assign$2({}, entry));
});
return toStack;
};
var expandRelativeMiddlewareList = function (from) {
var expandedMiddlewareList = [];
from.before.forEach(function (entry) {
if (entry.before.length === 0 && entry.after.length === 0) {
expandedMiddlewareList.push(entry);
}
else {
expandedMiddlewareList.push.apply(expandedMiddlewareList, __spreadArray([], __read$2(expandRelativeMiddlewareList(entry))));
}
});
expandedMiddlewareList.push(from);
from.after.reverse().forEach(function (entry) {
if (entry.before.length === 0 && entry.after.length === 0) {
expandedMiddlewareList.push(entry);
}
else {
expandedMiddlewareList.push.apply(expandedMiddlewareList, __spreadArray([], __read$2(expandRelativeMiddlewareList(entry))));
}
});
return expandedMiddlewareList;
};
var getMiddlewareList = function () {
var normalizedAbsoluteEntries = [];
var normalizedRelativeEntries = [];
var normalizedEntriesNameMap = {};
absoluteEntries.forEach(function (entry) {
var normalizedEntry = __assign$2(__assign$2({}, entry), { before: [], after: [] });
if (normalizedEntry.name)
normalizedEntriesNameMap[normalizedEntry.name] = normalizedEntry;
normalizedAbsoluteEntries.push(normalizedEntry);
});
relativeEntries.forEach(function (entry) {
var normalizedEntry = __assign$2(__assign$2({}, entry), { before: [], after: [] });
if (normalizedEntry.name)
normalizedEntriesNameMap[normalizedEntry.name] = normalizedEntry;
normalizedRelativeEntries.push(normalizedEntry);
});
normalizedRelativeEntries.forEach(function (entry) {
if (entry.toMiddleware) {
var toMiddleware = normalizedEntriesNameMap[entry.toMiddleware];
if (toMiddleware === undefined) {
throw new Error(entry.toMiddleware + " is not found when adding " + (entry.name || "anonymous") + " middleware " + entry.relation + " " + entry.toMiddleware);
}
if (entry.relation === "after") {
toMiddleware.after.push(entry);
}
if (entry.relation === "before") {
toMiddleware.before.push(entry);
}
}
});
var mainChain = sort(normalizedAbsoluteEntries)
.map(expandRelativeMiddlewareList)
.reduce(function (wholeList, expendedMiddlewareList) {
wholeList.push.apply(wholeList, __spreadArray([], __read$2(expendedMiddlewareList)));
return wholeList;
}, []);
return mainChain.map(function (entry) { return entry.middleware; });
};
var stack = {
add: function (middleware, options) {
if (options === void 0) { options = {}; }
var name = options.name, override = options.override;
var entry = __assign$2({ step: "initialize", priority: "normal", middleware: middleware }, options);
if (name) {
if (entriesNameSet.has(name)) {
if (!override)
throw new Error("Duplicate middleware name '" + name + "'");
var toOverrideIndex = absoluteEntries.findIndex(function (entry) { return entry.name === name; });
var toOverride = absoluteEntries[toOverrideIndex];
if (toOverride.step !== entry.step || toOverride.priority !== entry.priority) {
throw new Error("\"" + name + "\" middleware with " + toOverride.priority + " priority in " + toOverride.step + " step cannot be " +
("overridden by same-name middleware with " + entry.priority + " priority in " + entry.step + " step."));
}
absoluteEntries.splice(toOverrideIndex, 1);
}
entriesNameSet.add(name);
}
absoluteEntries.push(entry);
},
addRelativeTo: function (middleware, options