2023-07-21 10:08:56 +00:00
|
|
|
import {
|
|
|
|
|
QueryResult,
|
|
|
|
|
User,
|
|
|
|
|
App,
|
|
|
|
|
OAuthUnauthorizedClientError,
|
|
|
|
|
QueryError,
|
|
|
|
|
QueryService,
|
|
|
|
|
getRefreshedToken,
|
|
|
|
|
validateAndSetRequestOptionsBasedOnAuthType,
|
|
|
|
|
getAuthUrl,
|
|
|
|
|
} from '@tooljet-plugins/common';
|
2022-04-26 08:44:12 +00:00
|
|
|
import { SourceOptions, QueryOptions, RestAPIResult } from './types';
|
2023-07-21 10:08:56 +00:00
|
|
|
import got, { HTTPError, OptionsOfTextResponseBody } from 'got';
|
2022-04-26 08:44:12 +00:00
|
|
|
import urrl from 'url';
|
|
|
|
|
|
|
|
|
|
export default class Openapi implements QueryService {
|
|
|
|
|
private resolvePathParams(params: any, path: string) {
|
|
|
|
|
let newString = path;
|
|
|
|
|
Object.entries(params).map(([key, value]) => {
|
|
|
|
|
newString = newString.replace(`{${key}}`, value as any);
|
|
|
|
|
});
|
|
|
|
|
return newString;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private sanitizeObject(params: any) {
|
|
|
|
|
Object.keys(params).forEach((key) => (params[key] === '' ? delete params[key] : {}));
|
|
|
|
|
return params;
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-21 10:08:56 +00:00
|
|
|
async run(
|
|
|
|
|
sourceOptions: SourceOptions,
|
|
|
|
|
queryOptions: QueryOptions,
|
|
|
|
|
dataSourceId: string,
|
|
|
|
|
dataSourceUpdatedAt: string,
|
|
|
|
|
context?: { user?: User; app?: App }
|
|
|
|
|
): Promise<RestAPIResult> {
|
|
|
|
|
const { host, path, operation, params } = queryOptions;
|
|
|
|
|
const { request, query, header, path: pathParams } = params;
|
|
|
|
|
const url = new URL(host + this.resolvePathParams(pathParams, path));
|
|
|
|
|
const json = operation !== 'get' ? this.sanitizeObject(request) : undefined;
|
2022-04-26 08:44:12 +00:00
|
|
|
|
2023-07-21 10:08:56 +00:00
|
|
|
const _requestOptions: OptionsOfTextResponseBody = {
|
|
|
|
|
method: operation,
|
|
|
|
|
headers: header,
|
|
|
|
|
searchParams: {
|
|
|
|
|
...query,
|
|
|
|
|
},
|
|
|
|
|
json,
|
2022-04-26 08:44:12 +00:00
|
|
|
};
|
|
|
|
|
|
2023-07-21 10:08:56 +00:00
|
|
|
const authValidatedRequestOptions: QueryResult = validateAndSetRequestOptionsBasedOnAuthType(
|
|
|
|
|
sourceOptions,
|
|
|
|
|
context,
|
|
|
|
|
_requestOptions,
|
|
|
|
|
{ url }
|
|
|
|
|
);
|
|
|
|
|
const { status, data } = authValidatedRequestOptions;
|
|
|
|
|
if (status === 'needs_oauth') return authValidatedRequestOptions;
|
2022-04-26 08:44:12 +00:00
|
|
|
|
2023-07-21 10:08:56 +00:00
|
|
|
const requestOptions = data as OptionsOfTextResponseBody;
|
2022-04-26 08:44:12 +00:00
|
|
|
|
|
|
|
|
let result = {};
|
|
|
|
|
let requestObject = {};
|
|
|
|
|
let responseObject = {};
|
|
|
|
|
let responseHeaders = {};
|
|
|
|
|
|
|
|
|
|
try {
|
2023-07-21 10:08:56 +00:00
|
|
|
const response = await got(url, requestOptions);
|
2022-04-26 08:44:12 +00:00
|
|
|
|
|
|
|
|
result = JSON.parse(response.body);
|
|
|
|
|
requestObject = {
|
|
|
|
|
requestUrl: response.request.requestUrl,
|
|
|
|
|
method: response.request.options.method,
|
|
|
|
|
headers: response.request.options.headers,
|
|
|
|
|
params: urrl.parse(response.request.requestUrl.toString(), true).query,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
responseObject = {
|
|
|
|
|
body: response.body,
|
|
|
|
|
statusCode: response.statusCode,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
responseHeaders = response.headers;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.log(error);
|
|
|
|
|
|
|
|
|
|
if (error instanceof HTTPError) {
|
|
|
|
|
result = {
|
|
|
|
|
requestObject: {
|
|
|
|
|
requestUrl: error.request.requestUrl,
|
|
|
|
|
requestHeaders: error.request.options.headers,
|
|
|
|
|
requestParams: urrl.parse(error.request.requestUrl.toString(), true).query,
|
|
|
|
|
},
|
|
|
|
|
responseObject: {
|
|
|
|
|
statusCode: error.response.statusCode,
|
|
|
|
|
responseBody: error.response.body,
|
|
|
|
|
},
|
|
|
|
|
responseHeaders: error.response.headers,
|
|
|
|
|
};
|
|
|
|
|
}
|
2023-07-21 10:08:56 +00:00
|
|
|
if (sourceOptions['auth_type'] === 'oauth2' && error?.response?.statusCode == 401) {
|
2022-10-19 14:34:57 +00:00
|
|
|
throw new OAuthUnauthorizedClientError('Unauthorized status from API server', error.message, result);
|
|
|
|
|
}
|
2022-04-26 08:44:12 +00:00
|
|
|
throw new QueryError('Query could not be completed', error.message, result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
status: 'ok',
|
|
|
|
|
data: result,
|
|
|
|
|
request: requestObject,
|
|
|
|
|
response: responseObject,
|
|
|
|
|
responseHeaders,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-21 10:08:56 +00:00
|
|
|
authUrl(sourceOptions: SourceOptions): string {
|
|
|
|
|
return getAuthUrl(sourceOptions);
|
2022-04-26 08:44:12 +00:00
|
|
|
}
|
|
|
|
|
|
2023-07-21 10:08:56 +00:00
|
|
|
async refreshToken(sourceOptions: any, error: any, userId: string, isAppPublic: boolean) {
|
|
|
|
|
return getRefreshedToken(sourceOptions, error, userId, isAppPublic);
|
2022-04-26 08:44:12 +00:00
|
|
|
}
|
|
|
|
|
}
|