@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.
- package/lib/{common → apis/common}/handler.d.ts +7 -7
- package/lib/{common → apis/common}/handler.js +5 -6
- package/{lib-esm → lib/apis}/common/internalPost.d.ts +1 -1
- package/lib/{common → apis/common}/internalPost.js +12 -1
- package/lib/apis/common/publicApis.d.ts +8 -0
- package/lib/apis/common/publicApis.js +50 -0
- package/lib/apis/index.d.ts +25 -0
- package/lib/apis/index.js +45 -0
- package/lib/apis/server.d.ts +26 -0
- package/lib/apis/server.js +49 -0
- package/lib/errors/validation.d.ts +2 -1
- package/lib/errors/validation.js +5 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +8 -1
- package/lib/internals/index.d.ts +1 -1
- package/lib/internals/index.js +2 -2
- package/lib/internals/server.d.ts +1 -1
- package/lib/internals/server.js +2 -2
- package/lib/server.d.ts +2 -0
- package/lib/server.js +14 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/types/index.d.ts +19 -8
- package/lib/utils/createCancellableOperation.d.ts +2 -1
- package/lib/utils/createCancellableOperation.js +29 -19
- package/lib/utils/index.d.ts +3 -1
- package/lib/utils/index.js +7 -3
- package/lib/utils/index.native.d.ts +6 -0
- package/lib/utils/index.native.js +19 -0
- package/lib/utils/logger.d.ts +2 -0
- package/lib/utils/logger.js +7 -0
- package/lib/utils/normalizeHeaders.d.ts +1 -1
- package/lib/utils/parseSigningInfo.d.ts +14 -0
- package/lib/utils/parseSigningInfo.js +42 -0
- package/lib/utils/resolveApiUrl.d.ts +12 -0
- package/lib/utils/resolveApiUrl.js +38 -0
- package/lib/utils/resolveCredentials.d.ts +2 -2
- package/lib/utils/resolveCredentials.js +1 -1
- package/lib/utils/serviceError.d.ts +1 -1
- package/lib/utils/serviceError.js +8 -6
- package/lib-esm/{common → apis/common}/handler.d.ts +7 -7
- package/lib-esm/{common → apis/common}/handler.js +5 -6
- package/{lib → lib-esm/apis}/common/internalPost.d.ts +1 -1
- package/lib-esm/{common → apis/common}/internalPost.js +12 -1
- package/lib-esm/apis/common/publicApis.d.ts +8 -0
- package/lib-esm/apis/common/publicApis.js +41 -0
- package/lib-esm/apis/index.d.ts +25 -0
- package/lib-esm/apis/index.js +36 -0
- package/lib-esm/apis/server.d.ts +26 -0
- package/lib-esm/apis/server.js +40 -0
- package/lib-esm/errors/validation.d.ts +2 -1
- package/lib-esm/errors/validation.js +5 -0
- package/lib-esm/index.d.ts +1 -0
- package/lib-esm/index.js +1 -0
- package/lib-esm/internals/index.d.ts +1 -1
- package/lib-esm/internals/index.js +2 -2
- package/lib-esm/internals/server.d.ts +1 -1
- package/lib-esm/internals/server.js +2 -2
- package/lib-esm/server.d.ts +2 -0
- package/lib-esm/server.js +4 -0
- package/lib-esm/tsconfig.tsbuildinfo +1 -1
- package/lib-esm/types/index.d.ts +19 -8
- package/lib-esm/utils/createCancellableOperation.d.ts +2 -1
- package/lib-esm/utils/createCancellableOperation.js +31 -21
- package/lib-esm/utils/index.d.ts +3 -1
- package/lib-esm/utils/index.js +3 -1
- package/lib-esm/utils/index.native.d.ts +6 -0
- package/lib-esm/utils/index.native.js +10 -0
- package/lib-esm/utils/logger.d.ts +2 -0
- package/lib-esm/utils/logger.js +4 -0
- package/lib-esm/utils/normalizeHeaders.d.ts +1 -1
- package/lib-esm/utils/parseSigningInfo.d.ts +14 -0
- package/lib-esm/utils/parseSigningInfo.js +38 -0
- package/lib-esm/utils/resolveApiUrl.d.ts +12 -0
- package/lib-esm/utils/resolveApiUrl.js +34 -0
- package/lib-esm/utils/resolveCredentials.d.ts +2 -2
- package/lib-esm/utils/resolveCredentials.js +1 -1
- package/lib-esm/utils/serviceError.d.ts +1 -1
- package/lib-esm/utils/serviceError.js +8 -6
- package/package.json +6 -7
- package/src/{common → apis/common}/handler.ts +8 -9
- package/src/{common → apis/common}/internalPost.ts +13 -2
- package/src/apis/common/publicApis.ts +99 -0
- package/src/apis/index.ts +60 -0
- package/src/apis/server.ts +83 -0
- package/src/errors/validation.ts +6 -0
- package/src/index.ts +1 -0
- package/src/internals/index.ts +5 -2
- package/src/internals/server.ts +5 -2
- package/src/server.ts +5 -0
- package/src/types/index.ts +19 -8
- package/src/utils/createCancellableOperation.ts +37 -19
- package/src/utils/index.native.ts +13 -0
- package/src/utils/index.ts +3 -1
- package/src/utils/logger.ts +6 -0
- package/src/utils/normalizeHeaders.ts +1 -1
- package/src/utils/{parseUrl.ts → parseSigningInfo.ts} +20 -7
- package/src/utils/resolveApiUrl.ts +47 -0
- package/src/utils/resolveCredentials.ts +1 -1
- package/src/utils/serviceError.ts +9 -7
- package/lib/utils/parseUrl.d.ts +0 -10
- package/lib/utils/parseUrl.js +0 -41
- package/lib-esm/utils/parseUrl.d.ts +0 -10
- 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);
|
package/src/errors/validation.ts
CHANGED
|
@@ -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
package/src/internals/index.ts
CHANGED
|
@@ -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 {
|
|
28
|
+
export {
|
|
29
|
+
cancel,
|
|
30
|
+
updateRequestToBeCancellable,
|
|
31
|
+
} from '../apis/common/internalPost';
|
package/src/internals/server.ts
CHANGED
|
@@ -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 {
|
|
34
|
+
export {
|
|
35
|
+
cancel,
|
|
36
|
+
updateRequestToBeCancellable,
|
|
37
|
+
} from '../apis/common/internalPost';
|
package/src/server.ts
ADDED
package/src/types/index.ts
CHANGED
|
@@ -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
|
|
6
|
-
export type
|
|
7
|
-
export type
|
|
8
|
-
export type
|
|
9
|
-
export type
|
|
10
|
-
export type
|
|
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
|
-
|
|
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
|
-
):
|
|
25
|
+
): Operation<HttpResponse>;
|
|
24
26
|
|
|
25
27
|
/**
|
|
26
28
|
* @internal
|
|
27
29
|
*/
|
|
28
30
|
export function createCancellableOperation(
|
|
29
|
-
handler:
|
|
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:
|
|
37
|
+
handler:
|
|
38
|
+
| ((signal: AbortSignal) => Promise<HttpResponse>)
|
|
39
|
+
| (() => Promise<HttpResponse>)
|
|
34
40
|
): handler is () => Promise<HttpResponse> => !!abortController;
|
|
35
|
-
|
|
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(
|
|
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
|
-
|
|
47
|
-
|
|
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:
|
|
64
|
+
message: abortSignal.reason ?? error.message,
|
|
50
65
|
underlyingError: error,
|
|
51
66
|
});
|
|
67
|
+
logger.debug(error);
|
|
68
|
+
throw cancelledError;
|
|
52
69
|
}
|
|
53
|
-
|
|
54
|
-
|
|
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 (
|
|
79
|
+
if (publicApisAbortSignal.aborted === true) {
|
|
65
80
|
return;
|
|
66
81
|
}
|
|
67
|
-
|
|
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 (
|
|
71
|
-
|
|
72
|
-
|
|
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';
|
package/src/utils/index.ts
CHANGED
|
@@ -3,5 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
export { createCancellableOperation } from './createCancellableOperation';
|
|
5
5
|
export { resolveCredentials } from './resolveCredentials';
|
|
6
|
-
export {
|
|
6
|
+
export { parseSigningInfo } from './parseSigningInfo';
|
|
7
7
|
export { parseRestApiServiceError } from './serviceError';
|
|
8
|
+
export { resolveApiUrl } from './resolveApiUrl';
|
|
9
|
+
export { logger } from './logger';
|
|
@@ -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
|
|
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
|
|
12
|
-
*
|
|
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
|
|
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:
|
|
36
|
-
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
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
};
|
package/lib/utils/parseUrl.d.ts
DELETED
|
@@ -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
|
-
};
|
package/lib/utils/parseUrl.js
DELETED
|
@@ -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
|
-
};
|