@aws-sdk/middleware-bucket-endpoint 3.34.0 → 3.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist-cjs/bucketEndpointMiddleware.js +81 -0
  3. package/dist-cjs/bucketHostname.js +116 -0
  4. package/dist-cjs/bucketHostnameUtils.js +157 -0
  5. package/dist-cjs/configurations.js +64 -0
  6. package/{dist/cjs → dist-cjs}/index.js +0 -1
  7. package/dist-es/bucketEndpointMiddleware.js +100 -0
  8. package/dist-es/bucketHostname.js +118 -0
  9. package/dist-es/bucketHostnameUtils.js +144 -0
  10. package/dist-es/configurations.js +53 -0
  11. package/{dist/types/index.d.ts → dist-es/index.js} +0 -0
  12. package/{dist/types → dist-types}/bucketEndpointMiddleware.d.ts +0 -0
  13. package/{dist/types → dist-types}/bucketHostname.d.ts +0 -0
  14. package/{dist/types → dist-types}/bucketHostnameUtils.d.ts +0 -0
  15. package/{dist/types → dist-types}/configurations.d.ts +0 -0
  16. package/dist-types/index.d.ts +4 -0
  17. package/{dist/types → dist-types}/ts3.4/bucketEndpointMiddleware.d.ts +0 -0
  18. package/{dist/types → dist-types}/ts3.4/bucketHostname.d.ts +0 -0
  19. package/{dist/types → dist-types}/ts3.4/bucketHostnameUtils.d.ts +13 -62
  20. package/dist-types/ts3.4/configurations.d.ts +49 -0
  21. package/{dist/types → dist-types}/ts3.4/index.d.ts +0 -0
  22. package/package.json +15 -12
  23. package/dist/cjs/bucketEndpointMiddleware.js +0 -82
  24. package/dist/cjs/bucketHostname.js +0 -117
  25. package/dist/cjs/bucketHostnameUtils.js +0 -158
  26. package/dist/cjs/configurations.js +0 -65
  27. package/dist/es/bucketEndpointMiddleware.js +0 -103
  28. package/dist/es/bucketHostname.js +0 -123
  29. package/dist/es/bucketHostnameUtils.js +0 -210
  30. package/dist/es/configurations.js +0 -59
  31. package/dist/es/index.js +0 -5
  32. package/dist/types/ts3.4/configurations.d.ts +0 -87
  33. package/src/bucketEndpointMiddleware.ts +0 -101
  34. package/src/bucketHostname.ts +0 -223
  35. package/src/bucketHostnameUtils.ts +0 -272
  36. package/src/configurations.ts +0 -154
  37. package/src/index.ts +0 -15
  38. package/tsconfig.cjs.json +0 -9
  39. package/tsconfig.es.json +0 -10
  40. package/tsconfig.types.json +0 -9
package/CHANGELOG.md CHANGED
@@ -3,6 +3,41 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [3.38.0](https://github.com/aws/aws-sdk-js-v3/compare/v3.37.0...v3.38.0) (2021-10-22)
7
+
8
+ **Note:** Version bump only for package @aws-sdk/middleware-bucket-endpoint
9
+
10
+
11
+
12
+
13
+
14
+ # [3.37.0](https://github.com/aws/aws-sdk-js-v3/compare/v3.36.1...v3.37.0) (2021-10-15)
15
+
16
+ **Note:** Version bump only for package @aws-sdk/middleware-bucket-endpoint
17
+
18
+
19
+
20
+
21
+
22
+ # [3.36.0](https://github.com/aws/aws-sdk-js-v3/compare/v3.35.0...v3.36.0) (2021-10-08)
23
+
24
+
25
+ ### Features
26
+
27
+ * publish files in dist-* only ([#2873](https://github.com/aws/aws-sdk-js-v3/issues/2873)) ([53b4243](https://github.com/aws/aws-sdk-js-v3/commit/53b4243b066f25ff2412d5f0dea1036054b2df32))
28
+
29
+
30
+
31
+
32
+
33
+ # [3.35.0](https://github.com/aws/aws-sdk-js-v3/compare/v3.34.0...v3.35.0) (2021-10-04)
34
+
35
+ **Note:** Version bump only for package @aws-sdk/middleware-bucket-endpoint
36
+
37
+
38
+
39
+
40
+
6
41
  # [3.34.0](https://github.com/aws/aws-sdk-js-v3/compare/v3.33.0...v3.34.0) (2021-09-24)
7
42
 
8
43
 
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getBucketEndpointPlugin = exports.bucketEndpointMiddlewareOptions = exports.bucketEndpointMiddleware = void 0;
4
+ const protocol_http_1 = require("@aws-sdk/protocol-http");
5
+ const util_arn_parser_1 = require("@aws-sdk/util-arn-parser");
6
+ const bucketHostname_1 = require("./bucketHostname");
7
+ const bucketHostnameUtils_1 = require("./bucketHostnameUtils");
8
+ const bucketEndpointMiddleware = (options) => (next, context) => async (args) => {
9
+ const { Bucket: bucketName } = args.input;
10
+ let replaceBucketInPath = options.bucketEndpoint;
11
+ const request = args.request;
12
+ if (protocol_http_1.HttpRequest.isInstance(request)) {
13
+ if (options.bucketEndpoint) {
14
+ request.hostname = bucketName;
15
+ }
16
+ else if (util_arn_parser_1.validate(bucketName)) {
17
+ const bucketArn = util_arn_parser_1.parse(bucketName);
18
+ const clientRegion = bucketHostnameUtils_1.getPseudoRegion(await options.region());
19
+ const { partition, signingRegion = clientRegion } = (await options.regionInfoProvider(clientRegion)) || {};
20
+ const useArnRegion = await options.useArnRegion();
21
+ const { hostname, bucketEndpoint, signingRegion: modifiedSigningRegion, signingService } = bucketHostname_1.bucketHostname({
22
+ bucketName: bucketArn,
23
+ baseHostname: request.hostname,
24
+ accelerateEndpoint: options.useAccelerateEndpoint,
25
+ dualstackEndpoint: options.useDualstackEndpoint,
26
+ pathStyleEndpoint: options.forcePathStyle,
27
+ tlsCompatible: request.protocol === "https:",
28
+ useArnRegion,
29
+ clientPartition: partition,
30
+ clientSigningRegion: signingRegion,
31
+ clientRegion: clientRegion,
32
+ isCustomEndpoint: options.isCustomEndpoint,
33
+ disableMultiregionAccessPoints: await options.disableMultiregionAccessPoints(),
34
+ });
35
+ if (modifiedSigningRegion && modifiedSigningRegion !== signingRegion) {
36
+ context["signing_region"] = modifiedSigningRegion;
37
+ }
38
+ if (signingService && signingService !== "s3") {
39
+ context["signing_service"] = signingService;
40
+ }
41
+ request.hostname = hostname;
42
+ replaceBucketInPath = bucketEndpoint;
43
+ }
44
+ else {
45
+ const clientRegion = bucketHostnameUtils_1.getPseudoRegion(await options.region());
46
+ const { hostname, bucketEndpoint } = bucketHostname_1.bucketHostname({
47
+ bucketName,
48
+ clientRegion,
49
+ baseHostname: request.hostname,
50
+ accelerateEndpoint: options.useAccelerateEndpoint,
51
+ dualstackEndpoint: options.useDualstackEndpoint,
52
+ pathStyleEndpoint: options.forcePathStyle,
53
+ tlsCompatible: request.protocol === "https:",
54
+ isCustomEndpoint: options.isCustomEndpoint,
55
+ });
56
+ request.hostname = hostname;
57
+ replaceBucketInPath = bucketEndpoint;
58
+ }
59
+ if (replaceBucketInPath) {
60
+ request.path = request.path.replace(/^(\/)?[^\/]+/, "");
61
+ if (request.path === "") {
62
+ request.path = "/";
63
+ }
64
+ }
65
+ }
66
+ return next({ ...args, request });
67
+ };
68
+ exports.bucketEndpointMiddleware = bucketEndpointMiddleware;
69
+ exports.bucketEndpointMiddlewareOptions = {
70
+ tags: ["BUCKET_ENDPOINT"],
71
+ name: "bucketEndpointMiddleware",
72
+ relation: "before",
73
+ toMiddleware: "hostHeaderMiddleware",
74
+ override: true,
75
+ };
76
+ const getBucketEndpointPlugin = (options) => ({
77
+ applyToStack: (clientStack) => {
78
+ clientStack.addRelativeTo(exports.bucketEndpointMiddleware(options), exports.bucketEndpointMiddlewareOptions);
79
+ },
80
+ });
81
+ exports.getBucketEndpointPlugin = getBucketEndpointPlugin;
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.bucketHostname = void 0;
4
+ const bucketHostnameUtils_1 = require("./bucketHostnameUtils");
5
+ const bucketHostname = (options) => {
6
+ bucketHostnameUtils_1.validateCustomEndpoint(options);
7
+ return bucketHostnameUtils_1.isBucketNameOptions(options)
8
+ ?
9
+ getEndpointFromBucketName(options)
10
+ :
11
+ getEndpointFromArn(options);
12
+ };
13
+ exports.bucketHostname = bucketHostname;
14
+ const getEndpointFromBucketName = ({ accelerateEndpoint = false, clientRegion: region, baseHostname, bucketName, dualstackEndpoint = false, pathStyleEndpoint = false, tlsCompatible = true, isCustomEndpoint = false, }) => {
15
+ const [clientRegion, hostnameSuffix] = isCustomEndpoint ? [region, baseHostname] : bucketHostnameUtils_1.getSuffix(baseHostname);
16
+ if (pathStyleEndpoint || !bucketHostnameUtils_1.isDnsCompatibleBucketName(bucketName) || (tlsCompatible && bucketHostnameUtils_1.DOT_PATTERN.test(bucketName))) {
17
+ return {
18
+ bucketEndpoint: false,
19
+ hostname: dualstackEndpoint ? `s3.dualstack.${clientRegion}.${hostnameSuffix}` : baseHostname,
20
+ };
21
+ }
22
+ if (accelerateEndpoint) {
23
+ baseHostname = `s3-accelerate${dualstackEndpoint ? ".dualstack" : ""}.${hostnameSuffix}`;
24
+ }
25
+ else if (dualstackEndpoint) {
26
+ baseHostname = `s3.dualstack.${clientRegion}.${hostnameSuffix}`;
27
+ }
28
+ return {
29
+ bucketEndpoint: true,
30
+ hostname: `${bucketName}.${baseHostname}`,
31
+ };
32
+ };
33
+ const getEndpointFromArn = (options) => {
34
+ const { isCustomEndpoint, baseHostname, clientRegion } = options;
35
+ const hostnameSuffix = isCustomEndpoint ? baseHostname : bucketHostnameUtils_1.getSuffixForArnEndpoint(baseHostname)[1];
36
+ const { pathStyleEndpoint, accelerateEndpoint = false, tlsCompatible = true, bucketName, clientPartition = "aws", } = options;
37
+ bucketHostnameUtils_1.validateArnEndpointOptions({ pathStyleEndpoint, accelerateEndpoint, tlsCompatible });
38
+ const { service, partition, accountId, region, resource } = bucketName;
39
+ bucketHostnameUtils_1.validateService(service);
40
+ bucketHostnameUtils_1.validatePartition(partition, { clientPartition });
41
+ bucketHostnameUtils_1.validateAccountId(accountId);
42
+ const { accesspointName, outpostId } = bucketHostnameUtils_1.getArnResources(resource);
43
+ if (service === "s3-object-lambda") {
44
+ return getEndpointFromObjectLambdaArn({ ...options, tlsCompatible, bucketName, accesspointName, hostnameSuffix });
45
+ }
46
+ if (region === "") {
47
+ return getEndpointFromMRAPArn({ ...options, clientRegion, mrapAlias: accesspointName, hostnameSuffix });
48
+ }
49
+ if (outpostId) {
50
+ return getEndpointFromOutpostArn({ ...options, clientRegion, outpostId, accesspointName, hostnameSuffix });
51
+ }
52
+ return getEndpointFromAccessPointArn({ ...options, clientRegion, accesspointName, hostnameSuffix });
53
+ };
54
+ const getEndpointFromObjectLambdaArn = ({ dualstackEndpoint = false, tlsCompatible = true, useArnRegion, clientRegion, clientSigningRegion = clientRegion, accesspointName, bucketName, hostnameSuffix, }) => {
55
+ const { accountId, region, service } = bucketName;
56
+ bucketHostnameUtils_1.validateRegionalClient(clientRegion);
57
+ bucketHostnameUtils_1.validateRegion(region, { useArnRegion, clientRegion, clientSigningRegion, allowFipsRegion: true });
58
+ bucketHostnameUtils_1.validateNoDualstack(dualstackEndpoint);
59
+ const DNSHostLabel = `${accesspointName}-${accountId}`;
60
+ bucketHostnameUtils_1.validateDNSHostLabel(DNSHostLabel, { tlsCompatible });
61
+ const endpointRegion = useArnRegion ? region : clientRegion;
62
+ const signingRegion = useArnRegion ? region : clientSigningRegion;
63
+ return {
64
+ bucketEndpoint: true,
65
+ hostname: `${DNSHostLabel}.${service}${bucketHostnameUtils_1.isFipsRegion(clientRegion) ? "-fips" : ""}.${bucketHostnameUtils_1.getPseudoRegion(endpointRegion)}.${hostnameSuffix}`,
66
+ signingRegion,
67
+ signingService: service,
68
+ };
69
+ };
70
+ const getEndpointFromMRAPArn = ({ disableMultiregionAccessPoints, dualstackEndpoint = false, isCustomEndpoint, mrapAlias, hostnameSuffix, }) => {
71
+ if (disableMultiregionAccessPoints === true) {
72
+ throw new Error("SDK is attempting to use a MRAP ARN. Please enable to feature.");
73
+ }
74
+ bucketHostnameUtils_1.validateMrapAlias(mrapAlias);
75
+ bucketHostnameUtils_1.validateNoDualstack(dualstackEndpoint);
76
+ return {
77
+ bucketEndpoint: true,
78
+ hostname: `${mrapAlias}${isCustomEndpoint ? "" : `.accesspoint.s3-global`}.${hostnameSuffix}`,
79
+ signingRegion: "*",
80
+ };
81
+ };
82
+ const getEndpointFromOutpostArn = ({ useArnRegion, clientRegion, clientSigningRegion = clientRegion, bucketName, outpostId, dualstackEndpoint = false, tlsCompatible = true, accesspointName, isCustomEndpoint, hostnameSuffix, }) => {
83
+ bucketHostnameUtils_1.validateRegionalClient(clientRegion);
84
+ bucketHostnameUtils_1.validateRegion(bucketName.region, { useArnRegion, clientRegion, clientSigningRegion });
85
+ const DNSHostLabel = `${accesspointName}-${bucketName.accountId}`;
86
+ bucketHostnameUtils_1.validateDNSHostLabel(DNSHostLabel, { tlsCompatible });
87
+ const endpointRegion = useArnRegion ? bucketName.region : clientRegion;
88
+ const signingRegion = useArnRegion ? bucketName.region : clientSigningRegion;
89
+ bucketHostnameUtils_1.validateOutpostService(bucketName.service);
90
+ bucketHostnameUtils_1.validateDNSHostLabel(outpostId, { tlsCompatible });
91
+ bucketHostnameUtils_1.validateNoDualstack(dualstackEndpoint);
92
+ bucketHostnameUtils_1.validateNoFIPS(endpointRegion);
93
+ const hostnamePrefix = `${DNSHostLabel}.${outpostId}`;
94
+ return {
95
+ bucketEndpoint: true,
96
+ hostname: `${hostnamePrefix}${isCustomEndpoint ? "" : `.s3-outposts.${endpointRegion}`}.${hostnameSuffix}`,
97
+ signingRegion,
98
+ signingService: "s3-outposts",
99
+ };
100
+ };
101
+ const getEndpointFromAccessPointArn = ({ useArnRegion, clientRegion, clientSigningRegion = clientRegion, bucketName, dualstackEndpoint = false, tlsCompatible = true, accesspointName, isCustomEndpoint, hostnameSuffix, }) => {
102
+ bucketHostnameUtils_1.validateRegionalClient(clientRegion);
103
+ bucketHostnameUtils_1.validateRegion(bucketName.region, { useArnRegion, clientRegion, clientSigningRegion, allowFipsRegion: true });
104
+ const hostnamePrefix = `${accesspointName}-${bucketName.accountId}`;
105
+ bucketHostnameUtils_1.validateDNSHostLabel(hostnamePrefix, { tlsCompatible });
106
+ const endpointRegion = useArnRegion ? bucketName.region : clientRegion;
107
+ const signingRegion = useArnRegion ? bucketName.region : clientSigningRegion;
108
+ bucketHostnameUtils_1.validateS3Service(bucketName.service);
109
+ return {
110
+ bucketEndpoint: true,
111
+ hostname: `${hostnamePrefix}${isCustomEndpoint
112
+ ? ""
113
+ : `.s3-accesspoint${bucketHostnameUtils_1.isFipsRegion(clientRegion) ? "-fips" : ""}${dualstackEndpoint ? ".dualstack" : ""}.${bucketHostnameUtils_1.getPseudoRegion(endpointRegion)}`}.${hostnameSuffix}`,
114
+ signingRegion,
115
+ };
116
+ };
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateMrapAlias = exports.validateNoFIPS = exports.validateNoDualstack = exports.getArnResources = exports.validateCustomEndpoint = exports.validateDNSHostLabel = exports.validateAccountId = exports.isFipsRegion = exports.validateRegionalClient = exports.validateRegion = exports.validatePartition = exports.validateOutpostService = exports.validateS3Service = exports.validateService = exports.validateArnEndpointOptions = exports.getSuffixForArnEndpoint = exports.getSuffix = exports.isDnsCompatibleBucketName = exports.getPseudoRegion = exports.isBucketNameOptions = exports.S3_HOSTNAME_PATTERN = exports.DOT_PATTERN = void 0;
4
+ const DOMAIN_PATTERN = /^[a-z0-9][a-z0-9\.\-]{1,61}[a-z0-9]$/;
5
+ const IP_ADDRESS_PATTERN = /(\d+\.){3}\d+/;
6
+ const DOTS_PATTERN = /\.\./;
7
+ exports.DOT_PATTERN = /\./;
8
+ exports.S3_HOSTNAME_PATTERN = /^(.+\.)?s3[.-]([a-z0-9-]+)\./;
9
+ const S3_US_EAST_1_ALTNAME_PATTERN = /^s3(-external-1)?\.amazonaws\.com$/;
10
+ const AWS_PARTITION_SUFFIX = "amazonaws.com";
11
+ const isBucketNameOptions = (options) => typeof options.bucketName === "string";
12
+ exports.isBucketNameOptions = isBucketNameOptions;
13
+ const getPseudoRegion = (region) => (exports.isFipsRegion(region) ? region.replace(/fips-|-fips/, "") : region);
14
+ exports.getPseudoRegion = getPseudoRegion;
15
+ const isDnsCompatibleBucketName = (bucketName) => DOMAIN_PATTERN.test(bucketName) && !IP_ADDRESS_PATTERN.test(bucketName) && !DOTS_PATTERN.test(bucketName);
16
+ exports.isDnsCompatibleBucketName = isDnsCompatibleBucketName;
17
+ const getRegionalSuffix = (hostname) => {
18
+ const parts = hostname.match(exports.S3_HOSTNAME_PATTERN);
19
+ return [parts[2], hostname.replace(new RegExp(`^${parts[0]}`), "")];
20
+ };
21
+ const getSuffix = (hostname) => S3_US_EAST_1_ALTNAME_PATTERN.test(hostname) ? ["us-east-1", AWS_PARTITION_SUFFIX] : getRegionalSuffix(hostname);
22
+ exports.getSuffix = getSuffix;
23
+ const getSuffixForArnEndpoint = (hostname) => S3_US_EAST_1_ALTNAME_PATTERN.test(hostname)
24
+ ? [hostname.replace(`.${AWS_PARTITION_SUFFIX}`, ""), AWS_PARTITION_SUFFIX]
25
+ : getRegionalSuffix(hostname);
26
+ exports.getSuffixForArnEndpoint = getSuffixForArnEndpoint;
27
+ const validateArnEndpointOptions = (options) => {
28
+ if (options.pathStyleEndpoint) {
29
+ throw new Error("Path-style S3 endpoint is not supported when bucket is an ARN");
30
+ }
31
+ if (options.accelerateEndpoint) {
32
+ throw new Error("Accelerate endpoint is not supported when bucket is an ARN");
33
+ }
34
+ if (!options.tlsCompatible) {
35
+ throw new Error("HTTPS is required when bucket is an ARN");
36
+ }
37
+ };
38
+ exports.validateArnEndpointOptions = validateArnEndpointOptions;
39
+ const validateService = (service) => {
40
+ if (service !== "s3" && service !== "s3-outposts" && service !== "s3-object-lambda") {
41
+ throw new Error("Expect 's3' or 's3-outposts' or 's3-object-lambda' in ARN service component");
42
+ }
43
+ };
44
+ exports.validateService = validateService;
45
+ const validateS3Service = (service) => {
46
+ if (service !== "s3") {
47
+ throw new Error("Expect 's3' in Accesspoint ARN service component");
48
+ }
49
+ };
50
+ exports.validateS3Service = validateS3Service;
51
+ const validateOutpostService = (service) => {
52
+ if (service !== "s3-outposts") {
53
+ throw new Error("Expect 's3-posts' in Outpost ARN service component");
54
+ }
55
+ };
56
+ exports.validateOutpostService = validateOutpostService;
57
+ const validatePartition = (partition, options) => {
58
+ if (partition !== options.clientPartition) {
59
+ throw new Error(`Partition in ARN is incompatible, got "${partition}" but expected "${options.clientPartition}"`);
60
+ }
61
+ };
62
+ exports.validatePartition = validatePartition;
63
+ const validateRegion = (region, options) => {
64
+ if (region === "") {
65
+ throw new Error("ARN region is empty");
66
+ }
67
+ if (exports.isFipsRegion(options.clientRegion)) {
68
+ if (!options.allowFipsRegion) {
69
+ throw new Error("FIPS region is not supported");
70
+ }
71
+ else if (!isEqualRegions(region, options.clientRegion)) {
72
+ throw new Error(`Client FIPS region ${options.clientRegion} doesn't match region ${region} in ARN`);
73
+ }
74
+ }
75
+ if (!options.useArnRegion &&
76
+ !isEqualRegions(region, options.clientRegion || "") &&
77
+ !isEqualRegions(region, options.clientSigningRegion || "")) {
78
+ throw new Error(`Region in ARN is incompatible, got ${region} but expected ${options.clientRegion}`);
79
+ }
80
+ };
81
+ exports.validateRegion = validateRegion;
82
+ const validateRegionalClient = (region) => {
83
+ if (["s3-external-1", "aws-global"].includes(exports.getPseudoRegion(region))) {
84
+ throw new Error(`Client region ${region} is not regional`);
85
+ }
86
+ };
87
+ exports.validateRegionalClient = validateRegionalClient;
88
+ const isFipsRegion = (region) => region.startsWith("fips-") || region.endsWith("-fips");
89
+ exports.isFipsRegion = isFipsRegion;
90
+ const isEqualRegions = (regionA, regionB) => regionA === regionB || exports.getPseudoRegion(regionA) === regionB || regionA === exports.getPseudoRegion(regionB);
91
+ const validateAccountId = (accountId) => {
92
+ if (!/[0-9]{12}/.exec(accountId)) {
93
+ throw new Error("Access point ARN accountID does not match regex '[0-9]{12}'");
94
+ }
95
+ };
96
+ exports.validateAccountId = validateAccountId;
97
+ const validateDNSHostLabel = (label, options = { tlsCompatible: true }) => {
98
+ if (label.length >= 64 ||
99
+ !/^[a-z0-9][a-z0-9.-]*[a-z0-9]$/.test(label) ||
100
+ /(\d+\.){3}\d+/.test(label) ||
101
+ /[.-]{2}/.test(label) ||
102
+ ((options === null || options === void 0 ? void 0 : options.tlsCompatible) && exports.DOT_PATTERN.test(label))) {
103
+ throw new Error(`Invalid DNS label ${label}`);
104
+ }
105
+ };
106
+ exports.validateDNSHostLabel = validateDNSHostLabel;
107
+ const validateCustomEndpoint = (options) => {
108
+ if (options.isCustomEndpoint) {
109
+ if (options.dualstackEndpoint)
110
+ throw new Error("Dualstack endpoint is not supported with custom endpoint");
111
+ if (options.accelerateEndpoint)
112
+ throw new Error("Accelerate endpoint is not supported with custom endpoint");
113
+ }
114
+ };
115
+ exports.validateCustomEndpoint = validateCustomEndpoint;
116
+ const getArnResources = (resource) => {
117
+ const delimiter = resource.includes(":") ? ":" : "/";
118
+ const [resourceType, ...rest] = resource.split(delimiter);
119
+ if (resourceType === "accesspoint") {
120
+ if (rest.length !== 1 || rest[0] === "") {
121
+ throw new Error(`Access Point ARN should have one resource accesspoint${delimiter}{accesspointname}`);
122
+ }
123
+ return { accesspointName: rest[0] };
124
+ }
125
+ else if (resourceType === "outpost") {
126
+ if (!rest[0] || rest[1] !== "accesspoint" || !rest[2] || rest.length !== 3) {
127
+ throw new Error(`Outpost ARN should have resource outpost${delimiter}{outpostId}${delimiter}accesspoint${delimiter}{accesspointName}`);
128
+ }
129
+ const [outpostId, _, accesspointName] = rest;
130
+ return { outpostId, accesspointName };
131
+ }
132
+ else {
133
+ throw new Error(`ARN resource should begin with 'accesspoint${delimiter}' or 'outpost${delimiter}'`);
134
+ }
135
+ };
136
+ exports.getArnResources = getArnResources;
137
+ const validateNoDualstack = (dualstackEndpoint) => {
138
+ if (dualstackEndpoint)
139
+ throw new Error("Dualstack endpoint is not supported with Outpost or Multi-region Access Point ARN.");
140
+ };
141
+ exports.validateNoDualstack = validateNoDualstack;
142
+ const validateNoFIPS = (region) => {
143
+ if (exports.isFipsRegion(region !== null && region !== void 0 ? region : ""))
144
+ throw new Error(`FIPS region is not supported with Outpost, got ${region}`);
145
+ };
146
+ exports.validateNoFIPS = validateNoFIPS;
147
+ const validateMrapAlias = (name) => {
148
+ try {
149
+ name.split(".").forEach((label) => {
150
+ exports.validateDNSHostLabel(label);
151
+ });
152
+ }
153
+ catch (e) {
154
+ throw new Error(`"${name}" is not a DNS compatible name.`);
155
+ }
156
+ };
157
+ exports.validateMrapAlias = validateMrapAlias;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_CONFIG_OPTIONS = exports.NODE_USE_ARN_REGION_CONFIG_OPTIONS = exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_INI_NAME = exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_ENV_NAME = exports.NODE_USE_ARN_REGION_INI_NAME = exports.NODE_USE_ARN_REGION_ENV_NAME = exports.resolveBucketEndpointConfig = void 0;
4
+ function resolveBucketEndpointConfig(input) {
5
+ const { bucketEndpoint = false, forcePathStyle = false, useAccelerateEndpoint = false, useDualstackEndpoint = false, useArnRegion = false, disableMultiregionAccessPoints = false, } = input;
6
+ return {
7
+ ...input,
8
+ bucketEndpoint,
9
+ forcePathStyle,
10
+ useAccelerateEndpoint,
11
+ useDualstackEndpoint,
12
+ useArnRegion: typeof useArnRegion === "function" ? useArnRegion : () => Promise.resolve(useArnRegion),
13
+ disableMultiregionAccessPoints: typeof disableMultiregionAccessPoints === "function"
14
+ ? disableMultiregionAccessPoints
15
+ : () => Promise.resolve(disableMultiregionAccessPoints),
16
+ };
17
+ }
18
+ exports.resolveBucketEndpointConfig = resolveBucketEndpointConfig;
19
+ exports.NODE_USE_ARN_REGION_ENV_NAME = "AWS_S3_USE_ARN_REGION";
20
+ exports.NODE_USE_ARN_REGION_INI_NAME = "s3_use_arn_region";
21
+ exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_ENV_NAME = "AWS_S3_DISABLE_MULTIREGION_ACCESS_POINTS";
22
+ exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_INI_NAME = "s3_disable_multiregion_access_points";
23
+ exports.NODE_USE_ARN_REGION_CONFIG_OPTIONS = {
24
+ environmentVariableSelector: (env) => {
25
+ if (!Object.prototype.hasOwnProperty.call(env, exports.NODE_USE_ARN_REGION_ENV_NAME))
26
+ return undefined;
27
+ if (env[exports.NODE_USE_ARN_REGION_ENV_NAME] === "true")
28
+ return true;
29
+ if (env[exports.NODE_USE_ARN_REGION_ENV_NAME] === "false")
30
+ return false;
31
+ throw new Error(`Cannot load env ${exports.NODE_USE_ARN_REGION_ENV_NAME}. Expected "true" or "false", got ${env[exports.NODE_USE_ARN_REGION_ENV_NAME]}.`);
32
+ },
33
+ configFileSelector: (profile) => {
34
+ if (!Object.prototype.hasOwnProperty.call(profile, exports.NODE_USE_ARN_REGION_INI_NAME))
35
+ return undefined;
36
+ if (profile[exports.NODE_USE_ARN_REGION_INI_NAME] === "true")
37
+ return true;
38
+ if (profile[exports.NODE_USE_ARN_REGION_INI_NAME] === "false")
39
+ return false;
40
+ throw new Error(`Cannot load shared config entry ${exports.NODE_USE_ARN_REGION_INI_NAME}. Expected "true" or "false", got ${profile[exports.NODE_USE_ARN_REGION_INI_NAME]}.`);
41
+ },
42
+ default: false,
43
+ };
44
+ exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_CONFIG_OPTIONS = {
45
+ environmentVariableSelector: (env) => {
46
+ if (!Object.prototype.hasOwnProperty.call(env, exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_ENV_NAME))
47
+ return undefined;
48
+ if (env[exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_ENV_NAME] === "true")
49
+ return true;
50
+ if (env[exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_ENV_NAME] === "false")
51
+ return false;
52
+ throw new Error(`Cannot load env ${exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_ENV_NAME}. Expected "true" or "false", got ${env[exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_ENV_NAME]}.`);
53
+ },
54
+ configFileSelector: (profile) => {
55
+ if (!Object.prototype.hasOwnProperty.call(profile, exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_INI_NAME))
56
+ return undefined;
57
+ if (profile[exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_INI_NAME] === "true")
58
+ return true;
59
+ if (profile[exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_INI_NAME] === "false")
60
+ return false;
61
+ throw new Error(`Cannot load shared config entry ${exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_INI_NAME}. Expected "true" or "false", got ${profile[exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_INI_NAME]}.`);
62
+ },
63
+ default: false,
64
+ };
@@ -16,4 +16,3 @@ Object.defineProperty(exports, "validateRegion", { enumerable: true, get: functi
16
16
  Object.defineProperty(exports, "validateDNSHostLabel", { enumerable: true, get: function () { return bucketHostnameUtils_1.validateDNSHostLabel; } });
17
17
  Object.defineProperty(exports, "validateNoDualstack", { enumerable: true, get: function () { return bucketHostnameUtils_1.validateNoDualstack; } });
18
18
  Object.defineProperty(exports, "validateNoFIPS", { enumerable: true, get: function () { return bucketHostnameUtils_1.validateNoFIPS; } });
19
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLHFFQUEyQztBQUMzQywyREFBaUM7QUFDakMsMkRBQWlDO0FBQ2pDLDZEQVcrQjtBQVY3QixzSEFBQSxlQUFlLE9BQUE7QUFDZixzSEFBQSxlQUFlLE9BQUE7QUFDZiw4SEFBQSx1QkFBdUIsT0FBQTtBQUN2Qiw2SEFBQSxzQkFBc0IsT0FBQTtBQUN0Qix3SEFBQSxpQkFBaUIsT0FBQTtBQUNqQix3SEFBQSxpQkFBaUIsT0FBQTtBQUNqQixxSEFBQSxjQUFjLE9BQUE7QUFDZCwySEFBQSxvQkFBb0IsT0FBQTtBQUNwQiwwSEFBQSxtQkFBbUIsT0FBQTtBQUNuQixxSEFBQSxjQUFjLE9BQUEiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tIFwiLi9idWNrZXRFbmRwb2ludE1pZGRsZXdhcmVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2J1Y2tldEhvc3RuYW1lXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb25maWd1cmF0aW9uc1wiO1xuZXhwb3J0IHtcbiAgZ2V0QXJuUmVzb3VyY2VzLFxuICBnZXRQc2V1ZG9SZWdpb24sXG4gIGdldFN1ZmZpeEZvckFybkVuZHBvaW50LFxuICB2YWxpZGF0ZU91dHBvc3RTZXJ2aWNlLFxuICB2YWxpZGF0ZVBhcnRpdGlvbixcbiAgdmFsaWRhdGVBY2NvdW50SWQsXG4gIHZhbGlkYXRlUmVnaW9uLFxuICB2YWxpZGF0ZUROU0hvc3RMYWJlbCxcbiAgdmFsaWRhdGVOb0R1YWxzdGFjayxcbiAgdmFsaWRhdGVOb0ZJUFMsXG59IGZyb20gXCIuL2J1Y2tldEhvc3RuYW1lVXRpbHNcIjtcbiJdfQ==
@@ -0,0 +1,100 @@
1
+ import { __assign, __awaiter, __generator } from "tslib";
2
+ import { HttpRequest } from "@aws-sdk/protocol-http";
3
+ import { parse as parseArn, validate as validateArn } from "@aws-sdk/util-arn-parser";
4
+ import { bucketHostname } from "./bucketHostname";
5
+ import { getPseudoRegion } from "./bucketHostnameUtils";
6
+ export var bucketEndpointMiddleware = function (options) { return function (next, context) { return function (args) { return __awaiter(void 0, void 0, void 0, function () {
7
+ var bucketName, replaceBucketInPath, request, bucketArn, clientRegion, _a, _b, partition, _c, signingRegion, useArnRegion, _d, hostname, bucketEndpoint, modifiedSigningRegion, signingService, _e, clientRegion, _f, _g, hostname, bucketEndpoint;
8
+ var _h;
9
+ return __generator(this, function (_j) {
10
+ switch (_j.label) {
11
+ case 0:
12
+ bucketName = args.input.Bucket;
13
+ replaceBucketInPath = options.bucketEndpoint;
14
+ request = args.request;
15
+ if (!HttpRequest.isInstance(request)) return [3, 9];
16
+ if (!options.bucketEndpoint) return [3, 1];
17
+ request.hostname = bucketName;
18
+ return [3, 8];
19
+ case 1:
20
+ if (!validateArn(bucketName)) return [3, 6];
21
+ bucketArn = parseArn(bucketName);
22
+ _a = getPseudoRegion;
23
+ return [4, options.region()];
24
+ case 2:
25
+ clientRegion = _a.apply(void 0, [_j.sent()]);
26
+ return [4, options.regionInfoProvider(clientRegion)];
27
+ case 3:
28
+ _b = (_j.sent()) || {}, partition = _b.partition, _c = _b.signingRegion, signingRegion = _c === void 0 ? clientRegion : _c;
29
+ return [4, options.useArnRegion()];
30
+ case 4:
31
+ useArnRegion = _j.sent();
32
+ _e = bucketHostname;
33
+ _h = {
34
+ bucketName: bucketArn,
35
+ baseHostname: request.hostname,
36
+ accelerateEndpoint: options.useAccelerateEndpoint,
37
+ dualstackEndpoint: options.useDualstackEndpoint,
38
+ pathStyleEndpoint: options.forcePathStyle,
39
+ tlsCompatible: request.protocol === "https:",
40
+ useArnRegion: useArnRegion,
41
+ clientPartition: partition,
42
+ clientSigningRegion: signingRegion,
43
+ clientRegion: clientRegion,
44
+ isCustomEndpoint: options.isCustomEndpoint
45
+ };
46
+ return [4, options.disableMultiregionAccessPoints()];
47
+ case 5:
48
+ _d = _e.apply(void 0, [(_h.disableMultiregionAccessPoints = _j.sent(),
49
+ _h)]), hostname = _d.hostname, bucketEndpoint = _d.bucketEndpoint, modifiedSigningRegion = _d.signingRegion, signingService = _d.signingService;
50
+ if (modifiedSigningRegion && modifiedSigningRegion !== signingRegion) {
51
+ context["signing_region"] = modifiedSigningRegion;
52
+ }
53
+ if (signingService && signingService !== "s3") {
54
+ context["signing_service"] = signingService;
55
+ }
56
+ request.hostname = hostname;
57
+ replaceBucketInPath = bucketEndpoint;
58
+ return [3, 8];
59
+ case 6:
60
+ _f = getPseudoRegion;
61
+ return [4, options.region()];
62
+ case 7:
63
+ clientRegion = _f.apply(void 0, [_j.sent()]);
64
+ _g = bucketHostname({
65
+ bucketName: bucketName,
66
+ clientRegion: clientRegion,
67
+ baseHostname: request.hostname,
68
+ accelerateEndpoint: options.useAccelerateEndpoint,
69
+ dualstackEndpoint: options.useDualstackEndpoint,
70
+ pathStyleEndpoint: options.forcePathStyle,
71
+ tlsCompatible: request.protocol === "https:",
72
+ isCustomEndpoint: options.isCustomEndpoint,
73
+ }), hostname = _g.hostname, bucketEndpoint = _g.bucketEndpoint;
74
+ request.hostname = hostname;
75
+ replaceBucketInPath = bucketEndpoint;
76
+ _j.label = 8;
77
+ case 8:
78
+ if (replaceBucketInPath) {
79
+ request.path = request.path.replace(/^(\/)?[^\/]+/, "");
80
+ if (request.path === "") {
81
+ request.path = "/";
82
+ }
83
+ }
84
+ _j.label = 9;
85
+ case 9: return [2, next(__assign(__assign({}, args), { request: request }))];
86
+ }
87
+ });
88
+ }); }; }; };
89
+ export var bucketEndpointMiddlewareOptions = {
90
+ tags: ["BUCKET_ENDPOINT"],
91
+ name: "bucketEndpointMiddleware",
92
+ relation: "before",
93
+ toMiddleware: "hostHeaderMiddleware",
94
+ override: true,
95
+ };
96
+ export var getBucketEndpointPlugin = function (options) { return ({
97
+ applyToStack: function (clientStack) {
98
+ clientStack.addRelativeTo(bucketEndpointMiddleware(options), bucketEndpointMiddlewareOptions);
99
+ },
100
+ }); };