Source: sqlpassthru.js

import { SlashDBClient } from './slashdbclient.js';
import { SQLPassThruFilter } from './sqlpassthrufilter.js';
import { BaseRequestHandler } from './baserequesthandler.js';

const SDB_SPTQ_NO_CLIENTOBJ = 'Parameter clientObj missing or not valid SlashDBClient object';
const SDB_SPTQ_INVALID_QUERYNAME = 'Parameter queryName must be a non-empty string';
const SDB_SPTQ_INVALID_PATH_EMPTY = 'Empty path given';
const SDB_SPTQ_INVALID_PATH_TYPE = 'Path is not a string or a DataDiscoveryFilter object';

/** 
 * Executes HTTP requests for SlashDB SQL Pass-Thru functionality.  Extends the `BaseRequestHandler` class
 * for most methods.
 */
class SQLPassThruQuery extends BaseRequestHandler {

   /**
   * Create a `SQLPassThruQuery` object for a given SlashDB instance
   * @extends BaseRequestHandler
   * @param {string} queryID - ID of the query to execute, as registered in the SlashDB instance
   * @param {SlashDBClient} clientObj - a configured `SlashDBClient` object
   * @param {Object} [methods] - optional object of key/value pairs specifying which HTTP methods the query supports (e.g. `{GET:true, POST:false}`)
   * @param {Object} [params] - optional array of strings specifying names of parameters (e.g. `['FirstName','LastName']`)
   * @throws {TypeError} if `queryID` not a string
   * @throws {SyntaxError} if `queryID` contains '/' character
   * @throws {SyntaxError} if `queryID` contains spaces or parses to number
   */
    constructor(queryID, clientObj, methods=null, params=null) {
        super(clientObj)

		if (typeof(queryID) !== 'string' || queryID.trim().length < 1) {
			throw TypeError(SDB_SPTQ_INVALID_QUERYNAME);
		}
		if (queryID.indexOf('/') > -1) {
			throw SyntaxError(SDB_SPTQ_INVALID_QUERYNAME);
		}

		if (!isNaN(parseInt(queryID)) || queryID.indexOf(' ') > -1) {
			throw SyntaxError(SDB_SPTQ_INVALID_QUERYNAME);
		}
        
        // object key/value pairs of methods
        if (methods) {
            this.methods = methods;
        }

        // array of parameters
        if (params) {
            this.params = params;
        }

        this.queryName = queryID;
        this.queryPrefix = '/query/';

    }

    /**
     * Builds the full endpoint to the requested resource.  Meant for internal use only.
     * @param {string | SQLPassThruFilter} [path] - an optional string containing a URI segment with SQL query parameters/values and URL query parameters 
     * (e.g. `/FirstName/Tim?distinct=true`), or a `SQLPassThruFilter` object that contains all the query details
     * @returns {string} the full endpoint
     * @throws {ReferenceError} if no `SlashDBClient` object is found attached to this object
     * @throws {SyntaxError} if `path` parameter is an empty string
     * @throws {TypeError} if `path` parameter is neither a string or a `SQLPassThruFilter` object
     */
    _buildEndpointString(path) {

        if (! this.sdbClient || ! (this.sdbClient instanceof SlashDBClient)) {
            throw ReferenceError(SDB_SPTQ_NO_CLIENTOBJ);
        }
        
        let endpoint = this.queryPrefix + `${this.queryName}`;
        
        // if no path is provided, the HTTP operation just request to execute the query w/o parameters
        if (!path) {
            return this.sdbClient.host + endpoint;
        }

        
        // path can be string or SQLPassThruFilter object
        if (typeof(path) === 'string') {
            if (path.trim().length < 1) {
                throw SyntaxError(SDB_SPTQ_INVALID_PATH_EMPTY);
            }

            // prefix the URL path with fwd slash if it's missing
            if (Array.from(path)[0] !== '/') {
                path =`/${path}`;
            }
        }
        

        else if ( path instanceof SQLPassThruFilter) {
            path = path.endpoint;
        }

        else {
            throw TypeError(SDB_SPTQ_INVALID_PATH_TYPE);
        }

        return this.sdbClient.host + endpoint + path;
    }
}

export { SQLPassThruQuery }