generated from SAP/repository-template
-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathhttp-client.ts
128 lines (121 loc) · 3.49 KB
/
http-client.ts
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import {
ErrorWithCause,
mergeIgnoreCase,
removeLeadingSlashes,
removeTrailingSlashes
} from '@sap-cloud-sdk/util';
import { executeHttpRequest } from '@sap-cloud-sdk/http-client';
import { getAiCoreDestination } from './context.js';
import type { HttpDestinationOrFetchOptions } from '@sap-cloud-sdk/connectivity';
import type {
HttpRequestConfig,
HttpResponse
} from '@sap-cloud-sdk/http-client';
/**
* The type for parameters in custom request configuration.
*/
export type CustomRequestConfig = Pick<
HttpRequestConfig,
| 'headers'
| 'params'
| 'middleware'
| 'maxContentLength'
| 'proxy'
| 'httpAgent'
| 'httpsAgent'
| 'parameterEncoder'
> &
Record<string, any>;
/**
* The options to call an endpoint.
*/
export interface EndpointOptions {
/**
* The specific endpoint to call.
*/
url: string;
/**
* The API version to use.
*/
apiVersion?: string;
/**
* The resource group to use.
*/
resourceGroup?: string;
}
/**
* Executes a request to the AI Core service.
* @param endpointOptions - The options to call an endpoint.
* @param data - The input parameters for the request.
* @param requestConfig - The request configuration.
* @param destination - The destination to use for the request.
* @returns The {@link HttpResponse} from the AI Core service.
*/
export async function executeRequest(
endpointOptions: EndpointOptions,
data: any,
requestConfig?: CustomRequestConfig,
destination?: HttpDestinationOrFetchOptions
): Promise<HttpResponse> {
const aiCoreDestination = await getAiCoreDestination(destination);
const { url, apiVersion, resourceGroup = 'default' } = endpointOptions;
const mergedRequestConfig = {
...mergeWithDefaultRequestConfig(apiVersion, resourceGroup, requestConfig),
data: JSON.stringify(data)
};
try {
const response = await executeHttpRequest(
{ ...aiCoreDestination, url: getTargetUrl(aiCoreDestination.url, url) },
mergedRequestConfig,
{
fetchCsrfToken: false
}
);
return response;
} catch (error: any) {
throw new ErrorWithCause(
`Request failed with status code ${error.status}.`,
error
);
}
}
function mergeWithDefaultRequestConfig(
apiVersion?: string,
resourceGroup?: string,
requestConfig?: CustomRequestConfig
): HttpRequestConfig {
const defaultConfig: HttpRequestConfig = {
method: 'post',
headers: {
'content-type': 'application/json',
'ai-resource-group': resourceGroup,
'ai-client-type': 'AI SDK JavaScript'
},
params: apiVersion ? { 'api-version': apiVersion } : {}
};
return {
...defaultConfig,
...requestConfig,
headers: mergeIgnoreCase(defaultConfig.headers, requestConfig?.headers),
params: mergeIgnoreCase(defaultConfig.params, requestConfig?.params)
};
}
/**
* Get target url with endpoint path appended.
* Append path `v2` if the url contains empty pathname `/`.
* @param url - The url, e.g., `http://example.com` or `http://example.com:8000/abc`.
* @param endpointPath - The path to the endpoint, e.g., `/some/endpoint`.
* @returns Target url combining the url and endpoint path.
* @internal
*/
export function getTargetUrl(url: string, endpointPath: string): string {
// Remove the last trailing slash
url = removeTrailingSlashes(url);
// Remove the first leading slashes
endpointPath = removeLeadingSlashes(endpointPath);
const urlObj = new URL(url);
if (urlObj.pathname === '/') {
return url + '/v2/' + endpointPath;
}
return url + '/' + endpointPath;
}