@adoratorio/demetra
Version:
Internal use library for wordpress API request
256 lines • 10.9 kB
JavaScript
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