• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

terminusdb / terminusdb-client-js / 15007221089

13 May 2025 09:35PM UTC coverage: 30.205% (-0.04%) from 30.241%
15007221089

push

github

web-flow
Merge pull request #319 from hoijnet/issue/318-fix-woql-from

Issue/318 fix woql from (fixes #318)

885 of 4650 branches covered (19.03%)

Branch coverage included in aggregate %.

2 of 2 new or added lines in 1 file covered. (100.0%)

6 existing lines in 3 files now uncovered.

2485 of 6507 relevant lines covered (38.19%)

4.49 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

46.11
/lib/dispatchRequest.js
1
/* eslint-disable camelcase */
2
const pako = require('pako');
1✔
3
const axiosInstance = require('./axiosInstance');
1✔
4
const UTILS = require('./utils');
1✔
5
const CONST = require('./const');
1✔
6
const ErrorMessage = require('./errorMessage');
1✔
7
const { version } = require('../package.json');
1✔
8
// eslint-disable-next-line no-unused-vars
9
const typedef = require('./typedef');
1✔
10
/**
11
 * base 64 encodes a string using either the btoa implementation if available or the Buffer object.
12
 * @param {String} str string to be base 64 encoded
13
 */
14
function btoaImplementation(str) {
15
  try {
4✔
16
    return btoa(str);
4✔
17
  } catch (err) {
UNCOV
18
    return Buffer.from(str).toString('base64');
×
19
  }
20
}
21

22
/**
23
 * @param {object} response
24
 * @returns {object} Object having two properties result and dataVersion
25
 */
26
function getResultWithDataVersion(response) {
27
  return {
×
28
    result: response.data,
29
    dataVersion: response.headers['terminusdb-data-version']
×
30
      ? response.headers['terminusdb-data-version']
31
      : '',
32
  };
33
}
34
/**
35
 * Create the authorization header string
36
 * @param {object} auth_obj
37
 * @returns {object} Object with the Authorization header
38
 */
39

40
function formatAuthHeader(auth_obj) {
41
  if (!auth_obj) return '';
4!
42
  const authType = { jwt: 'Bearer', basic: 'Basic', apikey: 'Token' };
4✔
43
  let auth_key = auth_obj.key;
4✔
44

45
  if (auth_obj.type === 'basic') {
4!
46
    auth_key = btoaImplementation(`${auth_obj.user}:${auth_obj.key}`);
4✔
47
  }
48
  return `${authType[auth_obj.type]} ${auth_key}`;
4✔
49
}
50

51
function checkPayload(payload, options, compress) {
52
  if (!payload || typeof payload !== 'object') return false;
2!
53
  const jsonStringPost = JSON.stringify(payload);
2✔
54
  if (jsonStringPost && jsonStringPost.length > 1024 && compress) {
2!
55
    // eslint-disable-next-line no-param-reassign
56
    options.headers['Content-Encoding'] = 'gzip';
×
57
    return pako.gzip(jsonStringPost);
×
58
  }
59
  return false;
2✔
60
}
61

62
/**
63
 * @file Dispatch Request
64
 * @license Apache Version 2
65
 * @description Functions for dispatching API requests via the axios library.
66
 * @param {string} url  API endpoint URL
67
 * @param {string} action API action
68
 * @param {object} payload data to be transmitted to endpoint
69
 * @param {typedef.CredentialObj} local_auth the local authorization object
70
 * @param {typedef.CredentialObj} remote_auth the remote authoriuzation object
71
 * @param {object} customHeaders all the custom header to add to your call
72
 * @param {boolean} [getDataVersion] If true the function will return object having result
73
 * and dataVersion.
74
 * @param {boolean} [compress] If true, compress the data with gzip if its size is bigger than 1024
75
 */
76

77
// eslint-disable-next-line max-len
78
function DispatchRequest(url, action, payload, local_auth, remote_auth = null, customHeaders = null, getDataVersion = false, compress = false) {
4!
79
  /*
80
     *CORS is only required when trying to fetch data from a browser,
81
     *as browsers by default will block requests to different origins
82
     */
83
  const options = {
4✔
84
    mode: 'cors', // no-cors, cors, *same-origin
85
    redirect: 'follow', // manual, *follow, error
86
    referrer: 'client',
87
    maxContentLength: Infinity,
88
    maxBodyLength: Infinity,
89
    headers: {},
90
    // url:url,
91
    // no-referrer, *client
92
  };
93
  // Only allow self signed certs on 127.0.0.1
94
  // and on node
95
  if (url.startsWith('https://127.0.0.1') && typeof window === 'undefined') {
4!
96
    // eslint-disable-next-line global-require
97
    const https = require('https');
×
98
    const agent = new https.Agent({
×
99
      rejectUnauthorized: false,
100
    });
101
    options.httpsAgent = agent;
×
102
  }
103

104
  /*
105
     * I can call the local database using the local authorization key or
106
     * a jwt token
107
     */
108
  /* if (local_auth && local_auth.type === 'basic') {
109
    const encoded = btoaImplementation(`${local_auth.user}:${local_auth.key}`);
110
    options.headers = { Authorization: `Basic ${encoded}` };
111
  } else if (local_auth && local_auth.type === 'jwt') {
112
    options.headers = { Authorization: `Bearer ${local_auth.key}` };
113
  } else if (local_auth && local_auth.type === 'apikey') {
114
    options.headers = { Authorization: `Token ${local_auth.key}` };
115
  } */
116
  /*
117
     * I can call the local database or a custom installation using the local authorization key or
118
     * I Can call TerminusX using the jwt token or an apiToken
119
     */
120
  if (local_auth && typeof local_auth === 'object') {
4!
121
    options.headers.Authorization = formatAuthHeader(local_auth);
4✔
122
  }
123

124
  /*
125
   * pass the Authorization information of another
126
   * terminusdb server to the local terminusdb
127
   * for authentication you can use jwt or the apiKey token in TerminusX or
128
   * the Basic autentication if is allowed in the custom server
129
   */
130
  if (remote_auth && typeof remote_auth === 'object') {
4!
131
    options.headers['Authorization-Remote'] = formatAuthHeader(remote_auth);
×
132
  }
133

134
  if (customHeaders && typeof customHeaders === 'object') {
4!
135
    // eslint-disable-next-line array-callback-return
136
    Object.keys(customHeaders).map((key) => {
×
137
      options.headers[key] = customHeaders[key];
×
138
    });
139
  }
140

141
  if (typeof window === 'undefined') {
4!
142
    options.headers['User-Agent'] = `terminusdb-client-js/${version}`;
4✔
143
  }
144

145
  switch (action) {
4!
146
    case CONST.DELETE: {
147
      if (payload) {
×
148
        options.headers = options.headers ? options.headers : {};
×
149
        options.headers['Content-Type'] = 'application/json; charset=utf-8';
×
150
        options.data = payload;
×
151
      }
152
      return axiosInstance
×
153
        .delete(url, options)
154
        .then((response) => (getDataVersion ? getResultWithDataVersion(response) : response.data))
×
155
        .catch((err) => {
156
          throw ErrorMessage.apiErrorFormatted(url, options, err);
×
157
        });
158
    }
159
    case CONST.HEAD: {
160
      return axiosInstance
×
161
        .head(url, options)
162
        .then((response) => (getDataVersion ? getResultWithDataVersion(response) : response.data))
×
163
        .catch((err) => {
164
          throw ErrorMessage.apiErrorFormatted(url, options, err);
×
165
        });
166
    }
167
    case CONST.GET: {
168
      if (payload) {
2!
169
        const ext = UTILS.URIEncodePayload(payload);
×
170
        // eslint-disable-next-line no-param-reassign
171
        if (ext) url += `?${ext}`;
×
172
      }
173
      return axiosInstance
2✔
174
        .get(url, options)
175
        .then((response) => {
176
          const r = getDataVersion ? getResultWithDataVersion(response) : response.data;
2!
177
          return r;
2✔
178
        })
179
        .catch((err) => {
180
          throw ErrorMessage.apiErrorFormatted(url, options, err);
×
181
        });
182
    }
183
    case CONST.ADD_CSV:
184
    case CONST.INSERT_TRIPLES: {
185
      options.headers = options.headers ? options.headers : {};
×
186
      options.headers['Content-Type'] = 'application/form-data; charset=utf-8';
×
187
      return axiosInstance
×
188
        .put(url, payload, options)
189
        .then((response) => (getDataVersion ? getResultWithDataVersion(response) : response.data))
×
190
        .catch((err) => {
191
          throw ErrorMessage.apiErrorFormatted(url, options, err);
×
192
        });
193
    }
194
    case CONST.PUT: {
195
      options.headers = options.headers ? options.headers : {};
×
196
      options.headers['Content-Type'] = 'application/json; charset=utf-8';
×
197
      let compressedContent = null;
×
198
      const jsonString = JSON.stringify(payload);
×
199

200
      if (jsonString.length > 1024 && compress) {
×
201
        options.headers['Content-Encoding'] = 'gzip';
×
202
        compressedContent = pako.gzip(jsonString);
×
203
      }
204
      return axiosInstance
×
205
        .put(url, compressedContent || payload, options)
×
206
        .then((response) => (getDataVersion ? getResultWithDataVersion(response) : response.data))
×
207
        .catch((err) => {
208
          throw ErrorMessage.apiErrorFormatted(url, options, err);
×
209
        });
210
    }
211
    case CONST.QUERY_DOCUMENT: {
212
      options.headers = options.headers ? options.headers : {};
×
213
      options.headers['X-HTTP-Method-Override'] = 'GET';
×
214
      // eslint-disable-next-line no-fallthrough
215
    }
216
    default: {
217
      options.headers = options.headers ? options.headers : {};
2!
218
      if (!options.headers['content-type'] && !options.headers['Content-Type']) {
2!
219
        options.headers['Content-Type'] = 'application/json; charset=utf-8';
2✔
220
      }
221
      const compressedContentPost = checkPayload(payload, options, compress);
2✔
222
      return axiosInstance
2✔
223
        .post(url, compressedContentPost || payload || {}, options)
4!
224
        .then((response) => {
225
          const r = getDataVersion ? getResultWithDataVersion(response) : response.data;
2!
226
          return r;
2✔
227
        })
228
        .catch((err) => {
229
          throw ErrorMessage.apiErrorFormatted(url, options, err);
×
230
        });
231
    }
232
  }
233
}
234

235
module.exports = DispatchRequest;
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc