@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
JavaScript
'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];
};