UNPKG

pcp-server-nodejs-sdk

Version:

[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=PAYONE-GmbH_PCP-server-nodeJS-SDK&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=PAYONE-GmbH_PCP-server-nodeJS-SDK) [![Coverage](https://sonarcloud.io/api/pr

107 lines 4.07 kB
import fetch, {} from 'node-fetch'; import { CommunicatorConfiguration } from '../CommunicatorConfiguration.js'; import { ApiErrorResponseException, ApiResponseRetrievalException } from '../errors/index.js'; import { RequestHeaderGenerator } from '../RequestHeaderGenerator.js'; function isErrorResponse(parsed) { if (typeof parsed !== 'object' || parsed === null) { return false; } const record = parsed; if (Object.hasOwn(record, 'errorId') && typeof record['errorId'] !== 'string') { return false; } if (Object.hasOwn(record, 'errorId') && !Array.isArray(record['errors'])) { return false; } return true; } export const MERCHANT_ID_REQUIRED_ERROR = 'Merchant ID is required'; export const COMMERCE_CASE_ID_REQUIRED_ERROR = 'Commerce Case ID is required'; export const CHECKOUT_ID_REQUIRED_ERROR = 'Checkout ID is required'; export class BaseApiClient { static parseVoid() { return; } static parseJson(body) { const parsed = JSON.parse(body); if (typeof parsed !== 'object' || parsed === null) { throw new TypeError('Parsed JSON is not an object'); } return parsed; } requestHeaderGenerator; config; clientFetchOptions; constructor(config, clientFetchOptions) { this.config = config; this.requestHeaderGenerator = new RequestHeaderGenerator(config); this.clientFetchOptions = clientFetchOptions; } getRequestHeaderGenerator() { return this.requestHeaderGenerator; } getConfig() { return this.config; } /** * Set client-specific fetch options that will override global configuration options. * @param fetchOptions - Custom fetch options for this API client instance */ setFetchOptions(fetchOptions) { this.clientFetchOptions = fetchOptions; } /** * Get the effective fetch options by merging global and client-specific options. * Client-specific options take precedence over global options. */ getEffectiveFetchOptions() { const globalOptions = this.config.getFetchOptions(); if (!globalOptions && !this.clientFetchOptions) { return undefined; } // Merge options with client-specific taking precedence return { ...globalOptions, ...this.clientFetchOptions, // Special handling for headers - merge them instead of replacing headers: { ...globalOptions?.headers, ...this.clientFetchOptions?.headers, }, }; } async makeApiCall(url, requestInit, parseBody = BaseApiClient.parseJson) { // First apply SDK headers and authentication requestInit = this.requestHeaderGenerator.generateAdditionalRequestHeaders(url, requestInit); // Then merge with custom fetch options (user options take precedence) const effectiveFetchOptions = this.getEffectiveFetchOptions(); if (effectiveFetchOptions) { requestInit = { ...effectiveFetchOptions, ...requestInit, // Special handling for headers - merge them instead of replacing headers: { ...effectiveFetchOptions.headers, ...requestInit.headers, }, }; } const response = await fetch(url, requestInit); const body = await response.text(); let parsed; try { parsed = parseBody(body); } catch (error) { throw new ApiResponseRetrievalException(response.status, body, error instanceof Error ? error : undefined); } if (!response.ok) { if (isErrorResponse(parsed)) { throw new ApiErrorResponseException(response.status, body, parsed.errors ?? []); } throw new ApiResponseRetrievalException(response.status, body); } return parsed; } } //# sourceMappingURL=BaseApiClient.js.map