node-double-take
Version:
Node.js Wrapper for Double Take Facial Recognition HTTP API
112 lines (111 loc) • 3.92 kB
JavaScript
const fetch = require('node-fetch')
const FormData = require('form-data')
const fs = require('fs')
const { AbortController } = require('node-abort-controller')
module.exports = (apiHost) => {
const apiPaths = require('./apiPaths.js')
const fetchTimeout = (url, ms, { signal, ...options } = {}) => {
const controller = new AbortController();
const promise = fetch(url, { signal: controller.signal, ...options });
if (signal) signal.addEventListener("abort", () => controller.abort());
const timeout = setTimeout(() => controller.abort(), ms);
return promise.finally(() => clearTimeout(timeout));
}
function getFetchUrl(apiPoint,options){
const host = apiHost || `http://localhost:3000`
const timeout = parseInt(options.timeout) || 5000
const method = options.method || 'POST'
const fetchUrl = `${host}/${options.innerUri || 'api/'}${apiPoint}`
const queryData = Object.assign({},options.query || {});
let queryString = []
for(const queryKey in queryData){
const queryValue = queryData[queryKey]
queryString.push(`${queryKey}=${queryValue}`)
}
const finalFetch = `${fetchUrl}${queryString.length > 0 ? `?${queryString.join('&')}` : ''}`
return {
host,
method,
timeout,
withoutQuery: fetchUrl,
url: finalFetch,
}
}
function apiRequest(apiPoint,options){
options = options || {};
const response = {
ok: false
}
const {
withoutQuery,
timeout,
host,
url
} = getFetchUrl(apiPoint,options)
try {
const response = await fetchTimeout(url,timeout, {
method: method,
body: options.body
});
const jsonResponse = await response.json();
response.ok = true
response.data = jsonResponse
} catch (error) {
response.ok = false
response.err = error
return response
}
}
async function uploadFile(apiPoint = 'recognize/upload', options) {
const response = { ok: true };
const { fileData, fileName, fileType } = options;
const formData = new FormData();
formData.append('files[]', fileData, fileName);
try {
const {
withoutQuery,
timeout,
host,
url,
} = getFetchUrl(apiPoint,options); // Import your getFetchUrl function
const headers = formData.getHeaders();
if (fileType) {
headers['Content-Type'] = fileType;
}
const response = await fetchTimeout(url, timeout, {
method: 'POST',
body: formData,
headers,
});
const jsonResponse = await response.json();
response.ok = true
response.data = jsonResponse
return response;
} catch (error) {
response.ok = false;
response.err = error;
return response;
}
}
apiPaths.forEach((item) => {
switch(item.path){
case'recognize/upload':
api[item.name] = (file) => {
return uploadFile('recognize/upload', file)
}
break;
default:
api[item.name] = (options) => {
return apiRequest(item.path,{
method: item.method,
[item.method === 'GET' ? 'query' : 'body']: options
})
}
break;
}
})
return Object.assign({
apiRequest,
uploadFile,
},api)
}