@aws-sdk/middleware-bucket-endpoint 3.30.0 → 3.35.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 (38) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/dist-cjs/bucketEndpointMiddleware.js +82 -0
  3. package/dist-cjs/bucketHostname.js +117 -0
  4. package/dist-cjs/bucketHostnameUtils.js +158 -0
  5. package/dist-cjs/configurations.js +65 -0
  6. package/{dist/cjs → dist-cjs}/index.js +4 -4
  7. package/dist-es/bucketEndpointMiddleware.js +101 -0
  8. package/dist-es/bucketHostname.js +119 -0
  9. package/dist-es/bucketHostnameUtils.js +145 -0
  10. package/dist-es/configurations.js +54 -0
  11. package/dist-es/index.js +5 -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 +13 -2
  15. package/{dist/types → dist-types}/configurations.d.ts +13 -1
  16. package/{dist/types → dist-types}/index.d.ts +0 -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 -2
  20. package/{dist/types → dist-types}/ts3.4/configurations.d.ts +13 -1
  21. package/{dist/types → dist-types}/ts3.4/index.d.ts +0 -0
  22. package/package.json +15 -14
  23. package/src/bucketEndpointMiddleware.ts +63 -68
  24. package/src/bucketHostname.ts +148 -72
  25. package/src/bucketHostnameUtils.ts +33 -6
  26. package/src/configurations.ts +39 -1
  27. package/tsconfig.cjs.json +3 -4
  28. package/tsconfig.es.json +3 -4
  29. package/tsconfig.types.json +9 -0
  30. package/dist/cjs/bucketEndpointMiddleware.js +0 -83
  31. package/dist/cjs/bucketHostname.js +0 -92
  32. package/dist/cjs/bucketHostnameUtils.js +0 -199
  33. package/dist/cjs/configurations.js +0 -44
  34. package/dist/es/bucketEndpointMiddleware.js +0 -101
  35. package/dist/es/bucketHostname.js +0 -90
  36. package/dist/es/bucketHostnameUtils.js +0 -188
  37. package/dist/es/configurations.js +0 -34
  38. package/dist/es/index.js +0 -5
@@ -14,13 +14,21 @@ export interface BucketEndpointInputConfig {
14
14
  */
15
15
  useAccelerateEndpoint?: boolean;
16
16
  /**
17
- * Enables IPv6/IPv4 dualstack endpoint. When a DNS lookup is performed on an endpoint of this type, it returns an “A” record with an IPv4 address and an “AAAA” record with an IPv6 address. In most cases the network stack in the client environment will automatically prefer the AAAA record and make a connection using the IPv6 address. Note, however, that currently on Windows, the IPv4 address will be preferred.
17
+ * Enables IPv6/IPv4 dualstack endpoint. When a DNS lookup is performed on an endpoint of this type, it returns an “A”
18
+ * record with an IPv4 address and an “AAAA” record with an IPv6 address. In most cases the network stack in the
19
+ * client environment will automatically prefer the AAAA record and make a connection using the IPv6 address. Note,
20
+ * however, that currently on Windows, the IPv4 address will be preferred.
18
21
  */
19
22
  useDualstackEndpoint?: boolean;
20
23
  /**
21
24
  * Whether to override the request region with the region inferred from requested resource's ARN. Defaults to false
22
25
  */
23
26
  useArnRegion?: boolean | Provider<boolean>;
27
+ /**
28
+ * Whether to prevent SDK from making cross-region request when supplied bucket is a multi-region access point ARN.
29
+ * Defaults to false
30
+ */
31
+ disableMultiregionAccessPoints?: boolean | Provider<boolean>;
24
32
  }
25
33
  interface PreviouslyResolved {
26
34
  isCustomEndpoint: boolean;
@@ -62,14 +70,18 @@ export interface BucketEndpointResolvedConfig {
62
70
  * @internal
63
71
  */
64
72
  regionInfoProvider: RegionInfoProvider;
73
+ disableMultiregionAccessPoints: Provider<boolean>;
65
74
  }
66
75
  export declare function resolveBucketEndpointConfig<T>(input: T & PreviouslyResolved & BucketEndpointInputConfig): T & BucketEndpointResolvedConfig;
67
76
  export declare const NODE_USE_ARN_REGION_ENV_NAME = "AWS_S3_USE_ARN_REGION";
68
77
  export declare const NODE_USE_ARN_REGION_INI_NAME = "s3_use_arn_region";
78
+ export declare const NODE_DISABLE_MULTIREGION_ACCESS_POINT_ENV_NAME = "AWS_S3_DISABLE_MULTIREGION_ACCESS_POINTS";
79
+ export declare const NODE_DISABLE_MULTIREGION_ACCESS_POINT_INI_NAME = "s3_disable_multiregion_access_points";
69
80
  /**
70
81
  * Config to load useArnRegion from environment variables and shared INI files
71
82
  *
72
83
  * @api private
73
84
  */
74
85
  export declare const NODE_USE_ARN_REGION_CONFIG_OPTIONS: LoadedConfigSelectors<boolean>;
86
+ export declare const NODE_DISABLE_MULTIREGION_ACCESS_POINT_CONFIG_OPTIONS: LoadedConfigSelectors<boolean>;
75
87
  export {};
File without changes
@@ -19,6 +19,7 @@ export interface ArnHostnameParams extends Pick<BucketHostnameParams, Exclude<ke
19
19
  clientSigningRegion?: string;
20
20
  clientPartition?: string;
21
21
  useArnRegion?: boolean;
22
+ disableMultiregionAccessPoints?: boolean;
22
23
  }
23
24
  export declare const isBucketNameOptions: (options: BucketHostnameParams | ArnHostnameParams) => options is BucketHostnameParams;
24
25
  /**
@@ -97,6 +98,11 @@ export declare const validateAccountId: (accountId: string) => void;
97
98
  export declare const validateDNSHostLabel: (label: string, options?: {
98
99
  tlsCompatible?: boolean;
99
100
  }) => void;
101
+ export declare const validateCustomEndpoint: (options: {
102
+ isCustomEndpoint?: boolean;
103
+ dualstackEndpoint?: boolean;
104
+ accelerateEndpoint?: boolean;
105
+ }) => void;
100
106
  /**
101
107
  * Validate and parse an Access Point ARN or Outposts ARN
102
108
  * @internal
@@ -112,9 +118,14 @@ export declare const getArnResources: (resource: string) => {
112
118
  * Throw if dual stack configuration is set to true.
113
119
  * @internal
114
120
  */
115
- export declare const validateNoDualstack: (dualstackEndpoint: boolean) => void;
121
+ export declare const validateNoDualstack: (dualstackEndpoint?: boolean | undefined) => void;
116
122
  /**
117
123
  * Validate region is not appended or prepended with a `fips-`
118
124
  * @internal
119
125
  */
120
- export declare const validateNoFIPS: (region: string) => void;
126
+ export declare const validateNoFIPS: (region?: string | undefined) => void;
127
+ /**
128
+ * Validate the multi-region access point alias.
129
+ * @private
130
+ */
131
+ export declare const validateMrapAlias: (name: string) => void;
@@ -14,13 +14,21 @@ export interface BucketEndpointInputConfig {
14
14
  */
15
15
  useAccelerateEndpoint?: boolean;
16
16
  /**
17
- * Enables IPv6/IPv4 dualstack endpoint. When a DNS lookup is performed on an endpoint of this type, it returns an “A” record with an IPv4 address and an “AAAA” record with an IPv6 address. In most cases the network stack in the client environment will automatically prefer the AAAA record and make a connection using the IPv6 address. Note, however, that currently on Windows, the IPv4 address will be preferred.
17
+ * Enables IPv6/IPv4 dualstack endpoint. When a DNS lookup is performed on an endpoint of this type, it returns an “A”
18
+ * record with an IPv4 address and an “AAAA” record with an IPv6 address. In most cases the network stack in the
19
+ * client environment will automatically prefer the AAAA record and make a connection using the IPv6 address. Note,
20
+ * however, that currently on Windows, the IPv4 address will be preferred.
18
21
  */
19
22
  useDualstackEndpoint?: boolean;
20
23
  /**
21
24
  * Whether to override the request region with the region inferred from requested resource's ARN. Defaults to false
22
25
  */
23
26
  useArnRegion?: boolean | Provider<boolean>;
27
+ /**
28
+ * Whether to prevent SDK from making cross-region request when supplied bucket is a multi-region access point ARN.
29
+ * Defaults to false
30
+ */
31
+ disableMultiregionAccessPoints?: boolean | Provider<boolean>;
24
32
  }
25
33
  interface PreviouslyResolved {
26
34
  isCustomEndpoint: boolean;
@@ -62,14 +70,18 @@ export interface BucketEndpointResolvedConfig {
62
70
  * @internal
63
71
  */
64
72
  regionInfoProvider: RegionInfoProvider;
73
+ disableMultiregionAccessPoints: Provider<boolean>;
65
74
  }
66
75
  export declare function resolveBucketEndpointConfig<T>(input: T & PreviouslyResolved & BucketEndpointInputConfig): T & BucketEndpointResolvedConfig;
67
76
  export declare const NODE_USE_ARN_REGION_ENV_NAME = "AWS_S3_USE_ARN_REGION";
68
77
  export declare const NODE_USE_ARN_REGION_INI_NAME = "s3_use_arn_region";
78
+ export declare const NODE_DISABLE_MULTIREGION_ACCESS_POINT_ENV_NAME = "AWS_S3_DISABLE_MULTIREGION_ACCESS_POINTS";
79
+ export declare const NODE_DISABLE_MULTIREGION_ACCESS_POINT_INI_NAME = "s3_disable_multiregion_access_points";
69
80
  /**
70
81
  * Config to load useArnRegion from environment variables and shared INI files
71
82
  *
72
83
  * @api private
73
84
  */
74
85
  export declare const NODE_USE_ARN_REGION_CONFIG_OPTIONS: LoadedConfigSelectors<boolean>;
86
+ export declare const NODE_DISABLE_MULTIREGION_ACCESS_POINT_CONFIG_OPTIONS: LoadedConfigSelectors<boolean>;
75
87
  export {};
File without changes
package/package.json CHANGED
@@ -1,41 +1,42 @@
1
1
  {
2
2
  "name": "@aws-sdk/middleware-bucket-endpoint",
3
- "version": "3.30.0",
3
+ "version": "3.35.0",
4
4
  "scripts": {
5
+ "build": "yarn build:cjs && yarn build:es && yarn build:types",
5
6
  "build:cjs": "tsc -p tsconfig.cjs.json",
6
7
  "build:es": "tsc -p tsconfig.es.json",
7
- "build": "yarn build:es && yarn build:cjs",
8
- "downlevel-dts": "downlevel-dts dist/types dist/types/ts3.4",
8
+ "build:types": "tsc -p tsconfig.types.json",
9
+ "downlevel-dts": "downlevel-dts dist-types dist-types/ts3.4",
9
10
  "test": "jest"
10
11
  },
11
- "main": "./dist/cjs/index.js",
12
- "module": "./dist/es/index.js",
13
- "types": "./dist/types/index.d.ts",
12
+ "main": "./dist-cjs/index.js",
13
+ "module": "./dist-es/index.js",
14
+ "types": "./dist-types/index.d.ts",
14
15
  "author": {
15
16
  "name": "AWS SDK for JavaScript Team",
16
17
  "url": "https://aws.amazon.com/javascript/"
17
18
  },
18
19
  "license": "Apache-2.0",
19
20
  "dependencies": {
20
- "@aws-sdk/protocol-http": "3.29.0",
21
- "@aws-sdk/types": "3.29.0",
22
- "@aws-sdk/util-arn-parser": "3.29.0",
21
+ "@aws-sdk/protocol-http": "3.35.0",
22
+ "@aws-sdk/types": "3.35.0",
23
+ "@aws-sdk/util-arn-parser": "3.35.0",
23
24
  "tslib": "^2.3.0"
24
25
  },
25
26
  "devDependencies": {
26
- "@aws-sdk/middleware-stack": "3.29.0",
27
- "@aws-sdk/node-config-provider": "3.29.0",
27
+ "@aws-sdk/middleware-stack": "3.35.0",
28
+ "@aws-sdk/node-config-provider": "3.35.0",
28
29
  "@types/jest": "^26.0.4",
29
30
  "jest": "^26.1.0",
30
- "typescript": "~4.4.2"
31
+ "typescript": "~4.3.5"
31
32
  },
32
33
  "engines": {
33
34
  "node": ">= 10.0.0"
34
35
  },
35
36
  "typesVersions": {
36
37
  "<4.0": {
37
- "dist/types/*": [
38
- "dist/types/ts3.4/*"
38
+ "dist-types/*": [
39
+ "dist-types/ts3.4/*"
39
40
  ]
40
41
  }
41
42
  },
@@ -15,81 +15,76 @@ import { bucketHostname } from "./bucketHostname";
15
15
  import { getPseudoRegion } from "./bucketHostnameUtils";
16
16
  import { BucketEndpointResolvedConfig } from "./configurations";
17
17
 
18
- export const bucketEndpointMiddleware =
19
- (options: BucketEndpointResolvedConfig): BuildMiddleware<any, any> =>
20
- <Output extends MetadataBearer>(
21
- next: BuildHandler<any, Output>,
22
- context: HandlerExecutionContext
23
- ): BuildHandler<any, Output> =>
24
- async (args: BuildHandlerArguments<any>): Promise<BuildHandlerOutput<Output>> => {
25
- const { Bucket: bucketName } = args.input as { Bucket: string };
26
- let replaceBucketInPath = options.bucketEndpoint;
27
- const request = args.request;
28
- if (HttpRequest.isInstance(request)) {
29
- if (options.bucketEndpoint) {
30
- request.hostname = bucketName;
31
- } else if (validateArn(bucketName)) {
32
- const bucketArn = parseArn(bucketName);
33
- const clientRegion = getPseudoRegion(await options.region());
34
- const { partition, signingRegion = clientRegion } = (await options.regionInfoProvider(clientRegion)) || {};
35
- const useArnRegion = await options.useArnRegion();
36
- const {
37
- hostname,
38
- bucketEndpoint,
39
- signingRegion: modifiedSigningRegion,
40
- signingService,
41
- } = bucketHostname({
42
- bucketName: bucketArn,
43
- baseHostname: request.hostname,
44
- accelerateEndpoint: options.useAccelerateEndpoint,
45
- dualstackEndpoint: options.useDualstackEndpoint,
46
- pathStyleEndpoint: options.forcePathStyle,
47
- tlsCompatible: request.protocol === "https:",
48
- useArnRegion,
49
- clientPartition: partition,
50
- clientSigningRegion: signingRegion,
51
- clientRegion: clientRegion,
52
- isCustomEndpoint: options.isCustomEndpoint,
53
- });
18
+ export const bucketEndpointMiddleware = (options: BucketEndpointResolvedConfig): BuildMiddleware<any, any> => <
19
+ Output extends MetadataBearer
20
+ >(
21
+ next: BuildHandler<any, Output>,
22
+ context: HandlerExecutionContext
23
+ ): BuildHandler<any, Output> => async (args: BuildHandlerArguments<any>): Promise<BuildHandlerOutput<Output>> => {
24
+ const { Bucket: bucketName } = args.input as { Bucket: string };
25
+ let replaceBucketInPath = options.bucketEndpoint;
26
+ const request = args.request;
27
+ if (HttpRequest.isInstance(request)) {
28
+ if (options.bucketEndpoint) {
29
+ request.hostname = bucketName;
30
+ } else if (validateArn(bucketName)) {
31
+ const bucketArn = parseArn(bucketName);
32
+ const clientRegion = getPseudoRegion(await options.region());
33
+ const { partition, signingRegion = clientRegion } = (await options.regionInfoProvider(clientRegion)) || {};
34
+ const useArnRegion = await options.useArnRegion();
35
+ const { hostname, bucketEndpoint, signingRegion: modifiedSigningRegion, signingService } = bucketHostname({
36
+ bucketName: bucketArn,
37
+ baseHostname: request.hostname,
38
+ accelerateEndpoint: options.useAccelerateEndpoint,
39
+ dualstackEndpoint: options.useDualstackEndpoint,
40
+ pathStyleEndpoint: options.forcePathStyle,
41
+ tlsCompatible: request.protocol === "https:",
42
+ useArnRegion,
43
+ clientPartition: partition,
44
+ clientSigningRegion: signingRegion,
45
+ clientRegion: clientRegion,
46
+ isCustomEndpoint: options.isCustomEndpoint,
47
+ disableMultiregionAccessPoints: await options.disableMultiregionAccessPoints(),
48
+ });
54
49
 
55
- // If the request needs to use a region or service name inferred from ARN that different from client region, we
56
- // need to set them in the handler context so the signer will use them
57
- if (modifiedSigningRegion && modifiedSigningRegion !== signingRegion) {
58
- context["signing_region"] = modifiedSigningRegion;
59
- }
60
- if (signingService && signingService !== "s3") {
61
- context["signing_service"] = signingService;
62
- }
50
+ // If the request needs to use a region or service name inferred from ARN that different from client region, we
51
+ // need to set them in the handler context so the signer will use them
52
+ if (modifiedSigningRegion && modifiedSigningRegion !== signingRegion) {
53
+ context["signing_region"] = modifiedSigningRegion;
54
+ }
55
+ if (signingService && signingService !== "s3") {
56
+ context["signing_service"] = signingService;
57
+ }
63
58
 
64
- request.hostname = hostname;
65
- replaceBucketInPath = bucketEndpoint;
66
- } else {
67
- const clientRegion = getPseudoRegion(await options.region());
68
- const { hostname, bucketEndpoint } = bucketHostname({
69
- bucketName,
70
- clientRegion,
71
- baseHostname: request.hostname,
72
- accelerateEndpoint: options.useAccelerateEndpoint,
73
- dualstackEndpoint: options.useDualstackEndpoint,
74
- pathStyleEndpoint: options.forcePathStyle,
75
- tlsCompatible: request.protocol === "https:",
76
- isCustomEndpoint: options.isCustomEndpoint,
77
- });
59
+ request.hostname = hostname;
60
+ replaceBucketInPath = bucketEndpoint;
61
+ } else {
62
+ const clientRegion = getPseudoRegion(await options.region());
63
+ const { hostname, bucketEndpoint } = bucketHostname({
64
+ bucketName,
65
+ clientRegion,
66
+ baseHostname: request.hostname,
67
+ accelerateEndpoint: options.useAccelerateEndpoint,
68
+ dualstackEndpoint: options.useDualstackEndpoint,
69
+ pathStyleEndpoint: options.forcePathStyle,
70
+ tlsCompatible: request.protocol === "https:",
71
+ isCustomEndpoint: options.isCustomEndpoint,
72
+ });
78
73
 
79
- request.hostname = hostname;
80
- replaceBucketInPath = bucketEndpoint;
81
- }
74
+ request.hostname = hostname;
75
+ replaceBucketInPath = bucketEndpoint;
76
+ }
82
77
 
83
- if (replaceBucketInPath) {
84
- request.path = request.path.replace(/^(\/)?[^\/]+/, "");
85
- if (request.path === "") {
86
- request.path = "/";
87
- }
78
+ if (replaceBucketInPath) {
79
+ request.path = request.path.replace(/^(\/)?[^\/]+/, "");
80
+ if (request.path === "") {
81
+ request.path = "/";
88
82
  }
89
83
  }
84
+ }
90
85
 
91
- return next({ ...args, request });
92
- };
86
+ return next({ ...args, request });
87
+ };
93
88
 
94
89
  export const bucketEndpointMiddlewareOptions: RelativeMiddlewareOptions = {
95
90
  tags: ["BUCKET_ENDPOINT"],
@@ -1,3 +1,5 @@
1
+ import { ARN } from "@aws-sdk/util-arn-parser";
2
+
1
3
  import {
2
4
  ArnHostnameParams,
3
5
  BucketHostnameParams,
@@ -11,7 +13,9 @@ import {
11
13
  isFipsRegion,
12
14
  validateAccountId,
13
15
  validateArnEndpointOptions,
16
+ validateCustomEndpoint,
14
17
  validateDNSHostLabel,
18
+ validateMrapAlias,
15
19
  validateNoDualstack,
16
20
  validateNoFIPS,
17
21
  validateOutpostService,
@@ -30,33 +34,54 @@ export interface BucketHostname {
30
34
  }
31
35
 
32
36
  export const bucketHostname = (options: BucketHostnameParams | ArnHostnameParams): BucketHostname => {
33
- const { isCustomEndpoint, baseHostname, dualstackEndpoint, accelerateEndpoint } = options;
34
-
35
- if (isCustomEndpoint) {
36
- if (dualstackEndpoint) throw new Error("Dualstack endpoint is not supported with custom endpoint");
37
- if (accelerateEndpoint) throw new Error("Accelerate endpoint is not supported with custom endpoint");
38
- }
39
-
37
+ validateCustomEndpoint(options);
40
38
  return isBucketNameOptions(options)
41
39
  ? // Construct endpoint when bucketName is a string referring to a bucket name
42
- getEndpointFromBucketName({ ...options, isCustomEndpoint })
40
+ getEndpointFromBucketName(options)
43
41
  : // Construct endpoint when bucketName is an ARN referring to an S3 resource like Access Point
44
- getEndpointFromArn({ ...options, isCustomEndpoint });
42
+ getEndpointFromArn(options);
43
+ };
44
+
45
+ const getEndpointFromBucketName = ({
46
+ accelerateEndpoint = false,
47
+ clientRegion: region,
48
+ baseHostname,
49
+ bucketName,
50
+ dualstackEndpoint = false,
51
+ pathStyleEndpoint = false,
52
+ tlsCompatible = true,
53
+ isCustomEndpoint = false,
54
+ }: BucketHostnameParams): BucketHostname => {
55
+ const [clientRegion, hostnameSuffix] = isCustomEndpoint ? [region, baseHostname] : getSuffix(baseHostname);
56
+ if (pathStyleEndpoint || !isDnsCompatibleBucketName(bucketName) || (tlsCompatible && DOT_PATTERN.test(bucketName))) {
57
+ return {
58
+ bucketEndpoint: false,
59
+ hostname: dualstackEndpoint ? `s3.dualstack.${clientRegion}.${hostnameSuffix}` : baseHostname,
60
+ };
61
+ }
62
+
63
+ if (accelerateEndpoint) {
64
+ baseHostname = `s3-accelerate${dualstackEndpoint ? ".dualstack" : ""}.${hostnameSuffix}`;
65
+ } else if (dualstackEndpoint) {
66
+ baseHostname = `s3.dualstack.${clientRegion}.${hostnameSuffix}`;
67
+ }
68
+
69
+ return {
70
+ bucketEndpoint: true,
71
+ hostname: `${bucketName}.${baseHostname}`,
72
+ };
45
73
  };
46
74
 
47
- const getEndpointFromArn = (options: ArnHostnameParams & { isCustomEndpoint: boolean }): BucketHostname => {
75
+ const getEndpointFromArn = (options: ArnHostnameParams): BucketHostname => {
48
76
  const { isCustomEndpoint, baseHostname, clientRegion } = options;
49
77
  const hostnameSuffix = isCustomEndpoint ? baseHostname : getSuffixForArnEndpoint(baseHostname)[1];
50
78
 
51
79
  const {
52
80
  pathStyleEndpoint,
53
- dualstackEndpoint = false,
54
81
  accelerateEndpoint = false,
55
82
  tlsCompatible = true,
56
- useArnRegion,
57
83
  bucketName,
58
84
  clientPartition = "aws",
59
- clientSigningRegion = clientRegion,
60
85
  } = options;
61
86
 
62
87
  validateArnEndpointOptions({ pathStyleEndpoint, accelerateEndpoint, tlsCompatible });
@@ -66,82 +91,133 @@ const getEndpointFromArn = (options: ArnHostnameParams & { isCustomEndpoint: boo
66
91
  validateService(service);
67
92
  validatePartition(partition, { clientPartition });
68
93
  validateAccountId(accountId);
69
- validateRegionalClient(clientRegion);
70
94
  const { accesspointName, outpostId } = getArnResources(resource);
95
+ if (service === "s3-object-lambda") {
96
+ return getEndpointFromObjectLambdaArn({ ...options, tlsCompatible, bucketName, accesspointName, hostnameSuffix });
97
+ }
98
+ if (region === "") {
99
+ return getEndpointFromMRAPArn({ ...options, clientRegion, mrapAlias: accesspointName, hostnameSuffix });
100
+ }
101
+ if (outpostId) {
102
+ return getEndpointFromOutpostArn({ ...options, clientRegion, outpostId, accesspointName, hostnameSuffix });
103
+ }
104
+ return getEndpointFromAccessPointArn({ ...options, clientRegion, accesspointName, hostnameSuffix });
105
+ };
106
+
107
+ const getEndpointFromObjectLambdaArn = ({
108
+ dualstackEndpoint = false,
109
+ tlsCompatible = true,
110
+ useArnRegion,
111
+ clientRegion,
112
+ clientSigningRegion = clientRegion,
113
+ accesspointName,
114
+ bucketName,
115
+ hostnameSuffix,
116
+ }: ArnHostnameParams & {
117
+ accesspointName: string;
118
+ bucketName: ARN;
119
+ hostnameSuffix: string;
120
+ }): BucketHostname => {
121
+ const { accountId, region, service } = bucketName;
122
+ validateRegionalClient(clientRegion);
123
+ validateRegion(region, { useArnRegion, clientRegion, clientSigningRegion, allowFipsRegion: true });
124
+ validateNoDualstack(dualstackEndpoint);
71
125
  const DNSHostLabel = `${accesspointName}-${accountId}`;
72
126
  validateDNSHostLabel(DNSHostLabel, { tlsCompatible });
73
127
 
74
128
  const endpointRegion = useArnRegion ? region : clientRegion;
75
129
  const signingRegion = useArnRegion ? region : clientSigningRegion;
76
- if (service === "s3-object-lambda") {
77
- validateRegion(region, { useArnRegion, clientRegion, clientSigningRegion, allowFipsRegion: true });
78
- validateNoDualstack(dualstackEndpoint);
79
- return {
80
- bucketEndpoint: true,
81
- hostname: `${DNSHostLabel}.${service}${isFipsRegion(clientRegion) ? "-fips" : ""}.${getPseudoRegion(
82
- endpointRegion
83
- )}.${hostnameSuffix}`,
84
- signingRegion,
85
- signingService: service,
86
- };
87
- } else if (outpostId) {
88
- // if this is an Outpost ARN
89
- validateRegion(region, { useArnRegion, clientRegion, clientSigningRegion });
90
- validateOutpostService(service);
91
- validateDNSHostLabel(outpostId, { tlsCompatible });
92
- validateNoDualstack(dualstackEndpoint);
93
- validateNoFIPS(endpointRegion);
94
- const hostnamePrefix = `${DNSHostLabel}.${outpostId}`;
95
- return {
96
- bucketEndpoint: true,
97
- hostname: `${hostnamePrefix}${isCustomEndpoint ? "" : `.s3-outposts.${endpointRegion}`}.${hostnameSuffix}`,
98
- signingRegion,
99
- signingService: "s3-outposts",
100
- };
101
- }
102
- // construct endpoint from Accesspoint ARN
103
- validateRegion(region, { useArnRegion, clientRegion, clientSigningRegion, allowFipsRegion: true });
104
- validateS3Service(service);
105
- const hostnamePrefix = `${DNSHostLabel}`;
130
+
106
131
  return {
107
132
  bucketEndpoint: true,
108
- hostname: `${hostnamePrefix}${
109
- isCustomEndpoint
110
- ? ""
111
- : `.s3-accesspoint${isFipsRegion(clientRegion) ? "-fips" : ""}${
112
- dualstackEndpoint ? ".dualstack" : ""
113
- }.${getPseudoRegion(endpointRegion)}`
114
- }.${hostnameSuffix}`,
133
+ hostname: `${DNSHostLabel}.${service}${isFipsRegion(clientRegion) ? "-fips" : ""}.${getPseudoRegion(
134
+ endpointRegion
135
+ )}.${hostnameSuffix}`,
115
136
  signingRegion,
137
+ signingService: service,
116
138
  };
117
139
  };
118
140
 
119
- const getEndpointFromBucketName = ({
120
- accelerateEndpoint = false,
121
- clientRegion: region,
122
- baseHostname,
123
- bucketName,
141
+ const getEndpointFromMRAPArn = ({
142
+ disableMultiregionAccessPoints,
124
143
  dualstackEndpoint = false,
125
- pathStyleEndpoint = false,
126
- tlsCompatible = true,
127
- isCustomEndpoint = false,
128
- }: BucketHostnameParams & { isCustomEndpoint: boolean }): BucketHostname => {
129
- const [clientRegion, hostnameSuffix] = isCustomEndpoint ? [region, baseHostname] : getSuffix(baseHostname);
130
- if (pathStyleEndpoint || !isDnsCompatibleBucketName(bucketName) || (tlsCompatible && DOT_PATTERN.test(bucketName))) {
131
- return {
132
- bucketEndpoint: false,
133
- hostname: dualstackEndpoint ? `s3.dualstack.${clientRegion}.${hostnameSuffix}` : baseHostname,
134
- };
144
+ isCustomEndpoint,
145
+ mrapAlias,
146
+ hostnameSuffix,
147
+ }: ArnHostnameParams & { mrapAlias: string; hostnameSuffix: string }): BucketHostname => {
148
+ // If this is a multi-regional access point, and not explicitly opted out.
149
+ if (disableMultiregionAccessPoints === true) {
150
+ throw new Error("SDK is attempting to use a MRAP ARN. Please enable to feature.");
135
151
  }
152
+ validateMrapAlias(mrapAlias);
153
+ validateNoDualstack(dualstackEndpoint);
154
+ return {
155
+ bucketEndpoint: true,
156
+ hostname: `${mrapAlias}${isCustomEndpoint ? "" : `.accesspoint.s3-global`}.${hostnameSuffix}`,
157
+ signingRegion: "*",
158
+ };
159
+ };
136
160
 
137
- if (accelerateEndpoint) {
138
- baseHostname = `s3-accelerate${dualstackEndpoint ? ".dualstack" : ""}.${hostnameSuffix}`;
139
- } else if (dualstackEndpoint) {
140
- baseHostname = `s3.dualstack.${clientRegion}.${hostnameSuffix}`;
141
- }
161
+ const getEndpointFromOutpostArn = ({
162
+ useArnRegion,
163
+ clientRegion,
164
+ clientSigningRegion = clientRegion,
165
+ bucketName,
166
+ outpostId,
167
+ dualstackEndpoint = false,
168
+ tlsCompatible = true,
169
+ accesspointName,
170
+ isCustomEndpoint,
171
+ hostnameSuffix,
172
+ }: ArnHostnameParams & { outpostId: string; accesspointName: string; hostnameSuffix: string }): BucketHostname => {
173
+ // if this is an Outpost ARN
174
+ validateRegionalClient(clientRegion);
175
+ validateRegion(bucketName.region, { useArnRegion, clientRegion, clientSigningRegion });
176
+ const DNSHostLabel = `${accesspointName}-${bucketName.accountId}`;
177
+ validateDNSHostLabel(DNSHostLabel, { tlsCompatible });
178
+ const endpointRegion = useArnRegion ? bucketName.region : clientRegion;
179
+ const signingRegion = useArnRegion ? bucketName.region : clientSigningRegion;
180
+ validateOutpostService(bucketName.service);
181
+ validateDNSHostLabel(outpostId, { tlsCompatible });
182
+ validateNoDualstack(dualstackEndpoint);
183
+ validateNoFIPS(endpointRegion);
184
+ const hostnamePrefix = `${DNSHostLabel}.${outpostId}`;
185
+ return {
186
+ bucketEndpoint: true,
187
+ hostname: `${hostnamePrefix}${isCustomEndpoint ? "" : `.s3-outposts.${endpointRegion}`}.${hostnameSuffix}`,
188
+ signingRegion,
189
+ signingService: "s3-outposts",
190
+ };
191
+ };
142
192
 
193
+ const getEndpointFromAccessPointArn = ({
194
+ useArnRegion,
195
+ clientRegion,
196
+ clientSigningRegion = clientRegion,
197
+ bucketName,
198
+ dualstackEndpoint = false,
199
+ tlsCompatible = true,
200
+ accesspointName,
201
+ isCustomEndpoint,
202
+ hostnameSuffix,
203
+ }: ArnHostnameParams & { accesspointName: string; hostnameSuffix: string }): BucketHostname => {
204
+ // construct endpoint from Accesspoint ARN
205
+ validateRegionalClient(clientRegion);
206
+ validateRegion(bucketName.region, { useArnRegion, clientRegion, clientSigningRegion, allowFipsRegion: true });
207
+ const hostnamePrefix = `${accesspointName}-${bucketName.accountId}`;
208
+ validateDNSHostLabel(hostnamePrefix, { tlsCompatible });
209
+ const endpointRegion = useArnRegion ? bucketName.region : clientRegion;
210
+ const signingRegion = useArnRegion ? bucketName.region : clientSigningRegion;
211
+ validateS3Service(bucketName.service);
143
212
  return {
144
213
  bucketEndpoint: true,
145
- hostname: `${bucketName}.${baseHostname}`,
214
+ hostname: `${hostnamePrefix}${
215
+ isCustomEndpoint
216
+ ? ""
217
+ : `.s3-accesspoint${isFipsRegion(clientRegion) ? "-fips" : ""}${
218
+ dualstackEndpoint ? ".dualstack" : ""
219
+ }.${getPseudoRegion(endpointRegion)}`
220
+ }.${hostnameSuffix}`,
221
+ signingRegion,
146
222
  };
147
223
  };