UNPKG

@adoratorio/demetra

Version:

Internal use library for wordpress API request

256 lines 10.9 kB
import { LRUCache } from 'lru-cache'; import axios from 'axios'; import { validateUrl } from './validators'; import { SEND_MODES, } from './declarations'; import DemetraQueue from './Requests/DemetraQueue'; import DemetraRequestLanguages from './Requests/DemetraRequestLanguages'; import DemetraRequestSiteMap from './Requests/DemetraRequestSiteMap'; import DemetraRequestPage from './Requests/DemetraRequestPage'; import DemetraRequestChildren from './Requests/DemetraRequestChildren'; import DemetraRequestArchive from './Requests/DemetraRequestArchive'; import DemetraRequestExtra from './Requests/DemetraRequestExtra'; import DemetraRequestMenu from './Requests/DemetraRequestMenu'; import DemetraRequestTaxonomy from './Requests/DemetraRequestTaxonomy'; import DemetraRequestSend from './Requests/DemetraRequestSend'; import DemetraRequestSubscribe from './Requests/DemetraRequestSubscribe'; import DemetraRequestAttachments from './Requests/DemetraRequestAttachments'; class Demetra { static SEND_MODES = SEND_MODES; cache; queue; options; constructor(options = {}) { const defaults = { endpoint: '', uploadEndpoint: '', site: 'default', lang: 'en', debug: false, version: 2, cacheMaxAge: 1000 * 60 * 60, maxItems: 500, proxy: false, }; this.options = { ...defaults, ...options }; this.queue = new DemetraQueue; this.cache = new LRUCache({ max: this.options.maxItems, ttl: this.options.cacheMaxAge }); if (this.options.endpoint.length <= 0 || !validateUrl(this.options.endpoint)) { throw new Error('Invalid endpoint'); } if (this.options.uploadEndpoint.length <= 0) { this.options.uploadEndpoint = this.options.endpoint.replace('/api.php', '/upload.php'); } } async fetchQueue(sendModes = SEND_MODES.ONCE) { if (sendModes !== SEND_MODES.ONCE && sendModes !== SEND_MODES.SIMULTANEOUSLY && sendModes !== SEND_MODES.AWAIT) { throw new Error('Invalid SEND_MODES'); } let response; if (sendModes === SEND_MODES.ONCE) { response = this.sendOnce(); } if (sendModes === SEND_MODES.SIMULTANEOUSLY) { response = this.sendSimultaneously(); } if (sendModes === SEND_MODES.AWAIT) { response = this.sendConsequentially(); } this.queue.clear(); return response || []; } async fetchLanguages(site, options) { const params = new DemetraRequestLanguages(site, options, (options && options.lang) || this.options.lang, (options && options.version) || this.options.version); return this.fetch(params); } async fetchSitemap(site, options) { const params = new DemetraRequestSiteMap(site, options, (options && options.version) || this.options.version); return this.fetch(params); } async fetchPage(id, options) { const params = new DemetraRequestPage(id, options, (options && options.lang) || this.options.lang, (options && options.site) || this.options.site, (options && options.version) || this.options.version); return this.fetch(params); } async fetchChildren(id, options) { const params = new DemetraRequestChildren(id, options, (options && options.lang) || this.options.lang, (options && options.site) || this.options.site, (options && options.version) || this.options.version); return this.fetch(params); } async fetchArchive(id, options) { const params = new DemetraRequestArchive(id, options, (options && options.lang) || this.options.lang, (options && options.site) || this.options.site, (options && options.version) || this.options.version); return this.fetch(params); } async fetchExtra(id, options) { const params = new DemetraRequestExtra(id, options, (options && options.lang) || this.options.lang, (options && options.site) || this.options.site, (options && options.version) || this.options.version); return this.fetch(params); } async fetchMenu(id, options) { const params = new DemetraRequestMenu(id, options, (options && options.lang) || this.options.lang, (options && options.site) || this.options.site, (options && options.version) || this.options.version); return this.fetch(params); } async fetchTaxonomy(id, options) { const params = new DemetraRequestTaxonomy(id, options, (options && options.lang) || this.options.lang, (options && options.site) || this.options.site, (options && options.version) || this.options.version); return this.fetch(params); } async fetchAttachments(site, options) { const params = new DemetraRequestAttachments(site, options, (options && options.version) || this.options.version); return this.fetch(params); } async subscribe(email, lang, site) { const params = new DemetraRequestSubscribe(email, null, lang || this.options.lang, site || this.options.site, this.options.version); return this.fetch(params); } async subscribeWithAdditionalData(email, data, lang, site) { const params = new DemetraRequestSubscribe(email, data, lang || this.options.lang, site || this.options.site, this.options.version); return this.fetch(params); } async send(id, recipients, data, files) { let urls = []; if (files && files.length > 0) { const uploadResponses = await this.upload(files); uploadResponses.forEach((files) => { files.forEach((file) => { if (typeof file !== 'object') { throw new Error('Invalid response. It mus be an object'); } urls.push(file.data); }); }); } const params = new DemetraRequestSend(id, recipients, data, urls, this.options.lang, this.options.site, this.options.version); return this.fetch(params); } async fetch(params) { if (params.localCache && this.cache.has(params.hash)) { const cached = this.cache.get(params.hash) || {}; if (typeof cached === 'undefined') throw new Error('Unexpected empty cache entry'); return this.parseFromLocalCache(cached); } const requests = new Array(); requests.push(params); const headers = { 'Content-Type': 'application/json', }; const response = await axios({ method: 'post', headers, url: this.options.endpoint, data: JSON.stringify({ requests }), responseType: 'json', proxy: this.options.proxy, }); const json = response.data; json.forEach((response) => { this.debugLog(response); this.handleError(response); }); if (params.localCache) { this.cache.set(params.hash, json[0]); } return json[0] || {}; } async upload(files) { if (typeof this.options.uploadEndpoint === 'undefined') throw new Error('No upload endpoint defined'); files = Array.isArray(files) ? files : [files]; const responses = files.map((file) => { const formData = new FormData(); formData.append('file', file); const request = new Request(this.options.uploadEndpoint, { method: 'POST', body: formData }); return fetch(request); }); const promisesResponses = await Promise.all(responses); const jsons = promisesResponses.map(response => response.json()); return Promise.all(jsons); } async sendOnce() { const cachedDates = []; const uncachedRequests = []; this.queue.requests.forEach((request, index) => { if (request.localCache && this.cache.has(request.hash)) { const cached = this.cache.get(request.hash) || {}; cachedDates.push({ index, data: this.parseFromLocalCache(cached) }); } else { uncachedRequests.push(request); } }); const headers = { 'Content-Type': 'application/json', }; const response = await axios({ method: 'post', headers, url: this.options.endpoint, data: JSON.stringify({ requests: uncachedRequests }), responseType: 'json', proxy: this.options.proxy, }); const responses = response.data; uncachedRequests.forEach((request, index) => { if (request.localCache) { this.cache.set(request.hash, responses[index]); } }); cachedDates.forEach((cachedData) => { responses.splice(cachedData.index, 0, cachedData.data); }); responses.forEach((response) => { this.debugLog(response); this.handleError(response); }); return responses; } async sendSimultaneously() { const promises = this.queue.requests.map(request => this.fetch(request)); return Promise.all(promises); } async sendConsequentially() { const responses = []; for (const request of this.queue.requests) { responses.push(await this.fetch(request)); } return responses; } debugLog(response) { if (this.options.debug) { console.log(response); } } handleError(response) { if (response.status.code === 500) { if (!this.options.debug) { console.warn(`${response.status.code} - ${response.status.message}`); } else { throw new Error(`${response.status.code} - ${response.status.message}`); } } } parseFromLocalCache(cached) { cached.status.code = 304; cached.status.message = 'Data loaded from local cache'; cached.status.cache = true; return cached; } get endpoint() { return this.options.endpoint; } set endpoint(url) { this.options.endpoint = url; } get uploadEndpoint() { return this.options.uploadEndpoint; } set uploadEndpoint(url) { this.options.uploadEndpoint = url; } get lang() { return this.options.lang; } set lang(lang) { this.options.lang = lang; } } export default Demetra; export { DemetraRequestPage, DemetraRequestChildren, DemetraRequestArchive, DemetraRequestMenu, DemetraRequestExtra, DemetraRequestTaxonomy, DemetraRequestSiteMap, DemetraRequestLanguages, DemetraRequestAttachments, }; //# sourceMappingURL=index.js.map