pailingual-odata
Version:
TypeScript client for OData v4 services
238 lines (237 loc) • 8.94 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var metadata_1 = require("./metadata");
var utils_1 = require("./utils");
var guidRE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
var converters = {
"Edm.String": {
toEdm: function (v, forUri) { return forUri ? ("'" + v.toString().replace("'", "''").replace("/", "%2F") + "'") : v; }
},
"Edm.Guid": {
toEdm: function (v) {
if (v.match(guidRE))
return v;
throw new Error("Value '" + v + "' not parsed as Guid");
}
},
"Edm.DateTimeOffset": {
toEdm: function (v) { return v.toISOString(); },
fromEdm: function (v) { return new Date(v); }
},
"Edm.Boolean": {
toEdm: function (v) { return v ? "true" : "false"; }
}
};
var formatters = {};
function addFormatter(formatter) {
if (!formatter
|| !formatter.contentType
|| !formatter.serialize
|| !formatter.deserialize)
throw new Error("All formatter properties is required");
formatters[formatter.contentType] = formatter;
}
exports.addFormatter = addFormatter;
function getFormatter(contentType) {
var f = formatters[contentType];
if (!f)
throw new Error("Not supported format: " + contentType);
return f;
}
exports.getFormatter = getFormatter;
addFormatter({ contentType: "application/json", serialize: jsonSerialize, deserialize: jsonDeserialize });
function enumMemberByValue(type, value) {
for (var member in type.members)
if (type.members[member] === value)
return member;
}
function jsonSerialize(payload, metadata, options) {
if (options === void 0) { options = {}; }
var metadataMap = new MapObjToEntityType();
metadataMap.set(payload, metadata);
var otMetadata = new metadata_1.EdmEntityType("$$~~openType~~$$", {});
otMetadata.openType = true;
return JSON.stringify(payload, function (k, v) {
if (!k || Array.isArray(this))
return v;
var currentMetadata = metadataMap.get(this);
if (currentMetadata != null) {
var propMD = currentMetadata.properties[k]
|| currentMetadata.navProperties[k];
var valueType = propMD && propMD.type
|| ((currentMetadata.openType) ? otMetadata : undefined);
if (!valueType) {
throw new Error("Property '" + k + "' not found in metadata");
}
if (valueType instanceof metadata_1.EdmEntityType) {
if (Array.isArray(v))
for (var _i = 0, v_1 = v; _i < v_1.length; _i++) {
var item = v_1[_i];
metadataMap.set(item, valueType);
}
else if (v != null)
metadataMap.set(v, valueType);
return v;
}
else {
return convertToEdmValue(this[k], propMD.type, false) || v;
}
}
throw new Error("Metadata for object not found");
});
}
function serializeValue(value, type, forUri, opt) {
if (value == null)
return forUri ? "null" : null;
return convertToEdmValue(value, type, forUri, opt) || value.toString();
}
exports.serializeValue = serializeValue;
function convertToEdmValue(value, type, forUri, opt) {
if (opt === void 0) { opt = {}; }
if (value == null)
return null;
if (type instanceof metadata_1.EdmEnumType) {
var member = enumMemberByValue(type, value);
if (member) {
if (forUri) {
member = "'" + member + "'";
if (!opt.enumPrefixFree)
member = type.getFullName() + member;
}
return member;
}
throw new Error("Value '" + value + "' not found in enum '" + type.name + " '");
}
else {
var converter = converters[type];
if (converter && converter.toEdm)
return converter.toEdm(value, forUri, opt);
return null;
}
}
function convertFromEdmValue(value, type, options) {
var converter = converters[type];
if (converter && converter.fromEdm)
return converter.fromEdm(value, options);
return null;
}
var ODATA_CONTEXT = "@odata.context";
var ODATA_COUNT = "@odata.count";
var ODATA_TYPE = "@odata.type";
function jsonDeserialize(response, apiMetadata, options) {
var rawData = JSON.parse(response);
var context = rawData[ODATA_CONTEXT];
if (context) {
context = context.split("#")[1];
var count = rawData[ODATA_COUNT];
var isEntity = utils_1.endsWith(context, "$entity");
context = context.replace(/\/\$entity$/, "");
var type_1 = getSourceType(context, apiMetadata);
if (!isEntity && Array.isArray(rawData.value)) {
var value = rawData.value.map(function (v) { return convertObj(v, type_1, apiMetadata, options); });
if (count != null)
return { count: count, value: value };
return value;
}
else
return convertObj(rawData, type_1, apiMetadata, options);
}
}
function convertObj(obj, type, apiMetadata, options) {
if (obj != null) {
if (Array.isArray(obj))
return obj.map(function (v) { return convertObj(v, type, apiMetadata, options); });
if (obj[ODATA_TYPE]) {
var typeName = obj[ODATA_TYPE].substr(1);
type = apiMetadata.getEdmTypeMetadata(typeName);
if (type == null)
throw new Error("Metadata for type '" + typeName + "' not found.");
}
if (typeof type == "string") {
if (typeof obj == "object")
obj = obj.value;
return convertFromEdmValue(obj, type, options) || obj;
}
else {
var res = void 0;
if (type instanceof metadata_1.EdmEnumType) {
var res_1 = type.members[obj];
if (!res_1)
throw new Error("Member '" + obj + "' not found in enum '" + type.name + "'");
return res_1;
}
else {
var entityType = type;
res = {};
var edmProps = getEdmProperties(entityType);
for (var propName in obj) {
var edmPropertyType = edmProps[propName];
if (edmPropertyType)
res[propName] = convertObj(obj[propName], edmPropertyType, apiMetadata, options);
else if (!utils_1.startsWith(propName, "@")
&& entityType.openType == true)
res[propName] = obj[propName];
}
}
return res;
}
}
return null;
}
function getEdmProperties(type) {
var res = type.baseType
? getEdmProperties(type.baseType)
: {};
for (var prop in type.properties) {
res[prop] = type.properties[prop].type;
}
for (var prop in type.navProperties) {
res[prop] = type.navProperties[prop].type;
}
return res;
}
function getSourceType(source, apiMetadata) {
if (utils_1.startsWith(source, "Collection"))
source = source.substring("Collection".length + 1, source.length - 1);
var pos = source.indexOf("(");
if (pos > -1)
source = source.substring(0, pos);
var parts = source.split("/");
source = parts[parts.length - 1];
var es = apiMetadata.entitySets[source];
if (!es) {
var dotPos = source.lastIndexOf('.');
if (dotPos > -1) {
var ns = source.substr(0, dotPos);
var type = source.substr(dotPos + 1);
if (ns == "Edm") //Primitive type
return source;
var nsObj = apiMetadata.namespaces[ns];
if (nsObj && nsObj.types[type])
return nsObj.types[type];
}
}
return es;
}
var MapObjToEntityType = /** @class */ (function () {
function MapObjToEntityType() {
this.__keys = [];
this.__values = [];
}
MapObjToEntityType.prototype.get = function (key) {
if (key) {
var index = this.__keys.indexOf(key);
if (index > -1)
return this.__values[index];
}
};
MapObjToEntityType.prototype.set = function (key, entityType) {
if (key == null)
throw new Error("Key must be set");
var index = this.__keys.indexOf(key);
if (index == -1)
index = this.__keys.push(key) - 1;
this.__values[index] = entityType;
};
return MapObjToEntityType;
}());