@aws-amplify/api-rest 4.0.1-console-preview.b5a42af.0 → 4.0.1-console-preview.9607e4a.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 (103) hide show
  1. package/lib/{common → apis/common}/handler.d.ts +7 -7
  2. package/lib/{common → apis/common}/handler.js +5 -6
  3. package/{lib-esm → lib/apis}/common/internalPost.d.ts +1 -1
  4. package/lib/{common → apis/common}/internalPost.js +12 -1
  5. package/lib/apis/common/publicApis.d.ts +8 -0
  6. package/lib/apis/common/publicApis.js +50 -0
  7. package/lib/apis/index.d.ts +25 -0
  8. package/lib/apis/index.js +45 -0
  9. package/lib/apis/server.d.ts +26 -0
  10. package/lib/apis/server.js +49 -0
  11. package/lib/errors/validation.d.ts +2 -1
  12. package/lib/errors/validation.js +5 -0
  13. package/lib/index.d.ts +1 -0
  14. package/lib/index.js +8 -1
  15. package/lib/internals/index.d.ts +1 -1
  16. package/lib/internals/index.js +2 -2
  17. package/lib/internals/server.d.ts +1 -1
  18. package/lib/internals/server.js +2 -2
  19. package/lib/server.d.ts +2 -0
  20. package/lib/server.js +14 -0
  21. package/lib/tsconfig.tsbuildinfo +1 -1
  22. package/lib/types/index.d.ts +19 -8
  23. package/lib/utils/createCancellableOperation.d.ts +2 -1
  24. package/lib/utils/createCancellableOperation.js +29 -19
  25. package/lib/utils/index.d.ts +3 -1
  26. package/lib/utils/index.js +7 -3
  27. package/lib/utils/index.native.d.ts +6 -0
  28. package/lib/utils/index.native.js +19 -0
  29. package/lib/utils/logger.d.ts +2 -0
  30. package/lib/utils/logger.js +7 -0
  31. package/lib/utils/normalizeHeaders.d.ts +1 -1
  32. package/lib/utils/parseSigningInfo.d.ts +14 -0
  33. package/lib/utils/parseSigningInfo.js +42 -0
  34. package/lib/utils/resolveApiUrl.d.ts +12 -0
  35. package/lib/utils/resolveApiUrl.js +38 -0
  36. package/lib/utils/resolveCredentials.d.ts +2 -2
  37. package/lib/utils/resolveCredentials.js +1 -1
  38. package/lib/utils/serviceError.d.ts +1 -1
  39. package/lib/utils/serviceError.js +8 -6
  40. package/lib-esm/{common → apis/common}/handler.d.ts +7 -7
  41. package/lib-esm/{common → apis/common}/handler.js +5 -6
  42. package/{lib → lib-esm/apis}/common/internalPost.d.ts +1 -1
  43. package/lib-esm/{common → apis/common}/internalPost.js +12 -1
  44. package/lib-esm/apis/common/publicApis.d.ts +8 -0
  45. package/lib-esm/apis/common/publicApis.js +41 -0
  46. package/lib-esm/apis/index.d.ts +25 -0
  47. package/lib-esm/apis/index.js +36 -0
  48. package/lib-esm/apis/server.d.ts +26 -0
  49. package/lib-esm/apis/server.js +40 -0
  50. package/lib-esm/errors/validation.d.ts +2 -1
  51. package/lib-esm/errors/validation.js +5 -0
  52. package/lib-esm/index.d.ts +1 -0
  53. package/lib-esm/index.js +1 -0
  54. package/lib-esm/internals/index.d.ts +1 -1
  55. package/lib-esm/internals/index.js +2 -2
  56. package/lib-esm/internals/server.d.ts +1 -1
  57. package/lib-esm/internals/server.js +2 -2
  58. package/lib-esm/server.d.ts +2 -0
  59. package/lib-esm/server.js +4 -0
  60. package/lib-esm/tsconfig.tsbuildinfo +1 -1
  61. package/lib-esm/types/index.d.ts +19 -8
  62. package/lib-esm/utils/createCancellableOperation.d.ts +2 -1
  63. package/lib-esm/utils/createCancellableOperation.js +31 -21
  64. package/lib-esm/utils/index.d.ts +3 -1
  65. package/lib-esm/utils/index.js +3 -1
  66. package/lib-esm/utils/index.native.d.ts +6 -0
  67. package/lib-esm/utils/index.native.js +10 -0
  68. package/lib-esm/utils/logger.d.ts +2 -0
  69. package/lib-esm/utils/logger.js +4 -0
  70. package/lib-esm/utils/normalizeHeaders.d.ts +1 -1
  71. package/lib-esm/utils/parseSigningInfo.d.ts +14 -0
  72. package/lib-esm/utils/parseSigningInfo.js +38 -0
  73. package/lib-esm/utils/resolveApiUrl.d.ts +12 -0
  74. package/lib-esm/utils/resolveApiUrl.js +34 -0
  75. package/lib-esm/utils/resolveCredentials.d.ts +2 -2
  76. package/lib-esm/utils/resolveCredentials.js +1 -1
  77. package/lib-esm/utils/serviceError.d.ts +1 -1
  78. package/lib-esm/utils/serviceError.js +8 -6
  79. package/package.json +6 -7
  80. package/src/{common → apis/common}/handler.ts +8 -9
  81. package/src/{common → apis/common}/internalPost.ts +13 -2
  82. package/src/apis/common/publicApis.ts +99 -0
  83. package/src/apis/index.ts +60 -0
  84. package/src/apis/server.ts +83 -0
  85. package/src/errors/validation.ts +6 -0
  86. package/src/index.ts +1 -0
  87. package/src/internals/index.ts +5 -2
  88. package/src/internals/server.ts +5 -2
  89. package/src/server.ts +5 -0
  90. package/src/types/index.ts +19 -8
  91. package/src/utils/createCancellableOperation.ts +37 -19
  92. package/src/utils/index.native.ts +13 -0
  93. package/src/utils/index.ts +3 -1
  94. package/src/utils/logger.ts +6 -0
  95. package/src/utils/normalizeHeaders.ts +1 -1
  96. package/src/utils/{parseUrl.ts → parseSigningInfo.ts} +20 -7
  97. package/src/utils/resolveApiUrl.ts +47 -0
  98. package/src/utils/resolveCredentials.ts +1 -1
  99. package/src/utils/serviceError.ts +9 -7
  100. package/lib/utils/parseUrl.d.ts +0 -10
  101. package/lib/utils/parseUrl.js +0 -41
  102. package/lib-esm/utils/parseUrl.d.ts +0 -10
  103. package/lib-esm/utils/parseUrl.js +0 -37
@@ -0,0 +1,83 @@
1
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import {
5
+ AmplifyServer,
6
+ getAmplifyServerContext,
7
+ } from '@aws-amplify/core/internals/adapter-core';
8
+ import {
9
+ get as commonGet,
10
+ post as commonPost,
11
+ put as commonPut,
12
+ del as commonDel,
13
+ head as commonHead,
14
+ patch as commonPatch,
15
+ } from './common/publicApis';
16
+ import {
17
+ DeleteInput,
18
+ DeleteOperation,
19
+ GetInput,
20
+ GetOperation,
21
+ HeadInput,
22
+ HeadOperation,
23
+ PatchInput,
24
+ PatchOperation,
25
+ PostInput,
26
+ PostOperation,
27
+ PutInput,
28
+ PutOperation,
29
+ } from '../types';
30
+
31
+ /**
32
+ * GET HTTP request (server-side)
33
+ */
34
+ export const get = (
35
+ contextSpec: AmplifyServer.ContextSpec,
36
+ input: GetInput
37
+ ): GetOperation =>
38
+ commonGet(getAmplifyServerContext(contextSpec).amplify, input);
39
+
40
+ /**
41
+ * POST HTTP request (server-side)
42
+ */
43
+ export const post = (
44
+ contextSpec: AmplifyServer.ContextSpec,
45
+ input: PostInput
46
+ ): PostOperation =>
47
+ commonPost(getAmplifyServerContext(contextSpec).amplify, input);
48
+
49
+ /**
50
+ * PUT HTTP request (server-side)
51
+ */
52
+ export const put = (
53
+ contextSpec: AmplifyServer.ContextSpec,
54
+ input: PutInput
55
+ ): PutOperation =>
56
+ commonPut(getAmplifyServerContext(contextSpec).amplify, input);
57
+
58
+ /**
59
+ * DELETE HTTP request (server-side)
60
+ */
61
+ export const del = (
62
+ contextSpec: AmplifyServer.ContextSpec,
63
+ input: DeleteInput
64
+ ): DeleteOperation =>
65
+ commonDel(getAmplifyServerContext(contextSpec).amplify, input);
66
+
67
+ /**
68
+ * HEAD HTTP request (server-side)
69
+ */
70
+ export const head = (
71
+ contextSpec: AmplifyServer.ContextSpec,
72
+ input: HeadInput
73
+ ): HeadOperation =>
74
+ commonHead(getAmplifyServerContext(contextSpec).amplify, input);
75
+
76
+ /**
77
+ * PATCH HTTP request (server-side)
78
+ */
79
+ export const patch = (
80
+ contextSpec: AmplifyServer.ContextSpec,
81
+ input: PatchInput
82
+ ): PatchOperation =>
83
+ commonPatch(getAmplifyServerContext(contextSpec).amplify, input);
@@ -5,10 +5,16 @@ import { AmplifyErrorMap } from '@aws-amplify/core/internals/utils';
5
5
 
6
6
  export enum RestApiValidationErrorCode {
7
7
  NoCredentials = 'NoCredentials',
8
+ InvalidApiName = 'InvalidApiName',
8
9
  }
9
10
 
10
11
  export const validationErrorMap: AmplifyErrorMap<RestApiValidationErrorCode> = {
11
12
  [RestApiValidationErrorCode.NoCredentials]: {
12
13
  message: 'Credentials should not be empty.',
13
14
  },
15
+ [RestApiValidationErrorCode.InvalidApiName]: {
16
+ message: 'API name is invalid.',
17
+ recoverySuggestion:
18
+ 'Check if the API name matches the one in your configuration or `aws-exports.js`',
19
+ },
14
20
  };
package/src/index.ts CHANGED
@@ -2,3 +2,4 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  export { isCancelError } from './errors/CancelledError';
5
+ export { get, post, put, del, head, patch } from './apis';
@@ -2,7 +2,7 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
  import { Amplify } from '@aws-amplify/core';
4
4
 
5
- import { post as internalPost } from '../common/internalPost';
5
+ import { post as internalPost } from '../apis/common/internalPost';
6
6
  import { InternalPostInput } from '../types';
7
7
 
8
8
  /**
@@ -25,4 +25,7 @@ export const post = (input: InternalPostInput) => {
25
25
  return internalPost(Amplify, input);
26
26
  };
27
27
 
28
- export { cancel, updateRequestToBeCancellable } from '../common/internalPost';
28
+ export {
29
+ cancel,
30
+ updateRequestToBeCancellable,
31
+ } from '../apis/common/internalPost';
@@ -5,7 +5,7 @@ import {
5
5
  getAmplifyServerContext,
6
6
  } from '@aws-amplify/core/internals/adapter-core';
7
7
 
8
- import { post as internalPost } from '../common/internalPost';
8
+ import { post as internalPost } from '../apis/common/internalPost';
9
9
  import { InternalPostInput } from '../types';
10
10
 
11
11
  /**
@@ -31,4 +31,7 @@ export const post = (
31
31
  return internalPost(getAmplifyServerContext(contextSpec).amplify, input);
32
32
  };
33
33
 
34
- export { cancel, updateRequestToBeCancellable } from '../common/internalPost';
34
+ export {
35
+ cancel,
36
+ updateRequestToBeCancellable,
37
+ } from '../apis/common/internalPost';
package/src/server.ts ADDED
@@ -0,0 +1,5 @@
1
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export { isCancelError } from './errors/CancelledError';
5
+ export { get, post, put, del, head, patch } from './apis/server';
@@ -2,12 +2,12 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
  import { DocumentType } from '@aws-amplify/core/internals/utils';
4
4
 
5
- export type GetOptions = RestApiOptionsBase;
6
- export type PostOptions = RestApiOptionsBase;
7
- export type PutOptions = RestApiOptionsBase;
8
- export type PatchOptions = RestApiOptionsBase;
9
- export type DeleteOptions = Omit<RestApiOptionsBase, 'body'>;
10
- export type HeadOptions = Omit<RestApiOptionsBase, 'body'>;
5
+ export type GetInput = ApiInput<RestApiOptionsBase>;
6
+ export type PostInput = ApiInput<RestApiOptionsBase>;
7
+ export type PutInput = ApiInput<RestApiOptionsBase>;
8
+ export type PatchInput = ApiInput<RestApiOptionsBase>;
9
+ export type DeleteInput = ApiInput<Omit<RestApiOptionsBase, 'body'>>;
10
+ export type HeadInput = ApiInput<Omit<RestApiOptionsBase, 'body'>>;
11
11
 
12
12
  export type GetOperation = Operation<RestApiResponse>;
13
13
  export type PostOperation = Operation<RestApiResponse>;
@@ -16,7 +16,10 @@ export type PatchOperation = Operation<RestApiResponse>;
16
16
  export type DeleteOperation = Operation<Omit<RestApiResponse, 'body'>>;
17
17
  export type HeadOperation = Operation<Omit<RestApiResponse, 'body'>>;
18
18
 
19
- type RestApiOptionsBase = {
19
+ /**
20
+ * @internal
21
+ */
22
+ export type RestApiOptionsBase = {
20
23
  headers?: Headers;
21
24
  queryParams?: Record<string, string>;
22
25
  body?: DocumentType | FormData;
@@ -64,12 +67,20 @@ export interface RestApiResponse {
64
67
  }
65
68
 
66
69
  /**
67
- * Input type of REST API.
68
70
  * @internal
69
71
  */
70
72
  export type ApiInput<Options> = {
73
+ /**
74
+ * Name of the REST API configured in Amplify singleton.
75
+ */
71
76
  apiName: string;
77
+ /**
78
+ * Path of the REST API.
79
+ */
72
80
  path: string;
81
+ /**
82
+ * Options to overwrite the REST API call behavior.
83
+ */
73
84
  options?: Options;
74
85
  };
75
86
 
@@ -5,6 +5,7 @@ import { HttpResponse } from '@aws-amplify/core/internals/aws-client-utils';
5
5
  import { CancelledError, RestApiError } from '../errors';
6
6
  import { Operation } from '../types';
7
7
  import { parseRestApiServiceError } from './serviceError';
8
+ import { logger } from './logger';
8
9
 
9
10
  /**
10
11
  * Create a cancellable operation conforming to the internal POST API interface.
@@ -14,46 +15,60 @@ export function createCancellableOperation(
14
15
  handler: () => Promise<HttpResponse>,
15
16
  abortController: AbortController
16
17
  ): Promise<HttpResponse>;
18
+
17
19
  /**
18
20
  * Create a cancellable operation conforming to the external REST API interface.
19
21
  * @internal
20
22
  */
21
23
  export function createCancellableOperation(
22
24
  handler: (signal: AbortSignal) => Promise<HttpResponse>
23
- ): Promise<HttpResponse>;
25
+ ): Operation<HttpResponse>;
24
26
 
25
27
  /**
26
28
  * @internal
27
29
  */
28
30
  export function createCancellableOperation(
29
- handler: (signal?: AbortSignal) => Promise<HttpResponse>,
31
+ handler:
32
+ | ((signal: AbortSignal) => Promise<HttpResponse>)
33
+ | (() => Promise<HttpResponse>),
30
34
  abortController?: AbortController
31
35
  ): Operation<HttpResponse> | Promise<HttpResponse> {
32
36
  const isInternalPost = (
33
- handler: (signal?: AbortSignal) => Promise<HttpResponse>
37
+ handler:
38
+ | ((signal: AbortSignal) => Promise<HttpResponse>)
39
+ | (() => Promise<HttpResponse>)
34
40
  ): handler is () => Promise<HttpResponse> => !!abortController;
35
- const signal = abortController?.signal;
41
+
42
+ // For creating a cancellable operation for public REST APIs, we need to create an AbortController
43
+ // internally. Whereas for internal POST APIs, we need to accept in the AbortController from the
44
+ // callers.
45
+ const publicApisAbortController = new AbortController();
46
+ const publicApisAbortSignal = publicApisAbortController.signal;
47
+ const internalPostAbortSignal = abortController?.signal;
48
+
36
49
  const job = async () => {
37
50
  try {
38
51
  const response = await (isInternalPost(handler)
39
52
  ? handler()
40
- : handler(signal));
53
+ : handler(publicApisAbortSignal));
54
+
41
55
  if (response.statusCode >= 300) {
42
- throw parseRestApiServiceError(response)!;
56
+ throw await parseRestApiServiceError(response)!;
43
57
  }
44
58
  return response;
45
- } catch (error) {
46
- if (error.name === 'AbortError' || signal?.aborted === true) {
47
- throw new CancelledError({
59
+ } catch (error: any) {
60
+ const abortSignal = internalPostAbortSignal ?? publicApisAbortSignal;
61
+ if (error.name === 'AbortError' || abortSignal?.aborted === true) {
62
+ const cancelledError = new CancelledError({
48
63
  name: error.name,
49
- message: signal.reason ?? error.message,
64
+ message: abortSignal.reason ?? error.message,
50
65
  underlyingError: error,
51
66
  });
67
+ logger.debug(error);
68
+ throw cancelledError;
52
69
  }
53
- throw new RestApiError({
54
- ...error,
55
- underlyingError: error,
56
- });
70
+ logger.debug(error);
71
+ throw error;
57
72
  }
58
73
  };
59
74
 
@@ -61,15 +76,18 @@ export function createCancellableOperation(
61
76
  return job();
62
77
  } else {
63
78
  const cancel = (abortMessage?: string) => {
64
- if (signal?.aborted === true) {
79
+ if (publicApisAbortSignal.aborted === true) {
65
80
  return;
66
81
  }
67
- abortController?.abort(abortMessage);
82
+ publicApisAbortController.abort(abortMessage);
68
83
  // Abort reason is not widely support enough across runtimes and and browsers, so we set it
69
84
  // if it is not already set.
70
- if (signal?.reason !== abortMessage) {
71
- // @ts-expect-error reason is a readonly property
72
- signal['reason'] = abortMessage;
85
+ if (publicApisAbortSignal.reason !== abortMessage) {
86
+ type AbortSignalWithReasonSupport = Omit<AbortSignal, 'reason'> & {
87
+ reason?: string;
88
+ };
89
+ (publicApisAbortSignal as AbortSignalWithReasonSupport)['reason'] =
90
+ abortMessage;
73
91
  }
74
92
  };
75
93
  return { response: job(), cancel };
@@ -0,0 +1,13 @@
1
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { loadUrlPolyfill } from '@aws-amplify/react-native';
5
+
6
+ loadUrlPolyfill();
7
+
8
+ export { createCancellableOperation } from './createCancellableOperation';
9
+ export { resolveCredentials } from './resolveCredentials';
10
+ export { parseSigningInfo } from './parseSigningInfo';
11
+ export { parseRestApiServiceError } from './serviceError';
12
+ export { resolveApiUrl } from './resolveApiUrl';
13
+ export { logger } from './logger';
@@ -3,5 +3,7 @@
3
3
 
4
4
  export { createCancellableOperation } from './createCancellableOperation';
5
5
  export { resolveCredentials } from './resolveCredentials';
6
- export { parseUrl } from './parseUrl';
6
+ export { parseSigningInfo } from './parseSigningInfo';
7
7
  export { parseRestApiServiceError } from './serviceError';
8
+ export { resolveApiUrl } from './resolveApiUrl';
9
+ export { logger } from './logger';
@@ -0,0 +1,6 @@
1
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { Logger } from '@aws-amplify/core/internals/utils';
5
+
6
+ export const logger = new Logger('RestApis');
@@ -1,7 +1,7 @@
1
1
  // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- export const normalizeHeaders = (headers: Record<string, string>) => {
4
+ export const normalizeHeaders = (headers?: Record<string, string>) => {
5
5
  const normalizedHeaders: Record<string, string> = {};
6
6
  for (const key in headers) {
7
7
  normalizedHeaders[key.toLowerCase()] = headers[key];
@@ -1,6 +1,7 @@
1
1
  // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
+ import { AmplifyClassV6 } from '@aws-amplify/core';
4
5
  import {
5
6
  APIG_HOSTNAME_PATTERN,
6
7
  DEFAULT_IAM_SIGNING_REGION,
@@ -8,12 +9,24 @@ import {
8
9
  } from './constants';
9
10
 
10
11
  /**
11
- * Infer the signing service and region from the given URL. It supports raw API Gateway endpoint and AppSync endpoint.
12
- * Custom domain is not supported.
12
+ * Infer the signing service and region from the given URL, and for REST API only, from the Amplify configuration.
13
+ * It supports raw API Gateway endpoint and AppSync endpoint.
13
14
  *
14
15
  * @internal
15
16
  */
16
- export const parseUrl = (url: URL) => {
17
+ export const parseSigningInfo = (
18
+ url: URL,
19
+ restApiOptions?: {
20
+ amplify: AmplifyClassV6;
21
+ apiName: string;
22
+ }
23
+ ) => {
24
+ const {
25
+ service: signingService = DEFAULT_REST_IAM_SIGNING_SERVICE,
26
+ region: signingRegion = DEFAULT_IAM_SIGNING_REGION,
27
+ } =
28
+ restApiOptions?.amplify.getConfig()?.API?.REST?.[restApiOptions?.apiName] ??
29
+ {};
17
30
  const { hostname } = url;
18
31
  const [, service, region] = APIG_HOSTNAME_PATTERN.exec(hostname) ?? [];
19
32
  if (service === DEFAULT_REST_IAM_SIGNING_SERVICE) {
@@ -21,19 +34,19 @@ export const parseUrl = (url: URL) => {
21
34
  // @see: https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-call-api.html
22
35
  return {
23
36
  service,
24
- region,
37
+ region: region ?? signingRegion,
25
38
  };
26
39
  } else if (service === 'appsync-api') {
27
40
  // AppSync endpoint is internally supported because GraphQL operation will send request using POST handler.
28
41
  // example: https://xxxx.appsync-api.us-east-1.amazonaws.com/graphql
29
42
  return {
30
43
  service: 'appsync',
31
- region,
44
+ region: region ?? signingRegion,
32
45
  };
33
46
  } else {
34
47
  return {
35
- service: DEFAULT_REST_IAM_SIGNING_SERVICE,
36
- region: DEFAULT_IAM_SIGNING_REGION,
48
+ service: signingService,
49
+ region: signingRegion,
37
50
  };
38
51
  }
39
52
  };
@@ -0,0 +1,47 @@
1
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { AmplifyClassV6 } from '@aws-amplify/core';
5
+ import {
6
+ RestApiError,
7
+ RestApiValidationErrorCode,
8
+ assertValidationError,
9
+ validationErrorMap,
10
+ } from '../errors';
11
+
12
+ /**
13
+ * Resolve the REST API request URL by:
14
+ * 1. Loading the REST API endpoint from the Amplify configuration with corresponding API name.
15
+ * 2. Appending the path to the endpoint.
16
+ * 3. Merge the query parameters from path and the queryParameter argument which is taken from the public REST API
17
+ * options.
18
+ * 4. Validating the resulting URL string.
19
+ *
20
+ * @internal
21
+ */
22
+ export const resolveApiUrl = (
23
+ amplify: AmplifyClassV6,
24
+ apiName: string,
25
+ path: string,
26
+ queryParams?: Record<string, string>
27
+ ): URL => {
28
+ const urlStr = amplify.getConfig()?.API?.REST?.[apiName]?.endpoint;
29
+ assertValidationError(!!urlStr, RestApiValidationErrorCode.InvalidApiName);
30
+ try {
31
+ const url = new URL(urlStr + path);
32
+ if (queryParams) {
33
+ const mergedQueryParams = new URLSearchParams(url.searchParams);
34
+ Object.entries(queryParams).forEach(([key, value]) => {
35
+ mergedQueryParams.set(key, value);
36
+ });
37
+ url.search = new URLSearchParams(mergedQueryParams).toString();
38
+ }
39
+ return url;
40
+ } catch (error) {
41
+ throw new RestApiError({
42
+ name: RestApiValidationErrorCode.InvalidApiName,
43
+ ...validationErrorMap[RestApiValidationErrorCode.InvalidApiName],
44
+ recoverySuggestion: `Please make sure the REST endpoint URL is a valid URL string. Got ${urlStr}`,
45
+ });
46
+ }
47
+ };
@@ -10,7 +10,7 @@ import { RestApiValidationErrorCode, assertValidationError } from '../errors';
10
10
  export const resolveCredentials = async (amplify: AmplifyClassV6) => {
11
11
  const { credentials } = await amplify.Auth.fetchAuthSession();
12
12
  assertValidationError(
13
- !!credentials,
13
+ !!credentials && !!credentials.accessKeyId && !!credentials.secretAccessKey,
14
14
  RestApiValidationErrorCode.NoCredentials
15
15
  );
16
16
  return credentials;
@@ -14,7 +14,7 @@ import { RestApiError } from '../errors';
14
14
  */
15
15
  export const buildRestApiServiceError = (error: Error): RestApiError => {
16
16
  const restApiError = new RestApiError({
17
- name: error.name,
17
+ name: error?.name,
18
18
  message: error.message,
19
19
  underlyingError: error,
20
20
  });
@@ -23,11 +23,13 @@ export const buildRestApiServiceError = (error: Error): RestApiError => {
23
23
 
24
24
  export const parseRestApiServiceError = async (
25
25
  response?: HttpResponse
26
- ): Promise<RestApiError & MetadataBearer> => {
26
+ ): Promise<(RestApiError & MetadataBearer) | undefined> => {
27
27
  const parsedError = await parseJsonError(response);
28
- return parsedError
29
- ? Object.assign(buildRestApiServiceError(parsedError), {
30
- $metadata: parsedError.$metadata,
31
- })
32
- : undefined;
28
+ if (!parsedError) {
29
+ // Response is not an error.
30
+ return;
31
+ }
32
+ return Object.assign(buildRestApiServiceError(parsedError), {
33
+ $metadata: parsedError.$metadata,
34
+ });
33
35
  };
@@ -1,10 +0,0 @@
1
- /**
2
- * Infer the signing service and region from the given URL. It supports raw API Gateway endpoint and AppSync endpoint.
3
- * Custom domain is not supported.
4
- *
5
- * @internal
6
- */
7
- export declare const parseUrl: (url: URL) => {
8
- service: string;
9
- region: string;
10
- };
@@ -1,41 +0,0 @@
1
- "use strict";
2
- // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
- // SPDX-License-Identifier: Apache-2.0
4
- Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.parseUrl = void 0;
6
- var tslib_1 = require("tslib");
7
- var constants_1 = require("./constants");
8
- /**
9
- * Infer the signing service and region from the given URL. It supports raw API Gateway endpoint and AppSync endpoint.
10
- * Custom domain is not supported.
11
- *
12
- * @internal
13
- */
14
- var parseUrl = function (url) {
15
- var _a;
16
- var hostname = url.hostname;
17
- var _b = tslib_1.__read((_a = constants_1.APIG_HOSTNAME_PATTERN.exec(hostname)) !== null && _a !== void 0 ? _a : [], 3), service = _b[1], region = _b[2];
18
- if (service === constants_1.DEFAULT_REST_IAM_SIGNING_SERVICE) {
19
- // The configured endpoint is an API Gateway endpoint
20
- // @see: https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-call-api.html
21
- return {
22
- service: service,
23
- region: region,
24
- };
25
- }
26
- else if (service === 'appsync-api') {
27
- // AppSync endpoint is internally supported because GraphQL operation will send request using POST handler.
28
- // example: https://xxxx.appsync-api.us-east-1.amazonaws.com/graphql
29
- return {
30
- service: 'appsync',
31
- region: region,
32
- };
33
- }
34
- else {
35
- return {
36
- service: constants_1.DEFAULT_REST_IAM_SIGNING_SERVICE,
37
- region: constants_1.DEFAULT_IAM_SIGNING_REGION,
38
- };
39
- }
40
- };
41
- exports.parseUrl = parseUrl;
@@ -1,10 +0,0 @@
1
- /**
2
- * Infer the signing service and region from the given URL. It supports raw API Gateway endpoint and AppSync endpoint.
3
- * Custom domain is not supported.
4
- *
5
- * @internal
6
- */
7
- export declare const parseUrl: (url: URL) => {
8
- service: string;
9
- region: string;
10
- };
@@ -1,37 +0,0 @@
1
- // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
- // SPDX-License-Identifier: Apache-2.0
3
- import { __read } from "tslib";
4
- import { APIG_HOSTNAME_PATTERN, DEFAULT_IAM_SIGNING_REGION, DEFAULT_REST_IAM_SIGNING_SERVICE, } from './constants';
5
- /**
6
- * Infer the signing service and region from the given URL. It supports raw API Gateway endpoint and AppSync endpoint.
7
- * Custom domain is not supported.
8
- *
9
- * @internal
10
- */
11
- export var parseUrl = function (url) {
12
- var _a;
13
- var hostname = url.hostname;
14
- var _b = __read((_a = APIG_HOSTNAME_PATTERN.exec(hostname)) !== null && _a !== void 0 ? _a : [], 3), service = _b[1], region = _b[2];
15
- if (service === DEFAULT_REST_IAM_SIGNING_SERVICE) {
16
- // The configured endpoint is an API Gateway endpoint
17
- // @see: https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-call-api.html
18
- return {
19
- service: service,
20
- region: region,
21
- };
22
- }
23
- else if (service === 'appsync-api') {
24
- // AppSync endpoint is internally supported because GraphQL operation will send request using POST handler.
25
- // example: https://xxxx.appsync-api.us-east-1.amazonaws.com/graphql
26
- return {
27
- service: 'appsync',
28
- region: region,
29
- };
30
- }
31
- else {
32
- return {
33
- service: DEFAULT_REST_IAM_SIGNING_SERVICE,
34
- region: DEFAULT_IAM_SIGNING_REGION,
35
- };
36
- }
37
- };