UNPKG

@sap/xsodata

Version:

Expose data from a HANA database as OData V2 service with help of .xsodata files.

379 lines (312 loc) 10.8 kB
'use strict'; //Includes const Negotiator = require('negotiator'); const NotAcceptable = require('./../utils/errors/http/notAcceptable'); const UnsupportedMediaType = require('./../utils/errors/http/unsupportedMediaType'); exports.cTypes = { ctJson: 'application/json', ctAtom: 'application/atom+xml', ctAtomSvc: 'application/atomsvc+xml', ctAtomFeed: 'application/atom+xml;type=feed', ctAtomEntry: 'application/atom+xml;type=entry', ctAxml: 'application/xml', ctTxml: 'text/xml', ctPlain: 'text/plain', ctTast: 'text/*', ctAppast: 'application/*', ctAst: '*/*', fJson: 'json', fXml: 'xml', fAtom: 'atom', }; const cTypes = exports.cTypes; exports.checkInputContentType = function (actual, expected) { const cS = actual.split(';'); const type = cS[0]; if (type !== expected) { throw new UnsupportedMediaType( 'Content-Type ' + type + ' not supported.' ); } }; /** * Checks if actual parameter is a valid expected http content-type. * * @param actual {String} Content-Type as is * @param expected {String} Content-Type as expected * @returns {boolean} true if actual equals expected, alse false */ function isContentType(actual, expected) { let cS, type; if (actual) { cS = actual.split(';'); type = cS[0]; type = type.toLowerCase(); } if (expected) { expected = expected.toLowerCase(); } return type === expected; } exports.isContentType = isContentType; /** * Checks if type is supported content type. * * @param type {String} content type * @returns {boolean} True if is type of xml, else false */ function isSupportedContentType(type) { // TODO Align with .checkFeed() return isContentTypeXml(type) || isContentTypeJson(type); } exports.isSupportedContentType = isSupportedContentType; /** * Checks if content type is kind of xml. * * @param type {String} content type * @returns {boolean} True if is type of xml, else false */ function isContentTypeXml(type) { // TODO Align with .checkFeed() return ( isContentType(type, cTypes.ctAtom) || isContentType(type, cTypes.ctAxml) || isContentType(type, cTypes.ctTxml) || isContentType(type, cTypes.fXml) || isContentType(type, cTypes.ctPlain) ); } exports.isContentTypeXml = isContentTypeXml; /** * Checks if content type is kind of json. * * @param type {String} content type * @returns {boolean} True if is type of json, else false */ function isContentTypeJson(type) { // TODO Align with .checkFeed() return ( isContentType(type, cTypes.ctJson) || isContentType(type, cTypes.fJson) ); } exports.isContentTypeJson = isContentTypeJson; ///Code exports.checkServiceDocument = function (request, format) { const def = cTypes.ctAxml; //check $format if (format === cTypes.fJson) { return cTypes.ctJson; } else if (format === cTypes.fXml) { //throw new NotAcceptable('Format '' + format + ' not supported.'); return cTypes.ctAxml; } else if (format === cTypes.fAtom) { throw new NotAcceptable('Format ' + format + ' not supported.'); } //check no header if (!request.headers.accept && !request.headers.Accept) { return def; } //check header const inOut = {}; inOut[cTypes.ctAst] = cTypes.ctAxml; inOut[cTypes.ctAppast] = cTypes.ctAxml; inOut[cTypes.ctJson] = cTypes.ctJson; inOut[cTypes.ctAxml] = cTypes.ctAxml; const availableMediaTypes = [ cTypes.ctAst, cTypes.ctAppast, cTypes.ctJson, /*cTypes.ctAtomSvc,*/ cTypes.ctAxml, ]; const match = new Negotiator(request).mediaType(availableMediaTypes); if (!match) { throw new NotAcceptable('Format not supported.'); } return inOut[match]; }; exports.checkServiceMetadata = function (request, format) { const def = cTypes.ctAxml; //check $format if (format === cTypes.fJson) { throw new NotAcceptable('Format ' + format + ' not supported.'); } else if (format === cTypes.fXml) { //throw new NotAcceptable('Format '' + format + ' not supported.'); return cTypes.ctAxml; } else if (format === cTypes.fAtom) { throw new NotAcceptable('Format ' + format + ' not supported.'); } //check no header if (!request.headers.accept && !request.headers.Accept) { return def; } //check header const inOut = {}; inOut[cTypes.ctAst] = cTypes.ctAxml; inOut[cTypes.ctAppast] = cTypes.ctAxml; inOut[cTypes.ctAxml] = cTypes.ctAxml; const availableMediaTypes = [ cTypes.ctAst, cTypes.ctAppast /*, cTypes.ctJson*/, cTypes.ctAtomSvc, cTypes.ctAxml, ]; const match = new Negotiator(request).mediaType(availableMediaTypes); if (!match) { throw new NotAcceptable('Format not supported.'); } return inOut[match]; }; exports.checkFeed = function (request, format) { const def = cTypes.ctAtomFeed; //check $format if (format === cTypes.fJson) { return cTypes.ctJson; } else if (format === cTypes.fXml) { throw new NotAcceptable('Format ' + format + ' not supported.'); } else if (format === cTypes.fAtom) { throw new NotAcceptable('Format ' + format + ' not supported.'); } //check no header if (!request.headers.accept && !request.headers.Accept) { throw new NotAcceptable('Format ' + def + ' not supported.'); } //check header const inOut = {}; inOut[cTypes.ctAst] = cTypes.ctAtomFeed; inOut[cTypes.ctAppast] = cTypes.ctAtomFeed; inOut[cTypes.ctJson] = cTypes.ctJson; inOut[cTypes.ctAxml] = cTypes.ctAxml; inOut[cTypes.ctAtom] = cTypes.ctAtom; inOut[cTypes.ctAtomFeed] = cTypes.ctAtomFeed; const availableMediaTypes = [ /*cTypes.ctAst, cTypes.ctAppast, */ cTypes.ctJson /*, cTypes.ctAxml, cTypes.ctAtom, cTypes.ctAtomFeed*/, ]; const match = new Negotiator(request).mediaType(availableMediaTypes); if (!match) { throw new NotAcceptable('Format not supported.'); } if (match !== cTypes.ctJson) { throw new NotAcceptable( 'Format ' + inOut[cTypes.ctAst] + ' not supported.' ); } return inOut[match]; }; exports.checkEntry = function (request, format) { const def = cTypes.ctAtomEntry; //check $format if (format === cTypes.fJson) { return cTypes.ctJson; } else if (format === cTypes.fXml) { throw new NotAcceptable('Format ' + format + ' not supported.'); } else if (format === cTypes.fAtom) { throw new NotAcceptable('Format ' + format + ' not supported.'); } //check no header if (!request.headers.accept && !request.headers.Accept) { throw new NotAcceptable('Format ' + def + ' not supported.'); } //check header const inOut = {}; inOut[cTypes.ctAst] = cTypes.ctAtomEntry; inOut[cTypes.ctAppast] = cTypes.ctAtomEntry; inOut[cTypes.ctJson] = cTypes.ctJson; inOut[cTypes.ctAxml] = cTypes.ctAxml; inOut[cTypes.ctAtom] = cTypes.ctAtom; inOut[cTypes.ctAtomEntry] = cTypes.ctAtomEntry; const availableMediaTypes = [ /*cTypes.ctAst, cTypes.ctAppast,*/ cTypes.ctJson /*, cTypes.ctPlain, cTypes.ctAxml, cTypes.ctAtom, cTypes.ctAtomFeed*/, ]; const match = new Negotiator(request).mediaType(availableMediaTypes); if (!match) { throw new NotAcceptable('Format not supported.'); } if (match !== cTypes.ctJson) { throw new NotAcceptable( 'Format ' + inOut[cTypes.ctAst] + ' not supported.' ); } return inOut[match]; }; exports.checkProperty = function (request, format) { const def = cTypes.ctAxml; //check $format if (format === cTypes.fJson) { return cTypes.ctJson; } else if (format === cTypes.fXml) { throw new NotAcceptable('Format ' + format + ' not supported.'); } //check no header if (!request.headers.accept && !request.headers.Accept) { throw new NotAcceptable('Format ' + def + ' not supported.'); } //check header const inOut = {}; inOut[cTypes.ctAst] = cTypes.ctAxml; inOut[cTypes.ctTast] = cTypes.ctTxml; inOut[cTypes.ctAppast] = cTypes.ctAxml; inOut[cTypes.ctJson] = cTypes.ctJson; inOut[cTypes.ctTxml] = cTypes.ctTxml; inOut[cTypes.ctAxml] = cTypes.ctAxml; const availableMediaTypes = [ /*cTypes.ctAst, cTypes.ctTast, cTypes.ctAppast,*/ cTypes.ctJson /*, cTypes.ctTxml, cTypes.ctAxml*/, ]; const match = new Negotiator(request).mediaType(availableMediaTypes); if (!match) { throw new NotAcceptable('Format not supported.'); } if (match !== cTypes.ctJson) { throw new NotAcceptable( 'Format ' + inOut[cTypes.ctAst] + ' not supported.' ); } return inOut[match]; }; exports.checkValue = function (request, format) { //check $format if (format) { throw new NotAcceptable('Format ' + format + ' not supported.'); } //check no header if (!request.headers.accept && !request.headers.Accept) { //throw new NotAcceptable('Format '' + def + ' not supported.', 416); } //check header const inOut = {}; inOut[cTypes.ctAst] = cTypes.ctPlain; inOut[cTypes.ctTast] = cTypes.ctPlain; inOut[cTypes.ctPlain] = cTypes.ctPlain; const availableMediaTypes = [cTypes.ctAst, cTypes.ctTast, cTypes.ctPlain]; const match = new Negotiator(request).mediaType(availableMediaTypes); if (!match) { throw new NotAcceptable('Format not supported.'); } //if (match !== cTypes.ctPlain) { // throw new NotAcceptable('Format '' + inOut[cTypes.ctAst] + ' not supported.'); //} return inOut[match]; }; exports.checkCount = function (request, format) { //check $format if (format) { throw new NotAcceptable('Format ' + format + ' not supported.'); } //check no header if (!request.headers.accept && !request.headers.Accept) { //throw new NotAcceptable('Format '' + def + ' not supported.'); } //check header const inOut = {}; inOut[cTypes.ctAst] = cTypes.ctPlain; inOut[cTypes.ctTast] = cTypes.ctPlain; inOut[cTypes.ctPlain] = cTypes.ctPlain; const availableMediaTypes = [cTypes.ctAst, cTypes.ctTast, cTypes.ctPlain]; const match = new Negotiator(request).mediaType(availableMediaTypes); if (!match) { throw new NotAcceptable('Format not supported.'); } //if (match !== cTypes.ctPlain) { // throw new NotAcceptable('Format '' + inOut[cTypes.ctAst] + ' not supported.'); //} return inOut[match]; };