UNPKG

pailingual-odata

Version:

TypeScript client for OData v4 services

418 lines (417 loc) 19.3 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); } return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; import { startsWith, endsWith } from "./utils"; var COLLECTION_TYPE_PREFIX = "Collection("; export var EdmTypes; (function (EdmTypes) { EdmTypes["Int32"] = "Edm.Int32"; EdmTypes["Int16"] = "Edm.Int16"; EdmTypes["Boolean"] = "Edm.Boolean"; EdmTypes["String"] = "Edm.String"; EdmTypes["Single"] = "Edm.Single"; EdmTypes["Guid"] = "Edm.Guid"; EdmTypes["DateTimeOffset"] = "Edm.DateTimeOffset"; EdmTypes["Date"] = "Edm.Date"; EdmTypes["Double"] = "Edm.Double"; EdmTypes["TimeOfDay"] = "Edm.TimeOfDay"; EdmTypes["Decimal"] = "Edm.Decimal"; EdmTypes["Unknown"] = "Unknown"; })(EdmTypes || (EdmTypes = {})); var EdmEntityType = /** @class */ (function () { function EdmEntityType(name, properties, navProperties, keys, baseType, openType) { if (navProperties === void 0) { navProperties = {}; } var _this = this; this.name = name; this.properties = properties; this.navProperties = navProperties; this.keys = keys; this.baseType = baseType; this.openType = openType; this.getFullName = function () { return getFullName(_this); }; } return EdmEntityType; }()); export { EdmEntityType }; var EdmComplexType = /** @class */ (function (_super) { __extends(EdmComplexType, _super); function EdmComplexType() { return _super !== null && _super.apply(this, arguments) || this; } return EdmComplexType; }(EdmEntityType)); export { EdmComplexType }; var EdmEnumType = /** @class */ (function () { function EdmEnumType(name, members) { var _this = this; this.name = name; this.members = members; this.getFullName = function () { return getFullName(_this); }; } return EdmEnumType; }()); export { EdmEnumType }; var EdmEntityTypeReference = /** @class */ (function () { function EdmEntityTypeReference(type, nullable, collection) { if (nullable === void 0) { nullable = true; } if (collection === void 0) { collection = false; } this.type = type; this.nullable = nullable; this.collection = collection; } EdmEntityTypeReference.fromTypeReference = function (typeReference) { if (typeReference.type instanceof EdmEntityType) { return typeReference; } throw new Error("Instance must be reference to EdmEntityType"); }; return EdmEntityTypeReference; }()); export { EdmEntityTypeReference }; var EdmTypeReference = /** @class */ (function () { function EdmTypeReference(type, nullable, collection) { if (nullable === void 0) { nullable = true; } if (collection === void 0) { collection = false; } this.type = type; this.nullable = nullable; this.collection = collection; } return EdmTypeReference; }()); export { EdmTypeReference }; ; var OperationMetadata = /** @class */ (function () { function OperationMetadata(name, isAction, parameters, returnType, bindingTo) { var _this = this; this.name = name; this.isAction = isAction; this.parameters = parameters; this.returnType = returnType; this.bindingTo = bindingTo; this.getFullName = function () { return getFullName(_this); }; } return OperationMetadata; }()); export { OperationMetadata }; function getFullName(obj) { if (obj.namespace) return [obj.namespace.name, obj.name].join("."); return obj.name; } var Namespace = /** @class */ (function () { function Namespace(name) { this.name = name; this.operations = []; this.types = {}; } Namespace.prototype.addTypes = function () { var types = []; for (var _i = 0; _i < arguments.length; _i++) { types[_i] = arguments[_i]; } for (var _a = 0, types_1 = types; _a < types_1.length; _a++) { var type = types_1[_a]; type.namespace = this; this.types[type.name] = type; } }; Namespace.prototype.addOperations = function () { var operations = []; for (var _i = 0; _i < arguments.length; _i++) { operations[_i] = arguments[_i]; } for (var _a = 0, operations_1 = operations; _a < operations_1.length; _a++) { var operation = operations_1[_a]; operation.namespace = this; this.operations.push(operation); } }; return Namespace; }()); export { Namespace }; ; var __metadataCache = {}; export function loadMetadata(apiRoot, options, cache) { if (cache === void 0) { cache = true; } if (endsWith(apiRoot, "/")) apiRoot = apiRoot.substr(0, apiRoot.length - 1); var normalizedApiRoot = apiRoot.toLowerCase(), res = __metadataCache[normalizedApiRoot]; if (res == null || !cache) { return ApiMetadata.loadAsync(apiRoot, options) .then(function (md) { if (cache) __metadataCache[normalizedApiRoot] = md; return md; }); } return Promise.resolve(res); } var ApiMetadata = /** @class */ (function () { function ApiMetadata(apiRoot, containerName, namespaces, entitySets, singletons) { if (namespaces === void 0) { namespaces = {}; } if (entitySets === void 0) { entitySets = {}; } if (singletons === void 0) { singletons = {}; } this.apiRoot = apiRoot; this.containerName = containerName; this.namespaces = namespaces; this.entitySets = entitySets; this.singletons = singletons; } ApiMetadata.loadFromXml = function (apiRoot, metadataXml) { var parser = new DOMParser(); var metadataDoc = parser.parseFromString(metadataXml, "text/xml"); var namespaces = ApiMetadata.parseEntityTypes(metadataDoc); var entitySets = {}; var singletons = {}; var container = metadataDoc.querySelector("Schema>EntityContainer"); var containerName = container && getRequiredAttributeValue(container, "Name"); if (container) { var list = container.querySelectorAll("EntitySet,Singleton"); for (var i = 0; i < list.length; i++) { var e = list.item(i); var isSingleton = e.tagName.toUpperCase() === "SINGLETON"; var name_1 = getRequiredAttributeValue(e, "Name"); var typeName = getRequiredAttributeValue(e, isSingleton ? "Type" : "EntityType"); var target = isSingleton ? singletons : entitySets; target[name_1] = ApiMetadata.getEntitySetMetadata(typeName, namespaces); } } var list3 = metadataDoc.querySelectorAll("Schema>Function,Schema>Action"); for (var i = 0; i < list3.length; i++) { var e = list3.item(i); var metadata = ApiMetadata.parseOperationMetadata(e, namespaces); var namespaceName = getRequiredAttributeValue(e.parentElement, "Namespace"); if (!namespaces[namespaceName]) namespaces[namespaceName] = new Namespace(namespaceName); namespaces[namespaceName].addOperations(metadata); } return new ApiMetadata(apiRoot, containerName, namespaces, entitySets, singletons); }; ApiMetadata.loadAsync = function (apiRoot, options) { return __awaiter(this, void 0, void 0, function () { var uri, opt, fetchApi, credentials, response, _a, _b; return __generator(this, function (_c) { switch (_c.label) { case 0: uri = apiRoot + "/$metadata"; opt = options || {}; fetchApi = opt.fetch || fetch; credentials = opt.credentials; return [4 /*yield*/, fetchApi(uri, { credentials: credentials })]; case 1: response = _c.sent(); _a = this.loadFromXml; _b = [apiRoot]; return [4 /*yield*/, response.text()]; case 2: return [2 /*return*/, _a.apply(this, _b.concat([_c.sent()]))]; } }); }); }; ApiMetadata.parseEntityTypes = function (metadataDoc) { var namespaces = {}; var entityTypes = []; var list = metadataDoc.querySelectorAll("Schema>ComplexType,Schema>EntityType,Schema>EnumType"); var _loop_1 = function () { var e = list.item(i); var getOrAddEdmEntityType = function (namespace, name) { var namespaceMD = namespaces[namespace]; if (!namespaceMD) namespaces[namespace] = namespaceMD = new Namespace(namespace); var typeMetadata = namespaceMD.types[name]; if (!typeMetadata) { typeMetadata = e.tagName.toLowerCase() == "complextype" ? new EdmComplexType(name, {}) : new EdmEntityType(name, {}); namespaceMD.addTypes(typeMetadata); } return typeMetadata; }; var ns = getRequiredAttributeValue(e.parentElement, "Namespace"); var name_2 = getRequiredAttributeValue(e, "Name"); if (!(ns in namespaces)) namespaces[ns] = new Namespace(ns); if (e.tagName.toLowerCase() === "enumtype") { var enumType = new EdmEnumType(name_2, ApiMetadata.parseEnumMembers(e)); namespaces[ns].addTypes(enumType); } else { var typeMetadata = getOrAddEdmEntityType(ns, name_2); typeMetadata.openType = getAttributeBoolValue(e, "OpenType"); var baseType = getAttributeValue(e, "BaseType"); if (baseType) { var baseTypeNS = baseType.substring(0, baseType.lastIndexOf(".")); var baseTypeName = baseType.substr(baseTypeNS.length + 1); var bt = getOrAddEdmEntityType(baseTypeNS, baseTypeName); typeMetadata.baseType = bt; } entityTypes.push({ element: e, typeMetadata: typeMetadata }); } }; for (var i = 0; i < list.length; i++) { _loop_1(); } for (var _i = 0, entityTypes_1 = entityTypes; _i < entityTypes_1.length; _i++) { var e = entityTypes_1[_i]; Object.assign(e.typeMetadata, ApiMetadata.getEntityTypeProperties(e.element, namespaces)); e.typeMetadata.keys = this.parseEntityKeys(e.element); } return namespaces; }; ApiMetadata.parseEntityKeys = function (typeElement) { var res = new Array(); var list = typeElement.querySelectorAll("Key>PropertyRef"); for (var i = 0; i < list.length; i++) { res.push(getRequiredAttributeValue(list.item(i), "Name")); } return res; }; ApiMetadata.parseEnumMembers = function (element) { var res = {}; var list = element.querySelectorAll("Member"); for (var i = 0; i < list.length; i++) { var e = list.item(i); var name_3 = getRequiredAttributeValue(e, "Name"); var rawValue = getRequiredAttributeValue(e, "Value"); res[name_3] = (rawValue.match(/\d/)) ? parseInt(rawValue) : rawValue; } return res; }; ApiMetadata.getEntityTypeProperties = function (typeElement, namespaces) { var properties = {}; var navProperties = {}; var list = typeElement.querySelectorAll("Property,NavigationProperty"); for (var i = 0; i < list.length; i++) { var e = list.item(i); var name_4 = getRequiredAttributeValue(e, "Name"); var metadata = ApiMetadata.parseType(e, namespaces); if (e.tagName.toLowerCase() == "property") properties[name_4] = metadata; else navProperties[name_4] = EdmEntityTypeReference.fromTypeReference(metadata); } return { properties: properties, navProperties: navProperties }; }; ApiMetadata.prototype.getEntitySetMetadata = function (typeName) { return ApiMetadata.getEntitySetMetadata(typeName, this.namespaces); }; ApiMetadata.getEntitySetMetadata = function (typeName, namespaces) { var res = ApiMetadata.getEdmTypeMetadata(typeName, namespaces); if (res instanceof EdmEntityType) return res; throw new Error("EntitySet item type must be entity"); }; ApiMetadata.prototype.getEdmTypeMetadata = function (typeName) { return ApiMetadata.getEdmTypeMetadata(typeName, this.namespaces); }; ApiMetadata.getEdmTypeMetadata = function (typeName, namespaces) { if (startsWith(typeName, COLLECTION_TYPE_PREFIX)) typeName = typeName.substring(COLLECTION_TYPE_PREFIX.length, typeName.length - 1); var namespace = typeName.substring(0, typeName.lastIndexOf(".")); var typeNameNoNs = typeName.substr(namespace.length + 1); if (namespace == "Edm") { var t = EdmTypes[typeNameNoNs]; if (!t) throw new Error("Not registred Edm type: " + typeNameNoNs); return t; } var nsMeta = namespaces[namespace]; if (!nsMeta) throw new Error("Namespace '" + namespace + "' not found"); var typeElement = nsMeta.types[typeNameNoNs]; return typeElement; }; ApiMetadata.parseOperationMetadata = function (operationElement, namespaces) { var isAction = operationElement.tagName.toLowerCase() === "action"; var name = getRequiredAttributeValue(operationElement, "Name"); var returnTypeElement = operationElement.querySelector("ReturnType"); var returnType = returnTypeElement ? ApiMetadata.parseType(returnTypeElement, namespaces) : undefined; var parameters = new Array(); var bindingTo; var list = operationElement.querySelectorAll("Parameter"); for (var i = 0; i < list.length; i++) { var e = list.item(i); var type = ApiMetadata.parseType(e, namespaces); var name_5 = getRequiredAttributeValue(e, "Name"); if (getAttributeBoolValue(operationElement, "IsBound") && !bindingTo) bindingTo = EdmEntityTypeReference.fromTypeReference(type); else parameters.push({ name: name_5, type: type }); } return new OperationMetadata(name, isAction, parameters, returnType, bindingTo); }; ApiMetadata.parseType = function (element, namespaces) { var typeName = getRequiredAttributeValue(element, "Type"); var collection = startsWith(typeName, COLLECTION_TYPE_PREFIX); if (collection) typeName = typeName.substring(COLLECTION_TYPE_PREFIX.length, typeName.length - 1); var typeMetadata = ApiMetadata.getEdmTypeMetadata(typeName, namespaces); var res = new EdmTypeReference(typeMetadata, true, collection); res.nullable = getAttributeBoolValue(element, "Nullable") != false; return res; }; return ApiMetadata; }()); export { ApiMetadata }; function getRequiredAttributeValue(element, attrName) { return getAttributeValue(element, attrName) || (function () { throw new Error("Metadata: Attribute '" + attrName + "' in element '" + element.tagName + "' not found "); })(); } function getAttributeBoolValue(element, attrName) { var r = getAttributeValue(element, attrName); if (r != undefined) return r.toLowerCase() == "true"; } function getAttributeValue(element, attrName) { var attr = element.attributes.getNamedItem(attrName); if (attr) return attr.value; }