@nzz/q-server
Version:
__Q__ is a system that lets journalists create visual elements for stories. It is developed by [NZZ Storytelling](https://www.nzz.ch/storytelling) and used in the [NZZ](https://www.nzz.ch) newsroom.
128 lines (115 loc) • 4.7 kB
JavaScript
const querystring = require('querystring');
const fetch = require('node-fetch');
const clone = require('clone');
const deepmerge = require('deepmerge');
const Boom = require('boom');
const server = require('../server').getServer();
const deleteMetaProperties = require('../helper/meta-properties').deleteMetaProperties;
function isToolConfiguredForTarget(toolName, target, tools) {
let endpointConfig = tools.get(`/${toolName}/endpoint`, { target: target })
if (endpointConfig) {
return true;
}
return false;
}
function getRenderingInfo(data, target, toolRuntimeConfig) {
// we will change data in this function, so we clone it here to have be pure
data = clone(data);
const toolName = data.tool;
if (!isToolConfiguredForTarget(toolName, target, server.settings.app.tools)) {
return Promise.reject(Boom.notImplemented(`no endpoint for tool ${toolName} and target ${target}`));
}
const baseUrl = server.settings.app.tools.get(`/${toolName}/baseUrl`, { target: target })
const endpoint = server.settings.app.tools.get(`/${toolName}/endpoint`, { target: target })
let requestUrl;
if (endpoint.hasOwnProperty('path')) {
requestUrl = `${baseUrl}${endpoint.path}`;
} else if (endpoint.hasOwnProperty('url')) {
requestUrl = endpoint.url;
} else {
throw new Error('Endpoint has no path nor url configured');
}
// add _id, createdDate and updatedDate as query params to rendering info request
let queryParams = ['_id', 'createdDate', 'updatedDate'];
let query = {};
for (let queryParam of queryParams) {
if (data.hasOwnProperty(queryParam) && data[queryParam]) {
query[queryParam] = data[queryParam];
}
}
let queryString = querystring.stringify(query);
// strip the meta properties before sending the data to the tool service
const body = {
item: deleteMetaProperties(data),
toolRuntimeConfig: toolRuntimeConfig
}
return fetch(`${requestUrl}?${queryString}`, {
method: 'POST',
body: JSON.stringify(body),
headers: {
'Content-Type': 'application/json'
}
})
.then(response => {
if (!response.ok) {
return response.json()
.then(data => {
throw Boom.create(response.status, data.message);
})
} else {
return response.json();
}
})
.then(renderingInfo => {
// add stylesheets configured in tool config
if (endpoint.stylesheets && endpoint.stylesheets.length) {
console.log('DEPRECATION NOTICE: endpoint.stylesheets support will be removed in Q server 3.0. Use endpoint.additionalRenderingInfo.stylesheets');
if (Array.isArray(renderingInfo.stylesheets)) {
renderingInfo.stylesheets = renderingInfo.stylesheets.concat(endpoint.stylesheets);
} else {
renderingInfo.stylesheets = endpoint.stylesheets;
}
}
// add scripts configured in tool config
if (endpoint.scripts && endpoint.scripts.length) {
console.log('DEPRECATION NOTICE: endpoint.scripts support will be removed in Q server 3.0. Use endpoint.additionalRenderingInfo.scripts');
renderingInfo.scripts = renderingInfo.scripts.concat(endpoint.scripts)
}
return renderingInfo;
})
.then(renderingInfo => {
// check if the tool config has additional renderingInfo and apply it if so
if (endpoint.additionalRenderingInfo) {
renderingInfo = deepmerge(renderingInfo, endpoint.additionalRenderingInfo, {
arrayMerge: (destArr, srcArr) => {
return srcArr.concat(destArr);
}
});
}
return renderingInfo;
})
.then(renderingInfo => {
// add the path to the stylesheets returned from rendering service if they have a name property
if (renderingInfo.stylesheets !== undefined && renderingInfo.stylesheets.length > 0) {
for (var i = 0; i < renderingInfo.stylesheets.length; i++) {
let stylesheet = renderingInfo.stylesheets[i];
if (stylesheet.name !== undefined) {
stylesheet.path = `/tools/${toolName}/stylesheet/${stylesheet.name}`;
}
}
}
// add the path to the scripts returned from rendering service if they have a name property
if (renderingInfo.scripts !== undefined && renderingInfo.scripts.length > 0) {
for (var i = 0; i < renderingInfo.scripts.length; i++) {
let script = renderingInfo.scripts[i];
if (script.name !== undefined) {
script.path = `/tools/${toolName}/script/${script.name}`;
}
}
}
return renderingInfo;
})
}
module.exports = {
getRenderingInfo: getRenderingInfo
}