Source: rosetteRequest.js

/**
 * Analytics API.
 *
 * @copyright 2016-2024 Basis Technology Corporation.
 *
 * 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
 * @license 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.
 **/
"use strict";

var http = require("http");
var https = require("https");
var URL = require("url");
var zlib = require("zlib");

var rosetteConstants = require("./rosetteConstants");
var RosetteException = require("./rosetteExceptions");

var querystring = require('querystring');

/**
 * Compatible server version.
 *
 * @type string
 */
var BINDING_VERSION = rosetteConstants.BINDING_VERSION;
var USER_AGENT = `Babel-Street-Analytics-API-Node/${BINDING_VERSION}/${process.version}`;

/**
 * @class
 *
 * @copyright 2016-2024 Basis Technology Corporation.
 * @license http://www.apache.org/licenses/LICENSE-2.0
 */
function rosetteRequest() {
// constructor function
}

rosetteRequest.prototype.bindingVersion = function() {
    return BINDING_VERSION;
}
rosetteRequest.prototype.userAgent = function() {
    return USER_AGENT;
}

/**
 * Makes an HTTP request to the specified Analytics API endpoint and returns the result
 * @param {string} requestType - GET/POST
 * @param {string} userKey - The Analytics API user access key
 * @param {object} urlParts - Structure containing the url parameters
 * @param {object} parameters - Structure containing the API parameters
 * @param {function} callback - Callback function to be executed after the function to which it is passed is complete
 */
rosetteRequest.prototype.makeRequest = function(requestType, userKey, protocol, urlParts, parameters, callback) {
    var headers = {
        "accept": "application/json",
        "accept-encoding": "gzip",
        "content-type": "application/json",
        "user-agent": USER_AGENT,
        "X-BabelStreetAPI-Binding": "nodejs",
        "X-BabelStreetAPI-Binding-Version": BINDING_VERSION,
        //todo remove these in the future
        "X-RosetteAPI-Binding": "nodejs",
        "X-RosetteAPI-Binding-Version": BINDING_VERSION
    }

    if (userKey != null) {
        headers["X-BabelStreetAPI-Key"] = userKey;
    }

    // to see custom headers format example in languages examples
    if (parameters.customHeaders != null) {
        parameters.customHeaders.forEach(function(element, index) {
            headers[element[0]] = element[1];
        });

    }

    var path = urlParts.path;

    if (parameters.urlParameters != null) {
        path = `${path}?${querystring.stringify(parameters.urlParameters)}`;
    }

    var options = {
        hostname: urlParts.hostname,
        path: path,
        method: requestType,
        headers: headers,
        agent: false
    };

    if (urlParts.port) {
        options.port = urlParts.port;
    }

    requestTask(protocol, options, parameters, callback);
};

function requestTask(protocol, options, parameters, callback) {
    var result = Buffer.from("");
    // execute the http/https request
    var req = protocol.request(options, function(res) {
        res.on("data", function(docs) {
            result = Buffer.concat([result, docs]);
        });

        res.on("end", function(err) {
            if (err) {
                return callback(err)
            }

            if (res.headers["content-encoding"] === "gzip") {
                result = zlib.gunzipSync(result);
            }

            result = JSON.parse(result);
            result.headers = res.headers;
            result = JSON.stringify(result);

            if (res.statusCode === 200) {
                return callback(null, JSON.parse(result.toString()));
            } else {
                return callback(new RosetteException(res.statusCode, result.toString()));
            }
        });
    });

    req.on("error", function(e) {
        console.log(e)
        return callback(e);
    });

    if (parameters !== null) {
        req.write(JSON.stringify(parameters.loadParams()));
    }

    req.end();
}

rosetteRequest.prototype.makeDocumentRequest = function(endpoint, parameters, userKey, protocol, serviceURL, callback) {
    if (parameters.documentFile != null) {
        parameters.loadFile(parameters.documentFile, parameters, userKey, protocol, serviceURL, endpoint, callback);
    } else {
        // validate parameters
        if (!parameters.loadParams().content && !parameters.loadParams().contentUri) {
            return callback(new RosetteException("badArgument", "Must supply one of content or contentUri", "bad arguments"));
        } else if (parameters.loadParams().content != null && parameters.loadParams().contentUri != null) {
            return callback(new RosetteException("badArgument", "Cannot supply content and contentUri", "bad arguments"));
        } else {
            // configure URL
            var urlParts = URL.parse(serviceURL + endpoint);
            var req = new rosetteRequest();
            req.makeRequest('POST', userKey, protocol, urlParts, parameters, callback);
        }
    }
}

module.exports = rosetteRequest;