Files
alexis/lib/proxy.js
2023-08-01 12:47:58 +02:00

93 lines
4.5 KiB
JavaScript

'use strict'
const path = require('path')
const klaw = require('klaw')
const request = require('request')
const through2 = require('through2')
const Cookies = require('./cookies')
const Headers = require('./headers')
// check if a resource is available
const checkForResource = (fetchers, resource) => !fetchers[resource]
// check if a ressources subressource has a registered preHook
const checkForPostHooks = (fetchers, resource, subressource) => fetchers[resource].postHooks && fetchers[resource].postHooks[subressource]
// check if a ressources subressource has a registered preHook
const checkForPreHooks = (fetchers, resource, subressource) => fetchers[resource].preHooks && fetchers[resource].preHooks[subressource]
// resource not found
const resourceNotFound = (reject, resource) => reject(`Resource not found: ${resource}`)
// helper stream transform to exclude all non proxy files from components
const excludeNonComponentProxies = through2.obj(function (item, enc, next){
if (path.basename(item.path) === path.basename(__filename) && item.path !== __filename) this.push(item)
next()
})
// register all component proxies
const registerProxies = () => {
return new Promise((resolve, reject) => {
let items = {}
klaw(__dirname)
.pipe(excludeNonComponentProxies)
.on('data', item => items[path.dirname(item.path).split(path.sep).pop()] = require(item.path))
.on('error', reject)
.on('end', resolve.bind(null, items))
})
}
// get array of requests that should be made
const getActions = async (fetchers, resource, subressource, params) => {
if (checkForPreHooks(fetchers, resource, subressource)) {
return await fetchers[resource].preHooks[subressource](Object.assign({}, params, {url: fetchers[resource].urls[subressource]}))
} else {
return []
}
}
// called when the resquest is done
const requestDone = async (resolve, reject, fetchers, store, resource, subressource, err, response, body) => {
if (err) return reject(err)
try {
if (checkForPostHooks(fetchers, resource, subressource)) body = await fetchers[resource].postHooks[subressource](store, body)
resolve({[resource]: body})
} catch (error) {
reject(error)
}
}
// fetch one ressource
const fetch = async (logger, headers, fetchers, store, resource, subressource = 'fetch', params = {}) => {
if (checkForResource(fetchers, resource)) return resourceNotFound(reject, resource)
const actions = await getActions(fetchers, resource, subressource)
const requests = actions.map(action => new Promise((resolve, reject) => request(Object.assign({}, {headers}, action), requestDone.bind(null, resolve, reject, fetchers, store, resource, subressource))))
const data = await Promise.all(requests)
return data
}
// fetch all registered resources
const fetchAll = (logger, headers, fetchers, store) => Promise.all(Object.keys(fetchers).map(resource => fetch(logger, headers, fetchers, store, resource)))
// fetch resources periodically
const fetchInterval = (logger, headers, fetchers, store, interval = 10000) => setInterval(() => resolveInterval(fetchAll(logger, headers, fetchers)), interval)
// fire actions
const act = async (logger, headers, fetchers, store, resource, subresource, params, cb) => {
if (checkForResource(fetchers, resource) || !checkForPreHooks(fetchers, resource, subresource)) return resourceNotFound(reject, resource)
const actions = await fetchers[resource].preHooks[subresource](Object.assign({}, params, {url: fetchers[resource].urls[subresource]}))
const response = () => actions.map(action => {
return new Promise((resolve, reject) => request(Object.assign({}, {headers}, action), requestDone.bind(null, resolve, reject, fetchers, store, resource, subresource)))
})
const res = await Promise.all(response())
console.log('res', res)
cb(res)
}
module.exports = async (logger, data_dir, store, interval) => {
const json_cookies = require(path.join(data_dir, Cookies.JSON_COOKIE_FILE))
const cookies = Cookies.transformCookiesForHeader(json_cookies)
const headers = Headers.getFetchHeaders(cookies)
const action_headers = Headers.getActionHeaders(json_cookies, cookies)
const fetchers = await registerProxies()
return new Promise((resolve, reject) => {
resolve({
act: act.bind(this, logger, action_headers, fetchers, store),
fetch: fetch.bind(this, logger, headers, fetchers, store),
fetchAll: fetchAll.bind(this, logger, headers, fetchers, store),
fetchInterval: fetchInterval.bind(this, logger, headers, fetchers, store, interval),
})
})
}