module openflow { "use strict"; class messagequeue { constructor( public msg: QueueMessage, public callback: any) { } } interface IHashTable { [key: string]: T; } export type mapFunc = () => void; export type reduceFunc = (key: string, values: any[]) => any; export type finalizeFunc = (key: string, value: any) => any; const getCircularReplacer = () => { const seen = new WeakSet(); return (key, value) => { if (typeof value === "object" && value !== null) { if (seen.has(value)) { return; } seen.add(value); } return value; }; }; export class api { static $inject = ["$rootScope", "$location", "WebSocketClient"]; public messageQueue: IHashTable = {}; constructor(public $rootScope: ng.IRootScopeService, public $location, public WebSocketClient: WebSocketClient) { var cleanup1 = this.$rootScope.$on('socketopen', (event, data) => { if (event && data) { } this.gettoken(); // cleanup(); }); // var cleanup2 = this.$rootScope.$on('cordovadetected', (event, data) => { // if (event && data) { } // console.log("cordovadetected, reload token"); // this.gettoken(); // cleanup2(); // }); ['log', 'warn', 'debug', 'error'].forEach((methodName) => { //['error2'].forEach((methodName) => { const originalMethod = console[methodName]; console[methodName] = (...args) => { let initiator = 'unknown place'; try { throw new Error(); } catch (e) { if (typeof e.stack === 'string') { let isFirst = true; for (const line of e.stack.split('\n')) { const matches = line.match(/^\s+at\s+(.*)/); if (matches) { if (!isFirst) { // first line - current function // second line - caller (what we are looking for) initiator = matches[1]; break; } isFirst = false; } } } } var _type = "message"; if (methodName == "warn") _type = "warning"; if (methodName == "debug") _type = "debug"; if (methodName == "error") _type = "error"; var a = args[0]; try { if (a == "[object Object]") { a = JSON.stringify(args[0]); } } catch (error) { } var log = { message: a, _type: _type, host: window.location.hostname, initiator: initiator }; this.Insert("jslog", log).catch(() => { }); //originalMethod.apply(console, [...args, `\n at ${initiator}`]); originalMethod.apply(console, [...args]); }; }); // console.log = (msg) => { // var log = { message: msg, _type: "message", host: window.location.hostname }; // this.Insert("jslog", log).catch(() => { }); // } // (function () { // var oldLog = console.log; // console.log = function (msg) { // var log = { message: msg, _type: "message", host: window.location.hostname }; // me.Insert("jslog", log).catch(() => { }); // // oldLog.apply(console, arguments); // console.trace.apply(console, arguments); // }; // })(); // console.log = function (test) { // // var log = { message: arguments, _type: "message", host: window.location.hostname }; // // me.Insert("jslog", log).catch(() => { }); // console.warn(test) // return Function.prototype.bind.call(console.log, console, "test"); // }(); // console.warn = (msg) => { // var log = { message: msg, _type: "warning", host: window.location.hostname }; // this.Insert("jslog", log).catch(() => { }); // } // console.debug = (msg) => { // formerdebug.apply(console, { arguments: arguments }); // // formerdebug(msg); // var log = { message: msg, _type: "debug", host: window.location.hostname }; // this.Insert("jslog", log).catch(() => { }); // } window.onerror = (message, url, linenumber) => { var log = { message: message, url: url, linenumber: linenumber, _type: "error", host: window.location.hostname }; this.Insert("jslog", log).catch(() => { }); } var cleanup = $rootScope.$on('queuemessage', (event, data: QueueMessage) => { if (event && data) { } if (this.messageQueue[data.correlationId] !== undefined) { this.messageQueue[data.correlationId].callback(data); delete this.messageQueue[data.correlationId]; } }); } gettoken() { this.WebSocketClient.getJSON("/jwt", async (error: any, data: any) => { try { if (data !== null && data !== undefined) { if (data.jwt === null || data.jwt === undefined || data.jwt.trim() === "") { data.jwt = null; } if (data.rawAssertion === null || data.rawAssertion === undefined || data.rawAssertion.trim() === "") { data.rawAssertion = null; } if (data.jwt === null && data.rawAssertion === null) { console.log("data.jwt and data.rawAssertion is null"); data = null; } } if (data === null || data === undefined) { if (this.$location.path() !== "/Login") { console.log("path: " + this.$location.path()); console.log("WebSocketClient::onopen: Not signed in, redirect /Login"); var _url = this.$location.absUrl(); this.setCookie("url", _url, 365); this.$location.path("/Login"); this.$rootScope.$apply(); } return; } await this.SigninWithToken(data.jwt, data.rawAssertion, null); } catch (error) { this.WebSocketClient.user = null; console.error(error); this.$location.path("/Login"); this.$rootScope.$apply(); } }); } async SigninWithToken(jwt: string, rawAssertion: string, impersonate: string): Promise { var q: SigninMessage = new SigninMessage(); q.jwt = jwt; q.rawAssertion = rawAssertion; q.realm = "browser"; if (this.WebSocketClient.usingCordova) { q.realm = "mobile"; } q.impersonate = impersonate; q.onesignalid = this.WebSocketClient.oneSignalId; q.device = this.WebSocketClient.device; q.gpslocation = this.WebSocketClient.location; var msg: Message = new Message(); msg.command = "signin"; msg.data = JSON.stringify(q); q = await this.WebSocketClient.Send(msg); this.WebSocketClient.user = q.user; this.WebSocketClient.jwt = q.jwt; this.$rootScope.$broadcast("signin", q); return q; } async SigninWithUsername(username: string, password: string, impersonate: string): Promise { var q: SigninMessage = new SigninMessage(); q.username = username; q.password = password; q.realm = "browser"; if (this.WebSocketClient.usingCordova) { q.realm = "mobile"; } q.impersonate = impersonate; q.onesignalid = this.WebSocketClient.oneSignalId; q.device = this.WebSocketClient.device; q.gpslocation = this.WebSocketClient.location; var msg: Message = new Message(); msg.command = "signin"; msg.data = JSON.stringify(q); q = await this.WebSocketClient.Send(msg); this.WebSocketClient.user = q.user; this.WebSocketClient.jwt = q.jwt; this.$rootScope.$broadcast("signin", q); return q; } async Query(collection: string, query: any, projection: any = null, orderby: any = { _created: -1 }, top: number = 500, skip: number = 0): Promise { var q: QueryMessage = new QueryMessage(); q.collectionname = collection; q.query = query; q.projection = projection; q.orderby = orderby; q.top = top; q.skip = skip; var msg: Message = new Message(); msg.command = "query"; msg.data = JSON.stringify(q); q = await this.WebSocketClient.Send(msg); return q.result; } async MapReduce(collection: string, map: mapFunc, reduce: reduceFunc, finalize: finalizeFunc, query: any, out: string | any, scope: any): Promise { var q: MapReduceMessage = new MapReduceMessage(map, reduce, finalize, query, out); q.collectionname = collection; q.scope = scope; var msg: Message = new Message(); msg.command = "mapreduce"; q.out = out; // msg.data = JSON.stringify(q); msg.data = JSONfn.stringify(q); q = await this.WebSocketClient.Send(msg); return q.result; } async Insert(collection: string, model: any): Promise { var q: InsertOneMessage = new InsertOneMessage(); q.collectionname = collection; q.item = model; var msg: Message = new Message(); msg.command = "insertone"; msg.data = JSON.stringify(q); q = await this.WebSocketClient.Send(msg); return q.result; } async Update(collection: string, model: any): Promise { var q: UpdateOneMessage = new UpdateOneMessage(); q.collectionname = collection; q.item = model; var msg: Message = new Message(); msg.command = "updateone"; msg.data = JSON.stringify(q); q = await this.WebSocketClient.Send(msg); return q.result; } async Delete(collection: string, model: any): Promise { var q: DeleteOneMessage = new DeleteOneMessage(); q.collectionname = collection; q._id = model._id; var msg: Message = new Message(); msg.command = "deleteone"; msg.data = JSON.stringify(q); q = await this.WebSocketClient.Send(msg); } async RegisterQueue(queuename: string = undefined): Promise { var q: RegisterQueueMessage = new RegisterQueueMessage(); q.queuename = queuename; var msg: Message = new Message(); msg.command = "registerqueue"; msg.data = JSON.stringify(q); await this.WebSocketClient.Send(msg); } async _QueueMessage(queuename: string, data: any): Promise { return new Promise(async (resolve, reject) => { var q: QueueMessage = new QueueMessage(); q.correlationId = Math.random().toString(36).substr(2, 9); q.queuename = queuename; q.data = JSON.stringify(data); var msg: Message = new Message(); msg.command = "queuemessage"; msg.data = JSON.stringify(q); console.log("_QueueMessage: correlationId " + q.correlationId); this.messageQueue[q.correlationId] = new messagequeue(q, (msgresult: QueueMessage) => { resolve(msgresult); delete this.messageQueue[q.correlationId]; }); var res = await this.WebSocketClient.Send(msg); console.log("_QueueMessage"); console.log(res); }); } async QueueMessage(queuename: string, data: any): Promise { var result: any = await this._QueueMessage(queuename, data); var msg = result.data; try { result.data = JSON.parse(result.data); } catch (error) { } return msg; } async GetNoderedInstance(): Promise { var q: GetNoderedInstanceMessage = new GetNoderedInstanceMessage(); var msg: Message = new Message(); msg.command = "getnoderedinstance"; msg.data = JSON.stringify(q); q = await this.WebSocketClient.Send(msg); return q.result; } async GetNoderedInstanceLog(): Promise { var q: GetNoderedInstanceLogMessage = new GetNoderedInstanceLogMessage(); var msg: Message = new Message(); msg.command = "getnoderedinstancelog"; msg.data = JSON.stringify(q); q = await this.WebSocketClient.Send(msg); return q.result; } async EnsureNoderedInstance(): Promise { var q: EnsureNoderedInstanceMessage = new EnsureNoderedInstanceMessage(); var msg: Message = new Message(); msg.command = "ensurenoderedinstance"; msg.data = JSON.stringify(q); q = await this.WebSocketClient.Send(msg); } async DeleteNoderedInstance(): Promise { var q: DeleteNoderedInstanceMessage = new DeleteNoderedInstanceMessage(); var msg: Message = new Message(); msg.command = "deletenoderedinstance"; msg.data = JSON.stringify(q); q = await this.WebSocketClient.Send(msg); } async RestartNoderedInstance(): Promise { var q: RestartNoderedInstanceMessage = new RestartNoderedInstanceMessage(); var msg: Message = new Message(); msg.command = "restartnoderedinstance"; msg.data = JSON.stringify(q); q = await this.WebSocketClient.Send(msg); } async StartNoderedInstance(): Promise { var q: StartNoderedInstanceMessage = new StartNoderedInstanceMessage(); var msg: Message = new Message(); msg.command = "startnoderedinstance"; msg.data = JSON.stringify(q); q = await this.WebSocketClient.Send(msg); } async StopNoderedInstance(): Promise { var q: StopNoderedInstanceMessage = new StopNoderedInstanceMessage(); var msg: Message = new Message(); msg.command = "stopnoderedinstance"; msg.data = JSON.stringify(q); q = await this.WebSocketClient.Send(msg); } setCookie(cname, cvalue, exdays) { var d = new Date(); d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000)); var expires = "expires=" + d.toUTCString(); document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/"; } getCookie(cname) { var name = cname + "="; var decodedCookie = decodeURIComponent(document.cookie); var ca = decodedCookie.split(';'); for (var i = 0; i < ca.length; i++) { var c = ca[i]; while (c.charAt(0) == ' ') { c = c.substring(1); } if (c.indexOf(name) == 0) { return c.substring(name.length, c.length); } } return ""; } deleteCookie(cname) { document.cookie = cname + "=;Thu, 01 Jan 1970 00:00:00 UTC;path=/"; } } export class JSONfn { public static stringify(obj) { return JSON.stringify(obj, function (key, value) { return (typeof value === 'function') ? value.toString() : value; }); } public static parse(str) { return JSON.parse(str, function (key, value) { if (typeof value != 'string') return value; return (value.substring(0, 8) == 'function') ? eval('(' + value + ')') : value; }); } } function _timeSince(timeStamp) { var now: Date = new Date(), secondsPast: number = (now.getTime() - timeStamp.getTime()) / 1000; if (secondsPast < 60) { return parseInt(secondsPast.toString()) + 's'; } if (secondsPast < 3600) { return parseInt((secondsPast / 60).toString()) + 'm'; } if (secondsPast <= 86400) { return parseInt((secondsPast / 3600).toString()) + 'h'; } if (secondsPast > 86400) { let day = timeStamp.getDate(); let month = timeStamp.toDateString().match(/ [a-zA-Z]*/)[0].replace(" ", ""); let year = timeStamp.getFullYear() == now.getFullYear() ? "" : " " + timeStamp.getFullYear(); return day + " " + month + year; } } export class timesince implements ng.IDirective { // restrict = 'E'; require = 'ngModel'; replace = true; constructor(public $location: ng.ILocationService, public $timeout: ng.ITimeoutService) { } link: ng.IDirectiveLinkFn = (scope: ng.IScope, element: ng.IAugmentedJQuery, attr: ng.IAttributes, ngModelCtrl: any) => { scope.$watch(() => { if (ngModelCtrl.$viewValue === null || ngModelCtrl.$viewValue === undefined) { return; } var timeStamp = ngModelCtrl.$viewValue; element.text(_timeSince(new Date(timeStamp))); }); } static factory(): ng.IDirectiveFactory { const directive = ($location: ng.ILocationService, $timeout: ng.ITimeoutService) => new timesince($location, $timeout); directive.$inject = ['$location', '$timeout']; return directive; } } async function getString(locale: any, lib: string, key: string): Promise { return new Promise((resolve) => { try { if (locale === null || locale === undefined) { return resolve(); } locale.ready(lib).then(function () { var value = locale.getString(lib + "." + key); if (value !== null && value !== undefined && value !== "") { resolve(value); } else { resolve(key); } }); } catch (error) { } }); } var global_translate_notfound: string[] = []; export class translate implements ng.IDirective { require = '?ngModel'; replace = true; constructor(public $location: ng.ILocationService, public $timeout: ng.ITimeoutService, public locale) { } link: ng.IDirectiveLinkFn = (scope: ng.IScope, element: ng.IAugmentedJQuery, attr: ng.IAttributes, ngModelCtrl: any) => { var calculateValue = (value: string): string => { if (value === null || value === undefined || value === "") return value; var lib = (attr.lib ? attr.lib : "common"); if ((value.toString()).startsWith(lib + ".")) { return; } var key: string = (lib + "." + value).toLowerCase(); var result = this.locale.getString(key); if (result.startsWith(lib + ".")) { result = result.slice((lib + ".").length); } // var result = await getString(this.locale, lib, value); if (result == "%%KEY_NOT_FOUND%%" || result == "") { if (global_translate_notfound.indexOf(lib + "." + value) === -1) { global_translate_notfound.push(lib + "." + value); console.log("KEY_NOT_FOUND " + lib + "." + value); } result = value; } return result; }; var lib = (attr.lib ? attr.lib : "common"); this.locale.ready(lib).then(() => { var value: string = null; if (ngModelCtrl !== null) { ngModelCtrl.$formatters.push(function (value) { return calculateValue(value); }); // value = calculateValue(ngModelCtrl.$viewValue); // ngModelCtrl.$setViewValue(this.result); // ngModelCtrl.$render(); } else { var hashCode = (s: string) => { return s.split("").reduce(function (a, b) { a = ((a << 5) - a) + b.charCodeAt(0); return a & a }, 0); } var watchFunction = () => { if (attr.value !== null && attr.value !== undefined) { return hashCode(attr.value); } else { var value = element.text(); if (value !== null || value !== undefined) { return hashCode(value); } return value; } }; // attrs.$observe('i18n', function (newVal, oldVal) { // }); //scope.$watch(watchFunction, () => { if (attr.value !== null && attr.value !== undefined && element[0].tagName !== "OPTION") { value = calculateValue(attr.value); attr.$set('value', value); } else { value = element.text(); if (value !== null || value !== undefined) { var result = calculateValue(value); // console.log(value + "=" + result); element.text(result); } } //}); } }); } static factory(): ng.IDirectiveFactory { const directive = ($location: ng.ILocationService, $timeout: ng.ITimeoutService, locale) => new translate($location, $timeout, locale); directive.$inject = ['$location', '$timeout', 'locale']; return directive; } } export class entitiesCtrl { public loading: boolean = false; public basequery: any = {}; public baseprojection: any = {}; public collection: string = "entities"; public models: T[] = []; public orderby: any = { _created: -1 }; public autorefresh: boolean = false; public autorefreshinterval: number = 2000; public autorefreshpromise: any = null; public postloadData: any = null; public static $inject = [ "$scope", "$location", "$routeParams", "$interval", "WebSocketClient", "api" ]; constructor( public $scope: ng.IScope, public $location: ng.ILocationService, public $routeParams: ng.route.IRouteParamsService, public $interval: ng.IIntervalService, public WebSocketClient: WebSocketClient, public api: api ) { } async loadData(): Promise { if (this.loading == true) { console.log("allready loading data, exit"); return; } this.loading = true; this.models = await this.api.Query(this.collection, this.basequery, this.baseprojection, this.orderby); this.loading = false; if (this.autorefresh) { if (this.autorefreshpromise == null) { this.autorefreshpromise = this.$interval(() => { this.loadData(); }, this.autorefreshinterval); this.$scope.$on('$destroy', () => { this.$interval.cancel(this.autorefreshpromise); }); } } if (this.postloadData != null) { this.postloadData(); } else { if (!this.$scope.$$phase) { this.$scope.$apply(); } } } ToggleOrder(field: string) { if (this.orderby[field] == undefined) { this.orderby = {}; } if (this.orderby[field] == -1) { this.orderby[field] = 1; } else { this.orderby[field] = -1; } if (field === '_type') { this.orderby["type"] = this.orderby[field]; } this.loadData(); } async DeleteOne(model: any): Promise { this.loading = true; await this.api.Delete(this.collection, model); this.models = this.models.filter(function (m: any): boolean { return m._id !== model._id; }); this.loading = false; if (!this.$scope.$$phase) { this.$scope.$apply(); } } } export function nestedassign(target, source) { if (source === null || source === undefined) return null; var keys = Object.keys(source); for (var i = 0; i < keys.length; i++) { var sourcekey = keys[i]; if (Object.keys(source).find(targetkey => targetkey === sourcekey) !== undefined && Object.keys(source).find(targetkey => targetkey === sourcekey) !== null && typeof source === "object" && typeof source[sourcekey] === "object") { target[sourcekey] = nestedassign(target[sourcekey], source[sourcekey]); } else { target[sourcekey] = source[sourcekey]; } } return target; } export class entityCtrl { public loading: boolean = false; public basequery: any = {}; public baseprojection: any = {}; public collection: string = "entities"; public model: T = null; public id: string = null; public keys: string[] = []; public autorefresh: boolean = false; public autorefreshinterval: number = 2000; public autorefreshpromise: any = null; public postloadData: any = null; public static $inject = [ "$scope", "$location", "$routeParams", "$interval", "WebSocketClient", "api" ]; constructor( public $scope: ng.IScope, public $location: ng.ILocationService, public $routeParams: ng.route.IRouteParamsService, public $interval: ng.IIntervalService, public WebSocketClient: WebSocketClient, public api: api ) { this.id = $routeParams.id; this.basequery = { _id: this.id }; } async loadData(): Promise { if (this.loading == true) { console.log("allready loading data, exit"); return; } var updated: boolean = false; this.loading = true; var result = await this.api.Query(this.collection, this.basequery, this.baseprojection, null, 1); if (result.length > 0) { if (this.model == null) { this.model = result[0]; updated = true; } else { if (!angular.equals(this.model, result[0])) { this.model = result[0]; updated = true; } } } if (updated) { this.keys = Object.keys(this.model); for (var i: number = this.keys.length - 1; i >= 0; i--) { if (this.keys[i].startsWith('_')) this.keys.splice(i, 1); } } this.loading = false; if (this.postloadData != null) { this.postloadData(); } else { if (!this.$scope.$$phase) { this.$scope.$apply(); } } if (this.autorefresh) { if (this.autorefreshpromise == null) { this.autorefreshpromise = this.$interval(() => { this.loadData(); }, this.autorefreshinterval); this.$scope.$on('$destroy', () => { this.$interval.cancel(this.autorefreshpromise); }); } } } } }