'use strict';
const path = require('path');
const convert = require('js2xmlparser').parse;
const JSON_Adapter = require(path.join(__dirname, './json_content'));
/**
* Creates a formatted success message and converts to XML
* @param {*} data Any data to be included in XML response
* @param {Object} options Configurable options for XML response generation
* @param {Boolean} [options.skip_conversion=this.skip_conversion] If true rendering is skipped and the data argument is immediately returned
* @param {string} [options.xml_root=this.xml_root] Defines the value of the XML document root tag. If this.xml_root is not set and options.xml_root is not provided a TypeError will be thrown
* @param {Object} [options.xml_configuration=this.xml_configuration] Options for the convert function see js2xmlparser documentation for full details
* @return {string} Returns the rendered XML string or the data argument if options.skip_conversion is true
*/
const _RENDER = function (data, options) {
let skip_conversion = (typeof options.skip_conversion === 'boolean') ? options.skip_conversion : this.skip_conversion;
if (skip_conversion) return data;
let xml_root = options.xml_root || this.xml_root;
if (typeof xml_root !== 'string') throw new TypeError('xml_root must be a string, please provide options.xml_root or set this.xml_root');
let xml_configuration = options.xml_configuration || this.xml_configuration;
let xml_data = {
result: 'success',
status: 200,
data
};
return convert(xml_root, xml_data, (xml_configuration && typeof xml_configuration === 'object') ? xml_configuration : undefined);
};
/**
* Creates a formatted error response message and converts to XML
* @param {*} err Error data to be included in error response. If err is an instanceof Error or has a .message property it is assumed that the .message property is the only thing to include in error response
* @param {Object} options Configurable options for error XML formatting
* @param {Boolean} [options.skip_conversion=this.skip_conversion] If true rendering is skipped and the data argument is immediately returned
* @param {string} [options.xml_root=this.xml_root] Defines the value of the XML document root tag. If this.xml_root is not set and options.xml_root is not provided a TypeError will be thrown
* @param {Object} options.xml_configuration Options for the convert function see js2xmlparser documentation for full details
* @return {string} Returns the rendered XML string or the err argument if options.skip_conversion is true
*/
const _ERROR = function (err, options) {
let skip_conversion = (typeof options.skip_conversion === 'boolean') ? options.skip_conversion : this.skip_conversion;
if (skip_conversion) return err;
let xml_root = options.xml_root || this.xml_root;
if (typeof xml_root !== 'string') throw new TypeError('xml_root must be a string, please provide options.xml_root or set this.xml_root');
let xml_configuration = options.xml_configuration || this.xml_configuration;
let xml_data = {
result: 'error',
status: 500,
data: {
error: (err instanceof Error || typeof err.message === 'string') ? err.message : err
}
};
return convert(xml_root, xml_data, (xml_configuration && typeof xml_configuration === 'object') ? xml_configuration : undefined);
};
/**
* XML response adapter class which handles wrapping response data in object with status code and result message and converting into XML string.
* @type {XML_Adapter}
* @extends {JSON_Adapter}
*/
const XML_ADAPTER = class XML_Adapter extends JSON_Adapter {
/**
* @constructor
* @param {Object} [options={}] Configurable options for XML adapter
* @param {Boolean} options.skip_conversion If true render will just return data that is passed to it
* @param {string} options.xml_root The value that should be used in generating the root tag of the converted XML document
* @param {Object} options.xml_configuration Options that will be passed to the XML conversion function
*/
constructor (options = {}) {
super(options);
this.skip_conversion = options.skip_conversion;
this.xml_root = options.xml_root;
this.xml_configuration = options.xml_configuration;
}
/**
* Creates a formatted XML response
* @param {*} data Any data that should be sent with the success response
* @param {Object} [options={}] Configurable options for the XML success response formatting see _RENDER for more details
* @param {Function} [options.formatRender=_RENDER] Custom formatting function for XML rendering. It is recommended that the default value for this property is used and only custom options for the XML rendering are passed
* @param {Function} [cb=false] Optional callback function. If argument is not a function it will be ignored
* @param {Object} [options.req] Express request object. If options.req and options.res are defined the express .render method will be used to render template
* @param {Object} [options.res] Express response object. If options.res and options.req are defined the express .render method will be used to render template
* @param {Boolean} [options.skip_response] If true function will resolve with the rendered template instead of sending a response
* @return {*} Returns the formatted XML string if options.sync is true or a Promise if cb arugement is not passed
*/
render (data, options = {}, cb = false) {
if (typeof options === 'function') {
cb = options;
options = {};
}
options.formatRender = (typeof options.formatRender === 'function') ? options.formatRender : _RENDER.bind(this);
return super.render(data, options, cb);
}
/**
* Creates a formatted XML error response
* @param {*} [err={}] Any data that should be sent with the error response
* @param {Object} [options={}] Configurable options for the XML error response formatting see _ERROR for more details
* @param {Function} [options.formatError=_ERROR] Custom formatting function for XML rendering. It is recommended that the default value for this property is used and only custom options for the XML rendering are passed
* @param {Object} [options.req] Express request object. If options.req and options.res are defined the express .render method will be used to render template
* @param {Object} [options.res] Express response object. If options.res and options.req are defined the express .render method will be used to render template
* @param {Boolean} [options.skip_response] If true function will resolve with the rendered template instead of sending a response
* @param {Function} [cb=false] Optional callback function. If argument is not a function it will be ignored
* @return {*} Returns the formatted XML string if options.sync is true or a Promise if cb arugement is not passed
*/
error (err = {}, options = {}, cb = false) {
if (typeof options === 'function') {
cb = options;
options = {};
}
options.formatError = (typeof options.formatError === 'function') ? options.formatError : _ERROR.bind(this);
return super.error(err, options, cb);
}
};
module.exports = XML_ADAPTER;