@ibm-cloud/cloudant
Version:
IBM Cloudant Node.js SDK
208 lines • 7.77 kB
JavaScript
;
/**
* © Copyright IBM Corporation 2020, 2024. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
// eslint-disable-next-line max-classes-per-file
const ibm_cloud_sdk_core_1 = require("ibm-cloud-sdk-core");
const tough_cookie_1 = require("tough-cookie");
const node_https_1 = require("node:https");
const node_http_1 = require("node:http");
const auth_1 = require("../auth");
const errorResponseInterceptor_1 = require("./errorResponseInterceptor");
/**
* Set default timeout to 2.5 minutes (= 150 000 ms)
*/
const READ_TIMEOUT = 150_000;
/**
* Set Validation rules
*/
const DocumentOperations = [
'deleteDocument',
'getDocument',
'getDocumentAsMixed',
'getDocumentAsRelated',
'getDocumentAsStream',
'headDocument',
'putDocument',
'deleteAttachment',
'getAttachment',
'headAttachment',
'putAttachment',
];
const AttachmentOperations = [
'deleteAttachment',
'getAttachment',
'headAttachment',
'putAttachment',
];
const docIdRule = {
pathSegment: 'doc_id',
errorParameterName: 'Document ID',
operationIds: DocumentOperations,
};
const attIdRule = {
pathSegment: 'attachment_name',
errorParameterName: 'Attachment name',
operationIds: AttachmentOperations,
};
const validationRules = [docIdRule, attIdRule];
const rulesByOperation = {};
validationRules.forEach((rule) => {
rule.operationIds.forEach((operationId) => {
if (!(operationId in rulesByOperation)) {
rulesByOperation[operationId] = [];
}
rulesByOperation[operationId].push(rule);
});
});
Object.freeze(rulesByOperation);
/**
* --- Classes ---
*/
/**
* Extend Error interface to access the proper Error definition.
*/
class InvalidArgumentValueError extends Error {
code;
}
/**
* Cloudant specific service that extends the base service functions.
*
* Cloudant Service make it available to use CouchDB specific Session authentication
* during service requests.
*/
class CloudantBaseService extends ibm_cloud_sdk_core_1.BaseService {
timeout;
/**
* Configuration values to use Cloudant service.
* @param {Authenticator} userOptions.authenticator CouchdbSessionAuthenticator object can be used
* to authenticate requests to the service.
* @param {string} [userOptions.jar] A Cookie Jar. Enabled by default if there is no custom one.
*/
constructor(userOptions) {
userOptions.jar = userOptions.jar || new tough_cookie_1.CookieJar();
if (!('timeout' in userOptions)) {
userOptions.timeout = READ_TIMEOUT;
}
CloudantBaseService.setDefaultAgentsIfUnset(userOptions);
super(userOptions);
this.timeout = userOptions.timeout;
this.configureSessionAuthenticator();
// Add response interceptor for error transforms
this.addErrorTransformers();
}
addErrorTransformers() {
this.getHttpClient().interceptors.response.use((response) => response, errorResponseInterceptor_1.errorResponseStreamConverter);
this.getHttpClient().interceptors.response.use((response) => response, errorResponseInterceptor_1.errorResponseInterceptor);
}
getTimeout() {
return this.timeout;
}
/**
* Set the service URL to send requests to and
* use the new service URL for CouchDB Session Authentication
* to claim session token from.
*
* @param {string} url The base URL for the service.
*/
setServiceUrl(url) {
super.setServiceUrl(url);
this.configureSessionAuthenticator();
}
/**
* Configure the service using external configuration
* Cloudant specific extensions:
* - Apply the new base service options on CouchdbSessionAuthenticator.
*
* @param {string} serviceName The name of the service. Will be used to read from external
* configuration.
*/
configureService(serviceName) {
// Read external configuration and set as request defaults.
super.configureService(serviceName);
this.configureSessionAuthenticator();
// Add response interceptor for error transforms
this.addErrorTransformers();
}
/**
* Turn request body compression on or off.
* Cloudant specific extensions:
* - Apply the gzip compression option on CouchdbSessionAuthenticator.
*
* @param {boolean} setting Will turn it on if 'true', off if 'false'.
*/
setEnableGzipCompression(setting) {
// Read external configuration and set as request defaults.
super.setEnableGzipCompression(setting);
this.configureSessionAuthenticator();
}
/**
* In case of CouchdbSessionAuthenticator
* the service options should be applied on it.
*/
configureSessionAuthenticator() {
const auth = this.getAuthenticator();
if (auth instanceof auth_1.CouchdbSessionAuthenticator) {
auth.configure(this.baseOptions);
}
}
/**
* Extend createRequest to handle document and attachment validation.
*/
createRequest(parameters) {
let operationId = null;
if ('X-IBMCloud-SDK-Analytics' in parameters.defaultOptions.headers) {
// Extract operation id
const analyticsHeader = parameters.defaultOptions.headers['X-IBMCloud-SDK-Analytics'];
[, operationId] = analyticsHeader
.split(';')
.find((element) => element.startsWith('operation_id'))
.split('=');
// Check if operation id exists in rulesByOperation object
if (operationId != null &&
Object.keys(rulesByOperation).includes(operationId)) {
const violatedRules = rulesByOperation[operationId].filter((rule) => {
// get the path segment e.g. doc_id from the response's path object
if ('path' in parameters.options &&
rule.pathSegment in parameters.options.path) {
const segmentToValidate = parameters.options.path[rule.pathSegment];
return segmentToValidate.startsWith('_');
}
return false;
});
if (violatedRules.length > 0) {
const err = new InvalidArgumentValueError(`${violatedRules[0].errorParameterName} ${parameters.options.path[violatedRules[0].pathSegment]} starts with the invalid _ character.`);
err.code = 'ERR_INVALID_ARG_VALUE';
return Promise.reject(err);
}
}
}
return super.createRequest(parameters);
}
static setDefaultAgentsIfUnset(options) {
const cloudantDefaultAgentOptions = {
keepAlive: true,
};
if (!options.httpAgent) {
options.httpAgent = new node_http_1.Agent(cloudantDefaultAgentOptions);
}
if (!options.httpsAgent) {
options.httpsAgent = new node_https_1.Agent(cloudantDefaultAgentOptions);
}
}
}
exports.default = CloudantBaseService;
//# sourceMappingURL=cloudantBaseService.js.map