@aws-amplify/api-rest 3.5.6-unstable.7762f1a.0 → 4.0.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/README.md +3 -0
- package/internals/package.json +8 -0
- package/internals/server/package.json +8 -0
- package/lib/apis/common/handler.d.ts +27 -0
- package/lib/apis/common/handler.js +73 -0
- package/lib/apis/common/internalPost.d.ts +16 -0
- package/lib/apis/common/internalPost.js +65 -0
- package/lib/apis/common/publicApis.d.ts +8 -0
- package/lib/apis/common/publicApis.js +44 -0
- package/lib/apis/index.d.ts +203 -0
- package/lib/apis/index.js +215 -0
- package/lib/apis/server.d.ts +151 -0
- package/lib/apis/server.js +162 -0
- package/lib/errors/CanceledError.d.ts +17 -0
- package/lib/errors/CanceledError.js +32 -0
- package/lib/errors/RestApiError.d.ts +4 -0
- package/lib/errors/RestApiError.js +15 -0
- package/lib/errors/assertValidatonError.d.ts +5 -0
- package/lib/errors/assertValidatonError.js +17 -0
- package/lib/errors/index.d.ts +4 -0
- package/lib/errors/index.js +15 -0
- package/lib/errors/validation.d.ts +6 -0
- package/lib/errors/validation.js +19 -0
- package/lib/index.d.ts +2 -2
- package/lib/index.js +10 -6
- package/lib/internals/index.d.ts +19 -0
- package/lib/internals/index.js +30 -0
- package/lib/internals/server.d.ts +20 -0
- package/lib/internals/server.js +30 -0
- package/lib/server.d.ts +2 -0
- package/lib/server.js +14 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/lib/types/index.d.ts +90 -37
- package/lib/types/index.js +0 -23
- package/lib/utils/constants.d.ts +8 -0
- package/lib/utils/constants.js +13 -0
- package/lib/utils/createCancellableOperation.d.ts +12 -0
- package/lib/utils/createCancellableOperation.js +63 -0
- package/lib/utils/index.d.ts +6 -0
- package/lib/utils/index.js +17 -0
- package/lib/utils/logger.d.ts +2 -0
- package/lib/utils/logger.js +7 -0
- package/lib/utils/normalizeHeaders.d.ts +1 -0
- package/lib/utils/normalizeHeaders.js +13 -0
- package/lib/utils/parseSigningInfo.d.ts +14 -0
- package/lib/utils/parseSigningInfo.js +41 -0
- package/lib/utils/resolveApiUrl.d.ts +12 -0
- package/lib/utils/resolveApiUrl.js +40 -0
- package/lib/utils/resolveCredentials.d.ts +5 -0
- package/lib/utils/resolveCredentials.js +15 -0
- package/lib/utils/serviceError.d.ts +10 -0
- package/lib/utils/serviceError.js +30 -0
- package/lib-esm/apis/common/handler.d.ts +27 -0
- package/lib-esm/apis/common/handler.js +69 -0
- package/lib-esm/apis/common/internalPost.d.ts +16 -0
- package/lib-esm/apis/common/internalPost.js +59 -0
- package/lib-esm/apis/common/publicApis.d.ts +8 -0
- package/lib-esm/apis/common/publicApis.js +35 -0
- package/lib-esm/apis/index.d.ts +203 -0
- package/lib-esm/apis/index.js +206 -0
- package/lib-esm/apis/server.d.ts +151 -0
- package/lib-esm/apis/server.js +153 -0
- package/lib-esm/errors/CanceledError.d.ts +17 -0
- package/lib-esm/errors/CanceledError.js +27 -0
- package/lib-esm/errors/RestApiError.d.ts +4 -0
- package/lib-esm/errors/RestApiError.js +11 -0
- package/lib-esm/errors/assertValidatonError.d.ts +5 -0
- package/lib-esm/errors/assertValidatonError.js +13 -0
- package/lib-esm/errors/index.d.ts +4 -0
- package/lib-esm/errors/index.js +6 -0
- package/lib-esm/errors/validation.d.ts +6 -0
- package/lib-esm/errors/validation.js +16 -0
- package/lib-esm/index.d.ts +2 -2
- package/lib-esm/index.js +2 -3
- package/lib-esm/internals/index.d.ts +19 -0
- package/lib-esm/internals/index.js +24 -0
- package/lib-esm/internals/server.d.ts +20 -0
- package/lib-esm/internals/server.js +24 -0
- package/lib-esm/server.d.ts +2 -0
- package/lib-esm/server.js +4 -0
- package/lib-esm/tsconfig.tsbuildinfo +1 -0
- package/lib-esm/types/index.d.ts +90 -37
- package/lib-esm/types/index.js +1 -23
- package/lib-esm/utils/constants.d.ts +8 -0
- package/lib-esm/utils/constants.js +10 -0
- package/lib-esm/utils/createCancellableOperation.d.ts +12 -0
- package/lib-esm/utils/createCancellableOperation.js +59 -0
- package/lib-esm/utils/index.d.ts +6 -0
- package/lib-esm/utils/index.js +8 -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 -0
- package/lib-esm/utils/normalizeHeaders.js +9 -0
- package/lib-esm/utils/parseSigningInfo.d.ts +14 -0
- package/lib-esm/utils/parseSigningInfo.js +37 -0
- package/lib-esm/utils/resolveApiUrl.d.ts +12 -0
- package/lib-esm/utils/resolveApiUrl.js +36 -0
- package/lib-esm/utils/resolveCredentials.d.ts +5 -0
- package/lib-esm/utils/resolveCredentials.js +11 -0
- package/lib-esm/utils/serviceError.d.ts +10 -0
- package/lib-esm/utils/serviceError.js +25 -0
- package/package.json +113 -105
- package/server/package.json +8 -0
- package/src/apis/common/handler.ts +109 -0
- package/src/apis/common/internalPost.ts +81 -0
- package/src/apis/common/publicApis.ts +99 -0
- package/src/apis/index.ts +239 -0
- package/src/apis/server.ts +209 -0
- package/src/errors/CanceledError.ts +33 -0
- package/src/errors/RestApiError.ts +17 -0
- package/src/errors/assertValidatonError.ts +19 -0
- package/src/errors/index.ts +7 -0
- package/src/errors/validation.ts +20 -0
- package/src/index.ts +2 -2
- package/src/internals/index.ts +31 -0
- package/src/internals/server.ts +37 -0
- package/src/server.ts +5 -0
- package/src/types/index.ts +95 -44
- package/src/utils/constants.ts +15 -0
- package/src/utils/createCancellableOperation.ts +94 -0
- package/src/utils/index.ts +9 -0
- package/src/utils/logger.ts +6 -0
- package/src/utils/normalizeHeaders.ts +10 -0
- package/src/utils/parseSigningInfo.ts +52 -0
- package/src/utils/resolveApiUrl.ts +51 -0
- package/src/utils/resolveCredentials.ts +17 -0
- package/src/utils/serviceError.ts +35 -0
- package/lib/.tsbuildinfo +0 -3
- package/lib/RestAPI.d.ts +0 -108
- package/lib/RestAPI.js +0 -282
- package/lib/RestAPI.js.map +0 -1
- package/lib/RestClient.d.ts +0 -138
- package/lib/RestClient.js +0 -368
- package/lib/RestClient.js.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/types/index.js.map +0 -1
- package/lib-esm/.tsbuildinfo +0 -3
- package/lib-esm/RestAPI.d.ts +0 -108
- package/lib-esm/RestAPI.js +0 -280
- package/lib-esm/RestAPI.js.map +0 -1
- package/lib-esm/RestClient.d.ts +0 -138
- package/lib-esm/RestClient.js +0 -366
- package/lib-esm/RestClient.js.map +0 -1
- package/lib-esm/index.js.map +0 -1
- package/lib-esm/types/index.js.map +0 -1
- package/src/RestAPI.ts +0 -338
- package/src/RestClient.ts +0 -417
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const normalizeHeaders: (headers?: Record<string, string>) => Record<string, string>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
export const normalizeHeaders = (headers) => {
|
|
4
|
+
const normalizedHeaders = {};
|
|
5
|
+
for (const key in headers) {
|
|
6
|
+
normalizedHeaders[key.toLowerCase()] = headers[key];
|
|
7
|
+
}
|
|
8
|
+
return normalizedHeaders;
|
|
9
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { AmplifyClassV6 } from '@aws-amplify/core';
|
|
2
|
+
/**
|
|
3
|
+
* Infer the signing service and region from the given URL, and for REST API only, from the Amplify configuration.
|
|
4
|
+
* It supports raw API Gateway endpoint and AppSync endpoint.
|
|
5
|
+
*
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export declare const parseSigningInfo: (url: URL, restApiOptions?: {
|
|
9
|
+
amplify: AmplifyClassV6;
|
|
10
|
+
apiName: string;
|
|
11
|
+
}) => {
|
|
12
|
+
service: string;
|
|
13
|
+
region: string;
|
|
14
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { APIG_HOSTNAME_PATTERN, DEFAULT_IAM_SIGNING_REGION, DEFAULT_REST_IAM_SIGNING_SERVICE, } from './constants';
|
|
4
|
+
/**
|
|
5
|
+
* Infer the signing service and region from the given URL, and for REST API only, from the Amplify configuration.
|
|
6
|
+
* It supports raw API Gateway endpoint and AppSync endpoint.
|
|
7
|
+
*
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
export const parseSigningInfo = (url, restApiOptions) => {
|
|
11
|
+
const { service: signingService = DEFAULT_REST_IAM_SIGNING_SERVICE, region: signingRegion = DEFAULT_IAM_SIGNING_REGION, } = restApiOptions?.amplify.getConfig()?.API?.REST?.[restApiOptions?.apiName] ??
|
|
12
|
+
{};
|
|
13
|
+
const { hostname } = url;
|
|
14
|
+
const [, service, region] = APIG_HOSTNAME_PATTERN.exec(hostname) ?? [];
|
|
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,
|
|
20
|
+
region: region ?? signingRegion,
|
|
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 ?? signingRegion,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
return {
|
|
33
|
+
service: signingService,
|
|
34
|
+
region: signingRegion,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { AmplifyClassV6 } from '@aws-amplify/core';
|
|
2
|
+
/**
|
|
3
|
+
* Resolve the REST API request URL by:
|
|
4
|
+
* 1. Loading the REST API endpoint from the Amplify configuration with corresponding API name.
|
|
5
|
+
* 2. Appending the path to the endpoint.
|
|
6
|
+
* 3. Merge the query parameters from path and the queryParameter argument which is taken from the public REST API
|
|
7
|
+
* options.
|
|
8
|
+
* 4. Validating the resulting URL string.
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export declare const resolveApiUrl: (amplify: AmplifyClassV6, apiName: string, path: string, queryParams?: Record<string, string>) => URL;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { AmplifyUrl, AmplifyUrlSearchParams, } from '@aws-amplify/core/internals/utils';
|
|
4
|
+
import { RestApiError, RestApiValidationErrorCode, assertValidationError, validationErrorMap, } from '../errors';
|
|
5
|
+
/**
|
|
6
|
+
* Resolve the REST API request URL by:
|
|
7
|
+
* 1. Loading the REST API endpoint from the Amplify configuration with corresponding API name.
|
|
8
|
+
* 2. Appending the path to the endpoint.
|
|
9
|
+
* 3. Merge the query parameters from path and the queryParameter argument which is taken from the public REST API
|
|
10
|
+
* options.
|
|
11
|
+
* 4. Validating the resulting URL string.
|
|
12
|
+
*
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
export const resolveApiUrl = (amplify, apiName, path, queryParams) => {
|
|
16
|
+
const urlStr = amplify.getConfig()?.API?.REST?.[apiName]?.endpoint;
|
|
17
|
+
assertValidationError(!!urlStr, RestApiValidationErrorCode.InvalidApiName);
|
|
18
|
+
try {
|
|
19
|
+
const url = new AmplifyUrl(urlStr + path);
|
|
20
|
+
if (queryParams) {
|
|
21
|
+
const mergedQueryParams = new AmplifyUrlSearchParams(url.searchParams);
|
|
22
|
+
Object.entries(queryParams).forEach(([key, value]) => {
|
|
23
|
+
mergedQueryParams.set(key, value);
|
|
24
|
+
});
|
|
25
|
+
url.search = new AmplifyUrlSearchParams(mergedQueryParams).toString();
|
|
26
|
+
}
|
|
27
|
+
return url;
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
throw new RestApiError({
|
|
31
|
+
name: RestApiValidationErrorCode.InvalidApiName,
|
|
32
|
+
...validationErrorMap[RestApiValidationErrorCode.InvalidApiName],
|
|
33
|
+
recoverySuggestion: `Please make sure the REST endpoint URL is a valid URL string. Got ${urlStr}`,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { RestApiValidationErrorCode, assertValidationError } from '../errors';
|
|
4
|
+
/**
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export const resolveCredentials = async (amplify) => {
|
|
8
|
+
const { credentials } = await amplify.Auth.fetchAuthSession();
|
|
9
|
+
assertValidationError(!!credentials && !!credentials.accessKeyId && !!credentials.secretAccessKey, RestApiValidationErrorCode.NoCredentials);
|
|
10
|
+
return credentials;
|
|
11
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { MetadataBearer } from '@aws-sdk/types';
|
|
2
|
+
import { HttpResponse } from '@aws-amplify/core/internals/aws-client-utils';
|
|
3
|
+
import { RestApiError } from '../errors';
|
|
4
|
+
/**
|
|
5
|
+
* Internal-only method to create a new RestApiError from a service error.
|
|
6
|
+
*
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export declare const buildRestApiServiceError: (error: Error) => RestApiError;
|
|
10
|
+
export declare const parseRestApiServiceError: (response?: HttpResponse) => Promise<(RestApiError & MetadataBearer) | undefined>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { parseJsonError, } from '@aws-amplify/core/internals/aws-client-utils';
|
|
2
|
+
import { RestApiError } from '../errors';
|
|
3
|
+
/**
|
|
4
|
+
* Internal-only method to create a new RestApiError from a service error.
|
|
5
|
+
*
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export const buildRestApiServiceError = (error) => {
|
|
9
|
+
const restApiError = new RestApiError({
|
|
10
|
+
name: error?.name,
|
|
11
|
+
message: error.message,
|
|
12
|
+
underlyingError: error,
|
|
13
|
+
});
|
|
14
|
+
return restApiError;
|
|
15
|
+
};
|
|
16
|
+
export const parseRestApiServiceError = async (response) => {
|
|
17
|
+
const parsedError = await parseJsonError(response);
|
|
18
|
+
if (!parsedError) {
|
|
19
|
+
// Response is not an error.
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
return Object.assign(buildRestApiServiceError(parsedError), {
|
|
23
|
+
$metadata: parsedError.$metadata,
|
|
24
|
+
});
|
|
25
|
+
};
|
package/package.json
CHANGED
|
@@ -1,107 +1,115 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
2
|
+
"name": "@aws-amplify/api-rest",
|
|
3
|
+
"private": false,
|
|
4
|
+
"version": "4.0.0",
|
|
5
|
+
"description": "Api-rest category of aws-amplify",
|
|
6
|
+
"main": "./lib/index.js",
|
|
7
|
+
"module": "./lib-esm/index.js",
|
|
8
|
+
"typings": "./lib-esm/index.d.ts",
|
|
9
|
+
"react-native": {
|
|
10
|
+
"./lib/index": "./lib-esm/index.js"
|
|
11
|
+
},
|
|
12
|
+
"sideEffects": [
|
|
13
|
+
"./lib/RestAPI.js",
|
|
14
|
+
"./lib-esm/RestAPI.js"
|
|
15
|
+
],
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"test": "npm run lint && jest -w 1 --coverage",
|
|
21
|
+
"test:watch": "tslint 'src/**/*.ts' && jest -w 1 --watch",
|
|
22
|
+
"build-with-test": "npm run clean && npm test && tsc && webpack",
|
|
23
|
+
"build:cjs": "rimraf lib && tsc -m commonjs --outDir lib && webpack && webpack --config ./webpack.config.dev.js",
|
|
24
|
+
"build:esm": "rimraf lib-esm && tsc -m esnext --outDir lib-esm",
|
|
25
|
+
"build:cjs:watch": "rimraf lib && tsc -m commonjs --outDir lib --watch",
|
|
26
|
+
"build:esm:watch": "rimraf lib-esm && tsc -m esnext --outDir lib-esm --watch",
|
|
27
|
+
"build": "npm run clean && npm run build:esm && npm run build:cjs",
|
|
28
|
+
"clean": "npm run clean:size && rimraf lib-esm lib dist",
|
|
29
|
+
"clean:size": "rimraf dual-publish-tmp tmp*",
|
|
30
|
+
"format": "echo \"Not implemented\"",
|
|
31
|
+
"lint": "tslint 'src/**/*.ts' && npm run ts-coverage",
|
|
32
|
+
"ts-coverage": "typescript-coverage-report -p ./tsconfig.json -t 70.0"
|
|
33
|
+
},
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "https://github.com/aws-amplify/amplify-js.git"
|
|
37
|
+
},
|
|
38
|
+
"author": "Amazon Web Services",
|
|
39
|
+
"license": "Apache-2.0",
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/aws/aws-amplify/issues"
|
|
42
|
+
},
|
|
43
|
+
"homepage": "https://aws-amplify.github.io/",
|
|
44
|
+
"files": [
|
|
45
|
+
"lib",
|
|
46
|
+
"lib-esm",
|
|
47
|
+
"src",
|
|
48
|
+
"internals",
|
|
49
|
+
"server"
|
|
50
|
+
],
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"tslib": "^2.5.0"
|
|
53
|
+
},
|
|
54
|
+
"peerDependencies": {
|
|
55
|
+
"@aws-amplify/core": "^6.0.0"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@aws-amplify/core": "6.0.0",
|
|
59
|
+
"@aws-amplify/react-native": "^1.0.0",
|
|
60
|
+
"typescript": "5.0.2"
|
|
61
|
+
},
|
|
62
|
+
"size-limit": [
|
|
63
|
+
{
|
|
64
|
+
"name": "API (rest client)",
|
|
65
|
+
"path": "./lib-esm/index.js",
|
|
66
|
+
"import": "{ Amplify, RestAPI }",
|
|
67
|
+
"limit": "31.5 kB"
|
|
68
|
+
}
|
|
69
|
+
],
|
|
70
|
+
"jest": {
|
|
71
|
+
"globals": {
|
|
72
|
+
"ts-jest": {
|
|
73
|
+
"diagnostics": false,
|
|
74
|
+
"tsConfig": {
|
|
75
|
+
"allowJs": true,
|
|
76
|
+
"noEmitOnError": false
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"transform": {
|
|
81
|
+
"^.+\\.(js|jsx|ts|tsx)$": "ts-jest"
|
|
82
|
+
},
|
|
83
|
+
"testPathIgnorePatterns": [
|
|
84
|
+
"/testUtils/"
|
|
85
|
+
],
|
|
86
|
+
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(tsx?|jsx?)$",
|
|
87
|
+
"moduleFileExtensions": [
|
|
88
|
+
"ts",
|
|
89
|
+
"tsx",
|
|
90
|
+
"js",
|
|
91
|
+
"json",
|
|
92
|
+
"jsx"
|
|
93
|
+
],
|
|
94
|
+
"testEnvironment": "jsdom",
|
|
95
|
+
"testURL": "http://localhost/",
|
|
96
|
+
"coverageThreshold": {
|
|
97
|
+
"global": {
|
|
98
|
+
"branches": 0,
|
|
99
|
+
"functions": 0,
|
|
100
|
+
"lines": 0,
|
|
101
|
+
"statements": 0
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
"coveragePathIgnorePatterns": [
|
|
105
|
+
"node_modules",
|
|
106
|
+
"dist",
|
|
107
|
+
"lib",
|
|
108
|
+
"lib-esm"
|
|
109
|
+
],
|
|
110
|
+
"setupFiles": [
|
|
111
|
+
"<rootDir>/setupTests.ts"
|
|
112
|
+
]
|
|
113
|
+
},
|
|
114
|
+
"gitHead": "d505105326d7f6214f6bd1e06eb20be3a3651377"
|
|
107
115
|
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { AmplifyClassV6 } from '@aws-amplify/core';
|
|
4
|
+
import {
|
|
5
|
+
HttpRequest,
|
|
6
|
+
unauthenticatedHandler,
|
|
7
|
+
Headers,
|
|
8
|
+
getRetryDecider,
|
|
9
|
+
jitteredBackoff,
|
|
10
|
+
authenticatedHandler,
|
|
11
|
+
} from '@aws-amplify/core/internals/aws-client-utils';
|
|
12
|
+
import { DocumentType } from '@aws-amplify/core/internals/utils';
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
parseRestApiServiceError,
|
|
16
|
+
parseSigningInfo,
|
|
17
|
+
resolveCredentials,
|
|
18
|
+
} from '../../utils';
|
|
19
|
+
import { normalizeHeaders } from '../../utils/normalizeHeaders';
|
|
20
|
+
import { RestApiResponse } from '../../types';
|
|
21
|
+
|
|
22
|
+
type HandlerOptions = Omit<HttpRequest, 'body' | 'headers'> & {
|
|
23
|
+
body?: DocumentType | FormData;
|
|
24
|
+
headers?: Headers;
|
|
25
|
+
withCredentials?: boolean;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
type SigningServiceInfo = {
|
|
29
|
+
service?: string;
|
|
30
|
+
region?: string;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Make REST API call with best-effort IAM auth.
|
|
35
|
+
* @param amplify Amplify instance to to resolve credentials and tokens. Should use different instance in client-side
|
|
36
|
+
* and SSR
|
|
37
|
+
* @param options Options accepted from public API options when calling the handlers.
|
|
38
|
+
* @param signingServiceInfo Internal-only options enable IAM auth as well as to to overwrite the IAM signing service
|
|
39
|
+
* and region. If specified, and NONE of API Key header or Auth header is present, IAM auth will be used.
|
|
40
|
+
*
|
|
41
|
+
* @internal
|
|
42
|
+
*/
|
|
43
|
+
export const transferHandler = async (
|
|
44
|
+
amplify: AmplifyClassV6,
|
|
45
|
+
options: HandlerOptions & { abortSignal: AbortSignal },
|
|
46
|
+
signingServiceInfo?: SigningServiceInfo
|
|
47
|
+
): Promise<RestApiResponse> => {
|
|
48
|
+
const { url, method, headers, body, withCredentials, abortSignal } = options;
|
|
49
|
+
const resolvedBody = body
|
|
50
|
+
? body instanceof FormData
|
|
51
|
+
? body
|
|
52
|
+
: JSON.stringify(body ?? '')
|
|
53
|
+
: undefined;
|
|
54
|
+
const resolvedHeaders: Headers = {
|
|
55
|
+
...normalizeHeaders(headers),
|
|
56
|
+
...(resolvedBody
|
|
57
|
+
? {
|
|
58
|
+
'content-type':
|
|
59
|
+
body instanceof FormData
|
|
60
|
+
? 'multipart/form-data'
|
|
61
|
+
: 'application/json; charset=UTF-8',
|
|
62
|
+
}
|
|
63
|
+
: {}),
|
|
64
|
+
};
|
|
65
|
+
const request = {
|
|
66
|
+
url,
|
|
67
|
+
headers: resolvedHeaders,
|
|
68
|
+
method,
|
|
69
|
+
body: resolvedBody,
|
|
70
|
+
};
|
|
71
|
+
const baseOptions = {
|
|
72
|
+
retryDecider: getRetryDecider(parseRestApiServiceError),
|
|
73
|
+
computeDelay: jitteredBackoff,
|
|
74
|
+
withCrossDomainCredentials: withCredentials,
|
|
75
|
+
abortSignal,
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const isIamAuthApplicable = iamAuthApplicable(request, signingServiceInfo);
|
|
79
|
+
let response: RestApiResponse;
|
|
80
|
+
if (isIamAuthApplicable) {
|
|
81
|
+
const signingInfoFromUrl = parseSigningInfo(url);
|
|
82
|
+
const signingService =
|
|
83
|
+
signingServiceInfo?.service ?? signingInfoFromUrl.service;
|
|
84
|
+
const signingRegion =
|
|
85
|
+
signingServiceInfo?.region ?? signingInfoFromUrl.region;
|
|
86
|
+
const credentials = await resolveCredentials(amplify);
|
|
87
|
+
response = await authenticatedHandler(request, {
|
|
88
|
+
...baseOptions,
|
|
89
|
+
credentials,
|
|
90
|
+
region: signingRegion,
|
|
91
|
+
service: signingService,
|
|
92
|
+
});
|
|
93
|
+
} else {
|
|
94
|
+
response = await unauthenticatedHandler(request, {
|
|
95
|
+
...baseOptions,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
// Clean-up un-modeled properties from response.
|
|
99
|
+
return {
|
|
100
|
+
statusCode: response.statusCode,
|
|
101
|
+
headers: response.headers,
|
|
102
|
+
body: response.body,
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const iamAuthApplicable = (
|
|
107
|
+
{ headers }: HttpRequest,
|
|
108
|
+
signingServiceInfo?: SigningServiceInfo
|
|
109
|
+
) => !headers.authorization && !headers['x-api-key'] && !!signingServiceInfo;
|
|
@@ -0,0 +1,81 @@
|
|
|
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
|
+
|
|
6
|
+
import { InternalPostInput, RestApiResponse } from '../../types';
|
|
7
|
+
import { transferHandler } from './handler';
|
|
8
|
+
import { createCancellableOperation } from '../../utils';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* This weak map provides functionality to cancel a request given the promise containing the `post` request.
|
|
12
|
+
*
|
|
13
|
+
* 1. For every GraphQL POST request, an abort controller is created and supplied to the request.
|
|
14
|
+
* 2. The promise fulfilled by GraphGL POST request is then mapped to that abort controller.
|
|
15
|
+
* 3. The promise is returned to the external caller.
|
|
16
|
+
* 4. The caller can either wait for the promise to fulfill or call `cancel(promise)` to cancel the request.
|
|
17
|
+
* 5. If `cancel(promise)` is called, then the corresponding abort controller is retrieved from the map below.
|
|
18
|
+
* 6. GraphQL POST request will be rejected with the error message provided during cancel.
|
|
19
|
+
* 7. Caller can check if the error is because of cancelling by calling `isCancelError(error)`.
|
|
20
|
+
*/
|
|
21
|
+
const cancelTokenMap = new WeakMap<Promise<any>, AbortController>();
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
export const post = (
|
|
27
|
+
amplify: AmplifyClassV6,
|
|
28
|
+
{ url, options, abortController }: InternalPostInput
|
|
29
|
+
): Promise<RestApiResponse> => {
|
|
30
|
+
const controller = abortController ?? new AbortController();
|
|
31
|
+
const responsePromise = createCancellableOperation(async () => {
|
|
32
|
+
const response = transferHandler(
|
|
33
|
+
amplify,
|
|
34
|
+
{
|
|
35
|
+
url,
|
|
36
|
+
method: 'POST',
|
|
37
|
+
...options,
|
|
38
|
+
abortSignal: controller.signal,
|
|
39
|
+
},
|
|
40
|
+
options?.signingServiceInfo
|
|
41
|
+
);
|
|
42
|
+
return response;
|
|
43
|
+
}, controller);
|
|
44
|
+
|
|
45
|
+
const responseWithCleanUp = responsePromise.finally(() => {
|
|
46
|
+
cancelTokenMap.delete(responseWithCleanUp);
|
|
47
|
+
});
|
|
48
|
+
return responseWithCleanUp;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Cancels a request given the promise returned by `post`.
|
|
53
|
+
* If the request is already completed, this function does nothing.
|
|
54
|
+
* It MUST be used after `updateRequestToBeCancellable` is called.
|
|
55
|
+
*/
|
|
56
|
+
export const cancel = (
|
|
57
|
+
promise: Promise<RestApiResponse>,
|
|
58
|
+
message?: string
|
|
59
|
+
): boolean => {
|
|
60
|
+
const controller = cancelTokenMap.get(promise);
|
|
61
|
+
if (controller) {
|
|
62
|
+
controller.abort(message);
|
|
63
|
+
if (message && controller.signal.reason !== message) {
|
|
64
|
+
// In runtimes where `AbortSignal.reason` is not supported, we track the reason ourselves.
|
|
65
|
+
// @ts-expect-error reason is read-only property.
|
|
66
|
+
controller.signal['reason'] = message;
|
|
67
|
+
}
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
return false;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* MUST be used to make a promise including internal `post` API call cancellable.
|
|
75
|
+
*/
|
|
76
|
+
export const updateRequestToBeCancellable = (
|
|
77
|
+
promise: Promise<any>,
|
|
78
|
+
controller: AbortController
|
|
79
|
+
) => {
|
|
80
|
+
cancelTokenMap.set(promise, controller);
|
|
81
|
+
};
|