UNPKG

kipon-xrmservice

Version:

Dynamics 365 CE web api wrapper for angular, making life easier when building angular based web resources

3,517 lines 150 kB
import * as i0 from '@angular/core';
import { Injectable, NgModule } from '@angular/core';
import { Observable, BehaviorSubject, throwError } from 'rxjs';
import * as i1 from '@angular/common/http';
import { HttpHeaders, HttpResponse, HttpClientModule } from '@angular/common/http';
import { map, catchError, mergeMap } from 'rxjs/operators';

class FetchEntity {
    link(prototype, property, condition, attributes = null) {
        var res = new FetchEntity();
        res.entityPrototype = prototype;
        res.name = prototype._logicalName;
        res.condition = condition;
        res.attributes = attributes;
        res.parent = res;
        if (this.linkedentities == null) {
            this.linkedentities = [];
        }
        var next = new Link();
        next.entity = res;
        next.to = property;
        next.alias = property;
        this.linkedentities.push(next);
        return res;
    }
    innerjoin(prototype, alias, from, property, condition, attributes = null) {
        var res = new FetchEntity();
        res.entityPrototype = prototype;
        res.name = prototype._logicalName;
        res.condition = condition;
        res.attributes = attributes;
        res.parent = res;
        if (this.linkedentities == null) {
            this.linkedentities = [];
        }
        var next = new Link();
        next.entity = res;
        next.to = property;
        next.alias = alias;
        next.from = from;
        next.type = "inner";
        this.linkedentities.push(next);
        return res;
    }
    outerjoin(prototype, alias, from, property, condition, attributes = null) {
        var res = new FetchEntity();
        res.entityPrototype = prototype;
        res.name = prototype._logicalName;
        res.condition = condition;
        res.attributes = attributes;
        res.parent = res;
        if (this.linkedentities == null) {
            this.linkedentities = [];
        }
        var next = new Link();
        next.entity = res;
        next.to = property;
        next.alias = alias;
        next.from = from;
        next.type = "outer";
        this.linkedentities.push(next);
        return res;
    }
    aliasWithAttributes() {
        var result = [];
        this.resolveAlias(this.linkedentities, result);
        return result;
    }
    resolveAlias(links, result) {
        if (links != null && links.length > 0) {
            links.forEach(l => {
                if (l.entity.attributes != null && l.entity.attributes.length > 0) {
                    result.push(l.alias);
                }
                this.resolveAlias(l.entity.linkedentities, result);
            });
        }
    }
}
class Link {
    toFetchXml(populateAttrib) {
        var result = "";
        var fromString = "";
        if (this.from != null) {
            fromString = " alias='" + this.alias + "' from='" + this.from + "' link-type='" + this.type + "'";
        }
        if (this.from == null && this.alias != null && this.alias != '') {
            fromString = " alias='" + this.alias + "'";
        }
        result += "<link-entity name='" + this.entity.name + "' to='" + this.to + "'" + fromString + ">";
        if (populateAttrib) {
            if (this.entity.attributes != null && this.entity.attributes.length > 0) {
                this.entity.attributes.forEach(a => {
                    result += "<attribute name='" + a + "'/>";
                });
            }
        }
        if (this.entity.condition != null) {
            result += this.entity.condition.toFetchXml();
        }
        if (this.entity.linkedentities != null && this.entity.linkedentities.length > 0) {
            this.entity.linkedentities.forEach(l => {
                result += l.toFetchXml(populateAttrib);
            });
        }
        result += "</link-entity>";
        return result;
    }
}
class Fetchsort {
    toFetchXml() {
        if (this.descending) {
            return "<order attribute='" + this.attribute + "' descending='true' />";
        }
        return "<order attribute='" + this.attribute + "' />";
    }
}
class Fetchxml {
    constructor(prototype, condition) {
        this.root = new FetchEntity();
        this.root.entityPrototype = prototype;
        this.keyname = prototype._keyName;
        this.root.name = prototype._logicalName;
        this.root.condition = condition;
        this.root.attributes = prototype.columns(false);
    }
    entity() {
        return this.root;
    }
    sort(attribname, descending = false) {
        if (this.sorts == null) {
            this.sorts = [];
        }
        let nextsort = new Fetchsort();
        nextsort.attribute = attribname;
        nextsort.descending = descending;
        this.sorts.push(nextsort);
    }
    toCountFetchXml() {
        let result = "";
        var distinct = "";
        if (this.distinct != null) {
            distinct = " distinct='" + this.distinct + "'";
        }
        var aggr = "count";
        var dist = '';
        if (this.distinct) {
            dist = " distinct='true'";
            aggr = "countcolumn";
        }
        result += "<fetch mapping='logical'" + distinct + " aggregate='true'>";
        result += "<entity name='" + this.root.name + "'>";
        result += "<attribute name='" + this.keyname + "' aggregate='" + aggr + "' alias='count'" + dist + "  />";
        if (this.root.condition != null) {
            result += this.root.condition.toFetchXml();
        }
        if (this.root.linkedentities != null && this.root.linkedentities.length > 0) {
            this.root.linkedentities.forEach(l => {
                result += l.toFetchXml(false);
            });
        }
        result += "</entity>";
        result += "</fetch>";
        return result;
    }
    toFetchXml(pageCoocie = null, forPage = null) {
        let result = "";
        var page = "";
        if (this.count != null) {
            if (this.page == null) {
                this.page = 1;
            }
            if (forPage == null) {
                forPage = this.page;
            }
            page = " count='" + this.count + "' page='" + forPage + "'";
        }
        if (pageCoocie != null) {
            page += " paging-cookie='" + pageCoocie + "'";
        }
        else {
            page += " paging-cookie=''";
        }
        var distinct = "";
        if (this.distinct != null) {
            distinct = " distinct='" + this.distinct + "'";
        }
        result += "<fetch mapping='logical'" + page + distinct + ">";
        result += "<entity name='" + this.root.name + "'>";
        result += "<attribute name='" + this.keyname + "' />";
        this.root.attributes.forEach(a => {
            result += "<attribute name='" + a + "'/>";
        });
        if (this.root.condition != null) {
            result += this.root.condition.toFetchXml();
        }
        if (this.root.linkedentities != null && this.root.linkedentities.length > 0) {
            this.root.linkedentities.forEach(l => {
                result += l.toFetchXml(true);
            });
        }
        if (this.sorts != null && this.sorts.length > 0) {
            this.sorts.forEach(s => {
                result += s.toFetchXml();
            });
        }
        result += "</entity>";
        result += "</fetch>";
        return result;
    }
}

class XrmConfigService {
    constructor(http) {
        this.http = http;
    }
    loadAppConfig(url = null) {
        if (url == null) {
            url = '/assets/xrmConfig.json';
        }
        return this.http.get(url)
            .toPromise()
            .then(data => {
            this.appConfig = data;
        }).catch(err => {
            console.log('unable to load configuration /assets/xrmConfig.json');
            console.log(err);
        });
    }
    getConfig() {
        return this.appConfig;
    }
}
XrmConfigService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmConfigService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
XrmConfigService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmConfigService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmConfigService, decorators: [{
            type: Injectable
        }], ctorParameters: function () { return [{ type: i1.HttpClient }]; } });

const KiponXrmLOCAL_getFormType = "KiponXrmServiceLOCAL_getFormType";
const KiponXrmLOCAL_formentityr = "KiponXrmServiceLOCAL_formentityr";
const KiponXrmLOCAL_context = "KiponXrmServiceLOCAL_context";
class XrmFormKey {
}
class XrmContextInstance {
    constructor(ctx) {
        this.apiurl = '/api/data/v9.0/';
        this.clientUrl = ctx.getClientUrl();
        this.queryStringParameters = ctx.getQueryStringParameters();
        this.version = ctx.getVersion();
        this.userName = ctx.getUserName();
        this.userId = ctx.getUserId();
    }
    getClientUrl() {
        return this.clientUrl;
    }
    getQueryStringParameters() {
        return this.queryStringParameters;
    }
    getVersion() {
        return this.version;
    }
    getUserName() {
        return this.userName;
    }
    getUserId() {
        return this.userId;
    }
    $devClientUrl() {
        return this.clientUrl + this.apiurl;
        ;
    }
}
class XrmFormService {
    constructor() { }
    getContext() {
        if (window[KiponXrmLOCAL_context]) {
            return window[KiponXrmLOCAL_context];
        }
        if (typeof window["GetGlobalContext"] != "undefined") {
            window[KiponXrmLOCAL_context] = new XrmContextInstance(window["GetGlobalContext"]());
            return window[KiponXrmLOCAL_context];
        }
        if (window.parent && window.parent[KiponXrmLOCAL_context]) {
            window[KiponXrmLOCAL_context] = new XrmContextInstance(window.parent[KiponXrmLOCAL_context]);
            return window[KiponXrmLOCAL_context];
        }
        if (window.opener && window.opener[KiponXrmLOCAL_context]) {
            window[KiponXrmLOCAL_context] = new XrmContextInstance(window.opener[KiponXrmLOCAL_context]);
            return window[KiponXrmLOCAL_context];
        }
        if (window["Xrm"] && window["Xrm"]["Page"] && window["Xrm"]["Page"]["context"]) {
            window[KiponXrmLOCAL_context] = new XrmContextInstance(window["Xrm"]["Page"]["context"]);
            return window[KiponXrmLOCAL_context];
        }
        if (window.parent && window.parent["Xrm"] && window.parent["Xrm"]["Page"] && window.parent["Xrm"]["Page"]["context"]) {
            window[KiponXrmLOCAL_context] = new XrmContextInstance(window.parent["Xrm"]["Page"]["context"]);
            return window[KiponXrmLOCAL_context];
        }
        if (window.opener && window.opener["Xrm"] && window.opener["Xrm"]["Page"] && window.opener["Xrm"]["Page"]["context"]) {
            window[KiponXrmLOCAL_context] = new XrmContextInstance(window.opener["Xrm"]["Page"]["context"]);
            return window[KiponXrmLOCAL_context];
        }
        return null;
    }
    getFormType(clear = false) {
        if (!clear && window[KiponXrmLOCAL_getFormType])
            delete window[KiponXrmLOCAL_getFormType];
        if (window[KiponXrmLOCAL_getFormType]) {
            return window[KiponXrmLOCAL_getFormType];
        }
        if (!clear && window.parent && window.parent[KiponXrmLOCAL_getFormType]) {
            window[KiponXrmLOCAL_getFormType] = window.parent[KiponXrmLOCAL_getFormType];
            return window[KiponXrmLOCAL_getFormType];
        }
        if (!clear && window.opener && window.opener[KiponXrmLOCAL_getFormType]) {
            window[KiponXrmLOCAL_getFormType] = window.opener[KiponXrmLOCAL_getFormType];
            return window[KiponXrmLOCAL_getFormType];
        }
        if (window["Xrm"] && window["Xrm"]["Page"] && window["Xrm"]["Page"]["ui"] && window["Xrm"]["Page"]["ui"]["getFormType"]) {
            window[KiponXrmLOCAL_getFormType] = window["Xrm"]["Page"]["ui"]["getFormType"]();
            return window[KiponXrmLOCAL_getFormType];
        }
        if (window.parent && window.parent["Xrm"] && window.parent["Xrm"]["Page"] && window.parent["Xrm"]["Page"]["ui"] && window.parent["Xrm"]["Page"]["ui"]["getFormType"]) {
            window[KiponXrmLOCAL_getFormType] = window.parent["Xrm"]["Page"]["ui"]["getFormType"]();
            return window[KiponXrmLOCAL_getFormType];
        }
        if (window.opener && window.opener["Xrm"] && window.opener["Xrm"]["Page"] && window.opener["Xrm"]["Page"]["ui"] && window.opener["Xrm"]["Page"]["ui"]["getFormType"]) {
            window[KiponXrmLOCAL_getFormType] = window.opener["Xrm"]["Page"]["ui"]["getFormType"]();
            return window[KiponXrmLOCAL_getFormType];
        }
        return null;
    }
    getFormKey(id, type, clear = false) {
        if (typeof id != 'undefined' && id != null && id != '' && typeof type != 'undefined' && type != null && type != '') {
            let result = new XrmFormKey();
            result.id = id;
            result.type = type;
            window[KiponXrmLOCAL_formentityr] = result;
            return result;
        }
        if (clear && window[KiponXrmLOCAL_formentityr])
            delete window[KiponXrmLOCAL_formentityr];
        if (window[KiponXrmLOCAL_formentityr]) {
            return window[KiponXrmLOCAL_formentityr];
        }
        if (!clear && window.parent && window.parent[KiponXrmLOCAL_formentityr]) {
            window[KiponXrmLOCAL_formentityr] = window.parent[KiponXrmLOCAL_formentityr];
            return window[KiponXrmLOCAL_formentityr];
        }
        if (!clear && window.opener && window.opener[KiponXrmLOCAL_formentityr]) {
            window[KiponXrmLOCAL_formentityr] = window.opener[KiponXrmLOCAL_formentityr];
            return window[KiponXrmLOCAL_formentityr];
        }
        if (window["Xrm"] && window["Xrm"]["Page"] && window["Xrm"]["Page"]["data"] && window["Xrm"]["Page"]["data"]["entity"]) {
            var result = new XrmFormKey();
            result.id = window["Xrm"]["Page"]["data"]["entity"]["getId"]();
            result.type = window["Xrm"]["Page"]["data"]["entity"]["getEntityName"]();
            window[KiponXrmLOCAL_formentityr] = result;
            return window[KiponXrmLOCAL_formentityr];
        }
        if (window.parent && window.parent["Xrm"] && window.parent["Xrm"]["Page"] && window.parent["Xrm"]["Page"]["data"] && window.parent["Xrm"]["Page"]["data"]["entity"]) {
            var result = new XrmFormKey();
            result.id = window.parent["Xrm"]["Page"]["data"]["entity"]["getId"]();
            result.type = window.parent["Xrm"]["Page"]["data"]["entity"]["getEntityName"]();
            window[KiponXrmLOCAL_formentityr] = result;
            return window[KiponXrmLOCAL_formentityr];
        }
        if (window.opener && window.opener["Xrm"] && window.opener["Xrm"]["Page"] && window.opener["Xrm"]["Page"]["data"] && window.opener["Xrm"]["Page"]["data"]["entity"]) {
            var result = new XrmFormKey();
            result.id = window.opener["Xrm"]["Page"]["data"]["entity"]["getId"]();
            result.type = window.opener["Xrm"]["Page"]["data"]["entity"]["getEntityName"]();
            window[KiponXrmLOCAL_formentityr] = result;
            return window[KiponXrmLOCAL_formentityr];
        }
        return null;
    }
}
XrmFormService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmFormService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
XrmFormService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmFormService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmFormService, decorators: [{
            type: Injectable
        }], ctorParameters: function () { return []; } });

class XrmEntityKey {
}
class Expand {
    toExpandString() {
        let _ex = this.name;
        if (this.select != null || this.filter != null) {
            _ex += '(';
        }
        let semi = '';
        if (this.select != null) {
            _ex += '$select=' + this.select;
            semi = ';';
        }
        if (this.filter != null) {
            _ex += semi + '$filter=' + this.filter;
        }
        if (this.select != null || this.filter != null) {
            _ex += ')';
        }
        return _ex;
    }
}
class XrmService {
    constructor(http, injector, xrmformService) {
        this.http = http;
        this.injector = injector;
        this.xrmformService = xrmformService;
        this.defaultApiUrl = "/api/data/v9.0/";
        this.contextFallback = null;
        this.apiUrl = '/api/data/v9.0/';
        this.apiVersion = 'v9.0';
        this.debug = false;
        this.token = null;
        this.forceHttps = false;
        this.keyTries = 0;
    }
    setVersion(v) {
        this.apiUrl = this.defaultApiUrl.replace("9.0", v);
    }
    getContext() {
        if (this.contextFallback != null) {
            return this.contextFallback;
        }
        var x = this.xrmformService.getContext();
        if (x != null) {
            if (typeof x.getVersion == 'undefined') {
                x.getVersion = () => "9.0.0.0";
            }
            if (typeof x.$devClientUrl == 'undefined') {
                x.$devClientUrl = () => { return this.getContext().getClientUrl() + this.apiUrl; };
                this.contextFallback = x;
                this.initializeVersion(this.contextFallback.getVersion());
            }
            return x;
        }
        this.log('using fake context');
        let baseUrl = "http://localhost:4200";
        let version = 'v9.0';
        var comesfrom = window.location.href.toLowerCase();
        if (comesfrom.indexOf("webresources") >= 0) {
            var domain = window.location.href.split('/')[2];
            var proto = comesfrom.startsWith("https://") ? "https://" : "http://";
            // to-do, find a better way to render multi org sub url from the url. (for now - never needed on online, therefore blank for https, but might be needed for onpre running https ... )
            var sub = comesfrom.startsWith("https://") ? "" : "/" + window.location.href.split('/')[3];
            baseUrl = proto + domain + sub;
        }
        try {
            var configService = this.injector.get(XrmConfigService);
            if (configService != null) {
                let config = configService.getConfig();
                if (config != null && config.endpoints != null && config.endpoints.orgUri != null && config.endpoints.orgUri != '') {
                    baseUrl = config.endpoints.orgUri;
                }
                if (config != null && config.version != null && config.version != '') {
                    version = config.version;
                }
            }
        }
        catch (err) {
            // no worry, XrmConfigService is optional
        }
        this.contextFallback = {
            getClientUrl() {
                return baseUrl;
            },
            getQueryStringParameters() {
                let search = window.location.search;
                let hashes = search.slice(search.indexOf('?') + 1).split('&');
                let params = {};
                hashes.map(hash => {
                    let [key, val] = hash.split('=');
                    params[key] = decodeURIComponent(val);
                });
                return params;
            },
            getVersion() {
                return version.substring(1) + '.0.0';
            },
            getUserId() {
                return this["userid"];
            },
            getUserName() {
                return this["username"];
            },
            $devClientUrl() {
                return this['$clienturl'];
            }
        };
        var headers = this.getDefaultHeader();
        this.http.get(this.forceHTTPS(baseUrl) + "/api/data/" + version + "/WhoAmI()", { headers: headers }).subscribe(r => {
            this.log(r);
            let url = r['@odata.context'];
            let firstpart = url.split('/api/data/')[0];
            let version = url.split('/api/data/')[1].split('/')[0];
            this.contextFallback["$clienturl"] = firstpart + '/api/data/' + version + '/';
            this.contextFallback["userid"] = r["UserId"];
            this.contextFallback["username"] = "Dev. fallback from whoami";
            this.initializeVersion(this.contextFallback.getVersion());
        });
        var x = this.contextFallback;
        return this.contextFallback;
    }
    getCurrentUserId() {
        var ctx = this.getContext();
        if (ctx.getUserId() == null || ctx.getUserId() == '') {
            var headers = this.getDefaultHeader();
            var url = this.forceHTTPS(ctx.getClientUrl()) + this.apiUrl + "/WhoAmI()";
            this.log(url);
            return this.http.get(url, { headers: headers }).pipe(map(r => { return r["UserId"]; }));
        }
        else {
            this.log('get user from normal crm context');
            this.log('should result in ' + ctx.getUserId());
            return new Observable(obs => {
                setTimeout(() => obs.next(ctx.getUserId()), 100);
            });
        }
    }
    getCurrentKey(repeatForCreateForm = false) {
        // First we try to find id and type in the url, this allow forcing a specific entity, directly from standard url parameters
        let params = this.getQueryStringParameters();
        let result = new XrmEntityKey();
        let id = params["id"];
        let type = params["typename"];
        if (id == null || id == '') {
            params = this.getContext().getQueryStringParameters();
            id = params["id"];
            type = params["typename"];
        }
        if (this.xrmformService.getFormType() == 1 && repeatForCreateForm) {
            var obs = new Observable(sub => {
                this.tryGetKey(sub);
            });
            return obs;
        }
        let key = this.xrmformService.getFormKey(id, type);
        if (key != null && key.id != null) {
            result.id = this.toGuid(key.id);
            result.entityType = key.type;
            return new Observable(obs => obs.next(result));
        }
        if (this.xrmformService.getFormType() == 2) {
            key = this.xrmformService.getFormKey(id, type);
            if (key != null) {
                result.id = this.toGuid(key.id);
                result.entityType = key.type;
                return new Observable(obs => obs.next(result));
            }
            else {
                return new Observable(obs => {
                    var iv = setInterval(() => {
                        let key = this.xrmformService.getFormKey(id, type);
                        if (key != null) {
                            clearInterval(iv);
                            result.id = this.toGuid(key.id);
                            result.entityType = key.type;
                            obs.next(result);
                        }
                    }, 800);
                });
            }
        }
        else {
            // it was not an entity form, or the entity form was not in edit mode.
            result.id = this.toGuid(result.id);
            return new Observable(obs => obs.next(result));
        }
    }
    get(entityTypes, id, fields, expand = null) {
        let headers = new HttpHeaders({ 'Accept': 'application/json' });
        if (this.token != null) {
            headers = headers.append("Authorization", "Bearer " + this.token);
        }
        headers = headers.append("OData-MaxVersion", "4.0");
        headers = headers.append("OData-Version", "4.0");
        headers = headers.append("Content-Type", "application/json; charset=utf-8");
        headers = headers.append("Prefer", "odata.include-annotations=*");
        headers = headers.append("Cache-Control", "no-cache");
        let addFields = '';
        let sep = '?';
        if (fields != null && fields != '') {
            addFields = sep + "$select=" + fields;
            sep = '&';
        }
        let _ex = this.expandString(expand, sep);
        let _id = id.replace("{", "").replace("}", "");
        let url = this.getContext().getClientUrl() + this.apiUrl + entityTypes + "(" + _id + ")" + addFields + _ex;
        this.log(url);
        return this.http.get(this.forceHTTPS(url), { headers: headers });
    }
    query(entityTypes, fields, filter, orderBy = null, top = 0, count = false) {
        let me = this;
        let headers = new HttpHeaders({ 'Accept': 'application/json' });
        if (this.token != null) {
            headers = headers.append("Authorization", "Bearer " + this.token);
        }
        headers = headers.append("OData-MaxVersion", "4.0");
        headers = headers.append("OData-Version", "4.0");
        headers = headers.append("Content-Type", "application/json; charset=utf-8");
        headers = headers.append("Prefer", "odata.include-annotations=\"*\"");
        if (top > 0) {
            headers = headers.append("Prefer", "odata.maxpagesize=" + top.toString());
        }
        else {
        }
        headers = headers.append("Cache-Control", "no-cache");
        let url = this.getContext().getClientUrl() + this.apiUrl + entityTypes;
        if ((fields != null && fields != '') || (filter != null && filter != '') || (orderBy != null && orderBy != '') || top > 0) {
            url += "?";
        }
        let sep = '';
        if (fields != null && fields != '') {
            url += '$select=' + fields;
            sep = '&';
        }
        if (filter != null && filter != '') {
            url += sep + '$filter=' + filter;
            sep = '&';
        }
        if (orderBy != null && orderBy != '') {
            url += sep + '$orderby=' + orderBy;
            sep = '&';
        }
        if (count) {
            url += sep + '$count=true';
            sep = '&';
        }
        return this.http.get(this.forceHTTPS(url), { headers: headers }).pipe(map(response => {
            let result = me.resolveQueryResult(response, top, [url], 0);
            return result;
        }));
    }
    create(entityType, entity) {
        let headers = new HttpHeaders({ 'Accept': 'application/json' });
        if (this.token != null) {
            headers = headers.append("Authorization", "Bearer " + this.token);
        }
        headers = headers.append("OData-MaxVersion", "4.0");
        headers = headers.append("OData-Version", "4.0");
        headers = headers.append("Content-Type", "application/json; charset=utf-8");
        headers = headers.append("Prefer", "odata.include-annotations=*");
        headers = headers.append("Prefer", "return=representation");
        let options = {
            headers: headers,
        };
        return this.http.post(this.forceHTTPS(this.getContext().getClientUrl()) + this.apiUrl + entityType, entity, { headers: headers, observe: "response" }).pipe(map((res) => {
            if (res.body == null) {
                let entityId = res.headers.get('OData-EntityId');
                let result = { id: entityId.split('(')[1].replace(')', ''), $keyonly: true };
                return result;
            }
            else {
                return res.body;
            }
        }));
    }
    update(entityType, entity, id, fields = null) {
        let headers = new HttpHeaders({ 'Accept': 'application/json' });
        if (this.token != null) {
            headers = headers.append("Authorization", "Bearer " + this.token);
        }
        headers = headers.append("OData-MaxVersion", "4.0");
        headers = headers.append("OData-Version", "4.0");
        headers = headers.append("Content-Type", "application/json; charset=utf-8");
        headers = headers.append("Prefer", "odata.include-annotations=*");
        headers = headers.append("Prefer", "return=representation");
        let _f = '';
        if (fields != null) {
            _f = '?$select=' + fields;
        }
        let fUrl = this.getContext().getClientUrl() + this.apiUrl + entityType + "(" + id + ")" + _f;
        this.log(fUrl);
        return this.http.patch(this.forceHTTPS(fUrl), entity, { headers: headers }).pipe(map(response => {
            if (response == null || this.getContext().getVersion().startsWith("8.0") || this.getContext().getVersion().startsWith("8.1")) {
                return entity;
            }
            return response;
        }));
    }
    put(entityType, id, field, value, propertyValueAs = null) {
        if (propertyValueAs == null)
            propertyValueAs = 'value';
        let headers = new HttpHeaders({ 'Accept': 'application/json' });
        if (this.token != null) {
            headers = headers.append("Authorization", "Bearer " + this.token);
        }
        headers = headers.append("OData-MaxVersion", "4.0");
        headers = headers.append("OData-Version", "4.0");
        headers = headers.append("Content-Type", "application/json; charset=utf-8");
        headers = headers.append("Prefer", "odata.include-annotations=*");
        let v = {};
        v[propertyValueAs] = value;
        this.log(v);
        let url = this.getContext().getClientUrl() + this.apiUrl + entityType + "(" + id + ")/" + field;
        this.log(url);
        if (v[propertyValueAs] != null) {
            return this.http.put(this.forceHTTPS(url), v, { headers: headers }).pipe(map(response => null));
        }
        else {
            return this.http.delete(this.forceHTTPS(url), { headers: headers }).pipe(map(response => null));
        }
    }
    delete(entityType, id) {
        let headers = new HttpHeaders({ 'Accept': 'application/json' });
        if (this.token != null) {
            headers = headers.append("Authorization", "Bearer " + this.token);
        }
        headers = headers.append("OData-MaxVersion", "4.0");
        headers = headers.append("OData-Version", "4.0");
        headers = headers.append("Content-Type", "application/json; charset=utf-8");
        headers = headers.append("Prefer", "odata.include-annotations=*");
        let url = this.getContext().getClientUrl() + this.apiUrl + entityType + "(" + id + ")";
        this.log(url);
        return this.http.delete(this.forceHTTPS(url), { headers: headers }).pipe(map(response => null));
    }
    getParameter(param) {
        return this.getQueryStringParameters()[param];
    }
    associate(fromType, fromId, toType, toId, refname) {
        let headers = new HttpHeaders({ 'Accept': 'application/json' });
        if (this.token != null) {
            headers = headers.append("Authorization", "Bearer " + this.token);
        }
        headers = headers.append("OData-MaxVersion", "4.0");
        headers = headers.append("OData-Version", "4.0");
        headers = headers.append("Content-Type", "application/json; charset=utf-8");
        headers = headers.append("Prefer", "odata.include-annotations=*");
        let url = this.getContext().getClientUrl() + this.apiUrl + fromType + "(" + this.toGuid(fromId) + ")/" + refname + "/$ref";
        let data = {
            "@odata.id": this.getContext().$devClientUrl() + toType + "(" + this.toGuid(toId) + ")"
        };
        if (this.debug) {
            this.log(url);
            this.log(data);
        }
        return this.http.post(this.forceHTTPS(url), data, { headers: headers }).pipe(map(response => null));
    }
    disassociate(fromType, fromId, toType, toId, refname) {
        let headers = new HttpHeaders({ 'Accept': 'application/json' });
        if (this.token != null) {
            headers = headers.append("Authorization", "Bearer " + this.token);
        }
        headers = headers.append("OData-MaxVersion", "4.0");
        headers = headers.append("OData-Version", "4.0");
        let url = this.getContext().getClientUrl() + this.apiUrl + fromType + "(" + this.toGuid(fromId) + ")/" + refname + "/$ref?$id=" + this.getContext().$devClientUrl() + toType + "(" + this.toGuid(toId) + ")";
        this.log(url);
        return this.http.delete(this.forceHTTPS(url), { headers: headers }).pipe(map(response => {
            this.log(response);
            return null;
        }));
    }
    func(name, data, boundType = null, boundId = null) {
        let headers = new HttpHeaders({ 'Accept': 'application/json' });
        if (this.token != null) {
            headers = headers.append("Authorization", "Bearer " + this.token);
        }
        headers = headers.append("OData-MaxVersion", "4.0");
        headers = headers.append("OData-Version", "4.0");
        let url = this.getContext().getClientUrl() + this.apiUrl + name;
        if (boundType != null) {
            url = this.getContext().getClientUrl() + this.apiUrl + boundType + "(" + this.toGuid(boundId) + ")/" + name;
        }
        if (data != null && data.length > 0) {
            url += data;
        }
        else {
            url += "()";
        }
        this.log(url);
        return this.http.get(this.forceHTTPS(url), { headers: headers }).pipe(map(response => {
            this.log(response);
            return response;
        }));
    }
    action(name, data, boundType = null, boundId = null) {
        let headers = new HttpHeaders({ 'Accept': 'application/json' });
        if (this.token != null) {
            headers = headers.append("Authorization", "Bearer " + this.token);
        }
        headers = headers.append("OData-MaxVersion", "4.0");
        headers = headers.append("OData-Version", "4.0");
        let url = this.getContext().getClientUrl() + this.apiUrl + name;
        if (boundType != null) {
            url = this.getContext().getClientUrl() + this.apiUrl + boundType + "(" + this.toGuid(boundId) + ")/" + name;
        }
        this.log(url);
        return this.http.post(this.forceHTTPS(url), data, { headers: headers }).pipe(map(response => {
            this.log(response);
            return response;
        }));
    }
    log(message) {
        if (this.debug) {
            if (typeof message == 'string') {
                console.dir(message);
            }
            else {
                console.log(message);
            }
        }
    }
    tryGetKey(sub) {
        setTimeout(() => {
            var key = this.xrmformService.getFormKey(null, null, true);
            if (key.id != null && key.id != '' && key.type != null && key.type != '') {
                let result = new XrmEntityKey();
                result.entityType = key.type;
                result.id = key.id;
                sub.next(result);
            }
            else {
                this.keyTries++;
                if (this.keyTries < 900) {
                    // continue try for 1/2 hour at most
                    this.tryGetKey(sub);
                }
            }
        }, 2000);
    }
    initializeVersion(_v) {
        if (_v == null) {
            _v = '9.0.0.0';
        }
        let v = _v.split('.');
        this.setVersion(v[0] + "." + v[1]);
        this.apiVersion = 'v' + v[0] + '.' + v[1];
    }
    expandString(expand, sep) {
        if (expand == null || expand.name == null || expand.name == '')
            return '';
        let _ex = sep + '$expand=' + expand.toExpandString();
        if (expand.additional != null && expand.additional.length > 0) {
            expand.additional.forEach(ad => {
                _ex += "," + ad.toExpandString();
            });
        }
        return _ex;
    }
    resolveQueryResult(response, top, pages, pageIndex) {
        let me = this;
        let result = {
            context: response["@odata.context"],
            count: response["@odata.count"],
            value: response["value"],
            pages: pages,
            prev: null,
            next: null,
            pageIndex: pageIndex,
            top: top,
            nextLink: null
        };
        let nextLink = response["@odata.nextLink"];
        if (nextLink != null && nextLink != '') {
            let start = nextLink.indexOf('/api');
            nextLink = me.getContext().getClientUrl() + nextLink.substring(start);
            result = {
                context: result.context,
                count: response["@odata.count"],
                value: result.value,
                pages: pages,
                pageIndex: pageIndex,
                prev: null,
                top: top,
                nextLink: nextLink,
                next: () => {
                    let headers = new HttpHeaders({ 'Accept': 'application/json' });
                    if (this.token != null) {
                        headers = headers.append("Authorization", "Bearer " + this.token);
                    }
                    headers = headers.append("OData-MaxVersion", "4.0");
                    headers = headers.append("OData-Version", "4.0");
                    headers = headers.append("Content-Type", "application/json; charset=utf-8");
                    headers = headers.append("Prefer", "odata.include-annotations=\"*\"");
                    if (top > 0) {
                        headers = headers.append("Prefer", "odata.maxpagesize=" + top.toString());
                    }
                    headers = headers.append("Cache-Control", "no-cache");
                    return me.http.get(me.forceHTTPS(nextLink), { headers: headers }).pipe(map(r => {
                        pages.push(nextLink);
                        let pr = me.resolveQueryResult(r, top, pages, pageIndex + 1);
                        return pr;
                    }));
                }
            };
        }
        if (result.pageIndex >= 1) {
            result.prev = () => {
                let headers = new HttpHeaders({ 'Accept': 'application/json' });
                if (this.token != null) {
                    headers = headers.append("Authorization", "Bearer " + this.token);
                }
                headers = headers.append("OData-MaxVersion", "4.0");
                headers = headers.append("OData-Version", "4.0");
                headers = headers.append("Content-Type", "application/json; charset=utf-8");
                headers = headers.append("Prefer", "odata.include-annotations=\"*\"");
                if (top > 0) {
                    headers = headers.append("Prefer", "odata.maxpagesize=" + top.toString());
                }
                else {
                }
                headers = headers.append("Cache-Control", "no-cache");
                let lastPage = result.pages[result.pageIndex - 1];
                return me.http.get(me.forceHTTPS(lastPage), { headers: headers }).pipe(map(r => {
                    result.pages.splice(result.pages.length - 1, 1);
                    let pr = me.resolveQueryResult(r, top, result.pages, result.pageIndex - 1);
                    return pr;
                }));
            };
        }
        return result;
    }
    getQueryStringParameters() {
        let search = window.location.search;
        let hashes = search.slice(search.indexOf('?') + 1).split('&');
        let params = {};
        hashes.map(hash => {
            let [key, val] = hash.split('=');
            params[key] = decodeURIComponent(val);
        });
        return params;
    }
    toGuid(v) {
        // 5C48BB2A-BFC0-4E56-A262-8494E0F6A8FD
        if (v == null || v == '') {
            return v;
        }
        v = decodeURIComponent(v).replace('{', '').replace('}', '');
        if (v.indexOf('-') >= 0) {
            return v;
        }
        return v.substr(0, 8) + '-' + v.substr(8, 4) + '-' + v.substr(12, 4) + '-' + v.substr(16, 4) + '-' + v.substr(20);
    }
    getDefaultHeader() {
        let headers = new HttpHeaders({ 'Accept': 'application/json' });
        if (this.token != null) {
            this.log('crmtoken used: ' + this.token);
            headers = headers.append("Authorization", "Bearer " + this.token);
        }
        headers = headers.append("OData-MaxVersion", "4.0");
        headers = headers.append("OData-Version", "4.0");
        headers = headers.append("Content-Type", "application/json; charset=utf-8");
        headers = headers.append("Prefer", "odata.include-annotations=\"*\"");
        return headers;
    }
    forceHTTPS(v) {
        if (this.forceHttps && v.startsWith("http://")) {
            return v.replace("http://", "https://");
        }
        return v;
    }
}
XrmService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmService, deps: [{ token: i1.HttpClient }, { token: i0.Injector }, { token: XrmFormService }], target: i0.ɵɵFactoryTarget.Injectable });
XrmService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmService, decorators: [{
            type: Injectable
        }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: i0.Injector }, { type: XrmFormService }]; } });

class XrmAuthService {
    constructor(xrmConfigService, xrmService) {
        this.xrmConfigService = xrmConfigService;
        this.xrmService = xrmService;
    }
    authenticate() {
        if (window["AuthenticationContext"] == null) {
            throw "You must load adal.js to the page header scripts.";
        }
        this.authConfig = this.xrmConfigService.getConfig();
        let authCtx = new window["AuthenticationContext"](this.authConfig);
        let isCallback = authCtx.isCallback(window.location.hash);
        if (isCallback) {
            authCtx.handleWindowCallback();
        }
        var loginError = authCtx.getLoginError();
        if (!loginError && isCallback) {
            var x = Observable.create((_obs) => {
                this.obs = _obs;
            });
            setTimeout(() => {
                authCtx.acquireToken(this.authConfig.endpoints.orgUri, this.getToken);
            }, 1);
            return x;
        }
        if (loginError) {
            throw loginError;
        }
        if (!isCallback) {
            let user = authCtx.getCachedUser();
            if (user == null) {
                authCtx.login();
            }
            else {
                console.log(user);
            }
        }
        return Observable.create((obs) => {
            setTimeout(() => {
                obs.next(true);
            });
        });
    }
    getToken(error, token) {
        if (error) {
            console.log(error);
        }
        if (this.xrmService.debug) {
            console.log(token);
        }
        this.xrmService.token = token;
        this.obs.next(true);
    }
}
XrmAuthService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmAuthService, deps: [{ token: XrmConfigService }, { token: XrmService }], target: i0.ɵɵFactoryTarget.Injectable });
XrmAuthService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmAuthService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmAuthService, decorators: [{
            type: Injectable
        }], ctorParameters: function () { return [{ type: XrmConfigService }, { type: XrmService }]; } });

class XrmStateService {
    constructor() {
        this.runnings = [];
        this._running = false;
        this._success = 0;
        this._error = 0;
        this.statechanged$ = new BehaviorSubject(false);
    }
    statechanged() {
        return this.statechanged$;
    }
    /**
     * @deprecated You should subscribe to statechanged() instead of targeting this property directly
     */
    get running() { return this._running; }
    ;
    get success() { return this._success; }
    ;
    get error() { return this._error; }
    ;
    add(x) {
        this.runnings.push(x);
        this._running = true;
    }
    remove(x, error) {
        let pos = this.runnings.indexOf(x);
        this.runnings.splice(pos, 1);
        var current = this._running;
        this._running = this.runnings.length > 0;
        if (current != this._running) {
            this.statechanged$.next(this._running);
        }
        if (error) {
            this._error++;
        }
        else {
            this._success++;
        }
    }
}
XrmStateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
XrmStateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmStateService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmStateService, decorators: [{
            type: Injectable
        }], ctorParameters: function () { return []; } });

class XrmInterceptor {
    constructor(xrmState) {
        this.xrmState = xrmState;
        this.nextNumber = 0;
    }
    intercept(req, next) {
        this.nextNumber++;
        let me = this.nextNumber;
        this.xrmState['add'](me);
        return next.handle(req)
            .pipe(map((event) => {
            if (event instanceof HttpResponse) {
                this.xrmState['remove'](me, false);
            }
            return event;
        }), catchError(error => {
            this.xrmState['remove'](me, true);
            return throwError(error);
        }));
    }
}
XrmInterceptor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmInterceptor, deps: [{ token: XrmStateService }], target: i0.ɵɵFactoryTarget.Injectable });
XrmInterceptor.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmInterceptor });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmInterceptor, decorators: [{
            type: Injectable
        }], ctorParameters: function () { return [{ type: XrmStateService }]; } });

const XRMCONTEXTSERVICE_EMPTY_GUID = "00000000-0000-0000-0000-000000000000";
class FunctionPropertyValue {
    constructor(v) {
        this.v = '';
        this.v = v;
    }
    functionPropertyValueAsString() {
        return this.v;
    }
}
class Entity {
    constructor(pluralName, keyName, updateable = false, logicalname = null) {
        this._updateable = false;
        this._pluralName = pluralName;
        this._keyName = keyName;
        this._updateable = updateable;
        if (logicalname != null && logicalname != '') {
            this._logicalName = logicalname;
        }
        else {
            let x = this._pluralName != null ? this._pluralName.toLowerCase() : null;
            switch (x) {
                case "emails":
                    this._logicalName = "email";
                    break;
                case "appointments":
                    this._logicalName = "appointment";
                    break;
                case "letters":
                    this._logicalName = "letter";
                    break;
                case "phonecalls":
                    this._logicalName = "phonecall";
                    break;
                case "tasks":
                    this._logicalName = "task";
                    break;
                case "campaignresponses":
                    this._logicalName = "campaignresponse";
                    break;
                default: {
                    if (this._keyName.toLowerCase() == "activityid" && x != null) {
                        this._logicalName = x.substr(0, x.length - 1);
                    }
                    else {
                        this._logicalName = this._keyName.substr(0, (this._keyName.length - 2)).toLowerCase();
                    }
                    break;
                }
            }
        }
    }
    ToEntityReference(associatednavigationproperty = null) {
        return new EntityReference(this.id, this._pluralName, associatednavigationproperty, this._logicalName);
    }
    ignoreColumn(prop) {
        if (prop == "_pluralName" || prop == "_logicalName" || prop == "_keyName" || prop == "id" || prop == '_updateable' || prop == '$expand' || prop == 'access') {
            return true;
        }
        return false;
    }
    columns(webapi = false) {
        let result = [];
        let columns = this._keyName;
        for (var prop in this) {
            if (prop == this._keyName)
                continue;
            if (this.ignoreColumn(prop))
                continue;
            let v = this[prop];
            if (typeof v !== 'undefined' && v != null) {
                if (Array.isArray(v)) {
                    continue;
                }
                if (v instanceof Entity) {
                    continue;
                }
            }
            if (this.hasOwnProperty(prop)) {
                if (webapi && this[prop] instanceof EntityReference) {
                    result.push("_" + prop + "_value");
                }
                else {
                    result.push(prop);
                }
            }
        }
        return result;
    }
}
class Entities extends Array {
    constructor(fType, tType, refName, leftToRight, t) {
        super(0);
        Object.setPrototypeOf(this, new.target.prototype);
        this.parentType = fType;
        this.childType = tType;
        this.refName = refName;
        this.leftToRight = leftToRight;
        this.push(t);
    }
    add(entity) {
        let fromType = this.parentType;
        let fromId = this.parentId;
        let toType = this.childType;
        let toId = entity.id;
        if (!this.leftToRight) {
            fromType = this.childType;
            fromId = entity.id;
            toType = this.parentType;
            toId = this.parentId;
        }
        return this.xrmService.associate(fromType, fromId, toType, toId, this.refName).pipe(map(r => {
            this.push(entity);
            return null;
        }));
    }
    remove(entity) {
        let fromType = this.parentType;
        let fromId = this.parentId;
        let toType = this.childType;
        let toId = entity.id;
        if (!this.leftToRight) {
            fromType = this.childType;
            fromId = entity.id;
            toType = this.parentType;
            toId = this.parentId;
        }
        return this.xrmService.disassociate(fromType, fromId, toType, toId, this.refName).pipe(map(r => {
            var index = this.indexOf(entity);
            if (index >= 0) {
                this.splice(index, 1);
            }
            return null;
        }));
    }
}
class EntityReference {
    constructor(id = null, pluralName = null, associatednavigationproperty = null, logicalname = null) {
        this.id = id;
        this.pluralName = pluralName;
        this.associatednavigationproperty = associatednavigationproperty;
        this.logicalname = logicalname;
        if (this.pluralName != null && logicalname == null) {
            switch (this.pluralName.toLowerCase()) {
                case "emails":
                    this.logicalname = "email";
                    break;
                case "appointments":
                    this.logicalname = "appointment";
                    break;
                case "letters":
                    this.logicalname = "letter";
                    break;
                case "phonecalls":
                    this.logicalname = "phonecall";
                    break;
                case "tasks":
                    this.logicalname = "task";
                    break;
                default: {
                    this.logicalname = this.pluralName.substr(0, (this.pluralName.length - 1)).toLowerCase();
                    break;
                }
            }
        }
    }
    replace(v1, v2) {
        this.id.replace(v1, v2);
    }
    meta(pluralName, associatednavigationproperty) {
        this.pluralName = pluralName;
        this.associatednavigationproperty = associatednavigationproperty;
        return this;
    }
    clone() {
        let result = new EntityReference();
        result.id = this.id;
        result.name = this.name;
        result.logicalname = this.name;
        result.associatednavigationproperty = this.associatednavigationproperty;
        return result;
    }
    associatednavigationpropertyname() {
        if (this.associatednavigationproperty == null || this.associatednavigationproperty == '') {
            throw 'navigation property has not been set for this EntityReference instance';
        }
        if (this.associatednavigationproperty.endsWith('@odata.bind')) {
            return this.associatednavigationproperty;
        }
        return this.associatednavigationproperty + '@odata.bind';
    }
    equals(ref) {
        return this.id == ref.id && this.logicalname == ref.logicalname;
    }
    toJsonProperty() {
        return { '@odata.id': "'" + this.pluralName + "(" + this.id.replace("{", "").replace("}", "") + ")" + "'" };
    }
    static same(ref1, ref2) {
        if (ref1 == null && ref2 == null) {
            return true;
        }
        let id1 = null;
        let id2 = null;
        if (ref1 != null)
            id1 = ref1.id;
        if (ref2 != null)
            id2 = ref2.id;
        return id1 == id2;
    }
}
class OptionSetValue {
    constructor(value = null, name = null) {
        this.value = value;
        this.name = name;
    }
    equals(o) {
        if (this.value == null && (o == null || o.value == null))
            return true;
        return this.value == o.value;
    }
    clone() {
        let r = new OptionSetValue();
        r.name = this.name;
        r.value = this.value;
        return r;
    }
    toJsonProperty() {
        return this.value;
    }
    static same(o1, o2) {
        if (o1 == null && o2 == null)
            return true;
        let v1 = null;
        let v2 = null;
        if (o1 != null)
            v1 = o1.value;
        if (o2 != null)
            v2 = o2.value;
        return v1 == v2;
    }
}
var Operator;
(function (Operator) {
    Operator[Operator["And"] = 0] = "And";
    Operator[Operator["Or"] = 1] = "Or";
})(Operator || (Operator = {}));
var Comparator;
(function (Comparator) {
    Comparator[Comparator["Equals"] = 1] = "Equals";
    Comparator[Comparator["NotEquals"] = 2] = "NotEquals";
    Comparator[Comparator["Contains"] = 3] = "Contains";
    Comparator[Comparator["NotContains"] = 4] = "NotContains";
    Comparator[Comparator["DoesNotContainsData"] = 5] = "DoesNotContainsData";
    Comparator[Comparator["ContainsData"] = 6] = "ContainsData";
    Comparator[Comparator["StartsWith"] = 7] = "StartsWith";
    Comparator[Comparator["NotStartsWith"] = 8] = "NotStartsWith";
    Comparator[Comparator["EndsWith"] = 9] = "EndsWith";
    Comparator[Comparator["NotEndsWith"] = 10] = "NotEndsWith";
    Comparator[Comparator["GreaterThan"] = 11] = "GreaterThan";
    Comparator[Comparator["GreaterThanOrEqual"] = 12] = "GreaterThanOrEqual";
    Comparator[Comparator["LessThan"] = 13] = "LessThan";
    Comparator[Comparator["LessThanOrEQual"] = 14] = "LessThanOrEQual";
    Comparator[Comparator["Useroruserhierarchy"] = 100] = "Useroruserhierarchy";
    Comparator[Comparator["Userteams"] = 101] = "Userteams";
})(Comparator || (Comparator = {}));
class ColumnBuilder {
    constructor() {
        this.columns = null;
        this.hasEntityReference = false;
    }
}
class Filter {
    constructor() {
        this["raw"] = false;
    }
    toQueryString(prototype) {
        if (this["raw"] == true) {
            return this.field;
        }
        if (this.operator == 100) {
            return 'ownerid eq-useroruserhierarchy';
        }
        if (this.operator == 101) {
            return 'ownerid eq-userteams';
        }
        let result = '';
        let _f = this.field;
        if (this.operator == Comparator.Equals && this.value == null) {
            // this.operator = Comparator.DoesNotContainsData;
        }
        if (this.operator == Comparator.NotEquals && this.value == null) {
            // this.operator = Comparator.ContainsData;
        }
        switch (this.operator) {
            case Comparator.ContainsData: {
                return _f + ' ne null';
            }
            case Comparator.DoesNotContainsData: {
                return _f + ' eq null';
            }
        }
        if (this.value == null) {
            throw new Error("value is required for operation type " + this.operator);
        }
        let _v = "'" + this.value + "'";
        if (typeof this.value == 'number') {
            _v = this.value.toString();
        }
        if (typeof this.value == 'boolean') {
            _v = this.value.valueOf() ? 'true' : 'false';
        }
        if (prototype[this.field] instanceof OptionSetValue) {
            if (this.value != null && this.value.hasOwnProperty('value')) {
                _v = this.value.value;
            }
        }
        let isEref = false;
        if (prototype[this.field] instanceof EntityReference) {
            _f = "_" + this.field + "_value";
            if (this.value != null) {
                if (typeof this.value == 'string') {
                    _v = this.value.replace('{', '').replace('}', '');
                }
                else {
                    _v = this.value.id.replace('{', '').replace('}', '');
                }
            }
            isEref = true;
        }
        if (!isEref && _f.startsWith('_') && _f.endsWith('_value') && _v != null && this.value != null) {
            if (typeof this.value === "string") {
                _v = this.value.replace('{', '').replace('}', '');
            }
            else {
                if (this.value.hasOwnProperty("id")) {
                    _v = this.value.id.replace('{', '').replace('}', '');
                }
            }
        }
        var isDate = false;
        if (prototype[this.field] instanceof Date) {
            if (this.value instanceof Date) {
                _v = this.value.toISOString();
            }
            else {
                _v = this.value.toString();
            }
            isDate = true;
        }
        if (!isDate && this.value instanceof Date) {
            _v = this.value.toISOString();
            isDate = true;
        }
        if (_f == prototype._keyName) {
            _v = this.value.replace('{', '').replace('}', '');
        }
        if (_v != null && _v != '') {
            _v = encodeURIComponent(_v);
        }
        switch (this.operator) {
            case Comparator.Equals: {
                return _f + ' eq ' + _v;
            }
            case Comparator.NotEquals: {
                return _f + ' ne ' + _v;
            }
            case Comparator.GreaterThan: {
                return _f + ' gt ' + _v;
            }
            case Comparator.GreaterThanOrEqual: {
                return _f + ' ge ' + _v;
            }
            case Comparator.LessThan: {
                return _f + ' lt ' + _v;
            }
            case Comparator.LessThanOrEQual: {
                return _f + ' le ' + _v;
            }
            case Comparator.Contains: {
                return "contains(" + _f + "," + _v + ")";
            }
            case Comparator.NotContains: {
                return "not contains(" + _f + "," + _v + ")";
            }
            case Comparator.StartsWith: {
                return "startswith(" + _f + "," + _v + ")";
            }
            case Comparator.NotStartsWith: {
                return "not startswith(" + _f + "," + _v + ")";
            }
            case Comparator.EndsWith: {
                return "endswith(" + _f + "," + _v + ")";
            }
            case Comparator.NotEndsWith: {
                return "not endswith(" + _f + "," + _v + ")";
            }
        }
        return result;
    }
    toFetcmXml() {
        if (this.operator == 100) {
            return '<condition attribute="ownerid" operator="eq-useroruserhierarchy" />';
        }
        if (this.operator == 101) {
            return '<condition attribute="ownerid" operator="eq-userteams" />';
        }
        var result = "";
        let _v = this.value;
        if (this.value != null) {
            if (typeof this.value == 'number') {
                _v = this.value.toString();
            }
            if (typeof this.value == 'boolean') {
                _v = this.value.valueOf() ? 'true' : 'false';
            }
            if (this.value != null && this.value.hasOwnProperty('value')) {
                _v = this.value.value;
            }
        }
        if (_v == null) {
            this.adjustOperation();
        }
        var op = "eq";
        switch (this.operator) {
            case Comparator.Contains:
                op = "like";
                _v = "%" + _v + "%";
                break;
            case Comparator.ContainsData:
                op = "not-null";
                break;
            case Comparator.DoesNotContainsData:
                op = "null";
                break;
            case Comparator.EndsWith:
                op = "like";
                _v = "%" + _v;
                null;
                break;
            case Comparator.Equals:
                op = "eq";
                break;
            case Comparator.GreaterThan:
                op = "gt";
                break;
            case Comparator.GreaterThanOrEqual:
                op = "ge";
                break;
            case Comparator.LessThan:
                op = "lt";
                break;
            case Comparator.LessThanOrEQual:
                op = "le";
                break;
            case Comparator.NotContains:
                op = "not-like";
                "%" + _v + "%";
                break;
            case Comparator.NotEndsWith:
                op = "not-like";
                "&" + _v;
                break;
            case Comparator.NotEquals:
                op = "ne";
                break;
            case Comparator.NotStartsWith:
                op = "not-like";
                _v = _v + "%";
                break;
            case Comparator.StartsWith:
                op = "like";
                _v = _v + "%";
                break;
            default: throw "condition type not supported in fetch xml " + this.operator;
        }
        var aliasString = "";
        if (this.alias != null) {
            aliasString = " entityname='" + this.alias + "'";
        }
        if (_v != null) {
            result += "<condition" + aliasString + " attribute='" + this.field + "' operator='" + op + "' value='" + _v + "' />";
        }
        else {
            result += "<condition" + aliasString + " attribute='" + this.field + "' operator='" + op + "' />";
        }
        return result;
    }
    adjustOperation() {
        if (this.operator == Comparator.Equals) {
            this.operator = Comparator.DoesNotContainsData;
        }
        else if (this.operator == Comparator.NotEquals) {
            this.operator = Comparator.ContainsData;
        }
        if (this.operator != Comparator.DoesNotContainsData && this.operator != Comparator.ContainsData) {
            throw "null in condition value is only supported for containsdata and doesnotdontainsdata:" + this.field + "/" + (this.alias != null ? "alias:" + this.alias : "") + "/" + this.operator;
        }
    }
}
class Condition {
    constructor(operator = Operator.And) {
        this.operator = Operator.And;
        this.operator = operator;
        this.filter = [];
        this.children = [];
    }
    where(field, opr, value = null) {
        let f = new Filter();
        f.field = field;
        f.value = value;
        f.operator = opr;
        this.filter.push(f);
        return this;
    }
    alias(alias, field, opr, value = null) {
        let f = new Filter();
        f.alias = alias;
        f.field = field;
        f.value = value;
        f.operator = opr;
        this.filter.push(f);
        return this;
    }
    group(opr) {
        let result = new Condition(opr);
        result.parent = this;
        this.children.push(result);
        return result;
    }
    isActive() {
        return this.where("statecode", Comparator.Equals, 0);
    }
    isInactive() {
        return this.where("statecode", Comparator.Equals, 1);
    }
    owningUserIsCurrentUserOrHirachy() {
        return this.where("ownerid", 100);
    }
    currentUserIsMemberOfOwningTeam() {
        return this.where("ownerid", 101);
    }
    raw(filter) {
        let result = new Filter();
        result.field = filter;
        result["raw"] = true;
        this.filter.push(result);
        return this;
    }
    toQueryString(prototype) {
        if ((this.children == null || this.children.length == 0) && (this.filter == null || this.filter.length == 0)) {
            return null;
        }
        let me = this;
        let result = '';
        let opr = '';
        if (this.filter != null && this.filter.length > 0) {
            this.filter.forEach(r => {
                result += opr + r.toQueryString(prototype);
                if (me.operator == Operator.And) {
                    opr = ' and ';
                }
                else {
                    opr = ' or ';
                }
            });
        }
        if (this.children != null && this.children.length > 0) {
            this.children.forEach(c => {
                result += opr + "(" + c.toQueryString(prototype) + ")";
                if (me.operator == Operator.And) {
                    opr = ' and ';
                }
                else {
                    opr = ' or ';
                }
            });
        }
        return result;
    }
    toFetchXml() {
        let result = "";
        result += "<filter type='" + (this.operator == Operator.And ? "and" : "or") + "'>";
        if (this.filter != null && this.filter.length > 0)
            this.filter.forEach(f => {
                result += f.toFetcmXml();
            });
        if (this.children != null && this.children.length > 0) {
            this.children.forEach(c => {
                result += c.toFetchXml();
            });
        }
        result += "</filter>";
        return result;
    }
}
class XrmTransactionItem {
    constructor(type, prototype, instance, field = null, value = null) {
        this.id = null;
        this.type = type;
        this.prototype = prototype;
        this.instance = instance;
        this.field = field;
        this.value = value;
    }
}
class XrmTransaction {
    constructor() {
        this.oprs = [];
    }
    put(prototype, instance, field, value) {
        this.oprs.push(new XrmTransactionItem("put", prototype, instance, field, value));
    }
    delete(instance) {
        this.oprs.push(new XrmTransactionItem("delete", null, instance));
    }
    create(prototype, instance) {
        this.oprs.push(new XrmTransactionItem("create", prototype, instance));
    }
    update(prototype, instance) {
        this.oprs.push(new XrmTransactionItem("update", prototype, instance));
    }
}
class XrmAccess {
    constructor(lazy = false) {
        this.lazy = null;
        this.resolved = null;
        this.lazy = lazy;
    }
}
class ExpandProperty {
}
class XrmContextService {
    constructor(http, xrmService) {
        this.http = http;
        this.xrmService = xrmService;
        this.context = {};
        this.changemanager = {};
        this.tick = new Date().valueOf();
        this.includeOriginalPayload$ = false;
        this.pageCookieMatch = /[-pagingcookie=\"][a-z,A-Z,0-9,%-_.~]+/g;
    }
    setVersion(v) {
        this.xrmService.setVersion(v);
    }
    includeOroginalPayload(v) {
        this.includeOriginalPayload$ = v;
    }
    getContext() {
        return this.xrmService.getContext();
    }
    getCurrentKey(repeatForCreateForm = false) {
        return this.xrmService.getCurrentKey(repeatForCreateForm);
    }
    getServiceUrl() {
        return this.getContext().getClientUrl() + this.xrmService.apiUrl;
    }
    getCurrentUserId() {
        return this.xrmService.getCurrentUserId();
    }
    get(prototype, id) {
        let me = this;
        let columnDef = this.columnBuilder(prototype);
        let expand = null;
        let eps = this.getExpandProperties(prototype);
        if (eps != null && eps.length > 0) {
            let comma = ",";
            eps.forEach(ep => {
                if (expand == null) {
                    expand = this.$expandToExpand(ep);
                }
                else {
                    if (expand.additional == null) {
                        expand.additional = [];
                    }
                    expand.additional.push(this.$expandToExpand(ep));
                }
            });
        }
        return this.xrmService.get(prototype._pluralName, id, columnDef.columns, expand).pipe(map(r => {
            return me.resolve(prototype, r, prototype._updateable, null);
        }));
    }
    debug(setting) {
        this.xrmService.debug = setting;
    }
    count(xml) {
        let me = this;
        let headers = new HttpHeaders({ 'Accept': 'application/json' });
        if (this.xrmService.token != null) {
            headers = headers.append("Authorization", "Bearer " + this.xrmService.token);
        }
        headers = headers.append("OData-MaxVersion", "4.0");
        headers = headers.append("OData-Version", "4.0");
        headers = headers.append("Content-Type", "application/json; charset=utf-8");
        headers = headers.append("Prefer", "odata.include-annotations=\"*\"");
        headers = headers.append("Cache-Control", "no-cache");
        let options = {
            headers: headers
        };
        let fetchxml = xml.toCountFetchXml();
        let url = this.getContext().getClientUrl() + this.xrmService.apiUrl + xml.entity().entityPrototype._pluralName + "?fetchXml=" + encodeURIComponent(fetchxml);
        this.xrmService.log(fetchxml);
        this.xrmService.log(url);
        return new Observable(obs => {
            this.http.get(this.forceHTTPS(url), options).toPromise()
                .then(response => {
                if (response.value && response.value.length && response.value.length == 1) {
                    obs.next(response.value[0].count);
                }
                else {
                    obs.next(0);
                }
            })
                .catch(e => {
                if (e["error"] && e["error"]["error"] && e["error"]["error"]["code"]) {
                    var val = e["error"]["error"]["code"];
                    if (val != null && val.toString() == "0x8004e023") {
                        obs.next(50000);
                        return;
                    }
                }
                throwError(e);
            });
        });
    }
    fetch(xml) {
        let me = this;
        let headers = new HttpHeaders({ 'Accept': 'application/json' });
        if (this.xrmService.token != null) {
            headers = headers.append("Authorization", "Bearer " + this.xrmService.token);
        }
        headers = headers.append("OData-MaxVersion", "4.0");
        headers = headers.append("OData-Version", "4.0");
        headers = headers.append("Content-Type", "application/json; charset=utf-8");
        headers = headers.append("Prefer", "odata.include-annotations=\"*\"");
        headers = headers.append("Cache-Control", "no-cache");
        let options = {
            headers: headers
        };
        let fetchxml = xml.toFetchXml();
        let url = this.getContext().getClientUrl() + this.xrmService.apiUrl + xml.entity().entityPrototype._pluralName + "?fetchXml=" + encodeURIComponent(fetchxml);
        this.xrmService.log(fetchxml);
        this.xrmService.log(url);
        let localPrototype = xml.entity().entityPrototype;
        return this.http.get(this.forceHTTPS(url), options).pipe(map(response => {
            let result = me.resolveFetchResult(localPrototype, response, xml.count, [url], 0, xml);
            return result;
        }));
    }
    fetchxml(prototype, fetchxml) {
        let me = this;
        let headers = new HttpHeaders({ 'Accept': 'application/json' });
        if (this.xrmService.token != null) {
            headers = headers.append("Authorization", "Bearer " + this.xrmService.token);
        }
        headers = headers.append("OData-MaxVersion", "4.0");
        headers = headers.append("OData-Version", "4.0");
        headers = headers.append("Content-Type", "application/json; charset=utf-8");
        headers = headers.append("Prefer", "odata.include-annotations=\"*\"");
        headers = headers.append("Cache-Control", "no-cache");
        let options = {
            headers: headers
        };
        let url = this.getContext().getClientUrl() + this.xrmService.apiUrl + prototype._pluralName + "?fetchXml=" + encodeURIComponent(fetchxml);
        this.xrmService.log(fetchxml);
        this.xrmService.log(url);
        return this.http.get(this.forceHTTPS(url), options).pipe(map(response => {
            let result = me.resolveQueryResult(prototype, response, 0, [url], 0, null);
            return result;
        }));
    }
    query(prototype, condition, orderBy = null, top = 0, count = false) {
        let me = this;
        let fields = this.columnBuilder(prototype).columns;
        let con = condition;
        let filter = null;
        if (condition != null) {
            while (con.parent != null) {
                con = con.parent;
            }
            ;
            filter = con.toQueryString(prototype);
        }
        let headers = new HttpHeaders({ 'Accept': 'application/json' });
        if (this.xrmService.token != null) {
            headers = headers.append("Authorization", "Bearer " + this.xrmService.token);
        }
        headers = headers.append("OData-MaxVersion", "4.0");
        headers = headers.append("OData-Version", "4.0");
        headers = headers.append("Content-Type", "application/json; charset=utf-8");
        headers = headers.append("Prefer", "odata.include-annotations=\"*\"");
        if (top > 0) {
            headers = headers.append("Prefer", "odata.maxpagesize=" + top.toString());
        }
        headers = headers.append("Cache-Control", "no-cache");
        let options = {
            headers: headers
        };
        let url = this.getContext().getClientUrl() + this.xrmService.apiUrl + prototype._pluralName;
        if ((fields != null && fields != '') || (filter != null && filter != '') || (orderBy != null && orderBy != '') || top > 0) {
            url += "?";
        }
        let sep = '';
        if (fields != null && fields != '') {
            url += '$select=' + fields;
            sep = '&';
        }
        if (filter != null && filter != '') {
            url += sep + '$filter=' + filter;
            sep = '&';
        }
        if (orderBy != null && orderBy != '') {
            url += sep + '$orderby=' + orderBy;
            sep = '&';
        }
        if (count) {
            url += sep + '$count=true';
            sep = '&';
        }
        this.xrmService.log(url);
        return this.http.get(this.forceHTTPS(url), options).pipe(map(response => {
            let result = me.resolveQueryResult(prototype, response, top, [url], 0, null);
            return result;
        }));
    }
    create(prototype, instance) {
        let newr = this.prepareNewInstance(prototype, instance);
        this.xrmService.log(newr);
        return this.xrmService.create(prototype._pluralName, newr).pipe(map(_response => {
            let response = _response;
            this.xrmService.log(response);
            if (response != null) {
                if (response.hasOwnProperty('$keyonly')) {
                    instance._pluralName = prototype._pluralName;
                    instance._logicalName = prototype._logicalName;
                    instance._keyName = prototype._keyName;
                    instance.id = _response.id;
                    instance._updateable = true;
                    let key = response._pluralName + ':' + response.id;
                    for (let prop in prototype) {
                        if (typeof prototype[prop] === 'function') {
                            response[prop] = prototype[prop];
                            continue;
                        }
                    }
                    this.context[key] = instance;
                    this.updateCM(prototype, instance);
                    return instance;
                }
                else {
                    this.resolveNewInstance(prototype, instance, response);
                    return this.resolve(prototype, response, true, null);
                }
            }
            return null;
        }));
    }
    createAll(prototype, instances) {
        if (prototype != null && instances != null && instances.length > 0) {
            let trans = new XrmTransaction();
            instances.forEach(r => {
                trans.create(prototype, r);
            });
            return this.commit(trans);
        }
        throw "You must parse a prototype and at least one instance to be created";
    }
    update(prototype, instance, deleteReferenceAsEmptyGuid = false) {
        let me = this;
        let upd = this.prepareUpdate(prototype, instance, deleteReferenceAsEmptyGuid);
        if (upd == null) {
            upd = {};
        }
        this.xrmService.log(upd);
        let fields = this.columnBuilder(prototype).columns;
        return this.xrmService.update(prototype._pluralName, upd, instance.id, fields).pipe(map(response => {
            var wasnull = response[prototype._keyName] == null || response[prototype._keyName] == '';
            if (wasnull || this.getContext().getVersion().startsWith("8.0") || this.getContext().getVersion().startsWith("8.1")) {
                this.xrmService.log('version 8.0 update');
                this.updateCM(prototype, instance);
                return instance;
            }
            this.xrmService.log('version 9.0 or higher update');
            return me.resolve(prototype, response, true, null);
        }));
    }
    put(prototype, instance, field, value = 'ko-@value-not-parsed!') {
        let v = value;
        if (value == 'ko-@value-not-parsed!') {
            v = instance[field];
        }
        let pvx = this.preparePutValue(prototype, field, v);
        return this.xrmService.put(prototype._pluralName, instance.id, pvx.field, pvx.value, pvx.propertyAs).pipe(map(response => {
            if (value != 'ko-@value-not-parsed!') {
                this.assignValue(prototype, instance, field, value);
                return null;
            }
        }));
    }
    putAll(prototype, instances, field, value) {
        if (instances != null && instances.length == 1) {
            return this.put(prototype, instances[0], field, value);
        }
        if (instances != null && instances.length > 1) {
            let trans = new XrmTransaction();
            let pvx = this.preparePutValue(prototype, field, value);
            instances.forEach(r => {
                trans.put(prototype, r, field, pvx);
            });
            return this.commit(trans);
        }
        throw 'you must parse at least one instance in the instances array';
    }
    delete(t) {
        let me = this;
        return this.xrmService.delete(t._pluralName, t.id).pipe(map(r => {
            let key = t._pluralName + ":" + t.id;
            if (me.context.hasOwnProperty(key)) {
                delete me.context[key];
            }
            return null;
        }));
    }
    deleteAll(instances) {
        if (instances != null && instances.length == 1) {
            return this.delete(instances[0]);
        }
        if (instances != null && instances.length > 0) {
            let trans = new XrmTransaction();
            instances.forEach(r => {
                trans.delete(r);
            });
            return this.commit(trans);
        }
        throw 'you must parse at least one instance in the instances array';
    }
    markChangesCommitted(prototype, instance) {
        this.updateCM(prototype, instance);
    }
    func(name, data, entity = null) {
        var parameters = data;
        if (parameters != null) {
            parameters = this.toFuncParameterString(data);
        }
        if (entity == null) {
            return this.xrmService.func(name, parameters);
        }
        else {
            return this.xrmService.func(name, parameters, entity._pluralName, entity.id);
        }
    }
    action(name, data, entity = null) {
        if (entity != null) {
            return this.xrmService.action(name, data, entity._pluralName, entity.id);
        }
        else {
            return this.xrmService.action(name, data);
        }
    }
    commit(transaction) {
        let oprs = transaction["oprs"];
        if (oprs != null && oprs.length > 0) {
            this.tick++;
            let batch = 'batch_KO' + new Date().valueOf() + "$" + this.tick.toString();
            let change = 'changeset_KO' + new Date().valueOf() + "!" + this.tick.toString();
            let headers = new HttpHeaders({ 'Accept': 'application/json' });
            if (this.xrmService.token != null) {
                headers = headers.append("Authorization", "Bearer " + this.xrmService.token);
            }
            headers = headers.append("Content-Type", "multipart/mixed;boundary=" + batch);
            headers = headers.append("OData-MaxVersion", "4.0");
            headers = headers.append("OData-Version", "4.0");
            let body = '--' + batch + "\n";
            body += "Content-Type: multipart/mixed;boundary=" + change + "\n";
            body += "\n";
            let count = 1;
            oprs.forEach(r => {
                r.id = count;
                if (r.type == "put") {
                    let nextV = this.preparePutValue(r.prototype, r.field, r.value);
                    body += '--' + change + "\n";
                    body += "Content-Type: application/http\n";
                    body += "Content-Transfer-Encoding:binary\n";
                    body += "Content-ID: " + count.toString() + "\n";
                    body += "\n";
                    if (nextV.value != null) {
                        body += "PUT " + this.getContext().$devClientUrl() + r.prototype._pluralName + "(" + r.instance.id + ")/" + nextV.field + " HTTP/1.1\n";
                    }
                    else {
                        body += "DELETE " + this.getContext().$devClientUrl() + r.instance._pluralName + "(" + r.instance.id + ")/" + nextV.field + " HTTP/1.1\n";
                    }
                    let xr = {};
                    if (nextV.value != null) {
                        xr[nextV.propertyAs] = nextV.value;
                    }
                    body += "Content-Type: application/json;type=entry\n";
                    body += "\n";
                    body += JSON.stringify(xr) + "\n";
                }
                if (r.type == "delete") {
                    body += '--' + change + "\n";
                    body += "Content-Type: application/http\n";
                    body += "Content-Transfer-Encoding:binary\n";
                    body += "Content-ID: " + count.toString() + "\n";
                    body += "\n";
                    body += "DELETE " + this.getContext().$devClientUrl() + r.instance._pluralName + "(" + r.instance.id + ")" + " HTTP/1.1\n";
                    body += "Content-Type: application/json;type=entry\n";
                    body += "\n";
                    body += "{ }\n";
                }
                if (r.type == "create") {
                    let nextI = this.prepareNewInstance(r.prototype, r.instance);
                    body += '--' + change + "\n";
                    body += "Content-Type: application/http\n";
                    body += "Content-Transfer-Encoding:binary\n";
                    body += "Content-ID: " + count.toString() + "\n";
                    body += "\n";
                    body += "POST " + this.getContext().$devClientUrl() + r.prototype._pluralName + " HTTP/1.1\n";
                    body += "Content-Type: application/json;type=entry\n";
                    body += "\n";
                    body += JSON.stringify(nextI) + "\n";
                }
                if (r.type == "update") {
                    let nextU = this.prepareUpdate(r.prototype, r.instance, false);
                    if (nextU != null) {
                        let fields = "?$select=" + this.columnBuilder(r.prototype).columns;
                        body += '--' + change + "\n";
                        body += "Content-Type: application/http\n";
                        body += "Content-Transfer-Encoding:binary\n";
                        body += "Content-ID: " + count.toString() + "\n";
                        body += "\n";
                        body += "PATCH " + this.getContext().$devClientUrl() + r.prototype._pluralName + "(" + r.instance.id + ")" + fields + " HTTP/1.1\n";
                        body += "Content-Type: application/json;type=entry\n";
                        body += "\n";
                        body += JSON.stringify(nextU) + "\n";
                    }
                }
                count++;
            });
            body += '--' + change + '--\n';
            body += "\n";
            body += "--" + batch + "--\n";
            this.xrmService.log(body);
            let url = this.getContext().getClientUrl() + this.xrmService.apiUrl + "$batch";
            this.xrmService.log(url);
            return this.http.post(this.forceHTTPS(url), body, { headers: headers, responseType: "text" }).pipe(map(_txt => {
                let txt = _txt;
                this.xrmService.log(txt);
                oprs.forEach(r => {
                    if (r.type == 'put') {
                        this.assignValue(r.prototype, r.instance, r.field, r.value);
                        this.updateCM(r.prototype, r.instance);
                    }
                    if (r.type == 'update') {
                        this.updateCM(r.prototype, r.instance);
                    }
                    if (r.type == 'delete') {
                        let key = r.instance._pluralName + ':' + r.instance.id;
                        delete this.context[key];
                        delete this.changemanager[key];
                    }
                });
                let index = 0;
                txt.split('\n').forEach(l => {
                    if (l.startsWith('Content-ID:')) {
                        index = Number(l.split(':')[1].trim());
                        return true;
                    }
                    if (l.startsWith('OData-EntityId:')) {
                        let opr = oprs.find(o => o.id == index);
                        if (opr != null && opr.type == 'create') {
                            let id = l.split('OData-EntityId:')[1].split('/' + opr.prototype._pluralName + '(')[1].replace(')', '').trim();
                            opr.instance.id = id;
                            let key = opr.prototype._pluralName + ':' + opr.instance.id;
                            this.context[key] = opr.instance;
                            opr.instance._updateable = true;
                            this.updateCM(opr.prototype, opr.instance);
                        }
                    }
                    return true;
                });
                return null;
            }));
        }
        throw 'you must parse at least one operation to the transaction by calling put, create, update or delete';
    }
    log(type) {
        if (type == 'context') {
            this.xrmService.log(this.context);
            return;
        }
        if (type == 'xrmcontext') {
            this.xrmService.log(this.getContext());
            return;
        }
        if (type == 'url') {
            this.xrmService.log(this.getContext().getClientUrl());
        }
        if (type == 'version') {
            this.xrmService.log(this.getContext().getVersion());
        }
        this.xrmService.log('xrmContextService supported the current log types: context, xrmcontext, url, version');
    }
    clone(prototype, instance) {
        let r = new Entity(prototype._pluralName, prototype._keyName);
        for (let prop in prototype) {
            if (prototype.ignoreColumn(prop))
                continue;
            let pv = prototype[prop];
            if (typeof pv == 'function') {
                r[prop] = pv;
                continue;
            }
            let v = instance[prop];
            if (v == null) {
                r[prop] = null;
                continue;
            }
            if (v instanceof Date) {
                r[prop] = new Date(v.valueOf());
                continue;
            }
            if (v instanceof EntityReference) {
                r[prop] = v.clone();
                continue;
            }
            if (v instanceof OptionSetValue) {
                r[prop] = v.clone();
                continue;
            }
            if (v != null) {
                r[prop] = v;
            }
        }
        r.id = null;
        this.xrmService.log('clone');
        this.xrmService.log(r);
        return r;
    }
    applyAccess(prototype, instance) {
        if (!prototype.hasOwnProperty('access'))
            throw 'The metadata must define a property "access" of type XrmAccess';
        if (instance.hasOwnProperty('access') && instance['access']['resolved']) {
            return Observable.create(obs => obs.next(instance));
        }
        return this.mapAccess(prototype, instance);
    }
    prepareUpdate(prototype, instance, deletedReferenceAsEmptyGuid) {
        let me = this;
        let upd = {};
        let countFields = 0;
        let key = instance._pluralName + ':' + instance.id;
        let cm = this.changemanager[key];
        if (typeof cm === 'undefined' || cm === null) {
            throw 'the object is not under change control and cannot be updated within this context';
        }
        for (let prop in prototype) {
            if (prototype.hasOwnProperty(prop) && typeof prototype[prop] != 'function') {
                if (prototype.ignoreColumn(prop))
                    continue;
                let prevValue = cm[prop];
                let newValue = instance[prop];
                if ((prevValue === 'undefined' || prevValue === null) && (newValue === 'undefined' || newValue === null))
                    continue;
                if (instance[prop] instanceof EntityReference) {
                    if (instance[prop].associatednavigationproperty != null && instance[prop].associatednavigationproperty != '' && instance[prop]['pluralName'] != null && instance[prop]['pluralName'] != '') {
                        if (!EntityReference.same(prevValue, newValue)) {
                            if (deletedReferenceAsEmptyGuid && newValue != null && (newValue["id"] == null || newValue["id"] == '')) {
                                newValue["id"] = XRMCONTEXTSERVICE_EMPTY_GUID;
                            }
                            if (newValue != null && newValue["id"] != null && newValue["id"] != '') {
                                let x = newValue["id"];
                                x = x.replace('{', '').replace('}', '');
                                upd[instance[prop]['associatednavigationpropertyname']()] = '/' + instance[prop]['pluralName'] + '(' + x + ')';
                            }
                            else {
                                // this does not work, navigation properties can only be removed with SDK deleted method
                                upd["_" + instance[prop]['logicalname'].toLowerCase() + "_value"] = null;
                            }
                            countFields++;
                        }
                        continue;
                    }
                }
                if (prototype[prop] instanceof EntityReference) {
                    if (!EntityReference.same(prevValue, newValue)) {
                        if ((newValue == null || newValue["id"] == null || newValue["id"] == "") && deletedReferenceAsEmptyGuid) {
                            newValue["id"] = XRMCONTEXTSERVICE_EMPTY_GUID;
                        }
                        if (newValue != null && newValue["id"] != null && newValue["id"] != '') {
                            let x = newValue["id"];
                            x = x.replace('{', '').replace('}', '');
                            upd[prototype[prop]['associatednavigationpropertyname']()] = '/' + prototype[prop]['pluralName'] + '(' + x + ')';
                        }
                        else {
                            upd["_" + instance[prop]['logicalname'].toLowerCase() + "_value"] = null;
                        }
                        countFields++;
                    }
                    continue;
                }
                if (prototype[prop] instanceof OptionSetValue) {
                    if (!OptionSetValue.same(prevValue, newValue)) {
                        let o = newValue;
                        if (o == null || o.value == null) {
                            upd[prop.toString()] = null;
                        }
                        else {
                            upd[prop.toString()] = o.value;
                        }
                        countFields++;
                    }
                    continue;
                }
                if (prototype[prop] instanceof Date) {
                    if (prevValue instanceof Date && newValue instanceof Date) {
                        var d1 = prevValue.toISOString();
                        var d2 = newValue.toISOString();
                        if (d1 == d2) {
                            continue;
                        }
                    }
                    if (prevValue != newValue) {
                        this.xrmService.log('pre-value-update-date:[' + prevValue + ']/[' + newValue + ']');
                        if (newValue == null) {
                            upd[prop.toString()] = null;
                        }
                        else {
                            if (newValue instanceof Date) {
                                let d = newValue;
                                var sValue = d.toISOString();
                                if (sValue.indexOf("T00:00:00.000Z") > 0) {
                                    sValue = sValue.replace("T00:00:00.000Z", "");
                                }
                                upd[prop.toString()] = sValue;
                            }
                            else {
                                upd[prop.toString()] = newValue;
                            }
                        }
                        countFields++;
                    }
                    continue;
                }
                if (typeof prototype[prop] == "number") {
                    if (typeof newValue == "string") {
                        if (newValue == "") {
                            newValue = null;
                        }
                        else {
                            newValue = Number(newValue);
                            if (newValue == NaN) {
                                newValue = prevValue;
                            }
                        }
                    }
                    if (prevValue != newValue) {
                        upd[prop.toString()] = newValue;
                        countFields++;
                    }
                    continue;
                }
                if (prevValue === true && newValue === true) {
                    continue;
                }
                if (prevValue === false && newValue === false) {
                    continue;
                }
                if (prevValue != newValue) {
                    this.xrmService.log('pre-value-update:' + prop);
                    this.xrmService.log(prevValue);
                    this.xrmService.log('new-value-update:' + prop);
                    this.xrmService.log(newValue);
                    upd[prop.toString()] = instance[prop];
                    countFields++;
                }
            }
        }
        if (countFields > 0) {
            return upd;
        }
        return null;
    }
    /*
     * return an object that has been adjusted to patterns used in a webapi POST method. This is convinient in
     * combination with actions that uses parameters of type Entity, so the entity ex.
     */
    getCreatePayload(prototype, instance) {
        return this.prepareNewInstance(prototype, instance);
    }
    getUpdatePayload(prototype, instance, deletedReferenceAsEmptyGuid = false) {
        var next = this.prepareUpdate(prototype, instance, deletedReferenceAsEmptyGuid);
        if (next != null) {
            next[prototype._keyName] = instance.id;
            next["@odata.type"] = "Microsoft.Dynamics.CRM." + prototype._logicalName;
        }
        return next;
    }
    hasChanges(prototype, instance, deletedReferenceAsEmptyGuid = false) {
        return this.prepareUpdate(prototype, instance, deletedReferenceAsEmptyGuid) != null;
    }
    getEntityCollectionPayload(prototype, instances) {
        let result = [];
        instances.forEach(e => {
            let next = this.prepareNewInstance(prototype, e);
            if (e.id != null && e.id != '') {
                next[prototype._keyName] = e.id;
            }
            next["@odata.type"] = "Microsoft.Dynamics.CRM." + prototype._logicalName;
            result.push(next);
        });
        return result;
    }
    resolveAccess(prototype, instance) {
        var user = this.getContext().getUserId();
        if (user == null || user == '') {
            setTimeout(() => {
                this.resolveAccess(prototype, instance);
            }, 200);
            return;
        }
        this.mapAccess(prototype, instance).subscribe(r => { });
    }
    mapAccess(prototype, instance) {
        if (!prototype.hasOwnProperty('access') || !(prototype['access'] instanceof XrmAccess)) {
            return null;
        }
        if (!instance.hasOwnProperty('access')) {
            instance['access'] = new XrmAccess();
        }
        else {
            let r = instance['access'];
            if (r.resolved != null) {
                return null;
            }
        }
        var user = this.getContext().getUserId().replace('{', '').replace('}', '');
        let r = instance['access'];
        r.resolved = false;
        let headers = new HttpHeaders({ 'Accept': 'application/json' });
        if (this.xrmService.token != null) {
            headers = headers.append("Authorization", "Bearer " + this.xrmService.token);
        }
        headers = headers.append("OData-MaxVersion", "4.0");
        headers = headers.append("OData-Version", "4.0");
        headers = headers.append("Content-Type", "application/json; charset=utf-8");
        headers = headers.append("Prefer", "odata.include-annotations=\"*\"");
        headers = headers.append("Cache-Control", "no-cache");
        let url = this.getContext().getClientUrl() + this.xrmService.apiUrl + "systemusers(" + user + ")/Microsoft.Dynamics.CRM.RetrievePrincipalAccess(Target=@tid)?@tid={\"@odata.id\":\"" + prototype._pluralName + "(" + instance.id + ")\"}";
        this.xrmService.log(url);
        let _ta = instance['access'];
        _ta.resolved = null;
        return this.http.get(this.forceHTTPS(url), { headers: headers }).pipe(map(r => {
            this.xrmService.log(r);
            let i = instance['access'];
            let perm = r["AccessRights"];
            // ReadAccess, WriteAccess, AppendAccess, AppendToAccess, CreateAccess, DeleteAccess, ShareAccess, AssignAccess
            i.append = perm.indexOf('AppendAccess') >= 0;
            i.appendTo = perm.indexOf('AppendToAccess') >= 0;
            i.assign = perm.indexOf('AssignAccess') >= 0;
            i.create = perm.indexOf('CreateAccess') >= 0;
            i.delete = perm.indexOf('DeleteAccess') >= 0;
            i.read = perm.indexOf('ReadAccess') >= 0;
            i.share = perm.indexOf('ShareAccess') >= 0;
            i.write = perm.indexOf('WriteAccess') >= 0;
            i.resolved = true;
            return instance;
        }));
    }
    preparePutValue(prototype, field, value) {
        let t = prototype[field];
        if (t instanceof OptionSetValue) {
            if (value == null || value['value'] == null) {
                return { field: field, value: null, propertyAs: 'value' };
            }
            else {
                return { field: field, value: value['value'], propertyAs: 'value' };
            }
        }
        if (typeof t == 'number' && typeof value == 'string') {
            if (value == '') {
                value = null;
            }
            else {
                value = Number(value);
                if (value == NaN) {
                    value = null;
                }
            }
        }
        if (typeof t == 'number' && typeof value == 'number') {
            if (value == null) {
                return { field: field, value: null, propertyAs: null };
            }
            else {
                // this is a really really stupid hack, because dynamics do not accept Integer for decimal fields, so we force 
                // a decimal position into the value before it is send.
                let rv = value + t;
                return { field: field, value: rv, propertyAs: 'value' };
            }
        }
        if (t instanceof EntityReference) {
            field = t.associatednavigationpropertyname().split('@')[0] + "/$ref";
            if (value.id == null || value.id == '') {
                return { field: field, value: null, propertyAs: '@odata.id', isDefault: false };
            }
            else {
                return { field: field, value: this.getContext().$devClientUrl() + t.pluralName + "(" + value.id + ")", propertyAs: '@odata.id', isdecimal: false };
            }
        }
        if (value instanceof Date) {
            return { field: field, value: value.toISOString(), propertyAs: 'value' };
        }
        return { field: field, value: value, propertyAs: 'value' };
    }
    prepareNewInstance(prototype, instance) {
        let newr = {};
        for (let prop in prototype) {
            if (prototype.hasOwnProperty(prop) && typeof prototype[prop] !== 'function') {
                if (prototype.ignoreColumn(prop))
                    continue;
                let value = instance[prop];
                if (value !== 'undefined' && value !== null) {
                    if (instance[prop] instanceof EntityReference) {
                        if (instance[prop].associatednavigationproperty != null && instance[prop].associatednavigationproperty != '' && instance[prop]['pluralName'] != null && instance[prop]['pluralName'] != '') {
                            let ref = instance[prop];
                            if (ref != null && ref.id != null) {
                                newr[instance[prop]['associatednavigationpropertyname']()] = '/' + instance[prop]['pluralName'] + '(' + ref.id.replace('{', '').replace('}', '') + ')';
                            }
                            continue;
                        }
                    }
                    if (prototype[prop] instanceof EntityReference) {
                        let ref = instance[prop];
                        if (ref != null && ref.id != null) {
                            newr[prototype[prop]['associatednavigationpropertyname']()] = '/' + prototype[prop]['pluralName'] + '(' + ref.id.replace('{', '').replace('}', '') + ')';
                        }
                        continue;
                    }
                    if (prototype[prop] instanceof OptionSetValue) {
                        let o = instance[prop];
                        if (o != null && o.value != null) {
                            newr[prop.toString()] = o.value;
                        }
                        continue;
                    }
                    if (prototype[prop] instanceof Date) {
                        let d = value;
                        if (d != null) {
                            newr[prop.toString()] = d.toISOString();
                        }
                        continue;
                    }
                    if (typeof prototype[prop] == "number") {
                        if (typeof value == "string") {
                            if (value == "") {
                                continue;
                            }
                            value = Number(value);
                            if (value == NaN) {
                                continue;
                            }
                        }
                        newr[prop.toString()] = value;
                        continue;
                    }
                    newr[prop.toString()] = instance[prop];
                }
            }
        }
        return newr;
    }
    assignValue(prototype, instance, prop, value) {
        if (value != null) {
            instance[prop] = value;
            return;
        }
        let t = prototype[prop];
        if (t instanceof EntityReference) {
            instance[prop] = t.clone();
            return;
        }
        if (t instanceof OptionSetValue) {
            instance[prop] = new OptionSetValue();
            return;
        }
        instance[prop] = null;
    }
    $expandToExpand(prop) {
        if (prop != null) {
            let result = new Expand();
            result.name = prop.name;
            result.select = this.columnBuilder(prop.entity).columns;
            return result;
        }
        return null;
    }
    resolveFetchResult(prototype, response, top, pages, pageIndex, fetchXml) {
        let me = this;
        var result = this.resolveQueryResult(prototype, response, top, pages, pageIndex, fetchXml.entity().aliasWithAttributes());
        var pageCookie = response["@Microsoft.Dynamics.CRM.fetchxmlpagingcookie"];
        if (pageCookie != null && pageCookie != '') {
            this.xrmService.log('page-cookie');
            this.xrmService.log(pageCookie);
            var fragment = decodeURIComponent(decodeURIComponent(pageCookie.match(this.pageCookieMatch)[0].substring(14)));
            fragment = fragment.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\"/g, "&quot;");
            this.xrmService.log("page-cookie-fragment");
            this.xrmService.log(fragment);
            let fetchxml = fetchXml.toFetchXml(fragment, pageIndex + 2);
            result.nextLink = this.getContext().getClientUrl() + this.xrmService.apiUrl + prototype._pluralName + "?fetchXml=" + encodeURIComponent(fetchxml);
            result.next = () => {
                let headers = new HttpHeaders({ 'Accept': 'application/json' });
                if (this.xrmService.token != null) {
                    headers = headers.append("Authorization", "Bearer " + this.xrmService.token);
                }
                headers = headers.append("OData-MaxVersion", "4.0");
                headers = headers.append("OData-Version", "4.0");
                headers = headers.append("Content-Type", "application/json; charset=utf-8");
                headers = headers.append("Prefer", "odata.include-annotations=\"*\"");
                headers = headers.append("Cache-Control", "no-cache");
                let options = {
                    headers: headers
                };
                return this.http.get(this.forceHTTPS(result.nextLink), options).pipe(map(response => {
                    pages.push(result.nextLink);
                    let re = me.resolveFetchResult(prototype, response, top, pages, (pageIndex + 1), fetchXml);
                    return re;
                }));
            };
            if (pageIndex >= 1) {
                result.prev = () => {
                    let headers = new HttpHeaders({ 'Accept': 'application/json' });
                    if (this.xrmService.token != null) {
                        headers = headers.append("Authorization", "Bearer " + this.xrmService.token);
                    }
                    headers = headers.append("OData-MaxVersion", "4.0");
                    headers = headers.append("OData-Version", "4.0");
                    headers = headers.append("Content-Type", "application/json; charset=utf-8");
                    headers = headers.append("Prefer", "odata.include-annotations=\"*\"");
                    headers = headers.append("Cache-Control", "no-cache");
                    let options = {
                        headers: headers
                    };
                    let lastPage = result.pages[result.pageIndex - 1];
                    return me.http.get(me.forceHTTPS(lastPage), options).pipe(map(r => {
                        result.pages.splice(result.pages.length - 1, 1);
                        let pr = me.resolveFetchResult(prototype, r, top, result.pages, result.pageIndex - 1, fetchXml);
                        return pr;
                    }));
                };
            }
        }
        return result;
    }
    resolveQueryResult(prototype, response, top, pages, pageIndex, alias) {
        let me = this;
        let result = {
            context: response["@odata.context"],
            count: response["@odata.count"],
            value: [],
            pages: pages,
            pageIndex: pageIndex,
            top: top,
            nextLink: null,
            prev: null,
            next: null
        };
        let vals = response["value"];
        vals.forEach(r => {
            result.value.push(me.resolve(prototype, r, prototype._updateable, alias));
        });
        let nextLink = response["@odata.nextLink"];
        if (nextLink != null && nextLink != '') {
            let start = nextLink.indexOf('/api');
            nextLink = me.getContext().getClientUrl() + nextLink.substring(start);
            result = {
                context: result.context,
                count: result.count,
                value: result.value,
                pages: pages,
                pageIndex: pageIndex,
                top: top,
                nextLink: nextLink,
                prev: null,
                next: () => {
                    let headers = new HttpHeaders({ 'Accept': 'application/json' });
                    if (this.xrmService.token != null) {
                        headers = headers.append("Authorization", "Bearer " + this.xrmService.token);
                    }
                    headers = headers.append("OData-MaxVersion", "4.0");
                    headers = headers.append("OData-Version", "4.0");
                    headers = headers.append("Content-Type", "application/json; charset=utf-8");
                    if (top > 0) {
                        headers = headers.append("Prefer", "odata.include-annotations=\"*\",odata.maxpagesize=" + top.toString());
                    }
                    else {
                        headers = headers.append("Prefer", "odata.include-annotations=\"*\"");
                    }
                    headers = headers.append("Cache-Control", "no-cache");
                    let options = {
                        headers: headers
                    };
                    return me.http.get(me.forceHTTPS(nextLink), options).pipe(map(r => {
                        pages.push(nextLink);
                        let pr = me.resolveQueryResult(prototype, r, top, pages, pageIndex + 1, alias);
                        return pr;
                    }));
                }
            };
        }
        if (result.pageIndex >= 1) {
            result.prev = () => {
                let headers = new HttpHeaders({ 'Accept': 'application/json' });
                if (this.xrmService.token != null) {
                    headers = headers.append("Authorization", "Bearer " + this.xrmService.token);
                }
                headers = headers.append("OData-MaxVersion", "4.0");
                headers = headers.append("OData-Version", "4.0");
                headers = headers.append("Content-Type", "application/json; charset=utf-8");
                headers = headers.append("Prefer", "odata.include-annotations=\"*\"");
                if (top > 0) {
                    headers = headers.append("Prefer", "odata.maxpagesize=" + top.toString());
                }
                else {
                }
                headers = headers.append("Cache-Control", "no-cache");
                let options = {
                    headers: headers
                };
                let lastPage = result.pages[result.pageIndex - 1];
                return me.http.get(me.forceHTTPS(lastPage), options).pipe(map(r => {
                    result.pages.splice(result.pages.length - 1, 1);
                    let pr = me.resolveQueryResult(prototype, r, top, result.pages, result.pageIndex - 1, alias);
                    return pr;
                }));
            };
        }
        return result;
    }
    resolveNewInstance(prototype, instance, result) {
        let key = prototype._pluralName + ':' + instance[prototype._keyName];
        instance["id"] = result[prototype._keyName];
        instance["_pluralName"] = prototype._pluralName;
        instance["_logicalName"] = prototype._logicalName;
        instance["_keyName"] = prototype._keyName;
        this.context[key] = instance;
    }
    resolve(prototype, instance, updateable, alias) {
        let me = this;
        this.xrmService.log(instance);
        let key = prototype._pluralName + ':' + instance[prototype._keyName];
        let result = {};
        if (this.context.hasOwnProperty(key)) {
            result = this.context[key];
        }
        else {
            this.context[key] = result;
            result["id"] = instance[prototype._keyName];
            result["_pluralName"] = prototype._pluralName;
            result["_logicalName"] = prototype._logicalName;
            result["_keyName"] = prototype._keyName;
            delete result[prototype._keyName];
        }
        if (this.includeOriginalPayload$) {
            result["_original$"] = instance;
        }
        else {
            if (result.hasOwnProperty("_original$")) {
                delete result["_original$"];
            }
        }
        result['_updateable'] = updateable;
        for (let prop in prototype) {
            if (prototype.ignoreColumn(prop))
                continue;
            if (prototype.hasOwnProperty(prop) && typeof prototype[prop] != 'function') {
                let done = false;
                if (prototype[prop] instanceof EntityReference) {
                    let ref = new EntityReference();
                    let id = instance["_" + prop + "_value"];
                    if (id != null && id != 'undefined') {
                        ref.id = id.toLowerCase();
                        delete result["_" + prop + "_value"];
                        ref.logicalname = instance["_" + prop + "_value@Microsoft.Dynamics.CRM.lookuplogicalname"];
                        delete instance["_" + prop + "_value@Microsoft.Dynamics.CRM.lookuplogicalname"];
                        ref.name = instance["_" + prop + "_value@OData.Community.Display.V1.FormattedValue"];
                        delete instance["_" + prop + "_value@OData.Community.Display.V1.FormattedValue"];
                        ref.associatednavigationproperty = instance["_" + prop + "_value@Microsoft.Dynamics.CRM.associatednavigationproperty"];
                        delete instance["_" + prop + "_value@Microsoft.Dynamics.CRM.associatednavigationproperty"];
                    }
                    result[prop] = ref;
                    done = true;
                }
                if (!done && prototype[prop] instanceof OptionSetValue) {
                    let opt = new OptionSetValue();
                    opt.value = instance[prop];
                    opt.name = instance[prop + '@OData.Community.Display.V1.FormattedValue'];
                    result[prop] = opt;
                    done = true;
                }
                if (!done && prototype[prop] instanceof Date) {
                    let v = instance[prop];
                    if (v != null && v != '') {
                        result[prop] = new Date(Date.parse(v));
                    }
                    else {
                        result[prop] = null;
                    }
                    done = true;
                }
                if (!done) {
                    result[prop] = instance[prop];
                    done = true;
                }
            }
        }
        var names = Object.getOwnPropertyNames(Object.getPrototypeOf(prototype));
        names.forEach(r => {
            if (r != 'constructor' && typeof prototype[r] === 'function') {
                result[r] = prototype[r];
            }
        });
        let eps = this.getExpandProperties(prototype);
        if (eps != null && eps.length > 0) {
            eps.forEach(ep => {
                if (ep != null) {
                    if (ep.isArray) {
                        let _v = instance[ep.name];
                        if (_v != null && Array.isArray(_v)) {
                            let _tmp = [];
                            _v.forEach(_r => {
                                _tmp.push(me.resolve(ep.entity, _r, false, alias));
                            });
                            result[ep.name] = _tmp;
                            if (ep.value instanceof Entities) {
                                _tmp["add"] = ep.value["add"];
                                _tmp["remove"] = ep.value["remove"];
                                _tmp["xrmService"] = this.xrmService;
                                _tmp["parentType"] = prototype._pluralName;
                                _tmp["parentId"] = result["id"];
                                _tmp["childType"] = ep.value["childType"];
                                _tmp["refName"] = ep.value["refName"];
                                _tmp["leftToRight"] = ep.value["leftToRight"];
                            }
                        }
                    }
                    else {
                        let _v = instance[ep.name];
                        if (_v != null) {
                            result[ep.name] = this.resolve(ep.entity, _v, false, alias);
                            result[ep.name]['_keyName'] = ep.entity._keyName;
                            result[ep.name]['_pluralName'] = ep.entity._pluralName;
                            result[ep.name]['_logicalName'] = ep.entity._logicalName;
                        }
                    }
                }
            });
        }
        if (alias != null && alias.length > 0) {
            alias.forEach(a => {
                for (var p in result) {
                    if (p.startsWith(a + ".")) {
                        delete result[p];
                    }
                }
                for (var p in instance) {
                    if (p.startsWith(a + '.')) {
                        result[p] = instance[p];
                    }
                }
            });
        }
        if (result['onFetch'] !== 'undefined' && result["onFetch"] != null && typeof result["onFetch"] === 'function') {
            result['onFetch']();
        }
        if (prototype.hasOwnProperty('access') && !prototype['access']['lazy']) {
            if (!result.hasOwnProperty('access') || result.access.resolved == null) {
                this.resolveAccess(prototype, result);
            }
        }
        if (updateable) {
            this.updateCM(prototype, result);
        }
        return result;
    }
    updateCM(prototype, instance) {
        let key = prototype._pluralName + ':' + instance['id'];
        let change = {};
        this.xrmService.log('Adding to cm ' + key);
        this.changemanager[key] = change;
        for (let prop in prototype) {
            if (prototype.ignoreColumn(prop))
                continue;
            if (prototype.hasOwnProperty(prop) && typeof prototype[prop] != 'function') {
                let v = instance[prop];
                if (v == null)
                    continue;
                let done = false;
                if (v instanceof EntityReference) {
                    change[prop] = v.clone();
                    done = true;
                }
                if (!done && v instanceof OptionSetValue) {
                    change[prop] = v.clone();
                    done = true;
                }
                if (!done && v instanceof Date) {
                    change[prop] = new Date(v.valueOf());
                    done = true;
                }
                if (!done) {
                    change[prop] = v;
                    done = true;
                }
            }
        }
        this.xrmService.log(change);
    }
    columnBuilder(entity) {
        let result = new ColumnBuilder();
        var columns = entity.columns(true);
        result.columns = columns.join(",");
        result.hasEntityReference = columns.filter(r => r.startsWith("_") && r.endsWith("_value")).length > 0;
        return result;
    }
    getExpandProperties(entity) {
        var result = [];
        for (var prop in entity) {
            if (prop == entity._keyName)
                continue;
            if (entity.ignoreColumn(prop))
                continue;
            let _v = entity[prop];
            if (Array.isArray(_v)) {
                if (_v.length > 0) {
                    let pt = _v[0];
                    result.push({
                        name: prop,
                        entity: pt,
                        isArray: true,
                        value: _v
                    });
                }
            }
            else {
                if (_v instanceof Entity) {
                    result.push({
                        name: prop,
                        entity: _v,
                        isArray: false,
                        value: _v
                    });
                }
            }
        }
        return result;
    }
    toFuncParameterString(pam) {
        if (typeof pam === "string")
            return pam;
        let r = '(';
        var ix = 1;
        var cm = '';
        for (var p in pam) {
            if (pam.hasOwnProperty(p)) {
                r += cm + p + "=@p" + ix;
                ix++;
                cm = ',';
            }
        }
        r += ')';
        ix = 1;
        cm = '?';
        for (var p in pam) {
            if (pam.hasOwnProperty(p)) {
                r += cm + '@p' + ix + "=";
                ix++;
                cm = "&";
                var v = pam[p];
                if (v == null) {
                    v = '';
                    r += v;
                    continue;
                }
                var valueWrapper = v["functionPropertyValueAsString"];
                if (valueWrapper != null) {
                    r += valueWrapper.call(v);
                    continue;
                }
                if (v.hasOwnProperty("toJsonProperty")) {
                    v = v["toJsonProperty"]();
                }
                if (v instanceof Date) {
                    r += v.toISOString();
                    continue;
                }
                if (typeof v === "number") {
                    r += v.toString();
                    continue;
                }
                if (typeof v === "boolean") {
                    r += v ? "true" : "false";
                    continue;
                }
                if (typeof v === "string") {
                    r += "'" + v + "'";
                    continue;
                }
                r += JSON.stringify(this.transform(v));
            }
        }
        return r;
    }
    transform(input) {
        var transformed = false;
        var result = {};
        for (var pam in input) {
            if (input.hasOwnProperty(pam)) {
                var value = input[pam];
                if (value != null && value.hasOwnProperty("toJsonProperty")) {
                    result[pam] = value["toJsonProperty"]();
                    transformed = true;
                }
                else {
                    result[pam] = value;
                }
            }
        }
        if (!transformed) {
            return input;
        }
        return result;
    }
    forceHTTPS(v) {
        return this.xrmService.forceHTTPS(v);
    }
}
XrmContextService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmContextService, deps: [{ token: i1.HttpClient }, { token: XrmService }], target: i0.ɵɵFactoryTarget.Injectable });
XrmContextService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmContextService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmContextService, decorators: [{
            type: Injectable
        }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: XrmService }]; } });

class LabelMeta {
}
class DisplayNameMeta {
}
class EntityMeta extends Entity {
    constructor() {
        super("EntityDefinitions", "MetadataId");
        this.DisplayName = null;
        this.LogicalName = null;
        this.ObjectTypeCode = null;
        this.SchemaName = null;
        this.LogicalCollectionName = null;
        this.IsActivity = null;
        this.IsActivityParty = null;
        this.Attributes = null;
    }
    meta() {
        this.Attributes = [new AttributeMeta()];
        return this;
    }
}
class AttributeMeta extends Entity {
    constructor() {
        super("Attributes", "MetadataId");
        this.AttributeType = null;
        this.DisplayName = null;
        this.LogicalName = null;
        this.Description = null;
        this.SchemaName = null;
    }
    onFetch() {
        this.selected = false;
    }
}
class OneToManyRelationship {
    constructor() {
        this.MetadataId = null;
        this.RelationshipType = null;
        this.SchemaName = null;
        this.ReferencedAttribute = null;
        this.ReferencingAttribute = null;
        this.ReferencedEntity = null;
        this.ReferencingEntity = null;
    }
}
class ManyToManyRelationship {
    constructor() {
        this.MetadataId = null;
        this.Entity1LogicalName = null;
        this.Entity1NavigationPropertyName = null;
        this.Entity2LogicalName = null;
        this.Entity2NavigationPropertyName = null;
        this.SchemaName = null;
        this.RelationshipType = null;
        this.Other = null;
        this.OtherSchemaName = null;
        this.Entity1LogicalCollectionName = null;
        this.Entity2LogicalCollectionName = null;
    }
}
class LookupAttribute {
}
class AttributeOptionsetMeta {
}
class OptionSetMeta {
}
class OptionSetMetaValue {
}
class OptionsetLabelMeta {
}
class OptionsetLabel {
}
class XrmMetadataService {
    constructor(http, xrmService) {
        this.http = http;
        this.xrmService = xrmService;
        this.searchEntityMetaPrototype = new EntityMeta();
        this.getEntityMetaPrototype = new EntityMeta().meta();
    }
    search(name, unique = false) {
        let con = new Condition();
        if (!unique) {
            con
                .where("LogicalCollectionName", Comparator.ContainsData)
                .where("LogicalName", Comparator.ContainsData);
        }
        else {
            con.where("LogicalName", Comparator.Equals, name);
        }
        return this.xrmService.query(this.searchEntityMetaPrototype, con).pipe(map(_r => {
            let r = _r;
            if (name != null && name != '') {
                let _s = name.toLowerCase();
                let ma = [];
                // Metadata api does not support contains - therefore client site filter
                r.value.forEach(e => {
                    if (e != null && e.LogicalName != null && e.LogicalName.toLowerCase().indexOf(_s) >= 0) {
                        ma.push(e);
                    }
                });
                r.value = ma;
            }
            r.value = r.value.sort((a, b) => a.LogicalName.toLowerCase().localeCompare(b.LogicalName.toLowerCase()));
            return _r;
        }));
    }
    get(id) {
        return this.xrmService.get(this.getEntityMetaPrototype, id).pipe(map(_r => {
            let r = _r;
            if (r.Attributes != null && r.Attributes.length > 0) {
                r.Attributes = r.Attributes.sort((a, b) => {
                    if (a.LogicalName == null && b.LogicalName != null)
                        return 1;
                    if (a.LogicalName != null && b.LogicalName == null)
                        return -1;
                    if (a.LogicalName == null && b.LogicalName == null)
                        return 0;
                    return a.LogicalName.toLowerCase().localeCompare(b.LogicalName.toLowerCase());
                });
            }
            return r;
        }));
    }
    getManyToManyRelationships(entity) {
        let headers = new HttpHeaders({ 'Accept': 'application/json' });
        headers = headers.append("OData-MaxVersion", "4.0");
        headers = headers.append("OData-Version", "4.0");
        headers = headers.append("Content-Type", "application/json; charset=utf-8");
        headers = headers.append("Prefer", "odata.include-annotations=*");
        let options = {
            headers: headers
        };
        return this.http.get(this.xrmService.getServiceUrl() + 'EntityDefinitions(' + entity.id + ')' + '/ManyToManyRelationships?$select=MetadataId,Entity1LogicalName,Entity1NavigationPropertyName,Entity2LogicalName,Entity2NavigationPropertyName,SchemaName,RelationshipType', options)
            .pipe(map(response => {
            entity.ManyToManyRelations = response["value"];
            entity.ManyToManyRelations.forEach(r => {
                if (r.Entity1LogicalName == entity.LogicalName) {
                    r.Other = r.Entity2LogicalName;
                    r.OtherSchemaName = entity.SchemaName;
                    r.Entity1LogicalCollectionName = entity.LogicalCollectionName;
                }
                else {
                    r.Other = r.Entity1LogicalName;
                    r.Entity2LogicalCollectionName = entity.LogicalCollectionName;
                }
            });
            this.resolveRelationshipNames(entity.ManyToManyRelations);
            return entity;
        }));
    }
    resolveRelationshipNames(relations) {
        relations.forEach(r => {
            if (r.Entity1LogicalCollectionName == null) {
                this.search(r.Entity1LogicalName, true).subscribe(s => {
                    r.Entity1LogicalCollectionName = s.value[0].LogicalCollectionName;
                    if (r.Other == r.Entity1LogicalName) {
                        r.OtherSchemaName = s.value[0].SchemaName;
                    }
                });
            }
            if (r.Entity2LogicalCollectionName == null) {
                this.search(r.Entity2LogicalName, true).subscribe(s => {
                    r.Entity2LogicalCollectionName = s.value[0].LogicalCollectionName;
                    if (r.Other = r.Entity2LogicalName) {
                        r.OtherSchemaName = s.value[0].SchemaName;
                    }
                });
            }
        });
    }
    getOneToManyRelationships(entity) {
        let headers = new HttpHeaders({ 'Accept': 'application/json' });
        headers = headers.append("OData-MaxVersion", "4.0");
        headers = headers.append("OData-Version", "4.0");
        headers = headers.append("Content-Type", "application/json; charset=utf-8");
        headers = headers.append("Prefer", "odata.include-annotations=*");
        let options = {
            headers: headers
        };
        return this.http.get(this.xrmService.getServiceUrl() + 'EntityDefinitions(' + entity.id + ')' + '/OneToManyRelationships?$select=MetadataId,RelationshipType,SchemaName,ReferencedAttribute,ReferencingAttribute,ReferencedEntity,ReferencingEntity,ReferencingEntityNavigationPropertyName', options)
            .pipe(map(response => {
            entity.OneToManyRelations = response["value"];
            return entity;
        }));
    }
    getLookup(entity, attr) {
        if (attr.AttributeType == 'Lookup') {
            let headers = new HttpHeaders({ 'Accept': 'application/json' });
            headers = headers.append("OData-MaxVersion", "4.0");
            headers = headers.append("OData-Version", "4.0");
            headers = headers.append("Content-Type", "application/json; charset=utf-8");
            headers = headers.append("Prefer", "odata.include-annotations=*");
            let options = {
                headers: headers
            };
            return this.http.get(this.xrmService.getServiceUrl() + 'EntityDefinitions(' + entity.id + ')/Attributes(' + attr.id + ')/Microsoft.Dynamics.CRM.LookupAttributeMetadata?$select=Targets,LogicalName,SchemaName')
                .pipe(map(response => {
                attr.Lookup = response;
                return entity;
            }));
        }
        if (attr.AttributeType == 'Customer') {
            attr.Lookup = {
                LogicalName: attr.LogicalName,
                SchemaName: attr.SchemaName,
                Targets: ['account', 'contact']
            };
            return new Observable(o => {
                o.next(entity);
            });
        }
        throw 'unknown Lookup type ' + attr.AttributeType;
    }
    getPicklists(entity) {
        let headers = new HttpHeaders({ 'Accept': 'application/json' });
        headers = headers.append("OData-MaxVersion", "4.0");
        headers = headers.append("OData-Version", "4.0");
        headers = headers.append("Content-Type", "application/json; charset=utf-8");
        headers = headers.append("Prefer", "odata.include-annotations=*");
        let options = {
            headers: headers
        };
        return this.http.get(this.xrmService.getServiceUrl() + 'EntityDefinitions(LogicalName=\'' + entity.LogicalName + '\')/Attributes/Microsoft.Dynamics.CRM.PicklistAttributeMetadata?$select=LogicalName&$expand=OptionSet,GlobalOptionSet').pipe(map(r => r.value));
    }
}
XrmMetadataService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmMetadataService, deps: [{ token: i1.HttpClient }, { token: XrmContextService }], target: i0.ɵɵFactoryTarget.Injectable });
XrmMetadataService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmMetadataService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmMetadataService, decorators: [{
            type: Injectable
        }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: XrmContextService }]; } });

class KiponXrmserviceModule {
}
KiponXrmserviceModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: KiponXrmserviceModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
KiponXrmserviceModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.0.1", ngImport: i0, type: KiponXrmserviceModule, imports: [HttpClientModule] });
KiponXrmserviceModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: KiponXrmserviceModule, providers: [
        XrmAuthService,
        XrmService,
        XrmContextService,
        XrmStateService,
        XrmConfigService,
        XrmFormService
    ], imports: [HttpClientModule] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: KiponXrmserviceModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [
                        HttpClientModule
                    ],
                    declarations: [],
                    exports: [],
                    providers: [
                        XrmAuthService,
                        XrmService,
                        XrmContextService,
                        XrmStateService,
                        XrmConfigService,
                        XrmFormService
                    ]
                }]
        }] });

class Role extends Entity {
    constructor() {
        super('roles', 'roleid', true);
        this.businessunitid = new EntityReference().meta("businessunits", "businessunitid");
        this.name = null;
        this.parentroleid = new EntityReference().meta("roles", "parentroleid");
        this.parentrootroleid = new EntityReference().meta("roles", "parentrootroleid");
    }
    meta() {
        return this;
    }
}
class Team extends Entity {
    constructor() {
        super('teams', 'teamid', true);
        this.description = null;
        this.emailaddress = null;
        this.name = null;
        this.teamtype = new OptionSetValue();
    }
    meta() {
        return this;
    }
}
class SystemUser extends Entity {
    constructor() {
        super('systemusers', 'systemuserid', true);
        this.address1_name = null;
        this.address2_name = null;
        this.domainname = null;
        this.firstname = null;
        this.fullname = null;
        this.lastname = null;
        this.middlename = null;
        this.nickname = null;
    }
    hasRole(name) {
        if (this.systemuserroles_association != null && this.systemuserroles_association.length > 0) {
            for (var i = 0; i < this.systemuserroles_association.length; i++) {
                if (this.systemuserroles_association[i].name == name) {
                    return true;
                }
            }
        }
        return false;
    }
    memberOf(name) {
        if (this.teammembership_association != null && this.teammembership_association.length > 0) {
            for (var i = 0; i < this.teammembership_association.length; i++) {
                if (name == this.teammembership_association[i].name) {
                    return true;
                }
            }
        }
        return false;
    }
    onFetch() {
        this.roles = [];
        if (this.systemuserroles_association != null) {
            this.systemuserroles_association.forEach(r => {
                this.roles.push(r);
            });
        }
        this.teams = [];
        if (this.teammembership_association != null) {
            this.teammembership_association.forEach(t => {
                this.teams.push(t);
            });
        }
    }
    meta() {
        this.systemuserroles_association = new Entities('systemusers', 'roles', 'systemuserroles_association', true, new Role().meta());
        this.teammembership_association = new Entities('systemusers', 'teams', 'teammembership_association', false, new Team().meta());
        return this;
    }
}
class XrmSecurityService {
    constructor(xrmService) {
        this.xrmService = xrmService;
        this.rolePrototype = new Role().meta();
        this.teamPrototype = new Team().meta();
        this.userPrototype = new SystemUser().meta();
    }
    getUser(id) {
        return this.xrmService.get(this.userPrototype, id);
    }
    getCurrentUser() {
        return this.xrmService.getCurrentUserId().pipe(mergeMap(u => {
            return this.getUser(u);
        }));
    }
}
XrmSecurityService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmSecurityService, deps: [{ token: XrmContextService }], target: i0.ɵɵFactoryTarget.Injectable });
XrmSecurityService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmSecurityService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmSecurityService, decorators: [{
            type: Injectable
        }], ctorParameters: function () { return [{ type: XrmContextService }]; } });

class KiponXrmSecurityModule {
}
KiponXrmSecurityModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: KiponXrmSecurityModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
KiponXrmSecurityModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.0.1", ngImport: i0, type: KiponXrmSecurityModule });
KiponXrmSecurityModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: KiponXrmSecurityModule, providers: [
        XrmSecurityService
    ] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: KiponXrmSecurityModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [],
                    declarations: [],
                    exports: [],
                    providers: [
                        XrmSecurityService
                    ]
                }]
        }] });

class Annotation extends Entity {
    constructor() {
        super('annotations', 'annotationid', true);
        // 	annotationid:entity key column is always included, but name is converted to id
        this.filename = null;
        this.filesize = null;
        this.isdocument = null;
        this.notetext = null;
        this.objectid = new EntityReference().meta("accounts", "objectid_account");
        this.ownerid = new EntityReference().meta("systemusers", "ownerid");
        this.subject = null;
    }
    meta() {
        return this;
    }
}
class XrmAnnotationService {
    constructor(xrmService) {
        this.xrmService = xrmService;
        this.localPrototype = new Annotation().meta();
    }
    get(id) {
        return this.xrmService.get(this.localPrototype, id);
    }
    related(entity) {
        let condition = new Condition()
            .where('objectid', Comparator.Equals, entity.id)
            .where('objecttypecode', Comparator.Equals, entity._logicalName);
        return this.xrmService.query(this.localPrototype, condition);
    }
    add(entity, subject, body) {
        var anno = new Annotation();
        anno.isdocument = false;
        anno.subject = subject;
        anno.notetext = body;
        anno.objectid = new EntityReference().meta(entity._pluralName, "objectid_" + entity._logicalName);
        anno.objectid.id = entity.id;
        return this.xrmService.create(this.localPrototype, anno);
    }
    update(anno) {
        return this.xrmService.update(this.localPrototype, anno);
    }
    delete(anno) {
        return this.xrmService.delete(anno);
    }
}
XrmAnnotationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmAnnotationService, deps: [{ token: XrmContextService }], target: i0.ɵɵFactoryTarget.Injectable });
XrmAnnotationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmAnnotationService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: XrmAnnotationService, decorators: [{
            type: Injectable
        }], ctorParameters: function () { return [{ type: XrmContextService }]; } });

class KiponXrmAnnotationModule {
}
KiponXrmAnnotationModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: KiponXrmAnnotationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
KiponXrmAnnotationModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.0.1", ngImport: i0, type: KiponXrmAnnotationModule });
KiponXrmAnnotationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: KiponXrmAnnotationModule, providers: [
        XrmAnnotationService
    ] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: KiponXrmAnnotationModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [],
                    declarations: [],
                    exports: [],
                    providers: [
                        XrmAnnotationService
                    ]
                }]
        }] });

class KiponXrmMetadataModule {
}
KiponXrmMetadataModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: KiponXrmMetadataModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
KiponXrmMetadataModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.0.1", ngImport: i0, type: KiponXrmMetadataModule });
KiponXrmMetadataModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: KiponXrmMetadataModule, providers: [
        XrmMetadataService
    ] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: KiponXrmMetadataModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [],
                    declarations: [],
                    exports: [],
                    providers: [
                        XrmMetadataService
                    ]
                }]
        }] });

/*
 * Public API Surface of kipon-xrmservice
 */

/**
 * Generated bundle index. Do not edit.
 */

export { Annotation, AttributeMeta, AttributeOptionsetMeta, ColumnBuilder, Comparator, Condition, DisplayNameMeta, Entities, Entity, EntityMeta, EntityReference, Expand, FetchEntity, Fetchsort, Fetchxml, Filter, FunctionPropertyValue, KiponXrmAnnotationModule, KiponXrmMetadataModule, KiponXrmSecurityModule, KiponXrmserviceModule, LabelMeta, Link, LookupAttribute, ManyToManyRelationship, OneToManyRelationship, Operator, OptionSetValue, Role, SystemUser, Team, XrmAccess, XrmAnnotationService, XrmAuthService, XrmConfigService, XrmContextInstance, XrmContextService, XrmEntityKey, XrmFormKey, XrmFormService, XrmInterceptor, XrmMetadataService, XrmSecurityService, XrmService, XrmStateService, XrmTransaction };
//# sourceMappingURL=kipon-xrmservice.mjs.map