UNPKG

@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
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 }