15746 lines
619 KiB
JavaScript
15746 lines
619 KiB
JavaScript
var __extends = (this && this.__extends) || (function () {
|
||
var extendStatics = function (d, b) {
|
||
extendStatics = Object.setPrototypeOf ||
|
||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||
return extendStatics(d, b);
|
||
};
|
||
return function (d, b) {
|
||
if (typeof b !== "function" && b !== null)
|
||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||
extendStatics(d, b);
|
||
function __() { this.constructor = d; }
|
||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||
};
|
||
})();
|
||
/*
|
||
This file is part of »bacterio-plankton:base«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:base« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:base« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:base«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
// }
|
||
/*
|
||
This file is part of »bacterio-plankton:base«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:base« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:base« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:base«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
;
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var base;
|
||
(function (base) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function environment() {
|
||
return "node";
|
||
}
|
||
base.environment = environment;
|
||
})(base = lib_plankton.base || (lib_plankton.base = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:base«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:base« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:base« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:base«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
/*export*/ function pseudopointer_null() {
|
||
return {
|
||
"value": null
|
||
};
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
/*export*/ function pseudopointer_make(value) {
|
||
return {
|
||
"value": value
|
||
};
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
/*export*/ function pseudopointer_isset(pseudopointer) {
|
||
return (pseudopointer.value != null);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
/*export*/ function pseudopointer_read(pseudopointer) {
|
||
if (pseudopointer.value != null) {
|
||
return pseudopointer.value;
|
||
}
|
||
else {
|
||
var message = "nullpointer dereferencation";
|
||
throw (new Error(message));
|
||
}
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
/*export*/ function pseudopointer_write(pseudopointer, value) {
|
||
pseudopointer.value = value;
|
||
}
|
||
/*
|
||
This file is part of »bacterio-plankton:base«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:base« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:base« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:base«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
var instance_verbosity = 0;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function instance_collate(value1, value2) {
|
||
if (typeof (value1) === "object") {
|
||
if (value1 == null) {
|
||
return (value2 == null);
|
||
}
|
||
else {
|
||
if ("_collate" in value1) {
|
||
return value1["_collate"](value2);
|
||
}
|
||
else {
|
||
throw (new Error("[collate]" + " " + "object has no such method"));
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
if (instance_verbosity >= 1) {
|
||
// lib_plankton.log.warn("[collate]" + " " + "primitive value; using default implementation");
|
||
}
|
||
return (value1 === value2);
|
||
}
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function instance_compare(value1, value2) {
|
||
if (typeof (value1) === "object") {
|
||
if ("_compare" in value1) {
|
||
return value1["_compare"](value2);
|
||
}
|
||
else {
|
||
throw (new Error("[compare]" + " " + "object has no such method"));
|
||
}
|
||
}
|
||
else {
|
||
if (instance_verbosity >= 1) {
|
||
// lib_plankton.log.warn("[compare]" + " " + "primitive value; using default implementation");
|
||
}
|
||
return (value1 <= value2);
|
||
}
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function instance_clone(value) {
|
||
if (typeof (value) === "object") {
|
||
if ("_clone" in value) {
|
||
return value["_clone"]();
|
||
}
|
||
else {
|
||
throw (new Error("[clone]" + " " + "object has no such method"));
|
||
}
|
||
}
|
||
else {
|
||
if (instance_verbosity >= 1) {
|
||
// lib_plankton.log.warn("[clone]" + " " + "primitive value; using default implementation");
|
||
}
|
||
return value;
|
||
}
|
||
}
|
||
/**
|
||
* @desc the ability to generate a string out of the element, which identifies it to a high degree
|
||
* @author fenris
|
||
*/
|
||
function instance_hash(value) {
|
||
if (typeof (value) === "object") {
|
||
if ("_hash" in value) {
|
||
return value["_hash"]();
|
||
}
|
||
else {
|
||
throw (new Error("[hash]" + " " + "object has no such method"));
|
||
}
|
||
}
|
||
else {
|
||
if (instance_verbosity >= 1) {
|
||
// lib_plankton.log.warn("[hash]" + " " + "primitive value; using default implementation");
|
||
}
|
||
return String(value);
|
||
}
|
||
}
|
||
/**
|
||
* @desc the ability to map the element to a textual representation (most likely not injective)
|
||
* @author fenris
|
||
*/
|
||
function instance_show(value) {
|
||
if (typeof (value) === "object") {
|
||
if (value == null) {
|
||
return "NULL";
|
||
}
|
||
else {
|
||
if ("_show" in value) {
|
||
return value["_show"]();
|
||
}
|
||
else {
|
||
// throw (new Error("[show]" + " " + "object has no such method"));
|
||
return JSON.stringify(value);
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
if (instance_verbosity >= 1) {
|
||
// lib_plankton.log.warn("[show]" + " " + "primitive value; using default implementation");
|
||
}
|
||
return String(value);
|
||
}
|
||
}
|
||
/*
|
||
This file is part of »bacterio-plankton:base«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:base« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:base« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:base«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
/**
|
||
* @author frac
|
||
*/
|
||
var class_observer = /** @class */ (function () {
|
||
/**
|
||
* @author frac
|
||
*/
|
||
function class_observer() {
|
||
this.counter = 0;
|
||
this.actions = {};
|
||
this.buffer = [];
|
||
}
|
||
/**
|
||
* @author frac
|
||
*/
|
||
class_observer.prototype.empty = function () {
|
||
return (Object.keys(this.actions).length == 0);
|
||
};
|
||
/**
|
||
* @author frac
|
||
*/
|
||
class_observer.prototype.flush = function () {
|
||
this.actions = {};
|
||
};
|
||
/**
|
||
* @author frac
|
||
*/
|
||
class_observer.prototype.set = function (id, action) {
|
||
this.actions[id] = action;
|
||
};
|
||
/**
|
||
* @author frac
|
||
*/
|
||
class_observer.prototype.del = function (id) {
|
||
delete this.actions[id];
|
||
};
|
||
/**
|
||
* @author frac
|
||
*/
|
||
class_observer.prototype.add = function (action) {
|
||
this.set((this.counter++).toString(), action);
|
||
};
|
||
/**
|
||
* @author frac
|
||
*/
|
||
class_observer.prototype.notify = function (information, delayed) {
|
||
var _this = this;
|
||
if (information === void 0) { information = {}; }
|
||
if (delayed === void 0) { delayed = false; }
|
||
if (delayed) {
|
||
this.buffer.push(information);
|
||
}
|
||
else {
|
||
Object.keys(this.actions).forEach(function (id) { return _this.actions[id](information); });
|
||
}
|
||
};
|
||
/**
|
||
* @author frac
|
||
*/
|
||
class_observer.prototype.rollout = function () {
|
||
var _this = this;
|
||
this.buffer.forEach(function (information) { return _this.notify(information, false); });
|
||
this.buffer = [];
|
||
};
|
||
return class_observer;
|
||
}());
|
||
/**
|
||
* @author frac
|
||
*/
|
||
/*
|
||
export interface interface_readable<type_value> {
|
||
|
||
|**
|
||
* @author frac
|
||
*|
|
||
read() : type_executor<type_value, Error>;
|
||
|
||
}
|
||
*/
|
||
/**
|
||
* @author frac
|
||
*/
|
||
/*
|
||
export interface interface_writeable<type_value> {
|
||
|
||
|**
|
||
* @author frac
|
||
*|
|
||
write(value : type_value) : type_executor<void, Error>;
|
||
|
||
}
|
||
*/
|
||
/*
|
||
This file is part of »bacterio-plankton:base«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:base« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:base« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:base«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
/**
|
||
* @author frac
|
||
*/
|
||
var class_error = /** @class */ (function (_super) {
|
||
__extends(class_error, _super);
|
||
/**
|
||
* @author frac
|
||
*/
|
||
function class_error(message, suberrors) {
|
||
if (suberrors === void 0) { suberrors = []; }
|
||
var _this = _super.call(this, message) || this;
|
||
_this.suberrors = suberrors;
|
||
_this.mess = message;
|
||
return _this;
|
||
}
|
||
/**
|
||
* @override
|
||
* @author frac
|
||
*/
|
||
class_error.prototype.toString = function () {
|
||
return ( /*super.toString()*/this.mess + " " + ("[" + this.suberrors.map(function (x) { return x.toString(); }).join(",") + "]"));
|
||
};
|
||
return class_error;
|
||
}(Error));
|
||
/*
|
||
This file is part of »bacterio-plankton:base«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:base« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:base« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:base«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var base;
|
||
(function (base) {
|
||
/**
|
||
* returns the current UNIX timestamp
|
||
*
|
||
* @author fenris
|
||
*/
|
||
function get_current_timestamp(rounded) {
|
||
if (rounded === void 0) { rounded = false; }
|
||
var x = (Date.now() / 1000);
|
||
return (rounded ? Math.round(x) : x);
|
||
;
|
||
}
|
||
base.get_current_timestamp = get_current_timestamp;
|
||
/**
|
||
*/
|
||
function object_merge(core, mantle) {
|
||
return Object.assign(core, mantle);
|
||
}
|
||
base.object_merge = object_merge;
|
||
})(base = lib_plankton.base || (lib_plankton.base = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:pod«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:pod« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:pod« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:pod«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var pod;
|
||
(function (pod_1) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function make_empty() {
|
||
return {
|
||
"kind": "empty"
|
||
};
|
||
}
|
||
pod_1.make_empty = make_empty;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function make_filled(value) {
|
||
return {
|
||
"kind": "filled",
|
||
"value": value
|
||
};
|
||
}
|
||
pod_1.make_filled = make_filled;
|
||
/**
|
||
* whether the pod is filled
|
||
*
|
||
* @author fenris
|
||
*/
|
||
function is_filled(pod) {
|
||
return (pod.kind === "filled");
|
||
}
|
||
pod_1.is_filled = is_filled;
|
||
/**
|
||
* return the value, stored in the pod-wrapper
|
||
*
|
||
* @author fenris
|
||
*/
|
||
function cull(pod) {
|
||
if (!is_filled(pod)) {
|
||
throw (new Error("cull from empty"));
|
||
}
|
||
else {
|
||
return pod.value;
|
||
}
|
||
}
|
||
pod_1.cull = cull;
|
||
/**
|
||
* to pass on a empty-pod or to use a filled-pod
|
||
*
|
||
* @author fenris
|
||
*/
|
||
function propagate(pod, function_) {
|
||
if (!is_filled(pod)) {
|
||
return make_empty();
|
||
}
|
||
else {
|
||
return make_filled(function_(pod.value));
|
||
}
|
||
}
|
||
pod_1.propagate = propagate;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function distinguish(pod, function_empty, function_filled) {
|
||
return ((!is_filled(pod))
|
||
? function_empty()
|
||
: function_filled(pod.value));
|
||
}
|
||
pod_1.distinguish = distinguish;
|
||
/**
|
||
*/
|
||
function show(pod, options = {}) {
|
||
options = Object.assign({
|
||
"show_value": value => String(value),
|
||
}, options);
|
||
if (!is_filled(pod)) {
|
||
return "<·>";
|
||
}
|
||
else {
|
||
return ("<- " + options.show_value(pod.value) + " ->");
|
||
}
|
||
}
|
||
pod_1.show = show;
|
||
})(pod = lib_plankton.pod || (lib_plankton.pod = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:pod«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:pod« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:pod« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:pod«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var pod;
|
||
(function (pod) {
|
||
/**
|
||
*/
|
||
class class_pod {
|
||
constructor(subject) { this.subject = subject; }
|
||
tear() { return this.subject; }
|
||
static empty() { return (new class_pod(pod.make_empty())); }
|
||
static filled(value) { return (new class_pod(pod.make_filled(value))); }
|
||
is_empty() { return (!pod.is_filled(this.subject)); }
|
||
is_filled() { return pod.is_filled(this.subject); }
|
||
cull() { return pod.cull(this.subject); }
|
||
show(show_value = undefined) { return pod.show(this.subject, show_value); }
|
||
toString() { return this.show(); }
|
||
propagate(function_) { return new class_pod(pod.propagate(this.subject, function_)); }
|
||
distinguish(function_empty, function_filled) { return pod.distinguish(this.subject, function_empty, function_filled); }
|
||
}
|
||
pod.class_pod = class_pod;
|
||
})(pod = lib_plankton.pod || (lib_plankton.pod = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:call«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:call« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:call« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:call«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
/**
|
||
* might be completely obsolete
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var call;
|
||
(function (call) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function promise_reject(reason) {
|
||
return Promise.reject(reason);
|
||
}
|
||
call.promise_reject = promise_reject;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function promise_resolve(result) {
|
||
return Promise.resolve(result);
|
||
}
|
||
call.promise_resolve = promise_resolve;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function promise_make(executor) {
|
||
return (new Promise(executor));
|
||
}
|
||
call.promise_make = promise_make;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function promise_then_close(promise, resolver, rejector) {
|
||
promise.then(resolver, rejector);
|
||
}
|
||
call.promise_then_close = promise_then_close;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function promise_then_append(promise, resolver, rejector = null) {
|
||
if (rejector == null) {
|
||
rejector = (reason) => promise_reject(reason);
|
||
}
|
||
return (promise.then(resolver, rejector));
|
||
}
|
||
call.promise_then_append = promise_then_append;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function promise_all(promises) {
|
||
return Promise.all(promises);
|
||
}
|
||
call.promise_all = promise_all;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function promise_chain(promises, start = undefined) {
|
||
return (promises.reduce((chain, promise) => promise_then_append(chain, promise), promise_resolve(start)));
|
||
}
|
||
call.promise_chain = promise_chain;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function promise_condense(promises) {
|
||
return (promise_chain(promises.map(promise => result => promise_then_append(promise(), element => promise_resolve(result.concat([element])))), []));
|
||
}
|
||
call.promise_condense = promise_condense;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function promise_group(promises, options = {
|
||
"serial": false,
|
||
}) {
|
||
const decorate = function (promise, name) {
|
||
return (() => promise_then_append(promise(), value => promise_resolve({ "key": name, "value": value })));
|
||
};
|
||
if (options.serial) {
|
||
return (promise_then_append(promise_condense(Object.keys(promises)
|
||
.map(name => decorate(promises[name], name))), list => promise_resolve(Object.fromEntries(list.map(({ "key": key, "value": value }) => ([key, value]))))));
|
||
}
|
||
else {
|
||
return (promise_then_append(promise_all(Object.keys(promises)
|
||
.map(name => decorate(promises[name], name))
|
||
.map(promise => promise())), list => promise_resolve(Object.fromEntries(list.map(({ "key": key, "value": value }) => ([key, value]))))));
|
||
}
|
||
}
|
||
call.promise_group = promise_group;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function promise_wrap(promise, transformator_result, transformator_reason = lib_plankton.call.id) {
|
||
return (promise_make((resolve, reject) => {
|
||
promise_then_close(promise, result => resolve(transformator_result(result)), reason => reject(transformator_reason(reason)));
|
||
}));
|
||
}
|
||
call.promise_wrap = promise_wrap;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
/*
|
||
export function promise_show<type_result, type_reason>(label : string) : (result : type_result)=>type_promise<type_result, type_reason> {
|
||
return (
|
||
result => promise_make<type_result, type_reason>(
|
||
(resolve, reject) => {
|
||
// lib_plankton.log.info(label + ": " + instance_show(result));
|
||
process.stdout.write(label + ": " + instance_show(result));
|
||
resolve(result);
|
||
}
|
||
)
|
||
);
|
||
}
|
||
*/
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
/*
|
||
export function promise_log<type_result, type_reason>(result : type_result) : (result : type_result)=>type_promise<type_result, type_reason> {
|
||
return promise_show<type_result, type_reason>("log");
|
||
}
|
||
*/
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function promise_attach(state, promise, name) {
|
||
return (promise_wrap(promise, result => {
|
||
state[name] = result;
|
||
return state;
|
||
}));
|
||
}
|
||
call.promise_attach = promise_attach;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function promise_delay(promise, delay) {
|
||
return promise_make((resolve, reject) => {
|
||
call.timeout(() => {
|
||
promise_then_close(promise, resolve, reject);
|
||
return null;
|
||
}, delay);
|
||
});
|
||
}
|
||
call.promise_delay = promise_delay;
|
||
})(call = lib_plankton.call || (lib_plankton.call = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:call«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:call« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:call« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:call«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var call;
|
||
(function (call) {
|
||
/**
|
||
*/
|
||
class CancellablePromise extends Promise {
|
||
/**
|
||
*/
|
||
constructor(executor) {
|
||
super((resolve, reject) => { });
|
||
this.subject = (new Promise((resolve, reject) => {
|
||
Promise.race([
|
||
new Promise(executor),
|
||
new Promise((resolve_, reject_) => {
|
||
this.interval = setInterval(() => {
|
||
if (!this.cancelled) {
|
||
// do nothing
|
||
}
|
||
else {
|
||
reject_(new Error("cancelled"));
|
||
this.clear();
|
||
}
|
||
}, 0);
|
||
}),
|
||
])
|
||
.then(resolve, reject);
|
||
}));
|
||
this.cancelled = false;
|
||
this.interval = null;
|
||
}
|
||
/**
|
||
*/
|
||
clear() {
|
||
if (this.interval === null) {
|
||
// do nothing
|
||
}
|
||
else {
|
||
clearInterval(this.interval);
|
||
this.interval = null;
|
||
}
|
||
}
|
||
/**
|
||
*/
|
||
then(onfulfilled, onrejected) {
|
||
this.clear();
|
||
return this.subject.then(onfulfilled, onrejected);
|
||
}
|
||
/**
|
||
*/
|
||
catch(x) {
|
||
this.clear();
|
||
return this.subject.catch(x);
|
||
}
|
||
/**
|
||
*/
|
||
cancel() {
|
||
this.cancelled = true;
|
||
this.clear();
|
||
}
|
||
}
|
||
call.CancellablePromise = CancellablePromise;
|
||
})(call = lib_plankton.call || (lib_plankton.call = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:call«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:call« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:call« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:call«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
/**
|
||
* initializer might be obsolete, since promises are reusable after having been resolved or rejected
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var call;
|
||
(function (call) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
let enum_initializer_state;
|
||
(function (enum_initializer_state) {
|
||
enum_initializer_state[enum_initializer_state["initial"] = 0] = "initial";
|
||
enum_initializer_state[enum_initializer_state["waiting"] = 1] = "waiting";
|
||
enum_initializer_state[enum_initializer_state["successful"] = 2] = "successful";
|
||
enum_initializer_state[enum_initializer_state["failed"] = 3] = "failed";
|
||
})(enum_initializer_state = call.enum_initializer_state || (call.enum_initializer_state = {}));
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function initializer_make(fetcher) {
|
||
let subject = {
|
||
"fetcher": fetcher,
|
||
"state": enum_initializer_state.initial,
|
||
"queue": [],
|
||
"result": undefined,
|
||
"reason": undefined,
|
||
};
|
||
return subject;
|
||
}
|
||
call.initializer_make = initializer_make;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function initializer_actuate(subject) {
|
||
switch (subject.state) {
|
||
case enum_initializer_state.successful: {
|
||
subject.queue.forEach(entry => entry.resolve(subject.result));
|
||
break;
|
||
}
|
||
case enum_initializer_state.failed: {
|
||
subject.queue.forEach(entry => entry.reject(subject.reason));
|
||
break;
|
||
}
|
||
default: {
|
||
throw (new Error(`unhandled state ${subject.state}`));
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function initializer_reset(subject) {
|
||
subject.state = enum_initializer_state.initial;
|
||
subject.queue = [];
|
||
}
|
||
call.initializer_reset = initializer_reset;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function initializer_state(subject) {
|
||
return subject.state;
|
||
}
|
||
call.initializer_state = initializer_state;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function initializer_get(subject) {
|
||
switch (subject.state) {
|
||
case enum_initializer_state.initial: {
|
||
subject.state = enum_initializer_state.waiting;
|
||
return (call.promise_make((resolve, reject) => {
|
||
subject.queue.push({ "resolve": resolve, "reject": reject });
|
||
subject.fetcher().then(result => {
|
||
subject.state = enum_initializer_state.successful;
|
||
subject.result = result;
|
||
initializer_actuate(subject);
|
||
}, reason => {
|
||
subject.state = enum_initializer_state.failed;
|
||
subject.reason = reason;
|
||
initializer_actuate(subject);
|
||
});
|
||
}));
|
||
break;
|
||
}
|
||
case enum_initializer_state.waiting: {
|
||
return (call.promise_make((resolve, reject) => {
|
||
subject.queue.push({ "resolve": resolve, "reject": reject });
|
||
}));
|
||
break;
|
||
}
|
||
case enum_initializer_state.successful: {
|
||
return (call.promise_resolve(subject.result));
|
||
break;
|
||
}
|
||
case enum_initializer_state.failed: {
|
||
return (call.promise_reject(subject.reason));
|
||
break;
|
||
}
|
||
default: {
|
||
throw (new Error(`unhandled state ${subject.state}`));
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
call.initializer_get = initializer_get;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function initializer_get_sync(subject) {
|
||
switch (subject.state) {
|
||
case enum_initializer_state.successful: {
|
||
return subject.result;
|
||
break;
|
||
}
|
||
case enum_initializer_state.failed: {
|
||
throw subject.reason;
|
||
break;
|
||
}
|
||
default: {
|
||
throw (new Error(`unhandled state ${subject.state}`));
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function initializer_set_sync(subject, result) {
|
||
switch (subject.state) {
|
||
case enum_initializer_state.successful: {
|
||
subject.result = result;
|
||
break;
|
||
}
|
||
case enum_initializer_state.failed: {
|
||
subject.state = enum_initializer_state.successful;
|
||
subject.result = result;
|
||
break;
|
||
}
|
||
default: {
|
||
throw (new Error(`unhandled state ${subject.state}`));
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
})(call = lib_plankton.call || (lib_plankton.call = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:call«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:call« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:call« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:call«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var call;
|
||
(function (call) {
|
||
/*
|
||
The core idea of this library is to provide means for asynchronous program flow. The old-school way to do is,
|
||
is to use callbacks. While this approach is simple and easy to understand, it has some disadvantages. As an
|
||
attempt to relief and improve this, the promise-system was introduced. In principle it solves most of the
|
||
problems found in the callback-approach; however it has some downsides as well:
|
||
|
||
- Convolution of multiple principles
|
||
Promises unite the ideas of asynchronous program flow and error handling.
|
||
|
||
- Instant execution
|
||
Creating a promise results in the instant execution of the given executor prodecure. While this might be
|
||
convenient in some cases, it can be quite disturbing and counter-intuitive in others.
|
||
|
||
- Broken typing
|
||
The Promise system doesn't distinguish between an appending "then" (i.e. passing a function, which returns a
|
||
new promise) and a closing "then" (i.e. passing a function, which has no return value). On top of that it
|
||
allows returning simple values in an appending "then", which results in an implicit call of the executors
|
||
"resolve"-function. The price for these "pragmatic" features is that the whole system can't be typed well.
|
||
And even though JavaScript is not a strictly typed language, it was a quite questionable decision to design
|
||
the promise system in a way, which breaks typing from the start.
|
||
|
||
The deferral-system forseeks to solve these issues while retaining the advantages of the promise-system.
|
||
*/
|
||
/**
|
||
* @author fenris
|
||
* @desc activates the deferral and handles its output according to a given procedure
|
||
* @param {(value : type_value)=>void} procedure a function which receives the output of the deferral as argument
|
||
*/
|
||
function deferral_use(deferral, input, procedure) {
|
||
deferral.representation(input).then(value => {
|
||
procedure(value);
|
||
}, reason => {
|
||
throw reason;
|
||
});
|
||
}
|
||
call.deferral_use = deferral_use;
|
||
/**
|
||
* @author fenris
|
||
* @desc creates a deferral-subject (similar to "new Promise", where "convey" reflects "resolve"/"reject")
|
||
*/
|
||
function deferral_make(handler) {
|
||
return ({
|
||
"representation": ((input) => (new Promise((resolve, reject) => {
|
||
handler(input, resolve);
|
||
})))
|
||
});
|
||
}
|
||
call.deferral_make = deferral_make;
|
||
/**
|
||
* @author fenris
|
||
* @desc wraps a simple function into a deferral (similar to "Promise.resolve"/"Promise.reject")
|
||
*/
|
||
function deferral_wrap(function_) {
|
||
return (deferral_make((input, convey) => convey(function_(input))));
|
||
}
|
||
call.deferral_wrap = deferral_wrap;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function deferral_id() {
|
||
return (deferral_make((input, convey) => convey(input)));
|
||
}
|
||
call.deferral_id = deferral_id;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function deferral_const(value) {
|
||
return (deferral_make((input, convey) => convey(value)));
|
||
}
|
||
call.deferral_const = deferral_const;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function deferral_delay(output, delay) {
|
||
return (deferral_make((input, convey) => {
|
||
setTimeout(() => convey(output), delay);
|
||
}));
|
||
}
|
||
call.deferral_delay = deferral_delay;
|
||
/**
|
||
* @author fenris
|
||
* @desc connects two deferrals to form a new one; the output of the first is taken as input for the second
|
||
* (similar to "Promise.then" when passing a function which returns a new promise)
|
||
* @param {type_deferral<type_value1>} first a simple deferral
|
||
* @param {(value1 : type_value1)=>type_deferral<type_value2>} second a function depending from a value returning a deferral
|
||
*/
|
||
function deferral_compose_serial(first, second) {
|
||
return {
|
||
"representation": ((input) => first.representation(input).then((between) => second.representation(between)))
|
||
};
|
||
}
|
||
call.deferral_compose_serial = deferral_compose_serial;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function deferral_compose_parallel({ "left": deferral_left, "right": deferral_right, }) {
|
||
return (deferral_make((input, convey) => {
|
||
let object = {
|
||
"left": lib_plankton.pod.make_empty(),
|
||
"right": lib_plankton.pod.make_empty(),
|
||
};
|
||
let finish = function () {
|
||
if (lib_plankton.pod.is_filled(object.left)
|
||
&&
|
||
lib_plankton.pod.is_filled(object.right)) {
|
||
let result = {
|
||
"left": lib_plankton.pod.cull(object.left),
|
||
"right": lib_plankton.pod.cull(object.right),
|
||
};
|
||
convey(result);
|
||
}
|
||
else {
|
||
// do nothing
|
||
}
|
||
};
|
||
deferral_use(deferral_left, input, output_left => {
|
||
object.left = lib_plankton.pod.make_filled(output_left);
|
||
finish();
|
||
});
|
||
deferral_use(deferral_right, input, output_right => {
|
||
object.right = lib_plankton.pod.make_filled(output_right);
|
||
finish();
|
||
});
|
||
}));
|
||
}
|
||
call.deferral_compose_parallel = deferral_compose_parallel;
|
||
/**
|
||
* @author fenris
|
||
* @desc repeatedly applied serial composition
|
||
*/
|
||
function deferral_chain(members) {
|
||
return (members.reduce(
|
||
// (result, current) => deferral_compose_serial<type_value, type_value, type_value>(result, current),
|
||
deferral_compose_serial, deferral_id()));
|
||
}
|
||
call.deferral_chain = deferral_chain;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
/*
|
||
export function deferral_bunch<type_input, type_output>(
|
||
members : {[name : string] : type_deferral<type_input, type_output>}
|
||
) : type_deferral<type_input, {[name : string] : type_output}> {
|
||
|
||
}
|
||
*/
|
||
})(call = lib_plankton.call || (lib_plankton.call = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:call«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:call« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:call« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:call«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var call;
|
||
(function (call) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class class_deferral {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
constructor(subject) {
|
||
this.subject = subject;
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
static _cram(subject) {
|
||
return (new class_deferral(subject));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
static _tear(instance) {
|
||
return instance.subject;
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
static make(handler) {
|
||
return (class_deferral._cram(call.deferral_make(handler)));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
use(input, procedure) {
|
||
return (call.deferral_use(class_deferral._tear(this), input, procedure));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
compose_serial(second) {
|
||
return (class_deferral._cram(call.deferral_compose_serial(class_deferral._tear(this), class_deferral._tear(second))));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
static chain(members) {
|
||
return (class_deferral._cram(call.deferral_chain(members.map(member => class_deferral._tear(member)))));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
static wrap(function_) {
|
||
return (class_deferral._cram(call.deferral_wrap(function_)));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
static const_(value) {
|
||
return (class_deferral._cram(call.deferral_const(value)));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
static delay(output, delay) {
|
||
return (class_deferral._cram(call.deferral_delay(output, delay)));
|
||
}
|
||
}
|
||
call.class_deferral = class_deferral;
|
||
})(call = lib_plankton.call || (lib_plankton.call = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:call«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:call« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:call« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:call«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var call;
|
||
(function (call) {
|
||
/**
|
||
* converts the "arguments"-map into an array
|
||
*
|
||
* @param {Object} args
|
||
* @author fenris
|
||
*/
|
||
function args2list(args) {
|
||
return Object.keys(args).map(key => args[key]);
|
||
}
|
||
call.args2list = args2list;
|
||
/**
|
||
* just the empty function; useful for some callbacks etc.
|
||
*
|
||
* @author fenris
|
||
*/
|
||
function nothing() {
|
||
}
|
||
call.nothing = nothing;
|
||
/**
|
||
* just the identity; useful for some callbacks etc.; defined as function instead of const for using type parameters
|
||
*
|
||
* @author fenris
|
||
*/
|
||
function id(x) {
|
||
return x;
|
||
}
|
||
call.id = id;
|
||
/**
|
||
* just the identity; useful for some callbacks etc.
|
||
*
|
||
* @author fenris
|
||
*/
|
||
function const_(x) {
|
||
return (y => x);
|
||
}
|
||
call.const_ = const_;
|
||
/**
|
||
* composes two functions (i.e. returns a function that return the result of the successive execution of both input-functions)
|
||
*
|
||
* @param {function} function_f
|
||
* @param {function} function_g
|
||
* @author fenris
|
||
*/
|
||
function compose(function_f, function_g) {
|
||
return (function (x) {
|
||
// return function_g(function_f(x));
|
||
return function_g(function_f.apply(function_f, args2list(arguments)));
|
||
});
|
||
}
|
||
call.compose = compose;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function curryfy_real(f, n) {
|
||
switch (n) {
|
||
case 0: {
|
||
throw (new Error("[curryfy] impossible"));
|
||
// break;
|
||
}
|
||
case 1: {
|
||
return f;
|
||
// break;
|
||
}
|
||
default: {
|
||
return (function (x) {
|
||
return (curryfy_real(function () { return f.apply(f, [x].concat(args2list(arguments))); }, n - 1));
|
||
});
|
||
// break;
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* transforms a function with sequential input to a function with leveled input; example: add(2,3) = curryfy(add)(2)(3)
|
||
*
|
||
* @param {function} f
|
||
* @return {function} the currified version of the in put function
|
||
* @author fenris
|
||
*/
|
||
function curryfy(f) {
|
||
return curryfy_real(f, f.length);
|
||
}
|
||
call.curryfy = curryfy;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function convey(value, functions) {
|
||
let result = value;
|
||
functions.forEach(function_ => {
|
||
result = function_(result);
|
||
});
|
||
return result;
|
||
}
|
||
call.convey = convey;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function timeout(procedure, delay_in_seconds) {
|
||
return (
|
||
/*window.*/ setTimeout(procedure, Math.floor(delay_in_seconds * 1000)));
|
||
}
|
||
call.timeout = timeout;
|
||
/**
|
||
* Promise version of "setTimeout"
|
||
*
|
||
* @author fenris
|
||
*/
|
||
function defer(seconds, action) {
|
||
return (new Promise((resolve, reject) => {
|
||
setTimeout(() => resolve(action()), Math.floor(seconds * 1000));
|
||
}));
|
||
}
|
||
call.defer = defer;
|
||
/**
|
||
* a definition for a value being "defined"
|
||
*
|
||
* @author neuc
|
||
*/
|
||
function is_def(obj, options = {}) {
|
||
options = Object.assign({
|
||
"null_is_valid": false,
|
||
}, options);
|
||
return (!((typeof (obj) === "undefined")
|
||
||
|
||
(!options.null_is_valid && (obj === null))));
|
||
}
|
||
call.is_def = is_def;
|
||
/**
|
||
* returns the value if set and, when a type is specified, if the type is correct, if not return default_value
|
||
*
|
||
* @author neuc
|
||
*/
|
||
function def_val(value, default_value, options = {}) {
|
||
options = Object.assign({
|
||
"type": null,
|
||
"null_is_valid": false,
|
||
}, options);
|
||
if (is_def(value, { "null_is_valid": options.null_is_valid })
|
||
&&
|
||
(is_def(options.type)
|
||
? ((typeof (value) === options.type)
|
||
||
|
||
((value === null)
|
||
&&
|
||
options.null_is_valid))
|
||
: true)) {
|
||
return value;
|
||
}
|
||
else {
|
||
return default_value;
|
||
}
|
||
}
|
||
call.def_val = def_val;
|
||
;
|
||
/**
|
||
* provides the call for an attribute of a class as a regular function; useful for processing lists of objects
|
||
*
|
||
* @param {string} name the name of the attribute
|
||
* @return {function}
|
||
* @author fenris
|
||
*/
|
||
function attribute(name) {
|
||
return (object => object[name]);
|
||
}
|
||
call.attribute = attribute;
|
||
/**
|
||
* provides a method of a class as a regular function; useful for processing lists of objects
|
||
*
|
||
* @param {string} name the name of the method
|
||
* @return {function}
|
||
* @author fenris
|
||
*/
|
||
function method(name) {
|
||
return (function (object) { return object[name].apply(object, args2list(arguments).slice(1)); });
|
||
}
|
||
call.method = method;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function distinguish(coproduct, handlers, options = {}) {
|
||
options = Object.assign({
|
||
"fallback": null,
|
||
}, options);
|
||
if (coproduct.kind in handlers) {
|
||
const handler = handlers[coproduct.kind];
|
||
return handler(coproduct.data);
|
||
}
|
||
else {
|
||
const message = ("unhandled kind '" + coproduct.kind + "'");
|
||
if (options.fallback !== null) {
|
||
console.warn(message);
|
||
return options.fallback(coproduct);
|
||
}
|
||
else {
|
||
throw (new Error(message));
|
||
}
|
||
}
|
||
}
|
||
call.distinguish = distinguish;
|
||
/**
|
||
* rate limiting algorithm, based on the idea of mana (magic power) in video games:
|
||
* - an actor has a fixed mana capacity, i.e. the maximum amount of available power
|
||
* - an actor has a fixed rate of mana regeneration, i.e. how fast the power is filled up (linear growth)
|
||
* - an action has a defined mana heft, i.e. how much power is required and deducted in order to execute it
|
||
* - mana states are represented by snapshots, i.e. the amount of power at a certain point in time
|
||
*
|
||
* @author fenris
|
||
*/
|
||
async function rate_limit_check(setup, heft) {
|
||
if (heft > setup.capacity) {
|
||
return Promise.resolve({
|
||
"granted": false,
|
||
"seconds": null,
|
||
});
|
||
}
|
||
else {
|
||
// get current value
|
||
const current_timestamp = (Date.now() / 1000);
|
||
const old_snapshot_raw = (await setup.get_snapshot());
|
||
const old_snapshot = (old_snapshot_raw
|
||
??
|
||
{ "timestamp": current_timestamp, "value": setup.capacity });
|
||
const seconds_passed = (current_timestamp - old_snapshot.timestamp);
|
||
const current_value = Math.min(setup.capacity, (old_snapshot.value
|
||
+
|
||
(setup.regeneration_rate
|
||
*
|
||
seconds_passed)));
|
||
// analyze
|
||
if (current_value < heft) {
|
||
// too less
|
||
const seconds_needed = ((setup.regeneration_rate <= 0)
|
||
? null
|
||
: ((heft - old_snapshot.value) / setup.regeneration_rate));
|
||
return Promise.resolve({
|
||
"granted": false,
|
||
"seconds": ((seconds_needed === null) ? null : (seconds_needed - seconds_passed)),
|
||
});
|
||
}
|
||
else {
|
||
// enough -> update snapshot
|
||
const new_value = (current_value - heft);
|
||
// set_snapshot
|
||
if (old_snapshot_raw === null) {
|
||
await setup.set_snapshot({ "timestamp": current_timestamp, "value": new_value });
|
||
}
|
||
else {
|
||
await setup.update_snapshot(current_timestamp, (new_value - old_snapshot.value));
|
||
}
|
||
return Promise.resolve({
|
||
"granted": true,
|
||
"seconds": 0,
|
||
});
|
||
}
|
||
}
|
||
}
|
||
call.rate_limit_check = rate_limit_check;
|
||
})(call = lib_plankton.call || (lib_plankton.call = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||
return new (P || (P = Promise))(function (resolve, reject) {
|
||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
});
|
||
};
|
||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||
function step(op) {
|
||
if (f) throw new TypeError("Generator is already executing.");
|
||
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||
switch (op[0]) {
|
||
case 0: case 1: t = op; break;
|
||
case 4: _.label++; return { value: op[1], done: false };
|
||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||
default:
|
||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||
if (t[2]) _.ops.pop();
|
||
_.trys.pop(); continue;
|
||
}
|
||
op = body.call(thisArg, _);
|
||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||
}
|
||
};
|
||
/*
|
||
This file is part of »bacterio-plankton:email«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:email« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:lang« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:email«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var email;
|
||
(function (email) {
|
||
/**
|
||
*/
|
||
function send(smtp_credentials, sender, receivers, subject, content) {
|
||
return __awaiter(this, void 0, void 0, function () {
|
||
var nm_nodemailer, transporter, info;
|
||
return __generator(this, function (_a) {
|
||
switch (_a.label) {
|
||
case 0:
|
||
nm_nodemailer = require("nodemailer");
|
||
transporter = nm_nodemailer.createTransport({
|
||
"host": smtp_credentials.host,
|
||
"port": smtp_credentials.port,
|
||
"secure": false,
|
||
"auth": {
|
||
"user": smtp_credentials.username,
|
||
"pass": smtp_credentials.password
|
||
},
|
||
"debug": true
|
||
});
|
||
return [4 /*yield*/, transporter.sendMail({
|
||
"from": sender,
|
||
"to": receivers.join(", "),
|
||
"subject": subject,
|
||
"text": content
|
||
})];
|
||
case 1:
|
||
info = _a.sent();
|
||
return [2 /*return*/];
|
||
}
|
||
});
|
||
});
|
||
}
|
||
email.send = send;
|
||
})(email = lib_plankton.email || (lib_plankton.email = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
var __extends = (this && this.__extends) || (function () {
|
||
var extendStatics = function (d, b) {
|
||
extendStatics = Object.setPrototypeOf ||
|
||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||
return extendStatics(d, b);
|
||
};
|
||
return function (d, b) {
|
||
if (typeof b !== "function" && b !== null)
|
||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||
extendStatics(d, b);
|
||
function __() { this.constructor = d; }
|
||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||
};
|
||
})();
|
||
/*
|
||
This file is part of »bacterio-plankton:log«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:log« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:lang« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:log«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var log;
|
||
(function (log) {
|
||
/**
|
||
*/
|
||
var enum_level;
|
||
(function (enum_level) {
|
||
enum_level[enum_level["debug"] = 0] = "debug";
|
||
enum_level[enum_level["info"] = 1] = "info";
|
||
enum_level[enum_level["notice"] = 2] = "notice";
|
||
enum_level[enum_level["warning"] = 3] = "warning";
|
||
enum_level[enum_level["error"] = 4] = "error";
|
||
})(enum_level = log.enum_level || (log.enum_level = {}));
|
||
;
|
||
/**
|
||
*/
|
||
function level_order(level1, level2) {
|
||
return (level1 <= level2);
|
||
}
|
||
log.level_order = level_order;
|
||
/**
|
||
*/
|
||
function level_show(level) {
|
||
switch (level) {
|
||
case enum_level.debug: return "debug";
|
||
case enum_level.info: return "info";
|
||
case enum_level.notice: return "notice";
|
||
case enum_level.warning: return "warning";
|
||
case enum_level.error: return "error";
|
||
default: return "(unknown)";
|
||
}
|
||
}
|
||
log.level_show = level_show;
|
||
})(log = lib_plankton.log || (lib_plankton.log = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:log«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:log« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:lang« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:lang«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
/**
|
||
* @deprecated
|
||
* @todo remove
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var log;
|
||
(function (log) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
/*export*/ var level_stack = [0];
|
||
function level_push(level) { level_stack.push(level); }
|
||
log.level_push = level_push;
|
||
function level_pop() { if (level_stack.length > 1) {
|
||
level_stack.pop();
|
||
} }
|
||
log.level_pop = level_pop;
|
||
function level_get() { return level_stack.slice(-1)[0]; }
|
||
/*
|
||
export function level_inc() : void {level_push(level_get()+1);}
|
||
export function level_dec() : void {level_push(level_get()-1);}
|
||
*/
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
var indent_stack = [0];
|
||
function indent_push(indent) { indent_stack.push(indent); }
|
||
log.indent_push = indent_push;
|
||
function indent_pop() { if (indent_stack.length > 1) {
|
||
indent_stack.pop();
|
||
} }
|
||
log.indent_pop = indent_pop;
|
||
function indent_get() { return level_stack.slice(-1)[0]; }
|
||
function indent_inc() { level_push(level_get() + 1); }
|
||
log.indent_inc = indent_inc;
|
||
function indent_dec() { level_push(level_get() - 1); }
|
||
log.indent_dec = indent_dec;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function write(_a) {
|
||
var message = _a["message"], _b = _a["type"], type = _b === void 0 ? null : _b, _c = _a["prefix"], prefix = _c === void 0 ? null : _c, _d = _a["level"], level = _d === void 0 ? 0 : _d, _e = _a["indent"], indent = _e === void 0 ? 0 : _e;
|
||
var entry = {
|
||
"level": ((type === null)
|
||
? lib_plankton.log.enum_level.info
|
||
: {
|
||
"debug": lib_plankton.log.enum_level.debug,
|
||
"info": lib_plankton.log.enum_level.info,
|
||
"notice": lib_plankton.log.enum_level.notice,
|
||
"warning": lib_plankton.log.enum_level.warning,
|
||
"error": lib_plankton.log.enum_level.error
|
||
}[type]),
|
||
"incident": message,
|
||
"details": {
|
||
"prefix": prefix,
|
||
"level": level,
|
||
"indent": indent
|
||
}
|
||
};
|
||
lib_plankton.log.add(entry);
|
||
}
|
||
log.write = write;
|
||
})(log = lib_plankton.log || (lib_plankton.log = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:log«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:log« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:lang« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:log«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var log;
|
||
(function (log) {
|
||
/**
|
||
*/
|
||
var class_channel = /** @class */ (function () {
|
||
function class_channel() {
|
||
}
|
||
return class_channel;
|
||
}());
|
||
log.class_channel = class_channel;
|
||
})(log = lib_plankton.log || (lib_plankton.log = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:log«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:log« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:lang« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:log«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var log;
|
||
(function (log) {
|
||
/**
|
||
* output for writing log entries to stdout
|
||
*/
|
||
var class_channel_stdout = /** @class */ (function (_super) {
|
||
__extends(class_channel_stdout, _super);
|
||
function class_channel_stdout() {
|
||
return _super !== null && _super.apply(this, arguments) || this;
|
||
}
|
||
/**
|
||
*/
|
||
class_channel_stdout.prototype.add = function (entry) {
|
||
process.stdout.write(("<" + (new Date(Date.now())).toISOString().slice(0, 19) + ">")
|
||
+
|
||
" "
|
||
+
|
||
("[" + log.level_show(entry.level) + "]")
|
||
+
|
||
" "
|
||
+
|
||
("" + entry.incident + "")
|
||
+
|
||
": "
|
||
+
|
||
JSON.stringify(entry.details, undefined, " ")
|
||
+
|
||
"\n");
|
||
};
|
||
return class_channel_stdout;
|
||
}(log.class_channel));
|
||
log.class_channel_stdout = class_channel_stdout;
|
||
})(log = lib_plankton.log || (lib_plankton.log = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:log«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:log« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:lang« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:log«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var log;
|
||
(function (log) {
|
||
/**
|
||
*/
|
||
var class_channel_file = /** @class */ (function (_super) {
|
||
__extends(class_channel_file, _super);
|
||
/**
|
||
* [constructor]
|
||
*/
|
||
function class_channel_file(path, human_readable) {
|
||
var _this = _super.call(this) || this;
|
||
_this.path = path;
|
||
_this.human_readable = human_readable;
|
||
return _this;
|
||
}
|
||
/**
|
||
*/
|
||
class_channel_file.prototype.add = function (entry) {
|
||
var _this = this;
|
||
var nm_fs = require("fs");
|
||
var line = (this.human_readable
|
||
? (("<" + (new Date(Date.now())).toISOString().slice(0, 19) + ">")
|
||
+
|
||
" "
|
||
+
|
||
("[" + log.level_show(entry.level) + "]")
|
||
+
|
||
" "
|
||
+
|
||
("" + entry.incident + "")
|
||
+
|
||
": "
|
||
+
|
||
JSON.stringify(entry.details, undefined, " ")
|
||
+
|
||
"\n")
|
||
: (JSON.stringify({
|
||
"timestamp": lib_plankton.base.get_current_timestamp(),
|
||
"level_number": entry.level,
|
||
"level_name": log.level_show(entry.level),
|
||
"incident": entry.incident,
|
||
"details": entry.details
|
||
})
|
||
+
|
||
"\n"));
|
||
nm_fs.writeFile(this.path, line, {
|
||
"flag": "a+"
|
||
}, function (error) {
|
||
if (error !== null) {
|
||
process.stderr.write('-- [plankton] could not add log entry to file ' + _this.path + "\n");
|
||
}
|
||
else {
|
||
// do nothing
|
||
}
|
||
});
|
||
};
|
||
return class_channel_file;
|
||
}(log.class_channel));
|
||
log.class_channel_file = class_channel_file;
|
||
})(log = lib_plankton.log || (lib_plankton.log = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:log«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:log« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:lang« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:log«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var log;
|
||
(function (log) {
|
||
/**
|
||
*/
|
||
var class_channel_email = /** @class */ (function (_super) {
|
||
__extends(class_channel_email, _super);
|
||
/**
|
||
* [constructor]
|
||
*/
|
||
function class_channel_email(smtp_credentials, sender, receivers) {
|
||
var _this = _super.call(this) || this;
|
||
_this.smtp_credentials = smtp_credentials;
|
||
_this.sender = sender;
|
||
_this.receivers = receivers;
|
||
return _this;
|
||
}
|
||
/**
|
||
*/
|
||
class_channel_email.prototype.add = function (entry) {
|
||
var nm_fs = require("fs");
|
||
lib_plankton.email.send(this.smtp_credentials, this.sender, this.receivers, (("[" + log.level_show(entry.level) + "]")
|
||
+
|
||
" "
|
||
+
|
||
("" + entry.incident + "")), JSON.stringify(entry.details, undefined, " "));
|
||
};
|
||
return class_channel_email;
|
||
}(log.class_channel));
|
||
log.class_channel_email = class_channel_email;
|
||
})(log = lib_plankton.log || (lib_plankton.log = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:log«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:log« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:lang« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:log«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var log;
|
||
(function (log) {
|
||
/**
|
||
* output for desktop notifications via "libnotify"
|
||
*/
|
||
var class_channel_notify = /** @class */ (function (_super) {
|
||
__extends(class_channel_notify, _super);
|
||
function class_channel_notify() {
|
||
return _super !== null && _super.apply(this, arguments) || this;
|
||
}
|
||
/**
|
||
*/
|
||
class_channel_notify.prototype.add = function (entry) {
|
||
var nm_child_process = require("child_process");
|
||
var command = ("notify-send"
|
||
+
|
||
" "
|
||
+
|
||
("'"
|
||
+
|
||
("[" + log.level_show(entry.level) + "]")
|
||
+
|
||
" "
|
||
+
|
||
entry.incident
|
||
+
|
||
"'")
|
||
+
|
||
" "
|
||
+
|
||
("'"
|
||
+
|
||
(Object.keys(entry.details)
|
||
.map(function (key) { return (key + ": " + JSON.stringify(entry.details[key])); })
|
||
.join("\n"))
|
||
+
|
||
"'"));
|
||
nm_child_process.exec(command, function (error, stdout, stderr) {
|
||
// do noting
|
||
});
|
||
};
|
||
return class_channel_notify;
|
||
}(log.class_channel));
|
||
log.class_channel_notify = class_channel_notify;
|
||
})(log = lib_plankton.log || (lib_plankton.log = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:log«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:log« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:lang« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:log«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var log;
|
||
(function (log) {
|
||
/**
|
||
* decorator for filtering out log entries below a certain level threshold
|
||
*/
|
||
var class_channel_minlevel = /** @class */ (function (_super) {
|
||
__extends(class_channel_minlevel, _super);
|
||
/**
|
||
*/
|
||
function class_channel_minlevel(core, threshold) {
|
||
var _this = _super.call(this) || this;
|
||
_this.core = core;
|
||
_this.threshold = threshold;
|
||
return _this;
|
||
}
|
||
/**
|
||
*/
|
||
class_channel_minlevel.prototype.add = function (entry) {
|
||
if (!log.level_order(this.threshold, entry.level)) {
|
||
// do nothing
|
||
}
|
||
else {
|
||
this.core.add(entry);
|
||
}
|
||
};
|
||
return class_channel_minlevel;
|
||
}(log.class_channel));
|
||
log.class_channel_minlevel = class_channel_minlevel;
|
||
})(log = lib_plankton.log || (lib_plankton.log = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:log«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:log« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:lang« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:log«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var log;
|
||
(function (log) {
|
||
/**
|
||
*/
|
||
function translate_level(level_string) {
|
||
return {
|
||
"debug": log.enum_level.debug,
|
||
"info": log.enum_level.info,
|
||
"notice": log.enum_level.notice,
|
||
"warning": log.enum_level.warning,
|
||
"error": log.enum_level.error
|
||
}[level_string];
|
||
}
|
||
/**
|
||
*/
|
||
function channel_make(description) {
|
||
var _a, _b, _c, _d, _e;
|
||
switch (description.kind) {
|
||
default: {
|
||
throw (new Error("unhandled log channel kind: " + description.kind));
|
||
break;
|
||
}
|
||
case "stdout": {
|
||
return (new log.class_channel_minlevel(new log.class_channel_stdout(), translate_level((_a = description.data["threshold"]) !== null && _a !== void 0 ? _a : "debug")));
|
||
break;
|
||
}
|
||
case "file": {
|
||
return (new log.class_channel_minlevel(new log.class_channel_file(((_b = description.data["path"]) !== null && _b !== void 0 ? _b : "/tmp/plankton.log"), false), translate_level((_c = description.data["threshold"]) !== null && _c !== void 0 ? _c : "debug")));
|
||
break;
|
||
}
|
||
case "email": {
|
||
return (new log.class_channel_minlevel(new log.class_channel_email(description.data["smtp_credentials"], description.data["sender"], description.data["receivers"]), translate_level((_d = description.data["threshold"]) !== null && _d !== void 0 ? _d : "debug")));
|
||
break;
|
||
}
|
||
case "notify": {
|
||
return (new log.class_channel_minlevel(new log.class_channel_notify(), translate_level((_e = description.data["threshold"]) !== null && _e !== void 0 ? _e : "debug")));
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
log.channel_make = channel_make;
|
||
/**
|
||
*/
|
||
function conf_default() {
|
||
return [
|
||
new log.class_channel_minlevel(new log.class_channel_stdout(), log.enum_level.notice),
|
||
new log.class_channel_minlevel(new log.class_channel_notify(), log.enum_level.error),
|
||
];
|
||
}
|
||
log.conf_default = conf_default;
|
||
})(log = lib_plankton.log || (lib_plankton.log = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:log«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:log« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:lang« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:log«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var log;
|
||
(function (log) {
|
||
/**
|
||
*/
|
||
var _channel_stack = null;
|
||
/**
|
||
* pushes a new configuration on the stack and activates it
|
||
*/
|
||
function conf_push(channels) {
|
||
if (_channel_stack === null) {
|
||
_channel_stack = [];
|
||
}
|
||
_channel_stack.push(channels);
|
||
}
|
||
log.conf_push = conf_push;
|
||
/**
|
||
* pops the current active configuration from the stack
|
||
*/
|
||
function conf_pop() {
|
||
if (_channel_stack.length > 0) {
|
||
_channel_stack.pop();
|
||
}
|
||
else {
|
||
// do nothing
|
||
}
|
||
}
|
||
log.conf_pop = conf_pop;
|
||
/**
|
||
* makes the logging system ready
|
||
*/
|
||
function setup() {
|
||
if (_channel_stack === null) {
|
||
_channel_stack = [];
|
||
conf_push(log.conf_default());
|
||
}
|
||
else {
|
||
// do nothing
|
||
}
|
||
}
|
||
/**
|
||
* consumes a log entry, i.e. sends it to the currently active outputs
|
||
*/
|
||
function add(entry) {
|
||
setup();
|
||
_channel_stack.slice(-1)[0].forEach(function (channel) { return channel.add(entry); });
|
||
}
|
||
log.add = add;
|
||
/**
|
||
*/
|
||
function debug(incident, details) {
|
||
if (details === void 0) { details = {}; }
|
||
add({ "level": log.enum_level.debug, "incident": incident, "details": details });
|
||
}
|
||
log.debug = debug;
|
||
/**
|
||
*/
|
||
function info(incident, details) {
|
||
if (details === void 0) { details = {}; }
|
||
add({ "level": log.enum_level.info, "incident": incident, "details": details });
|
||
}
|
||
log.info = info;
|
||
/**
|
||
*/
|
||
function notice(incident, details) {
|
||
if (details === void 0) { details = {}; }
|
||
add({ "level": log.enum_level.notice, "incident": incident, "details": details });
|
||
}
|
||
log.notice = notice;
|
||
/**
|
||
*/
|
||
function warning(incident, details) {
|
||
if (details === void 0) { details = {}; }
|
||
add({ "level": log.enum_level.warning, "incident": incident, "details": details });
|
||
}
|
||
log.warning = warning;
|
||
/**
|
||
*/
|
||
function error(incident, details) {
|
||
if (details === void 0) { details = {}; }
|
||
add({ "level": log.enum_level.error, "incident": incident, "details": details });
|
||
}
|
||
log.error = error;
|
||
})(log = lib_plankton.log || (lib_plankton.log = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:log«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:log« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:lang« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:log«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var log;
|
||
(function (log) {
|
||
/**
|
||
*/
|
||
log.conf_push([
|
||
log.channel_make({
|
||
"kind": "stdout",
|
||
"data": {
|
||
"threshold": "info"
|
||
}
|
||
}),
|
||
]);
|
||
})(log = lib_plankton.log || (lib_plankton.log = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:string«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:string« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:string« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:string«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var plain_text_to_html = function (text) {
|
||
let ret = text;
|
||
ret = ret.replace(/ /g, " "); // convert multiple whitespace to forced ones
|
||
ret = ret.split("\n").join("<br/>");
|
||
return ret;
|
||
};
|
||
/**
|
||
* @desc makes a valid
|
||
*/
|
||
var format_sentence = function (str, rtl = false, caseSense = true) {
|
||
if (str === "") {
|
||
return str;
|
||
}
|
||
else {
|
||
let marks = {
|
||
".": true,
|
||
"?": true,
|
||
"!": true
|
||
};
|
||
let default_mark = ".";
|
||
let ret = str.split("");
|
||
if (!rtl) {
|
||
ret[0] = ret[0].toLocaleUpperCase();
|
||
if (!(ret[ret.length - 1] in marks)) {
|
||
ret.push(default_mark);
|
||
}
|
||
}
|
||
else {
|
||
ret[ret.length - 1] = ret[ret.length - 1].toLocaleUpperCase();
|
||
if (!(ret[0] in marks)) {
|
||
ret.unshift(default_mark);
|
||
}
|
||
}
|
||
return ret.join("");
|
||
}
|
||
};
|
||
var fill_string_template = function (template_string, object, fabric = function (object, key) { return object[key]; }, delimiter = "%", default_string = null, sloppy) {
|
||
function get_tags(str) {
|
||
let r = new RegExp(delimiter + "[^\\s^" + delimiter + "]+" + delimiter, "gi");
|
||
return ((str.match(r) || []).map(function (e) {
|
||
return e.slice(delimiter.length, e.length - delimiter.length);
|
||
}));
|
||
}
|
||
function replace_tag(str, tag, value) {
|
||
let r = new RegExp(delimiter + tag + delimiter, "gi");
|
||
return str.replace(r, value);
|
||
}
|
||
function replace_tags(str, obj) {
|
||
return (get_tags(str).reduce(function (ret, key) {
|
||
let value = "";
|
||
try {
|
||
value = fabric(obj, key);
|
||
if ((!sloppy && (value === void 0)) || (sloppy && (value == void 0))) {
|
||
value = default_string;
|
||
}
|
||
}
|
||
catch (e) {
|
||
console.warn("invalid placeholder " + key);
|
||
value = default_string;
|
||
}
|
||
return replace_tag(ret, key, value);
|
||
}, str));
|
||
}
|
||
return replace_tags(template_string, object);
|
||
};
|
||
var make_string_template = function (_template, _fabrics = {}) {
|
||
function replace_tag(str, tag, value) {
|
||
var r = new RegExp("%" + tag + "%", "gi");
|
||
return str.replace(r, value);
|
||
}
|
||
function replace_tags(str, obj) {
|
||
return (Object.keys(obj).reduce(function (ret, key) {
|
||
return replace_tag(ret, key, _fabrics[key] || obj[key]);
|
||
}, str));
|
||
}
|
||
return (function (tags) {
|
||
return replace_tags(_template, tags);
|
||
});
|
||
};
|
||
var make_eml_header = (function () {
|
||
let _template = "";
|
||
_template += "From: %from%\n";
|
||
_template += "To: %recipient%\n";
|
||
_template += "Subject: %subject%\n";
|
||
_template += "X-Mailer: greenscale-plankton.emlgen\n";
|
||
return make_string_template(_template);
|
||
})();
|
||
var make_eml_body = (function () {
|
||
let exports = {};
|
||
exports["simple_body"] = make_string_template("Content-Type: %contenttype%\n\n%body%\n\n");
|
||
// very basic implementation
|
||
// parts = [{contenttype:"text/html; charset=UTF-8", body: "<h1>foo</h1>" }, {...}]
|
||
exports["body_boundrary"] = function (parts, boundrary) {
|
||
let _template = "";
|
||
_template += "--%boundrary%\n";
|
||
_template += "Content-Type: %contenttype%\n\n%body%\n\n";
|
||
//_template += "--%boundrary%--\n\n";
|
||
let maker = make_string_template(_template);
|
||
return (parts.reduce(function (prev, curr) {
|
||
curr.boundrary = boundrary;
|
||
return [prev, maker(curr)].join("");
|
||
}, ""));
|
||
};
|
||
// body must be base64 encoded!
|
||
exports["attachment_boundrary"] = function (parts, boundrary) {
|
||
let _template = "";
|
||
_template += "--%boundrary%\n";
|
||
_template += "Content-Type: %contenttype%\n";
|
||
_template += "Content-Transfer-Encoding: base64\n";
|
||
_template += "Content-Disposition: %disposition%; filename=\"%name%\"\n\n";
|
||
_template += "%body%\n\n";
|
||
//_template += "--%boundrary%--\n\n";
|
||
let maker = make_string_template(_template);
|
||
return (parts.reduce(function (prev, curr) {
|
||
curr.boundrary = boundrary;
|
||
if (curr.disposition === void 0)
|
||
curr.disposition = "inline";
|
||
return [prev, maker(curr)].join("");
|
||
}, ""));
|
||
};
|
||
exports["gen_boundrary"] = function () {
|
||
return ("xxxxxxxxxxxxxxxxxxxxxx".replace(/[xy]/g, function (c) {
|
||
let r = crypto.getRandomValues(new Uint8Array(1))[0] % 16 | 0, v = c == "x" ? r : (r & 0x3 | 0x8);
|
||
return v.toString(16);
|
||
}));
|
||
};
|
||
// simple implementation without alternatives (old rfc)
|
||
exports["complete_boundrary"] = function (bodyparts, attachments) {
|
||
let ret = "";
|
||
let boundrary = exports["gen_boundrary"]();
|
||
ret += exports["body_boundrary"](bodyparts, boundrary);
|
||
ret += exports["attachment_boundrary"](attachments, boundrary);
|
||
ret += "--" + boundrary + "--\n\nINVISIBLE!!!!";
|
||
return (exports["simple_body"]({
|
||
"contenttype": sprintf("multipart/mixed; boundary=%s", [boundrary]),
|
||
"body": ret
|
||
}));
|
||
};
|
||
return exports;
|
||
})();
|
||
/*
|
||
This file is part of »bacterio-plankton:string«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:string« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:string« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:string«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var string;
|
||
(function (string) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
const hexdigits = 4;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
const index_max = (1 << (4 * hexdigits));
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
var index_is = 0;
|
||
/**
|
||
* @author neuc,frac
|
||
*/
|
||
function empty(str) {
|
||
return (str.trim() === "");
|
||
}
|
||
string.empty = empty;
|
||
/**
|
||
* @desc returns a unique string
|
||
* @param {string} prefix an optional prefix for the generated string
|
||
* @return {string}
|
||
* @author fenris
|
||
*/
|
||
function generate(prefix = "string_") {
|
||
if (index_is > index_max) {
|
||
throw (new Error("[string_generate] out of valid indices"));
|
||
}
|
||
else {
|
||
return string.sprintf(prefix + "%0" + hexdigits.toString() + "X", [index_is++]);
|
||
}
|
||
}
|
||
string.generate = generate;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function join(parts, glue = " ") {
|
||
if (parts.length == 0) {
|
||
return "";
|
||
}
|
||
else {
|
||
return parts.join(glue);
|
||
}
|
||
}
|
||
string.join = join;
|
||
/**
|
||
* @desc splits a string, but returns an empty list, if the string is empty
|
||
* @param {string} chain
|
||
* @param {string} separator
|
||
* @return {Array<string>}
|
||
* @author fenris
|
||
*/
|
||
function split(chain, separator = " ") {
|
||
if (chain.length == 0) {
|
||
return [];
|
||
}
|
||
else {
|
||
return chain.split(separator);
|
||
}
|
||
}
|
||
string.split = split;
|
||
/**
|
||
* @author neu3no
|
||
*/
|
||
function explode(str, needle, max) {
|
||
let temp = str.split(needle);
|
||
const right = temp.splice(max - 1);
|
||
temp.push(right.join(needle));
|
||
return temp;
|
||
}
|
||
string.explode = explode;
|
||
/**
|
||
* @desc concats a given word with itself n times
|
||
* @param {string} word
|
||
* @param {int}
|
||
* @return {string}
|
||
* @author fenris
|
||
*/
|
||
function repeat(word, count) {
|
||
// return ((count == 0) ? "" : (word + repeat(word, count-1)));
|
||
let result = "";
|
||
for (let n = 0; n < count; n += 1) {
|
||
result += word;
|
||
}
|
||
return result;
|
||
}
|
||
string.repeat = repeat;
|
||
/**
|
||
* @desc lengthens a string by repeatedly appending or prepending another string
|
||
* @param {string} word the string to pad
|
||
* @param {int} length the length, which the result shall have
|
||
* @param {string} symbol the string, which will be added (multiple times)
|
||
* @param {boolean} [prepend]; whether to prepend (~true) or append (~false); default: false
|
||
* @return {string} the padded string
|
||
* @author fenris
|
||
*/
|
||
function pad(word, length, symbol = " ", mode = "append") {
|
||
switch (mode) {
|
||
case "prepend": {
|
||
// insert symbols only at the beginning
|
||
while (word.length < length)
|
||
word = symbol + word;
|
||
return word.substring(word.length - length);
|
||
break;
|
||
}
|
||
case "append": {
|
||
// insert symbols only at the end
|
||
while (word.length < length)
|
||
word = word + symbol;
|
||
return word.substring(0, length);
|
||
break;
|
||
}
|
||
case "widen": {
|
||
// insert symbols at both sides
|
||
let left = (((length - word.length) & 1) === 0);
|
||
while (word.length < length) {
|
||
word = (left
|
||
? (symbol + word)
|
||
: (word + symbol));
|
||
left = (!left);
|
||
}
|
||
return word.substring(0, length);
|
||
break;
|
||
}
|
||
default: {
|
||
const message = ("unhandled mode '" + mode + "'");
|
||
console.warn(message);
|
||
return word;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
string.pad = pad;
|
||
/**
|
||
* @desc checks if a given string conttains a certain substring
|
||
* @param {string} string
|
||
* @param {string} part
|
||
* @return {boolean}
|
||
* @author fenris
|
||
*/
|
||
function contains(chain, part) {
|
||
if (typeof (chain) !== "string") {
|
||
return false;
|
||
}
|
||
return (chain.indexOf(part) >= 0);
|
||
}
|
||
string.contains = contains;
|
||
/**
|
||
* @desc checks if a given string starts with a certain substring
|
||
* @param {string} string
|
||
* @param {string} part
|
||
* @return {boolean}
|
||
* @author fenris
|
||
*/
|
||
function startsWith(chain, part) {
|
||
if (typeof (chain) !== "string") {
|
||
return false;
|
||
}
|
||
// return (string.indexOf(part) === 0);
|
||
return ((function (m, n) {
|
||
if (n === 0) {
|
||
return true;
|
||
}
|
||
else {
|
||
if (m === 0) {
|
||
return false;
|
||
}
|
||
else {
|
||
return ((chain[0] == part[0])
|
||
&&
|
||
startsWith(chain.substring(1), part.substring(1)));
|
||
}
|
||
}
|
||
})(chain.length, part.length));
|
||
}
|
||
string.startsWith = startsWith;
|
||
/**
|
||
* @desc checks if a given string ends with a certain substring
|
||
* @param {string} string
|
||
* @param {string} part
|
||
* @return {boolean}
|
||
* @author fenris
|
||
*/
|
||
function endsWith(chain, part) {
|
||
if (typeof (chain) !== "string") {
|
||
return false;
|
||
}
|
||
// return (string.lastIndexOf(part) === string.length-part.length);
|
||
return ((function (m, n) {
|
||
if (n === 0) {
|
||
return true;
|
||
}
|
||
else {
|
||
if (m === 0) {
|
||
return false;
|
||
}
|
||
else {
|
||
// console.info(("(" + string[m-1] + " == " + part[n-1] + ")") + " = " + String(string[m-1] == part[n-1]));
|
||
return ((chain[m - 1] === part[n - 1])
|
||
&&
|
||
endsWith(chain.substring(0, m - 1), part.substring(0, n - 1)));
|
||
}
|
||
}
|
||
})(chain.length, part.length));
|
||
}
|
||
string.endsWith = endsWith;
|
||
/**
|
||
* @desc count the occourrences of a string in a string
|
||
* @param string haystack_string the string wich should be examined
|
||
* @param string needle_string the string which should be counted
|
||
* @author neuc
|
||
*/
|
||
function count_occourrences(haystack_string, needle_string, check_escape) {
|
||
let cnt = 0;
|
||
let pos = -1;
|
||
do {
|
||
pos = haystack_string.indexOf(needle_string, pos + 1);
|
||
if ((!check_escape) || (haystack_string[pos - 1] != "\\")) {
|
||
cnt++;
|
||
}
|
||
} while (pos >= 0);
|
||
return (cnt - 1);
|
||
}
|
||
string.count_occourrences = count_occourrences;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function replace(str, replacements, options = {}) {
|
||
options = Object.assign({}, options);
|
||
let result = str;
|
||
replacements.forEach(replacement => {
|
||
lib_plankton.log.debug("lib_plankton.string.replace", {
|
||
"from": replacement.from,
|
||
"to": replacement.to,
|
||
});
|
||
result = result.replace(new RegExp(replacement.from, "g"), replacement.to);
|
||
});
|
||
return result;
|
||
}
|
||
string.replace = replace;
|
||
/**
|
||
* @desc replaces occurences of "{{name}}" in a string by the corresponding values of an argument object
|
||
* @author fenris
|
||
*/
|
||
function coin(str, args, options = {}) {
|
||
options = Object.assign({
|
||
"legacy": false,
|
||
"open": "{{",
|
||
"close": "}}",
|
||
}, options);
|
||
Object.keys(args).forEach((key) => {
|
||
// old syntax
|
||
{
|
||
if (options.legacy) {
|
||
const value = args[key];
|
||
const regexp_argument = new RegExp("\\${" + key + "}", "g");
|
||
lib_plankton.log.debug("lib_plankton.string.coin", {
|
||
"key": key,
|
||
"regex": regexp_argument.toString(),
|
||
"value": value,
|
||
});
|
||
str = str.replace(regexp_argument, value);
|
||
}
|
||
}
|
||
// new syntax
|
||
{
|
||
const value = args[key];
|
||
const regexp_argument = new RegExp(options.open + key + options.close, "g");
|
||
lib_plankton.log.debug("lib_plankton.string.coin", {
|
||
"key": key,
|
||
"regex": regexp_argument.toString(),
|
||
"value": value,
|
||
});
|
||
str = str.replace(regexp_argument, value);
|
||
}
|
||
});
|
||
return str;
|
||
}
|
||
string.coin = coin;
|
||
/**
|
||
* @author fenris
|
||
* @deprecated use limit
|
||
*/
|
||
function cut(str, length, delimiter = "…") {
|
||
if (str.length <= length) {
|
||
return str;
|
||
}
|
||
else {
|
||
return (str.slice(0, length - delimiter.length) + delimiter);
|
||
}
|
||
}
|
||
string.cut = cut;
|
||
/**
|
||
*/
|
||
function limit(str, options = {}) {
|
||
options = Object.assign({
|
||
"length": 120,
|
||
"indicator": "…",
|
||
}, options);
|
||
return ((str.length <= options.length)
|
||
? str
|
||
: (str.slice(0, options.length - options.indicator.length) + options.indicator));
|
||
}
|
||
string.limit = limit;
|
||
/**
|
||
*/
|
||
function slice(str, size) {
|
||
let slices = [];
|
||
let rest = str;
|
||
while (rest.length > 0) {
|
||
slices.push(rest.slice(0, size));
|
||
rest = rest.slice(size);
|
||
}
|
||
return slices;
|
||
}
|
||
string.slice = slice;
|
||
})(string = lib_plankton.string || (lib_plankton.string = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/**
|
||
* @deprecated
|
||
*/
|
||
var lib_string;
|
||
(function (lib_string) {
|
||
lib_string.empty = lib_plankton.string.empty;
|
||
lib_string.generate = lib_plankton.string.generate;
|
||
lib_string.split = lib_plankton.string.split;
|
||
lib_string.explode = lib_plankton.string.repeat;
|
||
lib_string.repeat = lib_plankton.string.repeat;
|
||
lib_string.pad = lib_plankton.string.pad;
|
||
lib_string.contains = lib_plankton.string.contains;
|
||
lib_string.startsWith = lib_plankton.string.startsWith;
|
||
lib_string.endsWith = lib_plankton.string.endsWith;
|
||
lib_string.count_occourrences = lib_plankton.string.count_occourrences;
|
||
lib_string.coin = lib_plankton.string.coin;
|
||
lib_string.stance = lib_plankton.string.coin;
|
||
lib_string.cut = lib_plankton.string.cut;
|
||
})(lib_string || (lib_string = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:string«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:string« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:string« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:string«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var string;
|
||
(function (string) {
|
||
var pattern = /%([-+#0 ]*)([0-9]*)[\.]{0,1}([0-9]*)([\w]{1})/;
|
||
var gpattern = /%([-+#0 ]*)([0-9]*)[\.]{0,1}([0-9]*)([\w]{1})/g;
|
||
function split_format(format) {
|
||
var tmp = format.match(pattern);
|
||
if (tmp === null)
|
||
return null;
|
||
return {
|
||
'flags': tmp[1].split(""),
|
||
'width': Number(tmp[2]),
|
||
'precision': tmp[3] === '' ? null : Number(tmp[3]),
|
||
'specifier': tmp[4],
|
||
'string': format
|
||
};
|
||
}
|
||
function make_err(format, arg, should) {
|
||
return ("[sprintf]" + " " + "argument for '" + format.string + "' has to be '" + should + "' but '" + arg + "' is '" + typeof arg + "'!");
|
||
}
|
||
function test_arg(format, arg, should) {
|
||
if (typeof arg !== should) {
|
||
console.warn(make_err(format, arg, should));
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
function string_fill(str, char, len, left) {
|
||
while (str.length < len) {
|
||
if (left) {
|
||
str += char;
|
||
}
|
||
else {
|
||
str = char + str;
|
||
}
|
||
}
|
||
return str;
|
||
}
|
||
/**
|
||
* the known_parameters are used to parse the different identifiers for the welln known syntax:
|
||
* flag width precision identifier
|
||
* %{[0#+- ]}{[0-9]*}.{[0-9]*}[fFdiueEgGsoxXaAsn]
|
||
* flags:
|
||
* 0 - fill with '0' instead of ' ' if the string length < width
|
||
* # - not implemented
|
||
* - - left-justified -> fill on the right side to reach width
|
||
* + - force using '+' on positive numbers
|
||
* ' ' - add a single space before positive numbers
|
||
*
|
||
* identifiers
|
||
* %f, %F - interpret given number as float, width: the minimal total width (fill with ' ' or '0' if the
|
||
* resulting string is too short, precision: cut more then given decimal places
|
||
* %d, %i, %u - interpret number as integer, decimal places will be cut. width: like float, precision:
|
||
* fill with '0' on right side until length given in precision is reached
|
||
* %e - interpret as float and write as scientifical number, width & precision like in float
|
||
* %E - same es %e but uppercase 'E'
|
||
* %g - use the shortest string of %f or %e
|
||
* %G - use the shortest string of %E or %E
|
||
* %s - simply print a string
|
||
* %o - print the given number in octal notation
|
||
* %x - print the given number in hex notation
|
||
* %X - same as %x but with uppercase characters
|
||
* %a - alias to %x
|
||
* %A - alias to %X
|
||
* %n - just print nothing
|
||
* @type {{}}
|
||
*/
|
||
var known_params = {};
|
||
known_params["f"] = function (format, arg) {
|
||
if (!test_arg(format, arg, "number"))
|
||
return "Ø";
|
||
var tmp = Math.abs(arg);
|
||
var sign = (arg < 0) ? -1 : 1;
|
||
var tmp_result = null;
|
||
if (format.precision !== null) {
|
||
tmp = Math.floor(Math.pow(10, format.precision) * tmp) / Math.pow(10, format.precision);
|
||
var tmp_ = (tmp * sign).toString().split(".");
|
||
if (tmp_.length === 1)
|
||
tmp_.push("");
|
||
tmp_[1] = string_fill(tmp_[1], "0", format.precision, true);
|
||
tmp_result = tmp_.join(".");
|
||
}
|
||
else {
|
||
tmp_result = (sign * tmp).toString();
|
||
}
|
||
if ((format.flags.indexOf(" ") >= 0) && (arg >= 0)) {
|
||
tmp_result = " " + tmp;
|
||
}
|
||
else if ((format.flags.indexOf("+") >= 0) && (arg >= 0)) {
|
||
tmp_result = "+" + tmp;
|
||
}
|
||
tmp_result = string_fill(tmp, (format.flags.indexOf("0") >= 0) ? "0" : " ", format.width, (format.flags.indexOf("-") >= 0));
|
||
return tmp_result;
|
||
};
|
||
known_params["F"] = known_params["f"];
|
||
known_params["d"] = function (format, arg) {
|
||
if (!test_arg(format, arg, 'number'))
|
||
return 'Ø';
|
||
var tmp = (((arg < 0 && format.specifier !== 'u') ? -1 : 1) * Math.floor(Math.abs(arg))).toString();
|
||
if ((format.specifier === 'd' || format.specifier === 'i') && format.flags.indexOf(' ') >= 0 && arg >= 0) {
|
||
tmp = ' ' + tmp;
|
||
}
|
||
else if ((format.specifier === 'd' || format.specifier === 'i') && format.flags.indexOf('+') >= 0 && arg >= 0) {
|
||
tmp = '+' + tmp;
|
||
}
|
||
tmp = string_fill(tmp, format.flags.indexOf('0') >= 0 ? '0' : ' ', format.width, format.flags.indexOf('-') >= 0);
|
||
tmp = string_fill(tmp, '0', format.precision === null ? 0 : format.precision, false);
|
||
return tmp;
|
||
};
|
||
known_params["i"] = known_params["d"];
|
||
known_params["u"] = known_params["d"];
|
||
known_params["e"] = function (format, arg) {
|
||
if (!test_arg(format, arg, 'number'))
|
||
return 'Ø';
|
||
var tmp = arg.toExponential(format.precision === null ? undefined : format.precision).toString();
|
||
if (format.flags.indexOf(' ') >= 0 && arg >= 0) {
|
||
tmp = ' ' + tmp;
|
||
}
|
||
else if (format.flags.indexOf('+') >= 0 && arg >= 0) {
|
||
tmp = '+' + tmp;
|
||
}
|
||
tmp = string_fill(tmp, format.flags.indexOf('0') >= 0 ? '0' : ' ', format.width, format.flags.indexOf('-') >= 0);
|
||
return tmp;
|
||
};
|
||
known_params["E"] = function (format, arg) {
|
||
return known_params["e"](format, arg).toUpperCase();
|
||
};
|
||
known_params["g"] = function (format, arg) {
|
||
if (!test_arg(format, arg, 'number'))
|
||
return 'Ø';
|
||
var tmpf = known_params["f"](format, arg);
|
||
var tmpe = known_params["e"](format, arg);
|
||
if (tmpf.length < tmpe.length) {
|
||
return tmpf;
|
||
}
|
||
else {
|
||
return tmpe;
|
||
}
|
||
};
|
||
known_params["G"] = function (format, arg) {
|
||
return known_params["g"](format, arg).toUpperCase();
|
||
};
|
||
known_params["s"] = function (format, arg) {
|
||
if (!test_arg(format, arg, 'string'))
|
||
return 'o.O';
|
||
var tmp = format.precision !== null ? arg.substr(0, format.precision) : arg;
|
||
tmp = string_fill(tmp, format.flags.indexOf('0') >= 0 ? '0' : ' ', format.width, format.flags.indexOf('-') >= 0);
|
||
return tmp;
|
||
};
|
||
known_params["o"] = function (format, arg) {
|
||
if (!test_arg(format, arg, 'number'))
|
||
return 'Ø';
|
||
var tmp = Math.floor(Math.round(Math.abs(arg))) * ((arg < 0) ? -1 : 1);
|
||
return known_params["s"](format, tmp.toString(8));
|
||
};
|
||
known_params["x"] = function (format, arg) {
|
||
if (!test_arg(format, arg, 'number'))
|
||
return 'Ø';
|
||
var tmp = Math.floor(Math.round(Math.abs(arg))) * ((arg < 0) ? -1 : 1);
|
||
return known_params["s"](format, tmp.toString(16));
|
||
};
|
||
known_params["a"] = known_params["x"];
|
||
known_params["X"] = function (format, arg) {
|
||
if (!test_arg(format, arg, 'number'))
|
||
return 'Ø';
|
||
return known_params["x"](format, arg).toUpperCase();
|
||
};
|
||
known_params["A"] = known_params["X"];
|
||
known_params["c"] = function (format, arg) {
|
||
var tmp = "";
|
||
if (typeof arg === "number") {
|
||
tmp = String.fromCharCode(arg);
|
||
}
|
||
else if ((typeof arg === "string") && (arg.length === 1)) {
|
||
tmp = arg[0];
|
||
}
|
||
else {
|
||
console.warn(make_err(format, arg, "number|string") + " and if string it needs to have the length of 1!");
|
||
}
|
||
return known_params["s"](format, tmp);
|
||
};
|
||
known_params["n"] = function () {
|
||
return "";
|
||
};
|
||
var decompose = function (chain, regexp) {
|
||
var result = regexp.exec(chain);
|
||
if (result == null) {
|
||
return null;
|
||
}
|
||
else {
|
||
var front = chain.substring(0, result.index);
|
||
var back = chain.substring(result.index + result[0].length);
|
||
return { "front": front, "match": result[0], "back": back };
|
||
}
|
||
};
|
||
/**
|
||
* an implementation of c sprintf
|
||
* @param {string} string format string
|
||
* @param {array} args arguments which should be filled into
|
||
* @returns {string}
|
||
*/
|
||
string.sprintf = function (input, args = [], original = null) {
|
||
if (original == null)
|
||
original = input;
|
||
var components = decompose(input, pattern);
|
||
if (components == null) {
|
||
if (args.length > 0) {
|
||
console.warn("[sprintf] superfluous arguments while formatting '" + original + "': ", args);
|
||
}
|
||
return input;
|
||
}
|
||
else {
|
||
var arg;
|
||
var rest;
|
||
if (args.length > 0) {
|
||
arg = args[0];
|
||
rest = args.slice(1);
|
||
}
|
||
else {
|
||
console.warn("[sprintf] out of arguments while formatting '" + original + "'");
|
||
arg = null;
|
||
rest = [];
|
||
return input;
|
||
}
|
||
var fmt = split_format(components["match"]);
|
||
return (components["front"]
|
||
+ known_params[fmt.specifier](fmt, arg)
|
||
+ string.sprintf(components["back"], rest, original));
|
||
}
|
||
};
|
||
/**
|
||
* an implementation of c printf
|
||
* @param {string} string format string
|
||
* @param {array} args arguments which should be filled into
|
||
* @returns {string}
|
||
*/
|
||
function printf(format, args) {
|
||
console.log(string.sprintf(format, args));
|
||
}
|
||
string.printf = printf;
|
||
})(string = lib_plankton.string || (lib_plankton.string = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
var sprintf = lib_plankton.string.sprintf;
|
||
var printf = lib_plankton.string.printf;
|
||
/*
|
||
This file is part of »bacterio-plankton:string«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:string« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:string« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:string«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var make_logger = (function () {
|
||
var _loggers = {};
|
||
var make_logger = function (prefix, current_loglevel) {
|
||
var log = [];
|
||
var level = [
|
||
"LOG", "INFO", "WARNING", "DEBUG"
|
||
];
|
||
var logger = function (obj, lvl) {
|
||
var txt = obj.txt || obj;
|
||
if (lvl == void 0)
|
||
lvl = 0;
|
||
var date = new Date();
|
||
log.push({
|
||
"message": sprintf("%s [%s:%s] %s", [date.toString(), level[lvl], prefix, txt]),
|
||
"timeStamp": +(date)
|
||
});
|
||
if (lvl <= current_loglevel) {
|
||
var msg = ["[" + prefix + "]", txt];
|
||
if (obj.arg)
|
||
msg = ["[" + prefix + "]"].concat(Array.prototype.slice.call(obj.arg));
|
||
if (lvl === 0)
|
||
console["_log"].apply(console, msg);
|
||
else if (lvl === 1)
|
||
console["_info"].apply(console, msg);
|
||
else if (lvl === 2)
|
||
console["_warn"].apply(console, msg);
|
||
else if (lvl >= 3)
|
||
console["_log"].apply(console, msg);
|
||
}
|
||
};
|
||
_loggers[prefix] = {
|
||
"logger": logger,
|
||
"log": log
|
||
};
|
||
return logger;
|
||
};
|
||
make_logger["loggers"] = _loggers;
|
||
make_logger["complete_log"] = function () {
|
||
var logs = Object.keys(_loggers)
|
||
.reduce(function (p, c) {
|
||
return [].concat(p, _loggers[c].log);
|
||
}, []);
|
||
logs.sort(function (x, y) {
|
||
return ((x.timeStamp > y.timeStamp) ? -1 : +1);
|
||
});
|
||
return logs.map(function (x, i, a) {
|
||
return x.message;
|
||
});
|
||
};
|
||
if ( /*!track_exports*/true) {
|
||
var _log_all = function (log, lvl, next = function () { }) {
|
||
return function () {
|
||
var msg = [];
|
||
for (var i = 0; i < arguments.length; i++) {
|
||
if (typeof arguments[i] === "string") {
|
||
msg.push(arguments[i]);
|
||
}
|
||
else {
|
||
msg.push(JSON.stringify(arguments[i]));
|
||
}
|
||
}
|
||
var obj = {
|
||
txt: msg.join("\t"),
|
||
arg: arguments
|
||
};
|
||
log(obj, lvl);
|
||
next();
|
||
};
|
||
};
|
||
{
|
||
var __warn = make_logger("deprecated console.warn", 99);
|
||
var __error = make_logger("deprecated console.error", 99);
|
||
var __log = make_logger("deprecated console.log", 99);
|
||
var __info = make_logger("deprecated console.info", 99);
|
||
// bad ass
|
||
console["_log"] = console.log;
|
||
console["_error"] = console.error;
|
||
console["_warn"] = console.warn;
|
||
console["_info"] = console.info;
|
||
/*
|
||
console["log"] = _log_all(__log, 0);
|
||
console["error"] = _log_all(__error, 2);
|
||
console["warn"] = _log_all(__warn, 2);
|
||
console["info"] = _log_all(__info, 0);
|
||
*/
|
||
}
|
||
/*
|
||
{
|
||
make_logger["send_log"] = function(){
|
||
eml_log(
|
||
function () {
|
||
alert("fehlerbericht wurde gesendet!");
|
||
}
|
||
);
|
||
};
|
||
var error_log = make_logger("global.error", 99);
|
||
window.onerror = _log_all(
|
||
error_log,
|
||
1,
|
||
function(){
|
||
if (global_config == undefined) {
|
||
return false;
|
||
}
|
||
if (global_config.report_error) {
|
||
make_logger["send_log"]();
|
||
}
|
||
}
|
||
);
|
||
}
|
||
*/
|
||
}
|
||
return make_logger;
|
||
})();
|
||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||
return new (P || (P = Promise))(function (resolve, reject) {
|
||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
});
|
||
};
|
||
/*
|
||
This file is part of »bacterio-plankton:database«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:database« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:database« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:database«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var database;
|
||
(function (database) {
|
||
/**
|
||
*/
|
||
let enum_type;
|
||
(function (enum_type) {
|
||
enum_type["boolean"] = "boolean";
|
||
enum_type["integer"] = "integer";
|
||
enum_type["string_short"] = "string_short";
|
||
enum_type["string_medium"] = "string_medium";
|
||
enum_type["string_long"] = "string_long";
|
||
enum_type["float"] = "float";
|
||
})(enum_type = database.enum_type || (database.enum_type = {}));
|
||
})(database = lib_plankton.database || (lib_plankton.database = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:database«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:database« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:database« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:database«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var database;
|
||
(function (database) {
|
||
/**
|
||
* @todo default case?
|
||
*/
|
||
function sql_common_value_format(value) {
|
||
if (value === undefined) {
|
||
throw (new Error("can not format undefined"));
|
||
}
|
||
else {
|
||
if (value === null) {
|
||
return "NULL";
|
||
}
|
||
else {
|
||
switch (typeof (value)) {
|
||
case "boolean": {
|
||
return (value ? "TRUE" : "FALSE");
|
||
break;
|
||
}
|
||
case "number": {
|
||
return value.toString();
|
||
break;
|
||
}
|
||
case "string": {
|
||
return ("'" + value + "'");
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
database.sql_common_value_format = sql_common_value_format;
|
||
/**
|
||
*/
|
||
function sql_common_formulation_create_table(description_create_table, options = {}) {
|
||
var _a, _b, _c, _d, _e, _f;
|
||
options = Object.assign({
|
||
"auto_increment_keyword": "AUTO INCREMENT",
|
||
"auto_increment_special": null,
|
||
"omit_comments": false,
|
||
"type_map": {
|
||
"boolean": "BOOLEAN",
|
||
"integer": "INTEGER",
|
||
"string_short": "VARCHAR(63)",
|
||
"string_medium": "VARCHAR(255)",
|
||
"string_long": "TEXT",
|
||
"float": "REAL",
|
||
},
|
||
"wrap_name": (x => x),
|
||
}, options);
|
||
return {
|
||
"template": lib_plankton.string.coin("CREATE TABLE IF NOT EXISTS\n\t{{name}}(\n{{entries}}\n\t){{comment}}\n;", {
|
||
"name": options.wrap_name(description_create_table.name),
|
||
"comment": ((options.omit_comments
|
||
||
|
||
(((_a = description_create_table.description) !== null && _a !== void 0 ? _a : null) === null))
|
||
? ""
|
||
: lib_plankton.string.coin(" COMMENT '{{comment}}'", {
|
||
"comment": description_create_table.description,
|
||
})),
|
||
"entries": (([]
|
||
// key field
|
||
.concat((((_b = description_create_table.key_field) !== null && _b !== void 0 ? _b : null) === null)
|
||
? []
|
||
: lib_plankton.string.coin("{{name}} {{parameters}}", {
|
||
"name": options.wrap_name(description_create_table.key_field.name),
|
||
"parameters": (((options.auto_increment_special === null)
|
||
?
|
||
([]
|
||
// type
|
||
.concat([
|
||
options.type_map[(_c = description_create_table.key_field.type) !== null && _c !== void 0 ? _c : "integer"],
|
||
])
|
||
// nullability
|
||
.concat([
|
||
"NOT NULL",
|
||
])
|
||
// primary key
|
||
.concat([
|
||
"PRIMARY KEY",
|
||
])
|
||
// auto increment
|
||
.concat((((_d = description_create_table.key_field.auto_increment) !== null && _d !== void 0 ? _d : true) === null)
|
||
?
|
||
[]
|
||
:
|
||
[
|
||
options.auto_increment_keyword,
|
||
]))
|
||
:
|
||
[
|
||
options.auto_increment_special
|
||
])
|
||
.join(" ")),
|
||
}))
|
||
// data fields
|
||
.concat(((_e = description_create_table.data_fields) !== null && _e !== void 0 ? _e : [])
|
||
.map((data_field) => {
|
||
var _a, _b;
|
||
return lib_plankton.string.coin("{{name}} {{parameters}}", {
|
||
"name": options.wrap_name(data_field.name),
|
||
"parameters": (([]
|
||
// type
|
||
.concat([
|
||
options.type_map[data_field.type],
|
||
])
|
||
// nullability
|
||
.concat((!((_a = data_field.nullable) !== null && _a !== void 0 ? _a : false))
|
||
? []
|
||
: ["NULL"])
|
||
// default
|
||
.concat((!data_field.hasOwnProperty("default"))
|
||
? []
|
||
: [
|
||
lib_plankton.string.coin(" DEFAULT {{value}}", {
|
||
"value": sql_common_value_format(data_field.default)
|
||
}),
|
||
])
|
||
// comment
|
||
.concat((options.omit_comments
|
||
||
|
||
(((_b = data_field.description) !== null && _b !== void 0 ? _b : null) === null))
|
||
? []
|
||
: [
|
||
lib_plankton.string.coin("COMMENT '{{comment}}'", {
|
||
"comment": data_field.description,
|
||
}),
|
||
]))
|
||
.join(" "))
|
||
});
|
||
}))
|
||
// constraints
|
||
.concat(((_f = description_create_table.constraints) !== null && _f !== void 0 ? _f : [])
|
||
.map((constraint) => {
|
||
switch (constraint.kind) {
|
||
default: {
|
||
throw (new Error("unhandled constraint kind: " + constraint.kind));
|
||
break;
|
||
}
|
||
case "foreign_key": {
|
||
return lib_plankton.string.coin("FOREIGN KEY ({{fields}}) REFERENCES {{reference_name}}({{reference_fields}})", {
|
||
"fields": (constraint.parameters["fields"]
|
||
.map(x => options.wrap_name(x))
|
||
.join(",")),
|
||
"reference_name": options.wrap_name(constraint.parameters["reference"]["name"]),
|
||
"reference_fields": (constraint.parameters["reference"]["fields"]
|
||
.map(x => options.wrap_name(x))
|
||
.join(",")),
|
||
});
|
||
break;
|
||
}
|
||
case "unique": {
|
||
return lib_plankton.string.coin("UNIQUE ({{fields}})", {
|
||
"fields": (constraint.parameters["fields"]
|
||
.map(x => options.wrap_name(x))
|
||
.join(",")),
|
||
});
|
||
break;
|
||
}
|
||
}
|
||
})))
|
||
.map(x => ("\t\t" + x))
|
||
.join(",\n")),
|
||
}),
|
||
"arguments": {}
|
||
};
|
||
}
|
||
database.sql_common_formulation_create_table = sql_common_formulation_create_table;
|
||
/**
|
||
*/
|
||
function sql_common_formulation_insert(description_insert, options = {}) {
|
||
options = Object.assign({
|
||
"wrap_name": (x => x),
|
||
"set_returning": false,
|
||
}, options);
|
||
const field_names = Object.keys(description_insert.values);
|
||
return {
|
||
"template": lib_plankton.string.coin("INSERT INTO {{table_name}}({{schema}}) VALUES ({{values}}){{returning}};", {
|
||
"table_name": options.wrap_name(description_insert.table_name),
|
||
"schema": (field_names
|
||
.map((field_name) => lib_plankton.string.coin("{{name}}", {
|
||
"name": options.wrap_name(field_name),
|
||
}))
|
||
.join(",")),
|
||
"values": (field_names
|
||
.map((field_name) => lib_plankton.string.coin("$value_{{name}}", {
|
||
"name": field_name,
|
||
}))
|
||
.join(",")),
|
||
"returning": ((options.set_returning
|
||
&&
|
||
((description_insert.returning !== undefined)
|
||
&&
|
||
(description_insert.returning !== null)))
|
||
?
|
||
(" RETURNING " + description_insert.returning)
|
||
:
|
||
""),
|
||
}),
|
||
"arguments": Object.fromEntries(Object.entries(description_insert.values)
|
||
.map(([name, value]) => ([
|
||
lib_plankton.string.coin("value_{{name}}", {
|
||
"name": name,
|
||
}),
|
||
value
|
||
]))),
|
||
};
|
||
}
|
||
database.sql_common_formulation_insert = sql_common_formulation_insert;
|
||
/**
|
||
*/
|
||
function sql_common_formulation_update(description_update, options = {}) {
|
||
var _a, _b;
|
||
options = Object.assign({
|
||
"wrap_name": (x => x),
|
||
}, options);
|
||
const field_names = Object.keys(description_update.values);
|
||
return {
|
||
"template": lib_plankton.string.coin("UPDATE {{table_name}} SET {{assignments}}{{macro_where}};", {
|
||
"table_name": options.wrap_name(description_update.table_name),
|
||
"assignments": (field_names
|
||
.map((field_name) => lib_plankton.string.coin("{{name}} = $value_{{suffix}}", {
|
||
"name": options.wrap_name(field_name),
|
||
"suffix": field_name,
|
||
}))
|
||
.join(", ")),
|
||
"macro_where": ((((_a = description_update.condition) !== null && _a !== void 0 ? _a : null) === null)
|
||
? ""
|
||
: lib_plankton.string.coin(" WHERE {{expression}}", {
|
||
"expression": description_update.condition,
|
||
})),
|
||
}),
|
||
"arguments": Object.assign(Object.fromEntries(Object.entries(description_update.values)
|
||
.map(([name, value]) => ([
|
||
lib_plankton.string.coin("value_{{name}}", {
|
||
"name": name,
|
||
}),
|
||
value
|
||
]))), ((_b = description_update.arguments) !== null && _b !== void 0 ? _b : {}))
|
||
};
|
||
}
|
||
database.sql_common_formulation_update = sql_common_formulation_update;
|
||
/**
|
||
*/
|
||
function sql_common_formulation_delete(description_delete, options = {}) {
|
||
var _a, _b;
|
||
options = Object.assign({
|
||
"wrap_name": (x => x),
|
||
}, options);
|
||
return {
|
||
"template": lib_plankton.string.coin("DELETE FROM {{table_name}}{{macro_where}};", {
|
||
"table_name": options.wrap_name(description_delete.table_name),
|
||
"macro_where": ((((_a = description_delete.condition) !== null && _a !== void 0 ? _a : null) === null)
|
||
? ""
|
||
: lib_plankton.string.coin(" WHERE {{expression}}", {
|
||
"expression": description_delete.condition,
|
||
})),
|
||
}),
|
||
"arguments": Object.assign({}, ((_b = description_delete.arguments) !== null && _b !== void 0 ? _b : {})),
|
||
};
|
||
}
|
||
database.sql_common_formulation_delete = sql_common_formulation_delete;
|
||
/**
|
||
*/
|
||
function sql_common_formulation_select(description_select, options = {}) {
|
||
var _a, _b, _c, _d, _e, _f, _g;
|
||
options = Object.assign({
|
||
"wrap_name": (x => x),
|
||
}, options);
|
||
return {
|
||
"template": lib_plankton.string.coin("SELECT {{fields}} FROM {{source}}{{macro_where}}{{macro_group_by}}{{macro_having}}{{macro_order_by}}{{macro_limit}};", {
|
||
"source": options.wrap_name(description_select.source),
|
||
"fields": ((((_a = description_select.fields) !== null && _a !== void 0 ? _a : null) === null)
|
||
? "*"
|
||
: (description_select.fields
|
||
.map(field_name => lib_plankton.string.coin("{{name}}", { "name": options.wrap_name(field_name) }))
|
||
.join(","))),
|
||
"macro_where": ((((_b = description_select.condition) !== null && _b !== void 0 ? _b : null) === null)
|
||
? ""
|
||
: lib_plankton.string.coin(" WHERE {{expression}}", {
|
||
"expression": description_select.condition,
|
||
})),
|
||
"macro_group_by": ((((_c = description_select.group_by) !== null && _c !== void 0 ? _c : null) === null)
|
||
? ""
|
||
: lib_plankton.string.coin(" GROUP BY {{expression}}", {
|
||
"expression": description_select.group_by,
|
||
})),
|
||
"macro_having": ((((_d = description_select.having) !== null && _d !== void 0 ? _d : null) === null)
|
||
? ""
|
||
: lib_plankton.string.coin(" HAVING {{expression}}", {
|
||
"expression": description_select.having,
|
||
})),
|
||
"macro_order_by": ((((_e = description_select.order_by) !== null && _e !== void 0 ? _e : null) === null)
|
||
? ""
|
||
: lib_plankton.string.coin(" ORDER BY {{expression}}", {
|
||
"expression": description_select.order_by,
|
||
})),
|
||
"macro_limit": ((((_f = description_select.limit) !== null && _f !== void 0 ? _f : null) === null)
|
||
? ""
|
||
: lib_plankton.string.coin(" LIMIT {{expression}}", {
|
||
"expression": description_select.limit.toFixed(0),
|
||
})),
|
||
}),
|
||
"arguments": Object.assign({}, ((_g = description_select.arguments) !== null && _g !== void 0 ? _g : {})),
|
||
};
|
||
}
|
||
database.sql_common_formulation_select = sql_common_formulation_select;
|
||
})(database = lib_plankton.database || (lib_plankton.database = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:database«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:database« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:database« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:database«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var database;
|
||
(function (database) {
|
||
/**
|
||
*/
|
||
function sqlite_make(parameters) {
|
||
return {
|
||
"path": parameters.path,
|
||
"handle": null,
|
||
};
|
||
}
|
||
database.sqlite_make = sqlite_make;
|
||
/**
|
||
*/
|
||
function sqlite_wrap_name(name) {
|
||
return ("`" + name + "`");
|
||
}
|
||
database.sqlite_wrap_name = sqlite_wrap_name;
|
||
/**
|
||
*/
|
||
function sqlite_init(subject) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
if (subject.handle === null) {
|
||
yield new Promise((resolve, reject) => {
|
||
const _nm_sqlite3 = require("sqlite3");
|
||
subject.handle = new _nm_sqlite3.Database(subject.path, (_nm_sqlite3.OPEN_READWRITE | _nm_sqlite3.OPEN_CREATE | _nm_sqlite3.OPEN_FULLMUTEX), () => { resolve(undefined); });
|
||
});
|
||
}
|
||
else {
|
||
// do nothing
|
||
}
|
||
return Promise.resolve(undefined);
|
||
});
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function sqlite_adjust_query(subject, query) {
|
||
const query_adjusted = {
|
||
"template": query.template,
|
||
"arguments": Object.fromEntries(Object.entries(query.arguments)
|
||
.map(([key, value]) => ([
|
||
("$" + key),
|
||
(((value === null)
|
||
||
|
||
(value === undefined))
|
||
? null
|
||
: ((typeof (value) === "boolean")
|
||
? (value ? "1" : "0")
|
||
: value.toString()))
|
||
]))),
|
||
};
|
||
lib_plankton.log.debug("database_sqlite_query", {
|
||
"original": query,
|
||
"adjusted": query_adjusted,
|
||
});
|
||
return query_adjusted;
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function sqlite_query_free_get(subject, query) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
yield sqlite_init(subject);
|
||
const query_adjusted = sqlite_adjust_query(subject, query);
|
||
return (new Promise((resolve, reject) => {
|
||
subject.handle.all(query_adjusted.template, query_adjusted.arguments, (error, rows) => {
|
||
if (error !== null) {
|
||
reject(error);
|
||
}
|
||
else {
|
||
resolve(rows);
|
||
}
|
||
});
|
||
}));
|
||
});
|
||
}
|
||
database.sqlite_query_free_get = sqlite_query_free_get;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function sqlite_query_free_put(subject, query) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
yield sqlite_init(subject);
|
||
const query_adjusted = sqlite_adjust_query(subject, query);
|
||
return (new Promise((resolve, reject) => {
|
||
subject.handle.run(query_adjusted.template, query_adjusted.arguments,
|
||
// this MUST be an old style function
|
||
function (error) {
|
||
if (error) {
|
||
reject(error);
|
||
}
|
||
else {
|
||
resolve(this["lastID"]);
|
||
}
|
||
});
|
||
}));
|
||
});
|
||
}
|
||
database.sqlite_query_free_put = sqlite_query_free_put;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function sqlite_query_free_set(subject, query) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
yield sqlite_init(subject);
|
||
const query_adjusted = sqlite_adjust_query(subject, query);
|
||
return (new Promise((resolve, reject) => {
|
||
subject.handle.run(query_adjusted.template, query_adjusted.arguments,
|
||
// this MUST be an old style function
|
||
function (error) {
|
||
if (error) {
|
||
reject(error);
|
||
}
|
||
else {
|
||
resolve(this["changes"]);
|
||
}
|
||
});
|
||
}));
|
||
});
|
||
}
|
||
database.sqlite_query_free_set = sqlite_query_free_set;
|
||
/**
|
||
*/
|
||
function sqlite_formulation_create_table(description_create_table) {
|
||
return database.sql_common_formulation_create_table(description_create_table, {
|
||
"auto_increment_keyword": "AUTOINCREMENT",
|
||
"auto_increment_special": null,
|
||
"omit_comments": true,
|
||
"type_map": {
|
||
"boolean": "INTEGER",
|
||
"integer": "INTEGER",
|
||
"string_short": "TEXT",
|
||
"string_medium": "TEXT",
|
||
"string_long": "TEXT",
|
||
"float": "REAL",
|
||
},
|
||
"wrap_name": sqlite_wrap_name,
|
||
});
|
||
}
|
||
database.sqlite_formulation_create_table = sqlite_formulation_create_table;
|
||
/**
|
||
*/
|
||
function sqlite_query_create_table(subject, description) {
|
||
return (sqlite_query_free_set(subject, sqlite_formulation_create_table(description))
|
||
.then(x => Promise.resolve(undefined)));
|
||
}
|
||
database.sqlite_query_create_table = sqlite_query_create_table;
|
||
/**
|
||
*/
|
||
function sqlite_formulation_insert(description_insert) {
|
||
return database.sql_common_formulation_insert(description_insert, {
|
||
"wrap_name": sqlite_wrap_name,
|
||
});
|
||
}
|
||
database.sqlite_formulation_insert = sqlite_formulation_insert;
|
||
/**
|
||
*/
|
||
function sqlite_query_insert(subject, description_insert) {
|
||
return sqlite_query_free_put(subject, sqlite_formulation_insert(description_insert));
|
||
}
|
||
database.sqlite_query_insert = sqlite_query_insert;
|
||
/**
|
||
*/
|
||
function sqlite_formulation_update(description_update) {
|
||
return database.sql_common_formulation_update(description_update, {
|
||
"wrap_name": sqlite_wrap_name,
|
||
});
|
||
}
|
||
database.sqlite_formulation_update = sqlite_formulation_update;
|
||
/**
|
||
*/
|
||
function sqlite_query_update(subject, description_update) {
|
||
return sqlite_query_free_set(subject, sqlite_formulation_update(description_update));
|
||
}
|
||
database.sqlite_query_update = sqlite_query_update;
|
||
/**
|
||
*/
|
||
function sqlite_formulation_delete(description_delete) {
|
||
return database.sql_common_formulation_delete(description_delete, {
|
||
"wrap_name": sqlite_wrap_name,
|
||
});
|
||
}
|
||
database.sqlite_formulation_delete = sqlite_formulation_delete;
|
||
/**
|
||
*/
|
||
function sqlite_query_delete(subject, description_delete) {
|
||
return sqlite_query_free_set(subject, sqlite_formulation_delete(description_delete));
|
||
}
|
||
database.sqlite_query_delete = sqlite_query_delete;
|
||
/**
|
||
*/
|
||
function sqlite_formulation_select(description_select) {
|
||
return database.sql_common_formulation_select(description_select, {
|
||
"wrap_name": sqlite_wrap_name,
|
||
});
|
||
}
|
||
database.sqlite_formulation_select = sqlite_formulation_select;
|
||
/**
|
||
*/
|
||
function sqlite_query_select(subject, description_select) {
|
||
return sqlite_query_free_get(subject, sqlite_formulation_select(description_select));
|
||
}
|
||
database.sqlite_query_select = sqlite_query_select;
|
||
/**
|
||
*/
|
||
function sqlite_database(parameters) {
|
||
const subject = sqlite_make(parameters);
|
||
return {
|
||
"wrap_name": (name) => sqlite_wrap_name(name),
|
||
"query_free_get": (query) => sqlite_query_free_get(subject, query),
|
||
"query_free_put": (query) => sqlite_query_free_put(subject, query),
|
||
"query_free_set": (query) => sqlite_query_free_set(subject, query),
|
||
"query_create_table": (description_create_table) => sqlite_query_create_table(subject, description_create_table),
|
||
"query_insert": (description_insert) => sqlite_query_insert(subject, description_insert),
|
||
"query_update": (description_update) => sqlite_query_update(subject, description_update),
|
||
"query_delete": (description_delete) => sqlite_query_delete(subject, description_delete),
|
||
"query_select": (description_select) => sqlite_query_select(subject, description_select),
|
||
};
|
||
}
|
||
database.sqlite_database = sqlite_database;
|
||
})(database = lib_plankton.database || (lib_plankton.database = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:database«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:database« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:database« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:database«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var database;
|
||
(function (database) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class class_sqlite {
|
||
constructor(parameters) { this.subject = database.sqlite_make(parameters); }
|
||
wrap_name(name) { return database.sqlite_wrap_name(name); }
|
||
query_free_get(query) { return database.sqlite_query_free_get(this.subject, query); }
|
||
query_free_put(query) { return database.sqlite_query_free_put(this.subject, query); }
|
||
query_free_set(query) { return database.sqlite_query_free_set(this.subject, query); }
|
||
query_create_table(description_create_table) { return database.sqlite_query_create_table(this.subject, description_create_table); }
|
||
query_insert(description_insert) { return database.sqlite_query_insert(this.subject, description_insert); }
|
||
query_update(description_update) { return database.sqlite_query_update(this.subject, description_update); }
|
||
query_delete(description_delete) { return database.sqlite_query_delete(this.subject, description_delete); }
|
||
query_select(description_select) { return database.sqlite_query_select(this.subject, description_select); }
|
||
}
|
||
database.class_sqlite = class_sqlite;
|
||
})(database = lib_plankton.database || (lib_plankton.database = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:database«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:database« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:database« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:database«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var database;
|
||
(function (database) {
|
||
/**
|
||
*/
|
||
function postgresql_make(parameters) {
|
||
var _a;
|
||
return {
|
||
"host": parameters.host,
|
||
"port": ((_a = parameters.port) !== null && _a !== void 0 ? _a : 5432),
|
||
"username": parameters.username,
|
||
"password": parameters.password,
|
||
"schema": parameters.schema,
|
||
"pool": null,
|
||
};
|
||
}
|
||
database.postgresql_make = postgresql_make;
|
||
/**
|
||
*/
|
||
function postgresql_wrap_name(name) {
|
||
return ("" + name + "");
|
||
}
|
||
database.postgresql_wrap_name = postgresql_wrap_name;
|
||
/**
|
||
* https://node-postgres.com/apis/pool
|
||
*/
|
||
function postgresql_init(subject) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
if (subject.pool === null) {
|
||
const nm_pg = require("pg");
|
||
subject.pool = (new nm_pg.Pool({
|
||
"host": subject.host,
|
||
"port": subject.port,
|
||
"database": subject.schema,
|
||
"user": subject.username,
|
||
"password": subject.password,
|
||
}));
|
||
}
|
||
else {
|
||
// do nothing
|
||
}
|
||
return Promise.resolve(undefined);
|
||
});
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function postgresql_adjust_query(subject, query) {
|
||
let query_adjusted = {
|
||
"template": query.template,
|
||
"arguments": []
|
||
};
|
||
let index = 1;
|
||
while (true) {
|
||
const regexp = (new RegExp("\\$([a-zA-Z_][0-9a-zA-Z_]*)", "g"));
|
||
const matching = regexp.exec(query_adjusted.template);
|
||
if (matching === null) {
|
||
break;
|
||
}
|
||
else {
|
||
const part = matching[0];
|
||
const name = matching[1];
|
||
query_adjusted.template = (query_adjusted.template.slice(0, matching.index)
|
||
+
|
||
("$" + index.toFixed(0))
|
||
+
|
||
query_adjusted.template.slice(matching.index + part.length));
|
||
query_adjusted.arguments.push(query.arguments[name]);
|
||
index += 1;
|
||
}
|
||
}
|
||
lib_plankton.log.debug("database_postgresql_query", {
|
||
"original": query,
|
||
"adjusted": query_adjusted,
|
||
});
|
||
return query_adjusted;
|
||
}
|
||
/**
|
||
* @author fenris
|
||
* @see https://node-postgres.com/apis/pool#poolquery
|
||
*/
|
||
function postgresql_query_free_get(subject, query) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
yield postgresql_init(subject);
|
||
const query_adjusted = postgresql_adjust_query(subject, query);
|
||
const result = yield subject.pool.query({
|
||
"text": query_adjusted.template,
|
||
"values": query_adjusted.arguments,
|
||
});
|
||
return result["rows"];
|
||
});
|
||
}
|
||
database.postgresql_query_free_get = postgresql_query_free_get;
|
||
/**
|
||
* @author fenris
|
||
* @see https://node-postgres.com/apis/pool#poolquery
|
||
*/
|
||
function postgresql_query_free_put(subject, query) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
yield postgresql_init(subject);
|
||
const query_adjusted = postgresql_adjust_query(subject, query);
|
||
const result = yield subject.pool.query(query_adjusted.template, query_adjusted.arguments);
|
||
if (result["rows"].length <= 0) {
|
||
return null;
|
||
}
|
||
else {
|
||
const x = result["rows"][0];
|
||
const keys = Object.keys(x);
|
||
if (keys.length <= 0) {
|
||
return null;
|
||
}
|
||
else {
|
||
return x[Object.keys(x)[0]];
|
||
}
|
||
}
|
||
});
|
||
}
|
||
database.postgresql_query_free_put = postgresql_query_free_put;
|
||
/**
|
||
* @author fenris
|
||
* @see https://node-postgres.com/apis/pool#poolquery
|
||
*/
|
||
function postgresql_query_free_set(subject, query) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
yield postgresql_init(subject);
|
||
const query_adjusted = postgresql_adjust_query(subject, query);
|
||
const result = yield subject.pool.query(query_adjusted.template, query_adjusted.arguments);
|
||
return result["rowCount"];
|
||
});
|
||
}
|
||
database.postgresql_query_free_set = postgresql_query_free_set;
|
||
/**
|
||
*/
|
||
function postgresql_formulation_create_table(description_create_table) {
|
||
return database.sql_common_formulation_create_table(description_create_table, {
|
||
"auto_increment_keyword": "",
|
||
"auto_increment_special": "SERIAL",
|
||
"omit_comments": false,
|
||
"type_map": {
|
||
"boolean": "BOOLEAN",
|
||
"integer": "INTEGER",
|
||
"string_short": "VARCHAR(63)",
|
||
"string_medium": "VARCHAR(255)",
|
||
"string_long": "TEXT",
|
||
"float": "REAL",
|
||
},
|
||
"wrap_name": postgresql_wrap_name,
|
||
});
|
||
}
|
||
database.postgresql_formulation_create_table = postgresql_formulation_create_table;
|
||
/**
|
||
*/
|
||
function postgresql_query_create_table(subject, description) {
|
||
return (postgresql_query_free_set(subject, postgresql_formulation_create_table(description))
|
||
.then(x => Promise.resolve(undefined)));
|
||
}
|
||
database.postgresql_query_create_table = postgresql_query_create_table;
|
||
/**
|
||
*/
|
||
function postgresql_formulation_insert(description_insert) {
|
||
return database.sql_common_formulation_insert(description_insert, {
|
||
"wrap_name": postgresql_wrap_name,
|
||
"set_returning": true
|
||
});
|
||
}
|
||
database.postgresql_formulation_insert = postgresql_formulation_insert;
|
||
/**
|
||
*/
|
||
function postgresql_query_insert(subject, description_insert) {
|
||
return postgresql_query_free_put(subject, postgresql_formulation_insert(description_insert));
|
||
}
|
||
database.postgresql_query_insert = postgresql_query_insert;
|
||
/**
|
||
*/
|
||
function postgresql_formulation_update(description_update) {
|
||
return database.sql_common_formulation_update(description_update, {
|
||
"wrap_name": postgresql_wrap_name,
|
||
});
|
||
}
|
||
database.postgresql_formulation_update = postgresql_formulation_update;
|
||
/**
|
||
*/
|
||
function postgresql_query_update(subject, description_update) {
|
||
return postgresql_query_free_set(subject, postgresql_formulation_update(description_update));
|
||
}
|
||
database.postgresql_query_update = postgresql_query_update;
|
||
/**
|
||
*/
|
||
function postgresql_formulation_delete(description_delete) {
|
||
return database.sql_common_formulation_delete(description_delete, {
|
||
"wrap_name": postgresql_wrap_name,
|
||
});
|
||
}
|
||
database.postgresql_formulation_delete = postgresql_formulation_delete;
|
||
/**
|
||
*/
|
||
function postgresql_query_delete(subject, description_delete) {
|
||
return postgresql_query_free_set(subject, postgresql_formulation_delete(description_delete));
|
||
}
|
||
database.postgresql_query_delete = postgresql_query_delete;
|
||
/**
|
||
*/
|
||
function postgresql_formulation_select(description_select) {
|
||
return database.sql_common_formulation_select(description_select, {
|
||
"wrap_name": postgresql_wrap_name,
|
||
});
|
||
}
|
||
database.postgresql_formulation_select = postgresql_formulation_select;
|
||
/**
|
||
*/
|
||
function postgresql_query_select(subject, description_select) {
|
||
return postgresql_query_free_get(subject, postgresql_formulation_select(description_select));
|
||
}
|
||
database.postgresql_query_select = postgresql_query_select;
|
||
/**
|
||
*/
|
||
function postgresql_database(parameters) {
|
||
const subject = postgresql_make(parameters);
|
||
return {
|
||
"wrap_name": (name) => postgresql_wrap_name(name),
|
||
"query_free_get": (query) => postgresql_query_free_get(subject, query),
|
||
"query_free_put": (query) => postgresql_query_free_put(subject, query),
|
||
"query_free_set": (query) => postgresql_query_free_set(subject, query),
|
||
"query_create_table": (description_create_table) => postgresql_query_create_table(subject, description_create_table),
|
||
"query_insert": (description_insert) => postgresql_query_insert(subject, description_insert),
|
||
"query_update": (description_update) => postgresql_query_update(subject, description_update),
|
||
"query_delete": (description_delete) => postgresql_query_delete(subject, description_delete),
|
||
"query_select": (description_select) => postgresql_query_select(subject, description_select),
|
||
};
|
||
}
|
||
database.postgresql_database = postgresql_database;
|
||
})(database = lib_plankton.database || (lib_plankton.database = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:database«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:database« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:database« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:database«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var database;
|
||
(function (database) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class class_postgresql {
|
||
constructor(parameters) { this.subject = database.postgresql_make(parameters); }
|
||
wrap_name(name) { return database.postgresql_wrap_name(name); }
|
||
query_free_get(query) { return database.postgresql_query_free_get(this.subject, query); }
|
||
query_free_put(query) { return database.postgresql_query_free_put(this.subject, query); }
|
||
query_free_set(query) { return database.postgresql_query_free_set(this.subject, query); }
|
||
query_create_table(description_create_table) { return database.postgresql_query_create_table(this.subject, description_create_table); }
|
||
query_insert(description_insert) { return database.postgresql_query_insert(this.subject, description_insert); }
|
||
query_update(description_update) { return database.postgresql_query_update(this.subject, description_update); }
|
||
query_delete(description_delete) { return database.postgresql_query_delete(this.subject, description_delete); }
|
||
query_select(description_select) { return database.postgresql_query_select(this.subject, description_select); }
|
||
}
|
||
database.class_postgresql = class_postgresql;
|
||
})(database = lib_plankton.database || (lib_plankton.database = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:database«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:database« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:database« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:database«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var database;
|
||
(function (database) {
|
||
/**
|
||
*/
|
||
function mysql_make(parameters) {
|
||
throw (new Error("not implemented"));
|
||
}
|
||
database.mysql_make = mysql_make;
|
||
/**
|
||
*/
|
||
function mysql_wrap_name(name) {
|
||
return ("`" + name + "`");
|
||
}
|
||
database.mysql_wrap_name = mysql_wrap_name;
|
||
/**
|
||
*/
|
||
function mysql_init(subject) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
throw (new Error("not implemented"));
|
||
});
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function mysql_adjust_query(subject, query) {
|
||
if (subject.verbose) {
|
||
console.info(query);
|
||
}
|
||
throw (new Error("not implemented"));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function mysql_query_free_get(subject, query) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
throw (new Error("not implemented"));
|
||
});
|
||
}
|
||
database.mysql_query_free_get = mysql_query_free_get;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function mysql_query_free_put(subject, query) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
throw (new Error("not implemented"));
|
||
});
|
||
}
|
||
database.mysql_query_free_put = mysql_query_free_put;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function mysql_query_free_set(subject, query) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
throw (new Error("not implemented"));
|
||
});
|
||
}
|
||
database.mysql_query_free_set = mysql_query_free_set;
|
||
/**
|
||
*/
|
||
function mysql_formulation_create_table(description_create_table) {
|
||
return database.sql_common_formulation_create_table(description_create_table, {
|
||
"auto_increment_keyword": "AUTO INCREMENT",
|
||
"omit_comments": false,
|
||
"type_map": {
|
||
"boolean": "BOOLEAN",
|
||
"integer": "INTEGER",
|
||
"string_short": "VARCHAR(63)",
|
||
"string_medium": "VARCHAR(255)",
|
||
"string_long": "TEXT",
|
||
"float": "REAL",
|
||
},
|
||
"wrap_name": mysql_wrap_name,
|
||
});
|
||
}
|
||
database.mysql_formulation_create_table = mysql_formulation_create_table;
|
||
/**
|
||
*/
|
||
function mysql_query_create_table(subject, description) {
|
||
return (mysql_query_free_set(subject, mysql_formulation_create_table(description))
|
||
.then(x => Promise.resolve(undefined)));
|
||
}
|
||
database.mysql_query_create_table = mysql_query_create_table;
|
||
/**
|
||
*/
|
||
function mysql_formulation_insert(description_insert) {
|
||
return database.sql_common_formulation_insert(description_insert, {
|
||
"wrap_name": mysql_wrap_name,
|
||
});
|
||
}
|
||
database.mysql_formulation_insert = mysql_formulation_insert;
|
||
/**
|
||
*/
|
||
function mysql_query_insert(subject, description_insert) {
|
||
return mysql_query_free_put(subject, mysql_formulation_insert(description_insert));
|
||
}
|
||
database.mysql_query_insert = mysql_query_insert;
|
||
/**
|
||
*/
|
||
function mysql_formulation_update(description_update) {
|
||
return database.sql_common_formulation_update(description_update, {
|
||
"wrap_name": mysql_wrap_name,
|
||
});
|
||
}
|
||
database.mysql_formulation_update = mysql_formulation_update;
|
||
/**
|
||
*/
|
||
function mysql_query_update(subject, description_update) {
|
||
return mysql_query_free_set(subject, mysql_formulation_update(description_update));
|
||
}
|
||
database.mysql_query_update = mysql_query_update;
|
||
/**
|
||
*/
|
||
function mysql_formulation_delete(description_delete) {
|
||
return database.sql_common_formulation_delete(description_delete, {
|
||
"wrap_name": mysql_wrap_name,
|
||
});
|
||
}
|
||
database.mysql_formulation_delete = mysql_formulation_delete;
|
||
/**
|
||
*/
|
||
function mysql_query_delete(subject, description_delete) {
|
||
return mysql_query_free_set(subject, mysql_formulation_delete(description_delete));
|
||
}
|
||
database.mysql_query_delete = mysql_query_delete;
|
||
/**
|
||
*/
|
||
function mysql_formulation_select(description_select) {
|
||
return database.sql_common_formulation_select(description_select, {
|
||
"wrap_name": mysql_wrap_name,
|
||
});
|
||
}
|
||
database.mysql_formulation_select = mysql_formulation_select;
|
||
/**
|
||
*/
|
||
function mysql_query_select(subject, description_select) {
|
||
return mysql_query_free_get(subject, mysql_formulation_select(description_select));
|
||
}
|
||
database.mysql_query_select = mysql_query_select;
|
||
/**
|
||
*/
|
||
function mysql_database(parameters) {
|
||
const subject = mysql_make(parameters);
|
||
return {
|
||
"wrap_name": (name) => mysql_wrap_name(name),
|
||
"query_free_get": (query) => mysql_query_free_get(subject, query),
|
||
"query_free_put": (query) => mysql_query_free_put(subject, query),
|
||
"query_free_set": (query) => mysql_query_free_set(subject, query),
|
||
"query_create_table": (description_create_table) => mysql_query_create_table(subject, description_create_table),
|
||
"query_insert": (description_insert) => mysql_query_insert(subject, description_insert),
|
||
"query_update": (description_update) => mysql_query_update(subject, description_update),
|
||
"query_delete": (description_delete) => mysql_query_delete(subject, description_delete),
|
||
"query_select": (description_select) => mysql_query_select(subject, description_select),
|
||
};
|
||
}
|
||
database.mysql_database = mysql_database;
|
||
})(database = lib_plankton.database || (lib_plankton.database = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:database«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:database« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:database« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:database«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var database;
|
||
(function (database) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class class_mysql {
|
||
constructor(parameters) { this.subject = database.mysql_make(parameters); }
|
||
wrap_name(name) { return database.mysql_wrap_name(name); }
|
||
query_free_get(query) { return database.mysql_query_free_get(this.subject, query); }
|
||
query_free_put(query) { return database.mysql_query_free_put(this.subject, query); }
|
||
query_free_set(query) { return database.mysql_query_free_set(this.subject, query); }
|
||
query_create_table(description_create_table) { return database.mysql_query_create_table(this.subject, description_create_table); }
|
||
query_insert(description_insert) { return database.mysql_query_insert(this.subject, description_insert); }
|
||
query_update(description_update) { return database.mysql_query_update(this.subject, description_update); }
|
||
query_delete(description_delete) { return database.mysql_query_delete(this.subject, description_delete); }
|
||
query_select(description_select) { return database.mysql_query_select(this.subject, description_select); }
|
||
}
|
||
database.class_mysql = class_mysql;
|
||
})(database = lib_plankton.database || (lib_plankton.database = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||
return new (P || (P = Promise))(function (resolve, reject) {
|
||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
});
|
||
};
|
||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||
function step(op) {
|
||
if (f) throw new TypeError("Generator is already executing.");
|
||
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||
switch (op[0]) {
|
||
case 0: case 1: t = op; break;
|
||
case 4: _.label++; return { value: op[1], done: false };
|
||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||
default:
|
||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||
if (t[2]) _.ops.pop();
|
||
_.trys.pop(); continue;
|
||
}
|
||
op = body.call(thisArg, _);
|
||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||
}
|
||
};
|
||
/*
|
||
This file is part of »bacterio-plankton:storage«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:storage« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:storage« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:storage«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
/*
|
||
This file is part of »bacterio-plankton:storage«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:storage« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:storage« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:storage«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
/*
|
||
This file is part of »bacterio-plankton:storage«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:storage« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:storage« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:storage«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var storage;
|
||
(function (storage) {
|
||
var memory;
|
||
(function (memory) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function make(parameters) {
|
||
return {
|
||
"data": {}
|
||
};
|
||
}
|
||
memory.make = make;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function clear(subject) {
|
||
subject.data = {};
|
||
}
|
||
memory.clear = clear;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function write(subject, key, value) {
|
||
var exists = (key in subject.data);
|
||
subject.data[key] = value;
|
||
return exists;
|
||
}
|
||
memory.write = write;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function delete_(subject, key) {
|
||
if (!(key in subject.data)) {
|
||
throw (new Error("no value for key '" + key + "'"));
|
||
}
|
||
else {
|
||
delete subject.data[key];
|
||
}
|
||
}
|
||
memory.delete_ = delete_;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function read(subject, key) {
|
||
if (!(key in subject.data)) {
|
||
throw (new Error("no value for key '" + key + "'"));
|
||
}
|
||
else {
|
||
return subject.data[key];
|
||
}
|
||
}
|
||
memory.read = read;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function list(subject) {
|
||
return Object.keys(subject.data);
|
||
}
|
||
memory.list = list;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function search(subject, term) {
|
||
return (list(subject)
|
||
.map(function (key) { return ({ "key": key, "preview": key }); }));
|
||
}
|
||
memory.search = search;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function implementation_chest(parameters) {
|
||
function wrap(core) {
|
||
return (new Promise(function (resolve, reject) { resolve(core()); }));
|
||
}
|
||
var subject = make(parameters);
|
||
return {
|
||
"setup": function (input) { return Promise.resolve(undefined); },
|
||
"clear": function () { return wrap(function () { return clear(subject); }); },
|
||
"write": function (key, value) { return wrap(function () { return write(subject, key, value); }); },
|
||
"delete": function (key) { return wrap(function () { return delete_(subject, key); }); },
|
||
"read": function (key) { return wrap(function () { return read(subject, key); }); },
|
||
"search": function (term) { return wrap(function () { return search(subject, term); }); }
|
||
};
|
||
}
|
||
memory.implementation_chest = implementation_chest;
|
||
})(memory = storage.memory || (storage.memory = {}));
|
||
})(storage = lib_plankton.storage || (lib_plankton.storage = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:storage«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:storage« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:storage« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:storage«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var storage;
|
||
(function (storage) {
|
||
var memory;
|
||
(function (memory) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
var class_chest = /** @class */ (function () {
|
||
function class_chest(parameters) {
|
||
this.subject = memory.make(parameters);
|
||
}
|
||
class_chest.prototype.setup = function (input) { return Promise.resolve(undefined); };
|
||
class_chest.prototype.clear = function () { memory.clear(this.subject); return Promise.resolve(undefined); };
|
||
class_chest.prototype.write = function (key, value) { return Promise.resolve(memory.write(this.subject, key, value)); };
|
||
class_chest.prototype["delete"] = function (key) { memory.delete_(this.subject, key); return Promise.resolve(undefined); };
|
||
class_chest.prototype.read = function (key) { return Promise.resolve(memory.read(this.subject, key)); };
|
||
class_chest.prototype.search = function (term) { return Promise.resolve(memory.search(this.subject, term)); };
|
||
return class_chest;
|
||
}());
|
||
memory.class_chest = class_chest;
|
||
})(memory = storage.memory || (storage.memory = {}));
|
||
})(storage = lib_plankton.storage || (lib_plankton.storage = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:storage«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:storage« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:storage« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:storage«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var storage;
|
||
(function (storage) {
|
||
var filesystem;
|
||
(function (filesystem) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function make(parameters) {
|
||
return {
|
||
"nodemodule": require("fs")
|
||
};
|
||
}
|
||
filesystem.make = make;
|
||
/**
|
||
*/
|
||
function clear(subject) {
|
||
return Promise.reject(new Error("nope"));
|
||
}
|
||
filesystem.clear = clear;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function write(subject, path, content) {
|
||
return (new Promise(function (resolve, reject) {
|
||
var exists = subject.nodemodule.existsSync(path);
|
||
subject.nodemodule.writeFile(path, content, {}, function (error) {
|
||
if (error === null) {
|
||
resolve(exists);
|
||
}
|
||
else {
|
||
reject(error);
|
||
}
|
||
});
|
||
}));
|
||
}
|
||
filesystem.write = write;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function delete_(subject, path) {
|
||
return (new Promise(function (resolve, reject) {
|
||
subject.nodemodule.unlink(path, function (error) {
|
||
if (error === null) {
|
||
resolve(undefined);
|
||
}
|
||
else {
|
||
reject(error);
|
||
}
|
||
});
|
||
}));
|
||
}
|
||
filesystem.delete_ = delete_;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function read(subject, path) {
|
||
return (new Promise(function (resolve, reject) {
|
||
subject.nodemodule.readFile(path, {}, function (error, content) {
|
||
if (error === null) {
|
||
resolve(content);
|
||
}
|
||
else {
|
||
reject(error);
|
||
}
|
||
});
|
||
}));
|
||
}
|
||
filesystem.read = read;
|
||
/**
|
||
*/
|
||
function implementation_chest(parameters) {
|
||
var subject = make(parameters);
|
||
return {
|
||
"setup": function (input) { return Promise.resolve(undefined); },
|
||
"clear": function () { return clear(subject); },
|
||
"write": function (key, value) { return write(subject, key, value); },
|
||
"delete": function (key) { return delete_(subject, key); },
|
||
"read": function (key) { return read(subject, key); },
|
||
"search": function (term) { return Promise.reject("not available"); }
|
||
};
|
||
}
|
||
filesystem.implementation_chest = implementation_chest;
|
||
})(filesystem = storage.filesystem || (storage.filesystem = {}));
|
||
})(storage = lib_plankton.storage || (lib_plankton.storage = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:storage«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:storage« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:storage« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:storage«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var storage;
|
||
(function (storage) {
|
||
var filesystem;
|
||
(function (filesystem) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
var class_chest = /** @class */ (function () {
|
||
function class_chest(parameters) {
|
||
this.subject = filesystem.make(parameters);
|
||
}
|
||
class_chest.prototype.setup = function (input) { return Promise.resolve(undefined); };
|
||
class_chest.prototype.clear = function () { return filesystem.clear(this.subject); };
|
||
class_chest.prototype.write = function (key, value) { return filesystem.write(this.subject, key, value); };
|
||
class_chest.prototype["delete"] = function (key) { return filesystem.delete_(this.subject, key); };
|
||
class_chest.prototype.read = function (key) { return filesystem.read(this.subject, key); };
|
||
class_chest.prototype.search = function (searchterm) { return Promise.reject(new Error("not available")); };
|
||
return class_chest;
|
||
}());
|
||
filesystem.class_chest = class_chest;
|
||
})(filesystem = storage.filesystem || (storage.filesystem = {}));
|
||
})(storage = lib_plankton.storage || (lib_plankton.storage = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:storage«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:storage« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:storage« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:storage«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var storage;
|
||
(function (storage) {
|
||
/**
|
||
*/
|
||
function sql_table_autokey_make(parameters) {
|
||
return {
|
||
"database_implementation": parameters.database_implementation,
|
||
"table_name": parameters.table_name,
|
||
"key_name": parameters.key_name
|
||
};
|
||
}
|
||
storage.sql_table_autokey_make = sql_table_autokey_make;
|
||
/**
|
||
*/
|
||
function sql_table_autokey_setup(subject, description_create_table) {
|
||
return __awaiter(this, void 0, void 0, function () {
|
||
return __generator(this, function (_a) {
|
||
return [2 /*return*/, subject.database_implementation.query_create_table(description_create_table)];
|
||
});
|
||
});
|
||
}
|
||
storage.sql_table_autokey_setup = sql_table_autokey_setup;
|
||
/**
|
||
*/
|
||
function sql_table_autokey_create(subject, value) {
|
||
return __awaiter(this, void 0, void 0, function () {
|
||
return __generator(this, function (_a) {
|
||
return [2 /*return*/, subject.database_implementation.query_insert({
|
||
"table_name": subject.table_name,
|
||
"values": value,
|
||
"returning": subject.key_name
|
||
})];
|
||
});
|
||
});
|
||
}
|
||
storage.sql_table_autokey_create = sql_table_autokey_create;
|
||
/**
|
||
*/
|
||
function sql_table_autokey_update(subject, key, value) {
|
||
return __awaiter(this, void 0, void 0, function () {
|
||
return __generator(this, function (_a) {
|
||
return [2 /*return*/, (subject.database_implementation.query_update({
|
||
"table_name": subject.table_name,
|
||
"values": value,
|
||
"condition": lib_plankton.string.coin("{{key_name}} = $key", {
|
||
"key_name": subject.database_implementation.wrap_name(subject.key_name)
|
||
}),
|
||
"arguments": {
|
||
"key": key
|
||
}
|
||
})
|
||
.then(function (x) { return Promise.resolve(undefined); }))];
|
||
});
|
||
});
|
||
}
|
||
storage.sql_table_autokey_update = sql_table_autokey_update;
|
||
/**
|
||
*/
|
||
function sql_table_autokey_delete(subject, key) {
|
||
return __awaiter(this, void 0, void 0, function () {
|
||
return __generator(this, function (_a) {
|
||
switch (_a.label) {
|
||
case 0: return [4 /*yield*/, subject.database_implementation.query_delete({
|
||
"table_name": subject.table_name,
|
||
"condition": lib_plankton.string.coin("{{key_name}} = $key", {
|
||
"key_name": subject.database_implementation.wrap_name(subject.key_name)
|
||
}),
|
||
"arguments": {
|
||
"key": key
|
||
}
|
||
})];
|
||
case 1:
|
||
_a.sent();
|
||
return [2 /*return*/, Promise.resolve(undefined)];
|
||
}
|
||
});
|
||
});
|
||
}
|
||
storage.sql_table_autokey_delete = sql_table_autokey_delete;
|
||
/**
|
||
*/
|
||
function sql_table_autokey_read(subject, key) {
|
||
return __awaiter(this, void 0, void 0, function () {
|
||
var rows;
|
||
return __generator(this, function (_a) {
|
||
switch (_a.label) {
|
||
case 0: return [4 /*yield*/, subject.database_implementation.query_select({
|
||
"source": subject.table_name,
|
||
"fields": null,
|
||
"condition": lib_plankton.string.coin("{{key_name}} = $key", {
|
||
"key_name": subject.database_implementation.wrap_name(subject.key_name)
|
||
}),
|
||
"arguments": {
|
||
"key": key
|
||
}
|
||
})];
|
||
case 1:
|
||
rows = _a.sent();
|
||
if (rows.length < 1) {
|
||
return [2 /*return*/, Promise.reject("not found")];
|
||
}
|
||
else if (rows.length > 1) {
|
||
return [2 /*return*/, Promise.reject("ambiguous")];
|
||
}
|
||
else {
|
||
delete rows[0][subject.key_name];
|
||
return [2 /*return*/, Promise.resolve(rows[0])];
|
||
}
|
||
return [2 /*return*/];
|
||
}
|
||
});
|
||
});
|
||
}
|
||
storage.sql_table_autokey_read = sql_table_autokey_read;
|
||
/**
|
||
* @todo correct preview
|
||
*/
|
||
function sql_table_autokey_search(subject, term) {
|
||
return __awaiter(this, void 0, void 0, function () {
|
||
var rows;
|
||
return __generator(this, function (_a) {
|
||
switch (_a.label) {
|
||
case 0: return [4 /*yield*/, subject.database_implementation.query_select({
|
||
"source": subject.table_name,
|
||
"fields": null,
|
||
"condition": ((term === null) ? null : term.expression),
|
||
"arguments": ((term === null) ? null : term.arguments)
|
||
})];
|
||
case 1:
|
||
rows = _a.sent();
|
||
return [2 /*return*/, Promise.resolve(rows
|
||
.map(function (row) { return ({
|
||
"key": row[subject.key_name],
|
||
"preview": row
|
||
}); }))];
|
||
}
|
||
});
|
||
});
|
||
}
|
||
storage.sql_table_autokey_search = sql_table_autokey_search;
|
||
/**
|
||
*/
|
||
function sql_table_autokey_store(parameters) {
|
||
var subject = sql_table_autokey_make(parameters);
|
||
return {
|
||
"setup": function (input) { return sql_table_autokey_setup(subject, input); },
|
||
"create": function (value) { return sql_table_autokey_create(subject, value); },
|
||
"update": function (key, value) { return sql_table_autokey_update(subject, key, value); },
|
||
"delete": function (key) { return sql_table_autokey_delete(subject, key); },
|
||
"read": function (key) { return sql_table_autokey_read(subject, key); },
|
||
"search": function (term) { return sql_table_autokey_search(subject, term); }
|
||
};
|
||
}
|
||
storage.sql_table_autokey_store = sql_table_autokey_store;
|
||
})(storage = lib_plankton.storage || (lib_plankton.storage = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:storage«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:storage« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:storage« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:storage«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var storage;
|
||
(function (storage) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
var class_sql_table_autokey = /** @class */ (function () {
|
||
function class_sql_table_autokey(parameters) {
|
||
this.subject = storage.sql_table_autokey_make(parameters);
|
||
}
|
||
class_sql_table_autokey.prototype.setup = function (input) { return storage.sql_table_autokey_setup(this.subject, input); };
|
||
class_sql_table_autokey.prototype.create = function (value) { return storage.sql_table_autokey_create(this.subject, value); };
|
||
class_sql_table_autokey.prototype.update = function (key, value) { return storage.sql_table_autokey_update(this.subject, key, value); };
|
||
class_sql_table_autokey.prototype["delete"] = function (key) { return storage.sql_table_autokey_delete(this.subject, key); };
|
||
class_sql_table_autokey.prototype.read = function (key) { return storage.sql_table_autokey_read(this.subject, key); };
|
||
class_sql_table_autokey.prototype.search = function (term) { return storage.sql_table_autokey_search(this.subject, term); };
|
||
return class_sql_table_autokey;
|
||
}());
|
||
storage.class_sql_table_autokey = class_sql_table_autokey;
|
||
})(storage = lib_plankton.storage || (lib_plankton.storage = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:storage«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:storage« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:storage« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:storage«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var storage;
|
||
(function (storage) {
|
||
var sql_table_common;
|
||
(function (sql_table_common) {
|
||
/**
|
||
*/
|
||
function make(parameters) {
|
||
return {
|
||
"database_implementation": parameters.database_implementation,
|
||
"table_name": parameters.table_name,
|
||
"key_names": parameters.key_names
|
||
};
|
||
}
|
||
sql_table_common.make = make;
|
||
/**
|
||
*/
|
||
function key_condition(subject, key) {
|
||
return {
|
||
"condition": lib_string.coin("({{clauses}})", {
|
||
"clauses": (subject.key_names
|
||
.map(function (key_name) { return lib_plankton.string.coin("({{name1}} = $key_{{name2}})", {
|
||
"name1": subject.database_implementation.wrap_name(key_name),
|
||
"name2": key_name
|
||
}); })
|
||
.join(" AND "))
|
||
}),
|
||
"arguments": Object.fromEntries(subject.key_names
|
||
.map(function (key_name, index) { return ([
|
||
lib_plankton.string.coin("key_{{name}}", {
|
||
"name": key_name
|
||
}),
|
||
key[index]
|
||
]); }))
|
||
};
|
||
}
|
||
/**
|
||
*/
|
||
function setup(subject, description_create_table) {
|
||
return __awaiter(this, void 0, void 0, function () {
|
||
return __generator(this, function (_a) {
|
||
return [2 /*return*/, subject.database_implementation.query_create_table(description_create_table)];
|
||
});
|
||
});
|
||
}
|
||
sql_table_common.setup = setup;
|
||
/**
|
||
*/
|
||
function clear(subject) {
|
||
return __awaiter(this, void 0, void 0, function () {
|
||
return __generator(this, function (_a) {
|
||
switch (_a.label) {
|
||
case 0: return [4 /*yield*/, subject.database_implementation.query_delete({
|
||
"table_name": subject.table_name,
|
||
"condition": "TRUE",
|
||
"arguments": {}
|
||
})];
|
||
case 1:
|
||
_a.sent();
|
||
return [2 /*return*/, Promise.resolve(undefined)];
|
||
}
|
||
});
|
||
});
|
||
}
|
||
sql_table_common.clear = clear;
|
||
/**
|
||
* @todo optimize: avoid read
|
||
*/
|
||
function write(subject, key, value) {
|
||
return __awaiter(this, void 0, void 0, function () {
|
||
var exists, error_1, field_names, condition;
|
||
return __generator(this, function (_a) {
|
||
switch (_a.label) {
|
||
case 0:
|
||
_a.trys.push([0, 2, , 3]);
|
||
return [4 /*yield*/, read(subject, key)];
|
||
case 1:
|
||
_a.sent();
|
||
exists = true;
|
||
return [3 /*break*/, 3];
|
||
case 2:
|
||
error_1 = _a.sent();
|
||
exists = false;
|
||
return [3 /*break*/, 3];
|
||
case 3:
|
||
field_names = Object.keys(value);
|
||
if (!!exists) return [3 /*break*/, 5];
|
||
return [4 /*yield*/, subject.database_implementation.query_insert({
|
||
"table_name": subject.table_name,
|
||
"values": Object.assign(
|
||
// key
|
||
Object.fromEntries(subject.key_names.map(function (key_name, index) { return ([key_name, key[index]]); })),
|
||
// value
|
||
value)
|
||
})];
|
||
case 4:
|
||
_a.sent();
|
||
return [3 /*break*/, 7];
|
||
case 5:
|
||
condition = key_condition(subject, key);
|
||
return [4 /*yield*/, subject.database_implementation.query_update({
|
||
"table_name": subject.table_name,
|
||
"values": value,
|
||
"condition": condition.condition,
|
||
"arguments": condition.arguments
|
||
})];
|
||
case 6:
|
||
_a.sent();
|
||
_a.label = 7;
|
||
case 7: return [2 /*return*/, Promise.resolve(exists)];
|
||
}
|
||
});
|
||
});
|
||
}
|
||
sql_table_common.write = write;
|
||
/**
|
||
*/
|
||
function delete_(subject, key) {
|
||
return __awaiter(this, void 0, void 0, function () {
|
||
var condition;
|
||
return __generator(this, function (_a) {
|
||
switch (_a.label) {
|
||
case 0:
|
||
condition = key_condition(subject, key);
|
||
return [4 /*yield*/, subject.database_implementation.query_delete({
|
||
"table_name": subject.table_name,
|
||
"condition": condition.condition,
|
||
"arguments": condition.arguments
|
||
})];
|
||
case 1:
|
||
_a.sent();
|
||
return [2 /*return*/, Promise.resolve(undefined)];
|
||
}
|
||
});
|
||
});
|
||
}
|
||
sql_table_common.delete_ = delete_;
|
||
/**
|
||
*/
|
||
function read(subject, key) {
|
||
return __awaiter(this, void 0, void 0, function () {
|
||
var condition, rows;
|
||
return __generator(this, function (_a) {
|
||
switch (_a.label) {
|
||
case 0:
|
||
condition = key_condition(subject, key);
|
||
return [4 /*yield*/, subject.database_implementation.query_select({
|
||
"source": subject.table_name,
|
||
"fields": null,
|
||
"condition": condition.condition,
|
||
"arguments": condition.arguments
|
||
})];
|
||
case 1:
|
||
rows = _a.sent();
|
||
if (rows.length < 1) {
|
||
return [2 /*return*/, Promise.reject("not found")];
|
||
}
|
||
else if (rows.length > 1) {
|
||
return [2 /*return*/, Promise.reject("ambiguous")];
|
||
}
|
||
else {
|
||
subject.key_names.forEach(function (key_name) { delete rows[0][key_name]; });
|
||
return [2 /*return*/, Promise.resolve(rows[0])];
|
||
}
|
||
return [2 /*return*/];
|
||
}
|
||
});
|
||
});
|
||
}
|
||
sql_table_common.read = read;
|
||
/**
|
||
* @todo correct preview
|
||
*/
|
||
function search(subject, term) {
|
||
return __awaiter(this, void 0, void 0, function () {
|
||
var rows;
|
||
return __generator(this, function (_a) {
|
||
switch (_a.label) {
|
||
case 0: return [4 /*yield*/, subject.database_implementation.query_select({
|
||
"source": subject.table_name,
|
||
"fields": null,
|
||
"condition": ((term === null) ? null : term.expression),
|
||
"arguments": ((term === null) ? null : term.arguments)
|
||
})];
|
||
case 1:
|
||
rows = _a.sent();
|
||
return [2 /*return*/, Promise.resolve(rows
|
||
.map(function (row) { return ({
|
||
"key": subject.key_names.map(function (name) { return row[name]; }),
|
||
"preview": row
|
||
}); }))];
|
||
}
|
||
});
|
||
});
|
||
}
|
||
sql_table_common.search = search;
|
||
/**
|
||
*/
|
||
function chest(parameters) {
|
||
var subject = make(parameters);
|
||
return {
|
||
"setup": function (input) { return setup(subject, input); },
|
||
"clear": function () { return clear(subject); },
|
||
"write": function (key, value) { return write(subject, key, value); },
|
||
"delete": function (key) { return delete_(subject, key); },
|
||
"read": function (key) { return read(subject, key); },
|
||
"search": function (term) { return search(subject, term); }
|
||
};
|
||
}
|
||
sql_table_common.chest = chest;
|
||
})(sql_table_common = storage.sql_table_common || (storage.sql_table_common = {}));
|
||
})(storage = lib_plankton.storage || (lib_plankton.storage = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:storage«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:storage« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:storage« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:storage«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var storage;
|
||
(function (storage) {
|
||
var sql_table_common;
|
||
(function (sql_table_common) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
var class_chest = /** @class */ (function () {
|
||
function class_chest(parameters) {
|
||
this.subject = sql_table_common.make(parameters);
|
||
}
|
||
class_chest.prototype.setup = function (input) { return sql_table_common.setup(this.subject, input); };
|
||
class_chest.prototype.clear = function () { return sql_table_common.clear(this.subject); };
|
||
class_chest.prototype.write = function (key, value) { return sql_table_common.write(this.subject, key, value); };
|
||
class_chest.prototype["delete"] = function (key) { return sql_table_common.delete_(this.subject, key); };
|
||
class_chest.prototype.read = function (key) { return sql_table_common.read(this.subject, key); };
|
||
class_chest.prototype.search = function (term) { return sql_table_common.search(this.subject, term); };
|
||
return class_chest;
|
||
}());
|
||
sql_table_common.class_chest = class_chest;
|
||
})(sql_table_common = storage.sql_table_common || (storage.sql_table_common = {}));
|
||
})(storage = lib_plankton.storage || (lib_plankton.storage = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:shape«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:shape« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:shape« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:shape«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var shape;
|
||
(function (shape_1) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function inspection_create() {
|
||
return {
|
||
"flaws": [],
|
||
"sub": []
|
||
};
|
||
}
|
||
shape_1.inspection_create = inspection_create;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function inspection_add(main, flaw) {
|
||
main.flaws.push(flaw);
|
||
}
|
||
shape_1.inspection_add = inspection_add;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function inspection_extend(main, prefix, sub) {
|
||
if ((sub.flaws.length <= 0)
|
||
&&
|
||
(sub.sub.length <= 0)) {
|
||
// do nothing
|
||
}
|
||
else {
|
||
main.sub.push({ "position": prefix, "inspection": sub });
|
||
}
|
||
}
|
||
shape_1.inspection_extend = inspection_extend;
|
||
/**
|
||
*/
|
||
function inspection_flatten(inspection) {
|
||
return (inspection.flaws
|
||
.concat(inspection.sub
|
||
.map((entry) => (inspection_flatten(entry.inspection)
|
||
.map(rest => lib_plankton.string.coin("[{{position}}] {{rest}}", {
|
||
"position": entry.position,
|
||
"rest": rest
|
||
}))))
|
||
.reduce((x, y) => x.concat(y), [])));
|
||
}
|
||
/**
|
||
*/
|
||
var _pool = {};
|
||
/**
|
||
* @todo cache
|
||
*/
|
||
function construct(shape) {
|
||
return _pool[shape.kind].construct(shape.parameters);
|
||
}
|
||
/**
|
||
*/
|
||
function get_logic(shape) {
|
||
if (!(shape.kind in _pool)) {
|
||
throw (new Error("missing shape: " + shape.kind));
|
||
}
|
||
else {
|
||
return _pool[shape.kind].logic(construct(shape));
|
||
}
|
||
}
|
||
/**
|
||
*/
|
||
function inspect(shape, value) {
|
||
return get_logic(shape).inspect(inspect, value);
|
||
}
|
||
shape_1.inspect = inspect;
|
||
/**
|
||
*/
|
||
function inspect_flat(shape, value) {
|
||
return inspection_flatten(inspect(shape, value));
|
||
}
|
||
shape_1.inspect_flat = inspect_flat;
|
||
/**
|
||
*/
|
||
function show(shape) {
|
||
return get_logic(shape).show(show);
|
||
}
|
||
shape_1.show = show;
|
||
/**
|
||
*/
|
||
function to_typescript_type(shape) {
|
||
return get_logic(shape).to_typescript_type(to_typescript_type);
|
||
}
|
||
shape_1.to_typescript_type = to_typescript_type;
|
||
/**
|
||
*/
|
||
function to_jsonschema(shape) {
|
||
return get_logic(shape).to_jsonschema(to_jsonschema);
|
||
}
|
||
shape_1.to_jsonschema = to_jsonschema;
|
||
/**
|
||
*/
|
||
function to_oas_schema(shape) {
|
||
return get_logic(shape).to_oas_schema(to_oas_schema);
|
||
}
|
||
shape_1.to_oas_schema = to_oas_schema;
|
||
/**
|
||
*/
|
||
function example(shape) {
|
||
return get_logic(shape).example(example);
|
||
}
|
||
shape_1.example = example;
|
||
/**
|
||
*/
|
||
function register(name, construct, logic) {
|
||
_pool[name] = {
|
||
"construct": construct,
|
||
"logic": logic,
|
||
};
|
||
}
|
||
shape_1.register = register;
|
||
})(shape = lib_plankton.shape || (lib_plankton.shape = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:shape«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:shape« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:shape« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:shape«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var shape;
|
||
(function (shape_2) {
|
||
var any;
|
||
(function (any) {
|
||
/**
|
||
*/
|
||
function make(options = {}) {
|
||
return {};
|
||
}
|
||
any.make = make;
|
||
/**
|
||
*/
|
||
function inspect(sub_inspect, subject, value) {
|
||
let inspection = shape_2.inspection_create();
|
||
return inspection;
|
||
}
|
||
/**
|
||
*/
|
||
function show(sub_show, subject) {
|
||
return "any";
|
||
}
|
||
/**
|
||
*/
|
||
function to_typescript_type(sub_to_typescript_type, subject) {
|
||
return "any";
|
||
}
|
||
/**
|
||
*/
|
||
function to_jsonschema(sub_to_jsonschema, subject) {
|
||
return {};
|
||
}
|
||
/**
|
||
*/
|
||
function example(sub_example, subject) {
|
||
return null;
|
||
}
|
||
shape_2.register("any", (parameters) => make({}), (subject) => ({
|
||
"inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value),
|
||
"show": (sub_show) => show(sub_show, subject),
|
||
"to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject),
|
||
"to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject),
|
||
"to_oas_schema": (sub_to_oas_schema) => to_jsonschema(sub_to_oas_schema, subject),
|
||
"example": (sub_example) => example(sub_example, subject),
|
||
}));
|
||
})(any = shape_2.any || (shape_2.any = {}));
|
||
})(shape = lib_plankton.shape || (lib_plankton.shape = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:shape«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:shape« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:shape« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:shape«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var shape;
|
||
(function (shape_3) {
|
||
var null_;
|
||
(function (null_) {
|
||
/**
|
||
*/
|
||
function make(options = {}) {
|
||
return {};
|
||
}
|
||
null_.make = make;
|
||
/**
|
||
*/
|
||
function inspect(sub_inspect, subject, value) {
|
||
let inspection = shape_3.inspection_create();
|
||
if (!(value === null)) {
|
||
shape_3.inspection_add(inspection, "null expected");
|
||
}
|
||
else {
|
||
// all good
|
||
}
|
||
return inspection;
|
||
}
|
||
/**
|
||
*/
|
||
function show(sub_show, subject) {
|
||
return "null";
|
||
}
|
||
/**
|
||
*/
|
||
function to_typescript_type(sub_to_typescript_type, subject) {
|
||
return "null";
|
||
}
|
||
/**
|
||
*/
|
||
function to_jsonschema(sub_to_jsonschema, subject) {
|
||
return {
|
||
"type": "null",
|
||
};
|
||
}
|
||
/**
|
||
*/
|
||
function example(sub_example, subject) {
|
||
return null;
|
||
}
|
||
shape_3.register("null", (parameters) => make({}), (subject) => ({
|
||
"inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value),
|
||
"show": (sub_show) => show(sub_show, subject),
|
||
"to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject),
|
||
"to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject),
|
||
"to_oas_schema": (sub_to_oas_schema) => to_jsonschema(sub_to_oas_schema, subject),
|
||
"example": (sub_example) => example(sub_example, subject),
|
||
}));
|
||
})(null_ = shape_3.null_ || (shape_3.null_ = {}));
|
||
})(shape = lib_plankton.shape || (lib_plankton.shape = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:shape«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:shape« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:shape« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:shape«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var shape;
|
||
(function (shape_4) {
|
||
var boolean;
|
||
(function (boolean) {
|
||
/**
|
||
*/
|
||
function make(options = {}) {
|
||
options = Object.assign({
|
||
"soft": false,
|
||
"defaultvalue": undefined,
|
||
"description": undefined,
|
||
}, options);
|
||
return {
|
||
"soft": options.soft,
|
||
"defaultvalue": ((options.defaultvalue === undefined)
|
||
? lib_plankton.pod.make_empty()
|
||
: lib_plankton.pod.make_filled(options.defaultvalue)),
|
||
"description": ((options.description === undefined)
|
||
? lib_plankton.pod.make_empty()
|
||
: lib_plankton.pod.make_filled(options.description)),
|
||
};
|
||
}
|
||
boolean.make = make;
|
||
/**
|
||
*/
|
||
function inspect(sub_inspect, subject, value) {
|
||
let inspection = shape_4.inspection_create();
|
||
if (value === null) {
|
||
if (subject.soft) {
|
||
// all good
|
||
}
|
||
else {
|
||
shape_4.inspection_add(inspection, "null is not allowed");
|
||
}
|
||
}
|
||
else {
|
||
const jstype_actual = typeof (value);
|
||
const jstype_expected = "boolean";
|
||
if (jstype_actual === jstype_expected) {
|
||
// all good
|
||
}
|
||
else {
|
||
shape_4.inspection_add(inspection, lib_plankton.string.coin("expected JS-type '{{expected}}' but got '{{actual}}'", {
|
||
"expected": jstype_expected,
|
||
"actual": jstype_actual,
|
||
}));
|
||
}
|
||
}
|
||
return inspection;
|
||
}
|
||
/**
|
||
*/
|
||
function show(sub_show, subject) {
|
||
const core = "boolean";
|
||
return (subject.soft ? ("~" + core) : core);
|
||
}
|
||
/**
|
||
*/
|
||
function to_typescript_type(sub_to_typescript_type, subject) {
|
||
const core = "boolean";
|
||
return (subject.soft ? ("(null | " + core + ")") : core);
|
||
}
|
||
/**
|
||
*/
|
||
function to_jsonschema(sub_to_jsonschema, subject) {
|
||
const common = {
|
||
"description": lib_plankton.pod.distinguish(subject.description, () => undefined, x => x),
|
||
"default": lib_plankton.pod.distinguish(subject.defaultvalue, () => undefined, x => x),
|
||
};
|
||
const core = {
|
||
"type": "boolean",
|
||
};
|
||
return (subject.soft
|
||
? {
|
||
"anyOf": [
|
||
Object.assign({ "type": "null" }, common),
|
||
Object.assign(core, common),
|
||
],
|
||
}
|
||
: core);
|
||
}
|
||
/**
|
||
*/
|
||
function example(sub_example, subject) {
|
||
return (subject.soft ? null : false);
|
||
}
|
||
shape_4.register("boolean", (parameters) => make({
|
||
"soft": parameters.soft,
|
||
"description": parameters.description,
|
||
"defaultvalue": parameters.defaultvalue,
|
||
}), (subject) => ({
|
||
"inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value),
|
||
"show": (sub_show) => show(sub_show, subject),
|
||
"to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject),
|
||
"to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject),
|
||
"to_oas_schema": (sub_to_oas_schema) => to_jsonschema(sub_to_oas_schema, subject),
|
||
"example": (sub_example) => example(sub_example, subject),
|
||
}));
|
||
})(boolean = shape_4.boolean || (shape_4.boolean = {}));
|
||
})(shape = lib_plankton.shape || (lib_plankton.shape = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:shape«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:shape« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:shape« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:shape«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var shape;
|
||
(function (shape_5) {
|
||
var integer;
|
||
(function (integer) {
|
||
/**
|
||
*/
|
||
function make(options = {}) {
|
||
options = Object.assign({
|
||
"soft": false,
|
||
"defaultvalue": undefined,
|
||
"description": undefined,
|
||
"minimum": undefined,
|
||
"maximum": undefined,
|
||
}, options);
|
||
return {
|
||
"soft": options.soft,
|
||
"defaultvalue": ((options.defaultvalue === undefined)
|
||
? lib_plankton.pod.make_empty()
|
||
: lib_plankton.pod.make_filled(options.defaultvalue)),
|
||
"description": ((options.description === undefined)
|
||
? lib_plankton.pod.make_empty()
|
||
: lib_plankton.pod.make_filled(options.description)),
|
||
"minimum": ((options.minimum === undefined)
|
||
? lib_plankton.pod.make_empty()
|
||
: lib_plankton.pod.make_filled(options.minimum)),
|
||
"maximum": ((options.minimum === undefined)
|
||
? lib_plankton.pod.make_empty()
|
||
: lib_plankton.pod.make_filled(options.maximum)),
|
||
};
|
||
}
|
||
integer.make = make;
|
||
/**
|
||
*/
|
||
function inspect(sub_inspect, subject, value) {
|
||
let inspection = shape_5.inspection_create();
|
||
if (value === null) {
|
||
if (subject.soft) {
|
||
// all good
|
||
}
|
||
else {
|
||
shape_5.inspection_add(inspection, "null is not allowed");
|
||
}
|
||
}
|
||
else {
|
||
const jstype_actual = typeof (value);
|
||
const jstype_expected = "number";
|
||
if (!(jstype_actual === jstype_expected)) {
|
||
shape_5.inspection_add(inspection, lib_plankton.string.coin("expected JS-type '{{expected}}' but got '{{actual}}'", {
|
||
"expected": jstype_expected,
|
||
"actual": jstype_actual,
|
||
}));
|
||
}
|
||
else {
|
||
if (isNaN(parseInt(value))) {
|
||
shape_5.inspection_add(inspection, "value is not parsable to a valid int");
|
||
}
|
||
else {
|
||
// minimum
|
||
{
|
||
if (!lib_plankton.pod.distinguish(subject.minimum, () => true, x => (value >= x))) {
|
||
shape_5.inspection_add(inspection, lib_plankton.string.coin("value is below the minimum of '{{minimum}}'", {
|
||
"minimum": lib_plankton.pod.cull(subject.minimum).toFixed(0),
|
||
}));
|
||
}
|
||
else {
|
||
// do nothing
|
||
}
|
||
}
|
||
// maximum
|
||
{
|
||
if (!lib_plankton.pod.distinguish(subject.maximum, () => true, x => (value <= x))) {
|
||
shape_5.inspection_add(inspection, lib_plankton.string.coin("value is beyond the maximum of '{{maximum}}'", {
|
||
"maximum": lib_plankton.pod.cull(subject.maximum).toFixed(0),
|
||
}));
|
||
}
|
||
else {
|
||
// do nothing
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return inspection;
|
||
}
|
||
/**
|
||
*/
|
||
function show(sub_show, subject) {
|
||
const core = "integer";
|
||
return (subject.soft ? ("~" + core) : core);
|
||
}
|
||
/**
|
||
*/
|
||
function to_typescript_type(sub_to_typescript_type, subject) {
|
||
const core = "number";
|
||
return (subject.soft ? ("(null | " + core + ")") : core);
|
||
}
|
||
/**
|
||
*/
|
||
function to_jsonschema(sub_to_jsonschema, subject) {
|
||
const common = {
|
||
"description": lib_plankton.pod.distinguish(subject.description, () => undefined, x => x),
|
||
"default": lib_plankton.pod.distinguish(subject.defaultvalue, () => undefined, x => x),
|
||
};
|
||
const core = {
|
||
"type": "integer",
|
||
"minimum": lib_plankton.pod.distinguish(subject.minimum, () => undefined, x => x),
|
||
"maximum": lib_plankton.pod.distinguish(subject.maximum, () => undefined, x => x),
|
||
};
|
||
return (subject.soft
|
||
? {
|
||
"anyOf": [
|
||
Object.assign({ "type": "null" }, common),
|
||
Object.assign(core, common),
|
||
],
|
||
}
|
||
: core);
|
||
}
|
||
/**
|
||
*/
|
||
function example(sub_example, subject) {
|
||
return (subject.soft ? null : 0);
|
||
}
|
||
shape_5.register("integer", (parameters) => make({
|
||
"soft": parameters.soft,
|
||
"description": parameters.description,
|
||
"defaultvalue": parameters.defaultvalue,
|
||
"minimum": parameters.minimum,
|
||
"maximum": parameters.maximum,
|
||
}), (subject) => ({
|
||
"inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value),
|
||
"show": (sub_show) => show(sub_show, subject),
|
||
"to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject),
|
||
"to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject),
|
||
"to_oas_schema": (sub_to_oas_schema) => to_jsonschema(sub_to_oas_schema, subject),
|
||
"example": (sub_example) => example(sub_example, subject),
|
||
}));
|
||
})(integer = shape_5.integer || (shape_5.integer = {}));
|
||
})(shape = lib_plankton.shape || (lib_plankton.shape = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:shape«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:shape« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:shape« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:shape«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var shape;
|
||
(function (shape_6) {
|
||
var float;
|
||
(function (float) {
|
||
/**
|
||
*/
|
||
function make(options = {}) {
|
||
options = Object.assign({
|
||
"soft": false,
|
||
"defaultvalue": undefined,
|
||
"description": undefined,
|
||
"minimum": undefined,
|
||
"maximum": undefined,
|
||
}, options);
|
||
return {
|
||
"soft": options.soft,
|
||
"defaultvalue": ((options.defaultvalue === undefined)
|
||
? lib_plankton.pod.make_empty()
|
||
: lib_plankton.pod.make_filled(options.defaultvalue)),
|
||
"description": ((options.description === undefined)
|
||
? lib_plankton.pod.make_empty()
|
||
: lib_plankton.pod.make_filled(options.description)),
|
||
"minimum": ((options.minimum === undefined)
|
||
? lib_plankton.pod.make_empty()
|
||
: lib_plankton.pod.make_filled(options.minimum)),
|
||
"maximum": ((options.minimum === undefined)
|
||
? lib_plankton.pod.make_empty()
|
||
: lib_plankton.pod.make_filled(options.maximum)),
|
||
};
|
||
}
|
||
float.make = make;
|
||
/**
|
||
*/
|
||
function inspect(sub_inspect, subject, value) {
|
||
let inspection = shape_6.inspection_create();
|
||
if (value === null) {
|
||
if (subject.soft) {
|
||
// all good
|
||
}
|
||
else {
|
||
shape_6.inspection_add(inspection, "null is not allowed");
|
||
}
|
||
}
|
||
else {
|
||
const jstype_actual = typeof (value);
|
||
const jstype_expected = "number";
|
||
if (!(jstype_actual === jstype_expected)) {
|
||
shape_6.inspection_add(inspection, lib_plankton.string.coin("expected JS-type '{{expected}}' but got '{{actual}}'", {
|
||
"expected": jstype_expected,
|
||
"actual": jstype_actual,
|
||
}));
|
||
}
|
||
else {
|
||
if (isNaN(parseInt(value))) {
|
||
shape_6.inspection_add(inspection, "value is not parsable to a valid float");
|
||
}
|
||
else {
|
||
// minimum
|
||
{
|
||
if (!lib_plankton.pod.distinguish(subject.minimum, () => true, x => (value >= x))) {
|
||
shape_6.inspection_add(inspection, lib_plankton.string.coin("value is below the minimum of '{{minimum}}'", {
|
||
"minimum": lib_plankton.pod.cull(subject.minimum).toFixed(0),
|
||
}));
|
||
}
|
||
else {
|
||
// do nothing
|
||
}
|
||
}
|
||
// maximum
|
||
{
|
||
if (!lib_plankton.pod.distinguish(subject.maximum, () => true, x => (value <= x))) {
|
||
shape_6.inspection_add(inspection, lib_plankton.string.coin("value is beyond the maximum of '{{maximum}}'", {
|
||
"maximum": lib_plankton.pod.cull(subject.maximum).toFixed(0),
|
||
}));
|
||
}
|
||
else {
|
||
// do nothing
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return inspection;
|
||
}
|
||
/**
|
||
*/
|
||
function show(sub_show, subject) {
|
||
const core = "float";
|
||
return (subject.soft ? ("~" + core) : core);
|
||
}
|
||
/**
|
||
*/
|
||
function to_typescript_type(sub_to_typescript_type, subject) {
|
||
const core = "number";
|
||
return (subject.soft ? ("(null | " + core + ")") : core);
|
||
}
|
||
/**
|
||
*/
|
||
function to_jsonschema(sub_to_jsonschema, subject) {
|
||
const common = {
|
||
"description": lib_plankton.pod.distinguish(subject.description, () => undefined, x => x),
|
||
"default": lib_plankton.pod.distinguish(subject.defaultvalue, () => undefined, x => x),
|
||
};
|
||
const core = {
|
||
"type": "float",
|
||
"minimum": lib_plankton.pod.distinguish(subject.minimum, () => undefined, x => x),
|
||
"maximum": lib_plankton.pod.distinguish(subject.maximum, () => undefined, x => x),
|
||
};
|
||
return (subject.soft
|
||
? {
|
||
"anyOf": [
|
||
Object.assign({ "type": "null" }, common),
|
||
Object.assign(core, common),
|
||
],
|
||
}
|
||
: core);
|
||
}
|
||
/**
|
||
*/
|
||
function example(sub_example, subject) {
|
||
return (subject.soft ? null : 0);
|
||
}
|
||
shape_6.register("float", (parameters) => make({
|
||
"soft": parameters.soft,
|
||
"description": parameters.description,
|
||
"defaultvalue": parameters.defaultvalue,
|
||
"minimum": parameters.minimum,
|
||
"maximum": parameters.maximum,
|
||
}), (subject) => ({
|
||
"inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value),
|
||
"show": (sub_show) => show(sub_show, subject),
|
||
"to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject),
|
||
"to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject),
|
||
"to_oas_schema": (sub_to_oas_schema) => to_jsonschema(sub_to_oas_schema, subject),
|
||
"example": (sub_example) => example(sub_example, subject),
|
||
}));
|
||
})(float = shape_6.float || (shape_6.float = {}));
|
||
})(shape = lib_plankton.shape || (lib_plankton.shape = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:shape«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:shape« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:shape« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:shape«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var shape;
|
||
(function (shape_7) {
|
||
var string;
|
||
(function (string) {
|
||
/**
|
||
*/
|
||
function make(options = {}) {
|
||
options = Object.assign({
|
||
"soft": false,
|
||
"defaultvalue": undefined,
|
||
"description": undefined,
|
||
"pattern": undefined,
|
||
"min_length": undefined,
|
||
"max_lenth": undefined,
|
||
}, options);
|
||
return {
|
||
"soft": options.soft,
|
||
"defaultvalue": ((options.defaultvalue === undefined)
|
||
? lib_plankton.pod.make_empty()
|
||
: lib_plankton.pod.make_filled(options.defaultvalue)),
|
||
"description": ((options.description === undefined)
|
||
? lib_plankton.pod.make_empty()
|
||
: lib_plankton.pod.make_filled(options.description)),
|
||
"pattern": ((options.pattern === undefined)
|
||
? lib_plankton.pod.make_empty()
|
||
: lib_plankton.pod.make_filled(options.pattern)),
|
||
"min_length": ((options.min_length === undefined)
|
||
? lib_plankton.pod.make_empty()
|
||
: lib_plankton.pod.make_filled(options.min_length)),
|
||
"max_length": ((options.max_length === undefined)
|
||
? lib_plankton.pod.make_empty()
|
||
: lib_plankton.pod.make_filled(options.max_length)),
|
||
};
|
||
}
|
||
string.make = make;
|
||
/**
|
||
*/
|
||
function inspect(sub_inspect, subject, value) {
|
||
let inspection = shape_7.inspection_create();
|
||
if (value === null) {
|
||
if (subject.soft) {
|
||
// all good
|
||
}
|
||
else {
|
||
shape_7.inspection_add(inspection, "null is not allowed");
|
||
}
|
||
}
|
||
else {
|
||
const jstype_actual = typeof (value);
|
||
const jstype_expected = "string";
|
||
if (!(jstype_actual === jstype_expected)) {
|
||
shape_7.inspection_add(inspection, lib_plankton.string.coin("expected JS-type '{{expected}}' but got '{{actual}}'", {
|
||
"expected": jstype_expected,
|
||
"actual": jstype_actual,
|
||
}));
|
||
}
|
||
else {
|
||
const value_ = value;
|
||
// pattern
|
||
{
|
||
if (!lib_plankton.pod.distinguish(subject.pattern, () => true, x => (new RegExp(x)).test(value_))) {
|
||
shape_7.inspection_add(inspection, lib_plankton.string.coin("string does not match the pattern '{{pattern}}'", {
|
||
"pattern": lib_plankton.pod.cull(subject.pattern),
|
||
}));
|
||
}
|
||
else {
|
||
// do nothing
|
||
}
|
||
}
|
||
// min_length
|
||
{
|
||
if (!lib_plankton.pod.distinguish(subject.min_length, () => true, x => (value_.length >= x))) {
|
||
shape_7.inspection_add(inspection, lib_plankton.string.coin("string is shorter than '{{min_length}}'", {
|
||
"min_length": lib_plankton.pod.cull(subject.min_length).toFixed(0),
|
||
}));
|
||
}
|
||
else {
|
||
// do nothing
|
||
}
|
||
}
|
||
// max_length
|
||
{
|
||
if (!lib_plankton.pod.distinguish(subject.max_length, () => true, x => (value_.length <= x))) {
|
||
shape_7.inspection_add(inspection, lib_plankton.string.coin("string is longer than '{{max_length}}'", {
|
||
"min_length": lib_plankton.pod.cull(subject.max_length).toFixed(0),
|
||
}));
|
||
}
|
||
else {
|
||
// do nothing
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return inspection;
|
||
}
|
||
/**
|
||
*/
|
||
function show(sub_show, subject) {
|
||
const core = "string";
|
||
return (subject.soft ? ("~" + core) : core);
|
||
}
|
||
/**
|
||
*/
|
||
function to_typescript_type(sub_to_typescript_type, subject) {
|
||
const core = "string";
|
||
return (subject.soft ? ("(null | " + core + ")") : core);
|
||
}
|
||
/**
|
||
*/
|
||
function to_jsonschema(sub_to_jsonschema, subject) {
|
||
const common = {
|
||
"description": lib_plankton.pod.distinguish(subject.description, () => undefined, x => x),
|
||
"default": lib_plankton.pod.distinguish(subject.defaultvalue, () => undefined, x => x),
|
||
};
|
||
const core = {
|
||
"type": "string",
|
||
// TODO: transform?
|
||
"pattern": lib_plankton.pod.distinguish(subject.pattern, () => undefined, x => x),
|
||
"minLength": lib_plankton.pod.distinguish(subject.min_length, () => undefined, x => x),
|
||
"maxLenth": lib_plankton.pod.distinguish(subject.max_length, () => undefined, x => x),
|
||
};
|
||
return (subject.soft
|
||
? {
|
||
"anyOf": [
|
||
Object.assign({ "type": "null" }, common),
|
||
Object.assign(core, common),
|
||
],
|
||
}
|
||
: core);
|
||
}
|
||
/**
|
||
*/
|
||
function example(sub_example, subject) {
|
||
return (subject.soft ? null : "");
|
||
}
|
||
shape_7.register("string", (parameters) => make({
|
||
"soft": parameters.soft,
|
||
"description": parameters.description,
|
||
"defaultvalue": parameters.defaultvalue,
|
||
"pattern": parameters.pattern,
|
||
"min_length": parameters.min_length,
|
||
"max_length": parameters.max_length,
|
||
}), (subject) => ({
|
||
"inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value),
|
||
"show": (sub_show) => show(sub_show, subject),
|
||
"to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject),
|
||
"to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject),
|
||
"to_oas_schema": (sub_to_oas_chema) => to_jsonschema(sub_to_oas_chema, subject),
|
||
"example": (sub_example) => example(sub_example, subject),
|
||
}));
|
||
})(string = shape_7.string || (shape_7.string = {}));
|
||
})(shape = lib_plankton.shape || (lib_plankton.shape = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:shape«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:shape« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:shape« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:shape«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var shape;
|
||
(function (shape_8) {
|
||
var email;
|
||
(function (email) {
|
||
/**
|
||
*/
|
||
function make(options = {}) {
|
||
options = Object.assign({
|
||
"soft": false,
|
||
"defaultvalue": undefined,
|
||
"description": undefined,
|
||
}, options);
|
||
return {
|
||
"core": {
|
||
"kind": "string",
|
||
"parameters": {
|
||
"soft": options.soft,
|
||
"defaultvalue": options.defaultvalue,
|
||
"description": options.description,
|
||
"pattern": "[^@]*@[^@]*",
|
||
"min_length": 0,
|
||
"max_length": 255,
|
||
}
|
||
},
|
||
};
|
||
}
|
||
email.make = make;
|
||
/**
|
||
*/
|
||
function inspect(sub_inspect, subject, value) {
|
||
return sub_inspect(subject.core, value);
|
||
}
|
||
/**
|
||
*/
|
||
function show(sub_show, subject) {
|
||
return sub_show(subject.core);
|
||
}
|
||
/**
|
||
*/
|
||
function to_typescript_type(sub_to_typescript_type, subject) {
|
||
return sub_to_typescript_type(subject.core);
|
||
}
|
||
/**
|
||
*/
|
||
function to_jsonschema(sub_to_jsonschema, subject) {
|
||
return sub_to_jsonschema(subject.core);
|
||
}
|
||
/**
|
||
*/
|
||
function example(sub_example, subject) {
|
||
return sub_example(subject.core);
|
||
}
|
||
shape_8.register("email", (parameters) => make({
|
||
"soft": parameters.soft,
|
||
"description": parameters.description,
|
||
"defaultvalue": parameters.defaultvalue,
|
||
}), (subject) => ({
|
||
"inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value),
|
||
"show": (sub_show) => show(sub_show, subject),
|
||
"to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject),
|
||
"to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject),
|
||
"to_oas_schema": (sub_to_oas_chema) => to_jsonschema(sub_to_oas_chema, subject),
|
||
"example": (sub_example) => example(sub_example, subject),
|
||
}));
|
||
})(email = shape_8.email || (shape_8.email = {}));
|
||
})(shape = lib_plankton.shape || (lib_plankton.shape = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:shape«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:shape« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:shape« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:shape«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var shape;
|
||
(function (shape_9) {
|
||
var list_;
|
||
(function (list_) {
|
||
/**
|
||
*/
|
||
function make(shape_element, options = {}) {
|
||
options = Object.assign({
|
||
"soft": false,
|
||
"defaultvalue": lib_plankton.pod.make_empty(),
|
||
"description": lib_plankton.pod.make_empty(),
|
||
}, options);
|
||
return {
|
||
"shape_element": shape_element,
|
||
"soft": options.soft,
|
||
"defaultvalue": ((options.defaultvalue === undefined)
|
||
? lib_plankton.pod.make_empty()
|
||
: lib_plankton.pod.make_filled(options.defaultvalue)),
|
||
"description": ((options.description === undefined)
|
||
? lib_plankton.pod.make_empty()
|
||
: lib_plankton.pod.make_filled(options.description)),
|
||
};
|
||
}
|
||
list_.make = make;
|
||
/**
|
||
*/
|
||
function inspect(sub_inspect, subject, value) {
|
||
let inspection = shape_9.inspection_create();
|
||
if (value === null) {
|
||
if (subject.soft) {
|
||
// all good
|
||
}
|
||
else {
|
||
shape_9.inspection_add(inspection, "null is not allowed");
|
||
}
|
||
}
|
||
else {
|
||
const jstype_actual = typeof (value);
|
||
const jstype_expected = "object";
|
||
if (!(jstype_actual === jstype_expected)) {
|
||
lib_plankton.string.coin("expected JS-type '{{expected}}' but got '{{actual}}'", {
|
||
"expected": jstype_expected,
|
||
"actual": jstype_actual,
|
||
});
|
||
}
|
||
else {
|
||
if (!(value instanceof Array)) {
|
||
shape_9.inspection_add(inspection, "value does not seem to be an array-instance");
|
||
}
|
||
else {
|
||
value.forEach((element, index) => {
|
||
shape_9.inspection_extend(inspection, lib_plankton.string.coin("element #{{index}}", {
|
||
"index": index.toFixed(0),
|
||
}),
|
||
// subject.shape_element.inspect(element)
|
||
sub_inspect(subject.shape_element, element));
|
||
});
|
||
}
|
||
}
|
||
}
|
||
return inspection;
|
||
}
|
||
/**
|
||
*/
|
||
function show(sub_show, subject) {
|
||
const core = lib_plankton.string.coin("list<{{element}}>", {
|
||
"element": sub_show(subject.shape_element),
|
||
});
|
||
return (subject.soft ? ("~" + core) : core);
|
||
}
|
||
/**
|
||
*/
|
||
function to_typescript_type(sub_to_typescript_type, subject) {
|
||
const core = lib_plankton.string.coin("Array<{{element}}>", {
|
||
"element": sub_to_typescript_type(subject.shape_element),
|
||
});
|
||
return (subject.soft ? ("(null | " + core + ")") : core);
|
||
}
|
||
/**
|
||
*/
|
||
function to_jsonschema(sub_to_jsonschema, subject) {
|
||
const common = {
|
||
"description": lib_plankton.pod.distinguish(subject.description, () => undefined, x => x),
|
||
"default": lib_plankton.pod.distinguish(subject.defaultvalue, () => undefined, x => x),
|
||
};
|
||
const core = {
|
||
"type": "array",
|
||
"items": sub_to_jsonschema(subject.shape_element),
|
||
};
|
||
return ((subject.soft
|
||
? {
|
||
"anyOf": [
|
||
Object.assign({ "type": "null" }, common),
|
||
Object.assign(core, common),
|
||
]
|
||
}
|
||
: core));
|
||
}
|
||
/**
|
||
*/
|
||
function example(sub_example, subject) {
|
||
return (subject.soft
|
||
? null
|
||
: [
|
||
sub_example(subject.shape_element)
|
||
]);
|
||
}
|
||
shape_9.register("list", (parameters) => make(parameters.shape_element, {
|
||
"soft": parameters.soft,
|
||
"description": parameters.description,
|
||
"defaultvalue": parameters.defaultvalue,
|
||
}), (subject) => ({
|
||
"inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value),
|
||
"show": (sub_show) => show(sub_show, subject),
|
||
"to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject),
|
||
"to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject),
|
||
"to_oas_schema": (sub_to_oas_schema) => to_jsonschema(sub_to_oas_schema, subject),
|
||
"example": (sub_example) => example(sub_example, subject),
|
||
}));
|
||
})(list_ = shape_9.list_ || (shape_9.list_ = {}));
|
||
})(shape = lib_plankton.shape || (lib_plankton.shape = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:shape«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:shape« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:shape« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:shape«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var shape;
|
||
(function (shape_10) {
|
||
var map;
|
||
(function (map) {
|
||
/**
|
||
*/
|
||
function make(shape_key, shape_value, options = {}) {
|
||
options = Object.assign({
|
||
"soft": false,
|
||
"defaultvalue": lib_plankton.pod.make_empty(),
|
||
"description": lib_plankton.pod.make_empty(),
|
||
}, options);
|
||
return {
|
||
"shape_key": shape_key,
|
||
"shape_value": shape_value,
|
||
"soft": options.soft,
|
||
"defaultvalue": ((options.defaultvalue === undefined)
|
||
? lib_plankton.pod.make_empty()
|
||
: lib_plankton.pod.make_filled(options.defaultvalue)),
|
||
"description": ((options.description === undefined)
|
||
? lib_plankton.pod.make_empty()
|
||
: lib_plankton.pod.make_filled(options.description)),
|
||
};
|
||
}
|
||
map.make = make;
|
||
/**
|
||
*/
|
||
function inspect(sub_inspect, subject, value) {
|
||
let inspection = shape_10.inspection_create();
|
||
if (value === null) {
|
||
if (subject.soft) {
|
||
// all good
|
||
}
|
||
else {
|
||
shape_10.inspection_add(inspection, "null is not allowed");
|
||
}
|
||
}
|
||
else {
|
||
const jstype_actual = typeof (value);
|
||
const jstype_expected = "object";
|
||
if (!(jstype_actual === jstype_expected)) {
|
||
lib_plankton.string.coin("expected JS-type '{{expected}}' but got '{{actual}}'", {
|
||
"expected": jstype_expected,
|
||
"actual": jstype_actual,
|
||
});
|
||
}
|
||
else {
|
||
Object.entries(value)
|
||
.forEach(([key, value]) => {
|
||
shape_10.inspection_extend(inspection, lib_plankton.string.coin("key '{{key}}'", {
|
||
"key": String(key),
|
||
}), sub_inspect(subject.shape_key, key));
|
||
shape_10.inspection_extend(inspection, lib_plankton.string.coin("value for '{{key}}'", {
|
||
"key": String(key),
|
||
}), sub_inspect(subject.shape_value, value));
|
||
});
|
||
}
|
||
}
|
||
return inspection;
|
||
}
|
||
/**
|
||
*/
|
||
function show(sub_show, subject) {
|
||
const core = lib_plankton.string.coin("map<{{key}},{{value}}>", {
|
||
"key": sub_show(subject.shape_key),
|
||
"value": sub_show(subject.shape_value),
|
||
});
|
||
return (subject.soft ? ("~" + core) : core);
|
||
}
|
||
/**
|
||
*/
|
||
function to_typescript_type(sub_to_typescript_type, subject) {
|
||
const core = lib_plankton.string.coin("Record<{{key}},{{value}}>", {
|
||
"key": sub_to_typescript_type(subject.shape_key),
|
||
"value": sub_to_typescript_type(subject.shape_key),
|
||
});
|
||
return (subject.soft ? ("(null | " + core + ")") : core);
|
||
}
|
||
/**
|
||
*/
|
||
function to_jsonschema(sub_to_jsonschema, subject) {
|
||
const common = {
|
||
"description": lib_plankton.pod.distinguish(subject.description, () => undefined, x => x),
|
||
"default": lib_plankton.pod.distinguish(subject.defaultvalue, () => undefined, x => x),
|
||
};
|
||
const core = {
|
||
"type": "object",
|
||
"additionalProperties": sub_to_jsonschema(subject.shape_value),
|
||
"properties": {},
|
||
"required": [],
|
||
};
|
||
return ((subject.soft
|
||
? {
|
||
"anyOf": [
|
||
Object.assign({ "type": "null" }, common),
|
||
Object.assign(core, common),
|
||
]
|
||
}
|
||
: core));
|
||
}
|
||
/**
|
||
*/
|
||
function example(sub_example, subject) {
|
||
return (subject.soft
|
||
? null
|
||
: {});
|
||
}
|
||
shape_10.register("map", (parameters) => make(parameters.shape_key, parameters.shape_value, {
|
||
"soft": parameters.soft,
|
||
"description": parameters.description,
|
||
"defaultvalue": parameters.defaultvalue,
|
||
}), (subject) => ({
|
||
"inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value),
|
||
"show": (sub_show) => show(sub_show, subject),
|
||
"to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject),
|
||
"to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject),
|
||
"to_oas_schema": (sub_to_oas_schema) => to_jsonschema(sub_to_oas_schema, subject),
|
||
"example": (sub_example) => example(sub_example, subject),
|
||
}));
|
||
})(map = shape_10.map || (shape_10.map = {}));
|
||
})(shape = lib_plankton.shape || (lib_plankton.shape = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:shape«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:shape« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:shape« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:shape«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var shape;
|
||
(function (shape_11) {
|
||
var record;
|
||
(function (record) {
|
||
/**
|
||
*/
|
||
function make(fields_raw, options = {}) {
|
||
options = Object.assign({
|
||
"soft": false,
|
||
"defaultvalue": lib_plankton.pod.make_empty(),
|
||
"description": lib_plankton.pod.make_empty(),
|
||
}, options);
|
||
return {
|
||
"fields": fields_raw.map(field_raw => ({
|
||
"name": field_raw.name,
|
||
"shape": field_raw.shape,
|
||
"required": (field_raw.required ?? true)
|
||
})),
|
||
"soft": options.soft,
|
||
"defaultvalue": ((options.defaultvalue === undefined)
|
||
? lib_plankton.pod.make_empty()
|
||
: lib_plankton.pod.make_filled(options.defaultvalue)),
|
||
"description": ((options.description === undefined)
|
||
? lib_plankton.pod.make_empty()
|
||
: lib_plankton.pod.make_filled(options.description)),
|
||
};
|
||
}
|
||
record.make = make;
|
||
/**
|
||
*/
|
||
function inspect(sub_inspect, subject, value) {
|
||
let inspection = shape_11.inspection_create();
|
||
if (value === null) {
|
||
if (subject.soft) {
|
||
// all good
|
||
}
|
||
else {
|
||
shape_11.inspection_add(inspection, "null is not allowed");
|
||
}
|
||
}
|
||
else {
|
||
const jstype_actual = typeof (value);
|
||
const jstype_expected = "object";
|
||
if (!(jstype_actual === jstype_expected)) {
|
||
shape_11.inspection_add(inspection, lib_plankton.string.coin("expected JS-type '{{expected}}' but got '{{actual}}'", {
|
||
"expected": jstype_expected,
|
||
"actual": jstype_actual,
|
||
}));
|
||
}
|
||
else {
|
||
subject.fields.forEach(field => {
|
||
if (!(field.name in value)) {
|
||
if (field.required) {
|
||
shape_11.inspection_add(inspection, "missing field '" + field.name + "'");
|
||
}
|
||
else {
|
||
// do nothing
|
||
}
|
||
}
|
||
else {
|
||
const value_ = value[field.name];
|
||
shape_11.inspection_extend(inspection, ("field '" + field.name + "'"), sub_inspect(field.shape, value_));
|
||
}
|
||
});
|
||
// extra fields
|
||
{
|
||
const allowed = subject.fields.map(field => field.name);
|
||
(Object.keys(value)
|
||
.filter(name => (!allowed.includes(name)))
|
||
.forEach(name => {
|
||
shape_11.inspection_add(inspection, "extra field '" + name + "'");
|
||
}));
|
||
}
|
||
}
|
||
}
|
||
return inspection;
|
||
}
|
||
/**
|
||
*/
|
||
function show(sub_show, subject) {
|
||
const core = lib_plankton.string.coin("record<{{fields}}>", {
|
||
"fields": (subject.fields
|
||
.map(field => lib_plankton.string.coin("{{prefix}}{{name}}:{{shape}}", {
|
||
"prefix": (field.required ? "" : "?"),
|
||
"name": field.name,
|
||
"shape": sub_show(field.shape),
|
||
}))
|
||
.join(",")),
|
||
});
|
||
return (subject.soft ? ("~" + core) : core);
|
||
}
|
||
/**
|
||
*/
|
||
function to_typescript_type(sub_to_typescript_type, subject) {
|
||
const core = lib_plankton.string.coin("{{{fields}}}", {
|
||
"fields": (subject.fields
|
||
.map(field => lib_plankton.string.coin("{{name}}{{infix}}{{shape}}", {
|
||
"name": field.name,
|
||
"infix": (field.required ? ":" : "?:"),
|
||
"shape": sub_to_typescript_type(field.shape),
|
||
}))
|
||
.join(";")),
|
||
});
|
||
return (subject.soft ? ("(null | " + core + ")") : core);
|
||
}
|
||
/**
|
||
*/
|
||
function to_jsonschema(sub_to_jsonschema, subject) {
|
||
const common = {
|
||
"description": lib_plankton.pod.distinguish(subject.description, () => undefined, x => x),
|
||
"default": lib_plankton.pod.distinguish(subject.defaultvalue, () => undefined, x => x),
|
||
};
|
||
const core = {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"properties": (Object.fromEntries(subject.fields
|
||
.map(field => ([
|
||
field.name,
|
||
sub_to_jsonschema(field.shape)
|
||
])))),
|
||
"required": (subject.fields
|
||
.filter(field => field.required)
|
||
.map(field => field.name)),
|
||
};
|
||
return ((subject.soft
|
||
? {
|
||
"anyOf": [
|
||
Object.assign({ "type": "null" }, common),
|
||
Object.assign(core, common),
|
||
]
|
||
}
|
||
: core));
|
||
}
|
||
/**
|
||
*/
|
||
function example(sub_example, subject) {
|
||
return (subject.soft
|
||
? null
|
||
: (Object.fromEntries(subject.fields
|
||
.filter(field => field.required)
|
||
.map(field => ([
|
||
field.name,
|
||
sub_example(field.shape)
|
||
])))));
|
||
}
|
||
shape_11.register("record", (parameters) => make((parameters.fields
|
||
.map(field_raw => ({
|
||
"name": field_raw.name,
|
||
"shape": field_raw.shape,
|
||
"required": field_raw.required,
|
||
}))), {
|
||
"soft": parameters.soft,
|
||
"description": parameters.description,
|
||
"defaultvalue": parameters.defaultvalue,
|
||
}), (subject) => ({
|
||
"inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value),
|
||
"show": (sub_show) => show(sub_show, subject),
|
||
"to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject),
|
||
"to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject),
|
||
"to_oas_schema": (sub_to_oas_schema) => to_jsonschema(sub_to_oas_schema, subject),
|
||
"example": (sub_example) => example(sub_example, subject),
|
||
}));
|
||
})(record = shape_11.record || (shape_11.record = {}));
|
||
})(shape = lib_plankton.shape || (lib_plankton.shape = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:code«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:code« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:code« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:code«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
/*
|
||
This file is part of »bacterio-plankton:code«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:code« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:code« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:code«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
/*
|
||
This file is part of »bacterio-plankton:code«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:code« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:code« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:code«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var code;
|
||
(function (code) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function inverse_encode(decode, to) {
|
||
return decode(to);
|
||
}
|
||
code.inverse_encode = inverse_encode;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function inverse_decode(encode, from) {
|
||
return encode(from);
|
||
}
|
||
code.inverse_decode = inverse_decode;
|
||
})(code = lib_plankton.code || (lib_plankton.code = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:code«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:code« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:code« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:code«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var code;
|
||
(function (code) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
var class_code_inverse = /** @class */ (function () {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function class_code_inverse(subject) {
|
||
this.subject = subject;
|
||
}
|
||
/**
|
||
* @implementation
|
||
* @author fenris
|
||
*/
|
||
class_code_inverse.prototype.encode = function (to) {
|
||
var _this = this;
|
||
return code.inverse_encode(function (x) { return _this.subject.decode(x); }, to);
|
||
};
|
||
/**
|
||
* @implementation
|
||
* @author fenris
|
||
*/
|
||
class_code_inverse.prototype.decode = function (from) {
|
||
var _this = this;
|
||
return code.inverse_decode(function (x) { return _this.subject.encode(x); }, from);
|
||
};
|
||
return class_code_inverse;
|
||
}());
|
||
code.class_code_inverse = class_code_inverse;
|
||
})(code = lib_plankton.code || (lib_plankton.code = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:code«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:code« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:code« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:code«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var code;
|
||
(function (code) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function pair_encode(encode_first, encode_second, from) {
|
||
var between = encode_first(from);
|
||
var to = encode_second(between);
|
||
return to;
|
||
}
|
||
code.pair_encode = pair_encode;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function pair_decode(decode_first, decode_second, to) {
|
||
var between = decode_second(to);
|
||
var from = decode_first(between);
|
||
return from;
|
||
}
|
||
code.pair_decode = pair_decode;
|
||
})(code = lib_plankton.code || (lib_plankton.code = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:code«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:code« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:code« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:code«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var code;
|
||
(function (code) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
var class_code_pair = /** @class */ (function () {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function class_code_pair(first, second) {
|
||
this.first = first;
|
||
this.second = second;
|
||
}
|
||
/**
|
||
* @implementation
|
||
* @author fenris
|
||
*/
|
||
class_code_pair.prototype.encode = function (from) {
|
||
var _this = this;
|
||
return code.pair_encode(function (x) { return _this.first.encode(x); }, function (x) { return _this.second.encode(x); }, from);
|
||
};
|
||
/**
|
||
* @implementation
|
||
* @author fenris
|
||
*/
|
||
class_code_pair.prototype.decode = function (to) {
|
||
var _this = this;
|
||
return code.pair_decode(function (x) { return _this.first.decode(x); }, function (x) { return _this.second.decode(x); }, to);
|
||
};
|
||
return class_code_pair;
|
||
}());
|
||
code.class_code_pair = class_code_pair;
|
||
})(code = lib_plankton.code || (lib_plankton.code = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:code«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:code« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:code« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:code«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var code;
|
||
(function (code) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function chain_encode(encode_links, from) {
|
||
var value = from;
|
||
encode_links
|
||
.forEach(function (link) {
|
||
value = link(value);
|
||
});
|
||
return value;
|
||
}
|
||
code.chain_encode = chain_encode;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function chain_decode(decode_links, to) {
|
||
var value = to;
|
||
decode_links
|
||
.reverse()
|
||
.forEach(function (link) {
|
||
value = link(value);
|
||
});
|
||
return value;
|
||
}
|
||
code.chain_decode = chain_decode;
|
||
})(code = lib_plankton.code || (lib_plankton.code = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:code«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:code« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:code« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:code«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var code;
|
||
(function (code) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
var class_code_chain = /** @class */ (function () {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function class_code_chain(links) {
|
||
this.links = links;
|
||
}
|
||
/**
|
||
* @implementation
|
||
* @author fenris
|
||
*/
|
||
class_code_chain.prototype.encode = function (from) {
|
||
return code.chain_encode(this.links.map(function (link) { return (function (x) { return link.encode(x); }); }), from);
|
||
};
|
||
/**
|
||
* @implementation
|
||
* @author fenris
|
||
*/
|
||
class_code_chain.prototype.decode = function (to) {
|
||
return code.chain_decode(this.links.map(function (link) { return (function (x) { return link.decode(x); }); }), to);
|
||
};
|
||
return class_code_chain;
|
||
}());
|
||
code.class_code_chain = class_code_chain;
|
||
})(code = lib_plankton.code || (lib_plankton.code = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:code«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:code« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:code« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:code«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var code;
|
||
(function (code) {
|
||
/**
|
||
* @author Christian Fraß <frass@greenscale.de>
|
||
*/
|
||
function flatten_encode(from, keys) {
|
||
if (keys === void 0) { keys = null; }
|
||
if (keys === null) {
|
||
if (from.length > 0) {
|
||
keys = Object.keys(from[0]);
|
||
}
|
||
else {
|
||
throw (new Error("encoding impossible"));
|
||
}
|
||
}
|
||
return {
|
||
"keys": keys,
|
||
"data": from.map(function (line) { return keys.map(function (name) { return line[name]; }); })
|
||
};
|
||
}
|
||
code.flatten_encode = flatten_encode;
|
||
/**
|
||
* @author Christian Fraß <frass@greenscale.de>
|
||
*/
|
||
function flatten_decode(to) {
|
||
return (to.data
|
||
.map(function (dataset) {
|
||
var dataset_ = {};
|
||
dataset
|
||
.forEach(function (value, index) {
|
||
var name = to.keys[index];
|
||
dataset_[name] = value;
|
||
});
|
||
return dataset_;
|
||
}));
|
||
}
|
||
code.flatten_decode = flatten_decode;
|
||
})(code = lib_plankton.code || (lib_plankton.code = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:code«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:code« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:code« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:code«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var code;
|
||
(function (code) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
var class_code_flatten = /** @class */ (function () {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function class_code_flatten() {
|
||
}
|
||
/**
|
||
* @implementation
|
||
* @author fenris
|
||
*/
|
||
class_code_flatten.prototype.encode = function (x) {
|
||
return code.flatten_encode(x);
|
||
};
|
||
/**
|
||
* @implementation
|
||
* @author fenris
|
||
*/
|
||
class_code_flatten.prototype.decode = function (x) {
|
||
return code.flatten_decode(x);
|
||
};
|
||
return class_code_flatten;
|
||
}());
|
||
code.class_code_flatten = class_code_flatten;
|
||
})(code = lib_plankton.code || (lib_plankton.code = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:www_form«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:www_form« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:www_form« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:www_form«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var www_form;
|
||
(function (www_form) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function encode(source) {
|
||
return (Object.entries(source)
|
||
.map(function (_a) {
|
||
var key = _a[0], value = _a[1];
|
||
return (key + "=" + encodeURIComponent(value));
|
||
})
|
||
.join("&"));
|
||
}
|
||
www_form.encode = encode;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function decode(target) {
|
||
return (Object.fromEntries(target.split("&")
|
||
.map(function (part) {
|
||
var components = part.split("=");
|
||
var key = components[0];
|
||
var value = decodeURIComponent(components.slice(1).join("="));
|
||
return [key, value];
|
||
})));
|
||
}
|
||
www_form.decode = decode;
|
||
})(www_form = lib_plankton.www_form || (lib_plankton.www_form = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:www_form«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:www_form« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:www_form« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:www_form«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var www_form;
|
||
(function (www_form) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
var class_www_form = /** @class */ (function () {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function class_www_form() {
|
||
}
|
||
/**
|
||
* @implementation
|
||
* @author fenris
|
||
*/
|
||
class_www_form.prototype.encode = function (source) {
|
||
return www_form.encode(source);
|
||
};
|
||
/**
|
||
* @implementation
|
||
* @author fenris
|
||
*/
|
||
class_www_form.prototype.decode = function (target) {
|
||
return www_form.decode(target);
|
||
};
|
||
return class_www_form;
|
||
}());
|
||
www_form.class_www_form = class_www_form;
|
||
})(www_form = lib_plankton.www_form || (lib_plankton.www_form = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:url«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:url« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:url« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:url«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
/*
|
||
This file is part of »bacterio-plankton:url«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:url« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:url« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:url«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var url;
|
||
(function (url_1) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function encode(url) {
|
||
let result = "";
|
||
// scheme
|
||
{
|
||
if (url.scheme !== null) {
|
||
result += (url.scheme + ":");
|
||
}
|
||
}
|
||
// host
|
||
{
|
||
if (url.host !== null) {
|
||
result += "//";
|
||
// username
|
||
{
|
||
if (url.username !== null) {
|
||
result += url.username;
|
||
// password
|
||
{
|
||
if (url.password !== null) {
|
||
result += (":" + url.password);
|
||
}
|
||
}
|
||
result += "@";
|
||
}
|
||
}
|
||
result += url.host;
|
||
}
|
||
}
|
||
// port
|
||
{
|
||
if (url.port !== null) {
|
||
result += (":" + url.port.toString());
|
||
}
|
||
}
|
||
// path
|
||
{
|
||
if (url.path !== null) {
|
||
result += url.path;
|
||
}
|
||
}
|
||
// query
|
||
{
|
||
if (url.query !== null) {
|
||
result += ("?" + encodeURI(url.query));
|
||
}
|
||
}
|
||
// hash
|
||
{
|
||
if (url.hash !== null) {
|
||
result += ("#" + url.hash);
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
url_1.encode = encode;
|
||
/**
|
||
* @author fenris
|
||
* @todo arguments
|
||
*/
|
||
function decode(url_raw) {
|
||
const builtin_url = new URL(url_raw);
|
||
return {
|
||
"scheme": builtin_url.protocol.slice(0, -1),
|
||
"host": builtin_url.hostname,
|
||
"username": ((builtin_url.username !== "")
|
||
?
|
||
builtin_url.username
|
||
:
|
||
null),
|
||
"password": ((builtin_url.password !== "")
|
||
?
|
||
builtin_url.password
|
||
:
|
||
null),
|
||
"port": ((builtin_url.port !== "")
|
||
?
|
||
parseInt(builtin_url.port)
|
||
:
|
||
null),
|
||
"path": builtin_url.pathname,
|
||
"query": builtin_url.search.slice(1),
|
||
"hash": ((builtin_url.hash !== "")
|
||
?
|
||
builtin_url.hash.slice(1)
|
||
:
|
||
null),
|
||
};
|
||
}
|
||
url_1.decode = decode;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function implementation_code() {
|
||
return {
|
||
"encode": encode,
|
||
"decode": decode,
|
||
};
|
||
}
|
||
url_1.implementation_code = implementation_code;
|
||
})(url = lib_plankton.url || (lib_plankton.url = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:url«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:url« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:url« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:url«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var url;
|
||
(function (url) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class class_url {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
constructor() {
|
||
}
|
||
/**
|
||
* @implementation
|
||
* @author fenris
|
||
*/
|
||
encode(x) {
|
||
return url.encode(x);
|
||
}
|
||
/**
|
||
* @implementation
|
||
* @author fenris
|
||
*/
|
||
decode(x) {
|
||
return url.decode(x);
|
||
}
|
||
}
|
||
url.class_url = class_url;
|
||
})(url = lib_plankton.url || (lib_plankton.url = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:random«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:random« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:random« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:random«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var random;
|
||
(function (random) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function sequence(n) {
|
||
return ((n <= 0) ? [] : sequence(n - 1).concat([n - 1]));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function interpolate(x, y, t) {
|
||
return (((1 - t) * x) + (t * y));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
var _statestack = [
|
||
{
|
||
"builtin": true,
|
||
"seed": Date.now()
|
||
},
|
||
];
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function state_get() {
|
||
return _statestack[_statestack.length - 1];
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function state_push(state) {
|
||
_statestack.push(state);
|
||
}
|
||
random.state_push = state_push;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function state_pop() {
|
||
if (_statestack.length <= 1) {
|
||
throw (new Error("no state to pop"));
|
||
}
|
||
else {
|
||
return _statestack.pop();
|
||
}
|
||
}
|
||
random.state_pop = state_pop;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function seed_tick() {
|
||
var state = state_get();
|
||
state.seed = ((state.seed << 8) % 99767);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function seed_get(tick) {
|
||
if (tick === void 0) { tick = true; }
|
||
if (tick) {
|
||
seed_tick();
|
||
}
|
||
else {
|
||
// do nothing
|
||
}
|
||
return state_get().seed;
|
||
}
|
||
/**
|
||
* returns a random floating point number in the interval [0,1[
|
||
*
|
||
* @author fenris
|
||
*/
|
||
function generate_unit() {
|
||
if (state_get().builtin) {
|
||
return Math.random();
|
||
}
|
||
else {
|
||
return ((Math.sin(seed_get() << 8) + 1) / 2);
|
||
}
|
||
}
|
||
random.generate_unit = generate_unit;
|
||
/**
|
||
* returns a random boolean value
|
||
*
|
||
* @param {float} [probability] the probability for the return-value "true"; default: 0.5
|
||
* @author fenris
|
||
*/
|
||
function generate_boolean(options) {
|
||
if (options === void 0) { options = {}; }
|
||
options = lib_plankton.base.object_merge({
|
||
"probability": 0.5
|
||
}, options);
|
||
return (generate_unit() < options.probability);
|
||
}
|
||
random.generate_boolean = generate_boolean;
|
||
/**
|
||
* returns a random integer number in the interval [a,b]
|
||
*
|
||
* @param {int} [minimum] the left side of the halfopen interval (i.e. the smallest included value in the range)
|
||
* @param {int} [minimum] the right side of the halfopen interval (i.e. the smallest excluded value in the range)
|
||
* @author fenris
|
||
*/
|
||
function generate_integer(options) {
|
||
if (options === void 0) { options = {}; }
|
||
options = lib_plankton.base.object_merge({
|
||
"minimum": 0,
|
||
"maximum": ((1 << 16) - 1)
|
||
}, options);
|
||
return Math.floor(interpolate(options.minimum, options.maximum + 1, generate_unit()));
|
||
}
|
||
random.generate_integer = generate_integer;
|
||
random.generate_int = generate_integer;
|
||
/**
|
||
* returns a random floating point number in the given interval
|
||
*
|
||
* @author fenris
|
||
*/
|
||
function generate_float(options) {
|
||
if (options === void 0) { options = {}; }
|
||
options = lib_plankton.base.object_merge({
|
||
"minimum": 0.0,
|
||
"maximum": 1.0
|
||
}, options);
|
||
return interpolate(options.minimum, options.maximum, generate_unit());
|
||
}
|
||
random.generate_float = generate_float;
|
||
/**
|
||
* returns a random date
|
||
*
|
||
* @author fenris
|
||
*/
|
||
function generate_date(options) {
|
||
if (options === void 0) { options = {}; }
|
||
options = lib_plankton.base.object_merge({
|
||
"minimum": new Date(0),
|
||
"maximum": new Date(Date.now())
|
||
}, options);
|
||
return (new Date(generate_integer({
|
||
"minimum": options.minimum.getTime(),
|
||
"maximum": options.maximum.getTime()
|
||
})));
|
||
}
|
||
random.generate_date = generate_date;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function generate_hexdigit() {
|
||
return (this.generate_integer({ "minimum": 0, "maximum": 15 }).toString(16).toUpperCase());
|
||
}
|
||
random.generate_hexdigit = generate_hexdigit;
|
||
/**
|
||
* generates a random string with an optional prefix
|
||
*
|
||
* @author fenris
|
||
*/
|
||
function generate_string(options) {
|
||
if (options === void 0) { options = {}; }
|
||
options = lib_plankton.base.object_merge({
|
||
"length": 8
|
||
}, options);
|
||
return (sequence(options.length)
|
||
.map(function (x) { return generate_integer({ "minimum": 65, "maximum": 90 }); })
|
||
.map(function (x) { return String.fromCharCode(x); })
|
||
.join("")
|
||
.toLowerCase());
|
||
}
|
||
random.generate_string = generate_string;
|
||
/**
|
||
* chooses a value randomly from a list of values with weights (a higher weight means a higher probability to be chosen)
|
||
*
|
||
* @author fenris
|
||
*/
|
||
function choose_weighted(sets) {
|
||
var sum = sets.reduce(function (sum, set_) { return (sum + set_.weight); }, 0);
|
||
if (sum === 0) {
|
||
throw (new Error("weights sum up to zero; are all zero or are negative weights included?"));
|
||
}
|
||
else {
|
||
var position_1 = generate_unit();
|
||
return (sets.reduce(function (current, set_) {
|
||
var next = { "index": null, "value": null };
|
||
next.index = (current.index + (set_.weight / sum));
|
||
next.value = (((current.index <= position_1) && (position_1 < next.index))
|
||
? set_.value
|
||
: current.value);
|
||
return next;
|
||
}, { "index": 0, "value": null }).value);
|
||
}
|
||
}
|
||
random.choose_weighted = choose_weighted;
|
||
/**
|
||
* chooses a value randomly from a list of values with equal probabilities
|
||
*
|
||
* @author fenris
|
||
*/
|
||
function choose_uniformly(values) {
|
||
return (choose_weighted(values.map(function (value) { return ({ "weight": 1, "value": value }); })));
|
||
}
|
||
random.choose_uniformly = choose_uniformly;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function shuffle(list) {
|
||
var list_ = [];
|
||
list.forEach(function (element) {
|
||
var index = generate_integer({ "minimum": 0, "maximum": list_.length });
|
||
list_.splice(index, 0, element);
|
||
});
|
||
return list_;
|
||
}
|
||
random.shuffle = shuffle;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function generate_vowel() {
|
||
return (choose_weighted([
|
||
{ "weight": 1.0, "value": "u" },
|
||
{ "weight": 4.0, "value": "o" },
|
||
{ "weight": 6.0, "value": "a" },
|
||
{ "weight": 4.0, "value": "e" },
|
||
{ "weight": 1.0, "value": "i" },
|
||
]));
|
||
}
|
||
random.generate_vowel = generate_vowel;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function generate_halfvowel() {
|
||
return (choose_weighted([
|
||
{ "weight": 4.0, "value": "y" },
|
||
{ "weight": 1.0, "value": "w" },
|
||
]));
|
||
}
|
||
random.generate_halfvowel = generate_halfvowel;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function generate_consonant() {
|
||
return (choose_weighted([
|
||
{ "weight": 5.0, "value": "l" },
|
||
{ "weight": 5.0, "value": "m" },
|
||
{ "weight": 5.0, "value": "n" },
|
||
{ "weight": 4.0, "value": "b" },
|
||
{ "weight": 4.0, "value": "p" },
|
||
{ "weight": 4.0, "value": "d" },
|
||
{ "weight": 2.0, "value": "dj" },
|
||
{ "weight": 4.0, "value": "t" },
|
||
{ "weight": 2.0, "value": "tc" },
|
||
{ "weight": 4.0, "value": "g" },
|
||
{ "weight": 4.0, "value": "k" },
|
||
{ "weight": 3.0, "value": "v" },
|
||
{ "weight": 3.0, "value": "f" },
|
||
{ "weight": 3.0, "value": "z" },
|
||
{ "weight": 3.0, "value": "s" },
|
||
{ "weight": 3.0, "value": "j" },
|
||
{ "weight": 3.0, "value": "c" },
|
||
{ "weight": 2.0, "value": "r" },
|
||
{ "weight": 1.0, "value": "h" },
|
||
{ "weight": 1.0, "value": "x" },
|
||
]));
|
||
}
|
||
random.generate_consonant = generate_consonant;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function generate_letter() {
|
||
return choose_uniformly([
|
||
"a",
|
||
"b",
|
||
"c",
|
||
"d",
|
||
"e",
|
||
"f",
|
||
"g",
|
||
"h",
|
||
"i",
|
||
"j",
|
||
"k",
|
||
"l",
|
||
"m",
|
||
"n",
|
||
"o",
|
||
"p",
|
||
"q",
|
||
"r",
|
||
"s",
|
||
"t",
|
||
"u",
|
||
"v",
|
||
"w",
|
||
"x",
|
||
"y",
|
||
"z",
|
||
]);
|
||
}
|
||
random.generate_letter = generate_letter;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function generate_syllable() {
|
||
return (generate_consonant()
|
||
+
|
||
generate_vowel()
|
||
+
|
||
(generate_boolean({ "probability": 1 / 8 })
|
||
? generate_halfvowel()
|
||
: "")
|
||
+
|
||
(generate_boolean({ "probability": 1 / 4 })
|
||
? generate_consonant()
|
||
: ""));
|
||
}
|
||
random.generate_syllable = generate_syllable;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function generate_word(options) {
|
||
if (options === void 0) { options = {}; }
|
||
options = lib_plankton.base.object_merge({
|
||
"syllable_count_minimum": 2,
|
||
"syllable_count_maximum": 5
|
||
}, options);
|
||
return (sequence(generate_integer({
|
||
"minimum": options.syllable_count_minimum,
|
||
"maximum": options.syllable_count_maximum
|
||
}))
|
||
.map(function (x) { return generate_syllable(); })
|
||
.join(""));
|
||
}
|
||
random.generate_word = generate_word;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function generate_text(options) {
|
||
if (options === void 0) { options = {}; }
|
||
options = lib_plankton.base.object_merge({
|
||
"word_count": generate_integer({ "minimum": 20, "maximum": 80 })
|
||
}, options);
|
||
return sequence(options.word_count).map(function (x) { return generate_word(); }).join(" ");
|
||
}
|
||
random.generate_text = generate_text;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function generate_city() {
|
||
var str = (
|
||
// prefix
|
||
(generate_boolean({ "probability": 0.25 })
|
||
? choose_uniformly([
|
||
"unter",
|
||
"ober",
|
||
"mittel",
|
||
"groß",
|
||
"klein",
|
||
"neu",
|
||
"alt",
|
||
])
|
||
: "")
|
||
+
|
||
// infix
|
||
choose_uniformly([
|
||
"stein",
|
||
"frei",
|
||
"berns",
|
||
"kirch",
|
||
"fels",
|
||
"weiden",
|
||
"buchen",
|
||
"eichen",
|
||
"eiben",
|
||
"linden",
|
||
"ulmen",
|
||
"birken",
|
||
"eschen",
|
||
"erlen",
|
||
"grün",
|
||
"kreuz",
|
||
"wald",
|
||
"reichen",
|
||
"lieben",
|
||
"schön",
|
||
"heinrichs",
|
||
"friedrichs",
|
||
"johann",
|
||
"walters",
|
||
"günthers",
|
||
"rupperts",
|
||
"wilhems",
|
||
"albert",
|
||
])
|
||
+
|
||
// suffix
|
||
choose_uniformly([
|
||
"feld",
|
||
"thal",
|
||
"berg",
|
||
"burg",
|
||
"stadt",
|
||
"dorf",
|
||
"heim",
|
||
"bach",
|
||
"au",
|
||
"rode",
|
||
"ing",
|
||
"nitz",
|
||
"hausen",
|
||
]));
|
||
return (str[0].toUpperCase() + str.substring(1));
|
||
}
|
||
random.generate_city = generate_city;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function generate_street() {
|
||
var str = (
|
||
// prefix
|
||
choose_uniformly([
|
||
"haupt",
|
||
"neben",
|
||
"bahnhof",
|
||
"markt",
|
||
"augustus",
|
||
"wilhelm",
|
||
"albert",
|
||
"friedrich",
|
||
"maximilian",
|
||
"wagner",
|
||
"linden",
|
||
"eichen",
|
||
"buchen",
|
||
"tannen",
|
||
"pappel",
|
||
"ulmen",
|
||
"eschen",
|
||
])
|
||
+
|
||
// core
|
||
choose_uniformly([
|
||
"straße",
|
||
"weg",
|
||
"allee",
|
||
"pfad",
|
||
"hain",
|
||
"anger",
|
||
"passage",
|
||
"platz",
|
||
])
|
||
+
|
||
// number
|
||
(" " + generate_integer({ "minimum": 1, "maximum": 80 }).toString()));
|
||
return (str[0].toUpperCase() + str.substring(1));
|
||
}
|
||
random.generate_street = generate_street;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function generate_guid(options) {
|
||
if (options === void 0) { options = {}; }
|
||
options = lib_plankton.base.object_merge({
|
||
"with_braces": false
|
||
}, options);
|
||
/*
|
||
return (
|
||
[8,4,4,4,12]
|
||
.map(length => sequence(length).map(_ => this.generate_hexdigit()).join(""))
|
||
.join("-")
|
||
);
|
||
*/
|
||
var guid = ("xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(new RegExp("[xy]", "g"), function (symbol) {
|
||
var r = generate_integer({ "minimum": 0, "maximum": 15 });
|
||
var v = ((symbol == "y") ? ((r & 0x3) | 0x8) : r);
|
||
return (v.toString(16).toUpperCase());
|
||
}));
|
||
return (options.with_braces
|
||
? ("{" + guid + "}")
|
||
: guid);
|
||
}
|
||
random.generate_guid = generate_guid;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function generate_domain(options) {
|
||
if (options === void 0) { options = {}; }
|
||
options = lib_plankton.base.object_merge({
|
||
"steps": 3
|
||
}, options);
|
||
return (sequence(generate_integer({ "minimum": 1, "maximum": options.steps }))
|
||
.map(function () { return generate_word(); })
|
||
// tld
|
||
.concat(sequence(generate_integer({ "minimum": 2, "maximum": 3 }))
|
||
.map(function () { return generate_letter(); })
|
||
.join(""))).join(".");
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function generate_url() {
|
||
return (lib_plankton.url.encode({
|
||
"scheme": choose_uniformly([
|
||
"http",
|
||
"https",
|
||
"git",
|
||
"smb",
|
||
"ftp",
|
||
]),
|
||
"host": generate_domain(),
|
||
"username": null,
|
||
"password": null,
|
||
"port": generate_integer({ "minimum": 20, "maximum": 99999 }),
|
||
"path": ("/"
|
||
+
|
||
(sequence(generate_integer({ "minimum": 0, "maximum": 3 }))
|
||
.map(function () { return generate_word(); })
|
||
.join("/"))),
|
||
"query": choose_uniformly([
|
||
null,
|
||
lib_plankton.www_form.encode(Object.fromEntries(sequence(generate_integer({ "minimum": 0, "maximum": 3 }))
|
||
.map(function () { return ([
|
||
generate_word(),
|
||
generate_integer().toFixed(0),
|
||
]); }))),
|
||
]),
|
||
"hash": null
|
||
}));
|
||
}
|
||
random.generate_url = generate_url;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function generate_email_address() {
|
||
return (
|
||
// user
|
||
generate_word()
|
||
+
|
||
"@"
|
||
+
|
||
generate_domain({ "steps": 1 }));
|
||
}
|
||
random.generate_email_address = generate_email_address;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function generate_telephone_number() {
|
||
return (
|
||
// country prefix
|
||
("+"
|
||
+
|
||
generate_integer({ "minimum": 1, "maximum": 999 }).toFixed(0))
|
||
+
|
||
" "
|
||
+
|
||
// provider
|
||
+(sequence(3)
|
||
.map(function () { return generate_integer({ "minimum": 0, "maximum": 9 }); })
|
||
.join(""))
|
||
+
|
||
" "
|
||
+
|
||
// custom
|
||
+(sequence(7)
|
||
.map(function () { return generate_integer({ "minimum": 0, "maximum": 9 }); })
|
||
.join("")));
|
||
}
|
||
random.generate_telephone_number = generate_telephone_number;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function generate_time() {
|
||
return {
|
||
"hour": generate_integer({ "minimum": 0, "maximum": 23 }),
|
||
"minute": generate_integer({ "minimum": 0, "maximum": 59 }),
|
||
"second": generate_integer({ "minimum": 0, "maximum": 59 })
|
||
};
|
||
}
|
||
random.generate_time = generate_time;
|
||
/**
|
||
* @author fenris
|
||
* @deprecated
|
||
* @todo remove
|
||
*/
|
||
function generate_for_shape(shape) {
|
||
throw (new Error("deprecated! use lib_shape!"));
|
||
}
|
||
random.generate_for_shape = generate_for_shape;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
/*
|
||
export function generate_for_shape_(
|
||
shape : lib_plankton.shape.type_shape
|
||
) : any
|
||
{
|
||
switch (shape.name) {
|
||
case "boolean": {
|
||
return generate_boolean();
|
||
break;
|
||
}
|
||
case "int": {
|
||
const min = shape.parameters["min"];
|
||
const max = shape.parameters["max"];
|
||
return generate_integer(
|
||
{
|
||
"minimum": ((min == null) ? undefined : min),
|
||
"maximum": ((max == null) ? undefined : max),
|
||
}
|
||
);
|
||
break;
|
||
}
|
||
case "float": {
|
||
return generate_float(
|
||
{
|
||
"minimum": shape.parameters["min"],
|
||
"maximum": shape.parameters["max"],
|
||
}
|
||
);
|
||
break;
|
||
}
|
||
case "string": {
|
||
return generate_string();
|
||
break;
|
||
}
|
||
case "url": {
|
||
return generate_url();
|
||
break;
|
||
}
|
||
case "email": {
|
||
return generate_email_address();
|
||
break;
|
||
}
|
||
case "time": {
|
||
return generate_time();
|
||
break;
|
||
}
|
||
case "array": {
|
||
return (
|
||
sequence(generate_integer({"minimum": 2, "maximum": 5}))
|
||
.map(() => generate_for_shape_(shape.parameters["shape_element"]))
|
||
);
|
||
break;
|
||
}
|
||
case "object": {
|
||
return Object.fromEntries(
|
||
shape.parameters["fields"]
|
||
.map(
|
||
field => ([
|
||
field["name"],
|
||
generate_for_shape_(field["shape"]),
|
||
])
|
||
)
|
||
);
|
||
break;
|
||
}
|
||
case "date": {
|
||
return generate_date();
|
||
break;
|
||
}
|
||
case "enumeration": {
|
||
return choose_uniformly<any>(shape.parameters["options"])["value"];
|
||
break;
|
||
}
|
||
default: {
|
||
const message : string = `unhandled shape kind '${shape.name}'`;
|
||
// console.warn(message);
|
||
// return null;
|
||
throw (new Error(message));
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
*/
|
||
})(random = lib_plankton.random || (lib_plankton.random = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||
return new (P || (P = Promise))(function (resolve, reject) {
|
||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
});
|
||
};
|
||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||
function step(op) {
|
||
if (f) throw new TypeError("Generator is already executing.");
|
||
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||
switch (op[0]) {
|
||
case 0: case 1: t = op; break;
|
||
case 4: _.label++; return { value: op[1], done: false };
|
||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||
default:
|
||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||
if (t[2]) _.ops.pop();
|
||
_.trys.pop(); continue;
|
||
}
|
||
op = body.call(thisArg, _);
|
||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||
}
|
||
};
|
||
/*
|
||
This file is part of »bacterio-plankton:storage«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:session« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:session« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:storage«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var session;
|
||
(function (session_1) {
|
||
/**
|
||
*/
|
||
var _conf = null;
|
||
/**
|
||
*/
|
||
function check_conf() {
|
||
if (_conf === null) {
|
||
throw (new Error("session system not set up yet"));
|
||
}
|
||
else {
|
||
// do nothing
|
||
}
|
||
}
|
||
/**
|
||
*/
|
||
function begin(name, options) {
|
||
if (options === void 0) { options = {}; }
|
||
return __awaiter(this, void 0, void 0, function () {
|
||
var key, attempts, session_old, error_1, session_2, session_raw;
|
||
return __generator(this, function (_a) {
|
||
switch (_a.label) {
|
||
case 0:
|
||
options = Object.assign({
|
||
"lifetime": _conf.default_lifetime,
|
||
"data": null
|
||
}, options);
|
||
check_conf();
|
||
key = null;
|
||
attempts = 0;
|
||
_a.label = 1;
|
||
case 1:
|
||
if (!true) return [3 /*break*/, 6];
|
||
attempts += 1;
|
||
key = lib_plankton.call.convey(_conf.key_length, [
|
||
function (x) { return (new Array(x)).fill(null); },
|
||
function (x) { return x.map(function () { return lib_plankton.random.generate_hexdigit(); }); },
|
||
function (x) { return x.join(""); },
|
||
]);
|
||
session_old = null;
|
||
_a.label = 2;
|
||
case 2:
|
||
_a.trys.push([2, 4, , 5]);
|
||
return [4 /*yield*/, _conf.data_chest.read(key)];
|
||
case 3:
|
||
session_old = _a.sent();
|
||
return [3 /*break*/, 5];
|
||
case 4:
|
||
error_1 = _a.sent();
|
||
session_old = null;
|
||
return [3 /*break*/, 5];
|
||
case 5:
|
||
if (session_old !== null) {
|
||
key = null;
|
||
if (attempts >= _conf.key_max_attempts) {
|
||
// fail
|
||
return [3 /*break*/, 6];
|
||
}
|
||
else {
|
||
// retry
|
||
}
|
||
}
|
||
else {
|
||
// suuccess
|
||
return [3 /*break*/, 6];
|
||
}
|
||
return [3 /*break*/, 1];
|
||
case 6:
|
||
if (!(key === null)) return [3 /*break*/, 7];
|
||
throw (new Error("failed to generate unique session key"));
|
||
case 7:
|
||
session_2 = {
|
||
"key": key,
|
||
"name": name,
|
||
"expiry": (lib_plankton.base.get_current_timestamp() + options.lifetime),
|
||
"data": options.data
|
||
};
|
||
session_raw = {
|
||
"key": session_2.key,
|
||
"name": session_2.name,
|
||
"expiry": Math.floor(session_2.expiry),
|
||
"data": JSON.stringify(session_2.data)
|
||
};
|
||
lib_plankton.call.timeout(function () {
|
||
lib_plankton.log.info("session_dropping_due_to_being_expired", {
|
||
"key": key,
|
||
"name": name,
|
||
"lifetime": options.lifetime
|
||
});
|
||
end(key);
|
||
}, options.lifetime);
|
||
return [4 /*yield*/, _conf.data_chest.write(key, session_raw)];
|
||
case 8:
|
||
_a.sent();
|
||
return [2 /*return*/, Promise.resolve(key)];
|
||
}
|
||
});
|
||
});
|
||
}
|
||
session_1.begin = begin;
|
||
/**
|
||
*/
|
||
function get(key) {
|
||
check_conf();
|
||
return (_conf.data_chest.read(key)
|
||
.then(function (session_raw) {
|
||
var session = {
|
||
"key": session_raw["key"],
|
||
"name": session_raw["name"],
|
||
"expiry": session_raw["expiry"],
|
||
"data": JSON.parse(session_raw["data"])
|
||
};
|
||
var now = lib_plankton.base.get_current_timestamp();
|
||
if (now > session.expiry) {
|
||
lib_plankton.log.info("session_dropping_due_to_being_stale", {
|
||
"key": session.key,
|
||
"name": session.name
|
||
});
|
||
end(key);
|
||
return Promise.reject();
|
||
}
|
||
else {
|
||
return Promise.resolve(session);
|
||
}
|
||
}));
|
||
}
|
||
session_1.get = get;
|
||
/**
|
||
*/
|
||
function end(key) {
|
||
check_conf();
|
||
return _conf.data_chest["delete"](key);
|
||
}
|
||
session_1.end = end;
|
||
/**
|
||
*/
|
||
function setup(options) {
|
||
if (options === void 0) { options = {}; }
|
||
return __awaiter(this, void 0, void 0, function () {
|
||
return __generator(this, function (_a) {
|
||
switch (_a.label) {
|
||
case 0:
|
||
options = Object.assign({
|
||
"key_length": 16,
|
||
"key_max_attempts": 3,
|
||
"default_lifetime": 900,
|
||
"data_chest": lib_plankton.storage.memory.implementation_chest({}),
|
||
"clear": false
|
||
}, options);
|
||
_conf = {
|
||
"key_length": options.key_length,
|
||
"key_max_attempts": options.key_max_attempts,
|
||
"default_lifetime": options.default_lifetime,
|
||
"data_chest": options.data_chest
|
||
};
|
||
if (!options.clear) return [3 /*break*/, 2];
|
||
return [4 /*yield*/, _conf.data_chest.clear()];
|
||
case 1:
|
||
_a.sent();
|
||
return [3 /*break*/, 2];
|
||
case 2: return [2 /*return*/, Promise.resolve(undefined)];
|
||
}
|
||
});
|
||
});
|
||
}
|
||
session_1.setup = setup;
|
||
})(session = lib_plankton.session || (lib_plankton.session = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:file«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:file« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:file« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:file«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var file;
|
||
(function (file) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function exists(path) {
|
||
var nm_fs = require("fs");
|
||
return (new Promise(function (resolve, reject) {
|
||
nm_fs.stat(path, function (error, stats) {
|
||
if (error) {
|
||
resolve(false);
|
||
}
|
||
else {
|
||
resolve(true);
|
||
}
|
||
});
|
||
}));
|
||
}
|
||
file.exists = exists;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function read(path) {
|
||
var nm_fs = require("fs");
|
||
return (new Promise(function (resolve, reject) {
|
||
nm_fs.readFile(path, {
|
||
"encoding": "utf8",
|
||
"flag": "r"
|
||
}, function (error, content) {
|
||
if (error == null) {
|
||
resolve(content);
|
||
}
|
||
else {
|
||
reject(error);
|
||
}
|
||
});
|
||
}));
|
||
}
|
||
file.read = read;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function read_buffer(path) {
|
||
var nm_fs = require("fs");
|
||
return (new Promise(function (resolve, reject) {
|
||
nm_fs.readFile(path, {
|
||
"flag": "r"
|
||
}, function (error, content) {
|
||
if (error == null) {
|
||
resolve(content);
|
||
}
|
||
else {
|
||
reject(error);
|
||
}
|
||
});
|
||
}));
|
||
}
|
||
file.read_buffer = read_buffer;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function read_stdin() {
|
||
return (new Promise(function (resolve, reject) {
|
||
var input_raw = "";
|
||
process.stdin.setEncoding("utf8");
|
||
process.stdin.on("readable", function () {
|
||
var chunk;
|
||
while ((chunk = process.stdin.read()) !== null) {
|
||
input_raw += chunk;
|
||
}
|
||
});
|
||
process.stdin.on("end", function () {
|
||
resolve(input_raw);
|
||
});
|
||
}));
|
||
}
|
||
file.read_stdin = read_stdin;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function write(path, content, options) {
|
||
if (options === void 0) { options = {}; }
|
||
options = Object.assign({
|
||
"encoding": "utf-8"
|
||
}, options);
|
||
var nm_fs = require("fs");
|
||
return (new Promise(function (resolve, reject) {
|
||
nm_fs.writeFile(path, content, {
|
||
"encoding": options.encoding,
|
||
"flag": "w"
|
||
}, function (error) {
|
||
if (error == null) {
|
||
resolve(undefined);
|
||
}
|
||
else {
|
||
reject(error);
|
||
}
|
||
});
|
||
}));
|
||
}
|
||
file.write = write;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function write_buffer(path, content, options) {
|
||
if (options === void 0) { options = {}; }
|
||
options = Object.assign({}, options);
|
||
var nm_fs = require("fs");
|
||
return (new Promise(function (resolve, reject) {
|
||
nm_fs.writeFile(path, content, {
|
||
"flag": "w"
|
||
}, function (error) {
|
||
if (error == null) {
|
||
resolve(undefined);
|
||
}
|
||
else {
|
||
reject(error);
|
||
}
|
||
});
|
||
}));
|
||
}
|
||
file.write_buffer = write_buffer;
|
||
/**
|
||
*/
|
||
function delete_(path) {
|
||
var nm_fs = require("fs");
|
||
return (new Promise(function (resolve, reject) {
|
||
nm_fs.unlink(path, function () {
|
||
resolve(undefined);
|
||
});
|
||
}));
|
||
}
|
||
file.delete_ = delete_;
|
||
})(file = lib_plankton.file || (lib_plankton.file = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:structures«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:structures« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:structures« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:structures«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var structures;
|
||
(function (structures) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function map_clear(map_forEach, map_delete) {
|
||
map_forEach((value, key) => {
|
||
map_delete(key);
|
||
});
|
||
}
|
||
structures.map_clear = map_clear;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function map_keys(map_forEach) {
|
||
let keys = [];
|
||
map_forEach((value, key) => {
|
||
keys.push(key);
|
||
});
|
||
return keys;
|
||
}
|
||
structures.map_keys = map_keys;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function map_values(map_forEach) {
|
||
let values = [];
|
||
map_forEach((value, key) => {
|
||
values.push(value);
|
||
});
|
||
return values;
|
||
}
|
||
structures.map_values = map_values;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function map_pairs(map_forEach) {
|
||
let pairs = [];
|
||
map_forEach((value, key) => {
|
||
let pair = { "key": key, "value": value };
|
||
pairs.push(pair);
|
||
});
|
||
return pairs;
|
||
}
|
||
structures.map_pairs = map_pairs;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function map_toString(map_forEach, show_key = instance_show, show_value = instance_show) {
|
||
return ("["
|
||
+
|
||
(map_pairs(map_forEach)
|
||
.map(({ "key": key, "value": value }) => (show_key(key)
|
||
+
|
||
" -> "
|
||
+
|
||
show_value(value)))
|
||
.join(", "))
|
||
+
|
||
"]");
|
||
}
|
||
structures.map_toString = map_toString;
|
||
})(structures = lib_plankton.structures || (lib_plankton.structures = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:structures«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:structures« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:structures« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:structures«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
/*
|
||
This file is part of »bacterio-plankton:structures«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:structures« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:structures« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:structures«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var structures;
|
||
(function (structures) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class class_mapbase {
|
||
/**
|
||
* @desc [constructor]
|
||
*/
|
||
constructor() {
|
||
}
|
||
/**
|
||
* @desc [mutator]
|
||
*/
|
||
clear() {
|
||
return (structures.map_clear((procedure) => this.forEach(procedure), (key) => this.delete(key)));
|
||
}
|
||
/**
|
||
*/
|
||
get_safe(key) {
|
||
try {
|
||
const value = this.get(key);
|
||
return lib_plankton.pod.class_pod.filled(value);
|
||
}
|
||
catch (error) {
|
||
return lib_plankton.pod.class_pod.empty();
|
||
}
|
||
}
|
||
/**
|
||
* @desc [accessor]
|
||
*/
|
||
keys() {
|
||
return (structures.map_keys((procedure) => this.forEach(procedure)));
|
||
}
|
||
/**
|
||
* @desc [accessor]
|
||
*/
|
||
values() {
|
||
return (structures.map_values((procedure) => this.forEach(procedure)));
|
||
}
|
||
/**
|
||
* @desc [accessor]
|
||
*/
|
||
pairs() {
|
||
return (structures.map_pairs((procedure) => this.forEach(procedure)));
|
||
}
|
||
/**
|
||
* @desc [accessor]
|
||
*/
|
||
toString(show_key = instance_show, show_value = instance_show) {
|
||
return (structures.map_toString((procedure) => this.forEach(procedure), show_key, show_value));
|
||
}
|
||
}
|
||
structures.class_mapbase = class_mapbase;
|
||
})(structures = lib_plankton.structures || (lib_plankton.structures = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:structures«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:structures« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:structures« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:structures«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
/*
|
||
This file is part of »bacterio-plankton:structures«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:structures« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:structures« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:structures«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var structures;
|
||
(function (structures) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class class_pair {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
constructor(first, second) {
|
||
this.first = first;
|
||
this.second = second;
|
||
}
|
||
/**
|
||
* @desc [accessor] [getter]
|
||
* @author fenris
|
||
*/
|
||
first_get() {
|
||
return this.first;
|
||
}
|
||
/**
|
||
* @desc [accessor] [getter]
|
||
* @author fenris
|
||
*/
|
||
second_get() {
|
||
return this.second;
|
||
}
|
||
/**
|
||
* @desc [mutator] [setter]
|
||
* @author fenris
|
||
*/
|
||
first_set(first) {
|
||
this.first = first;
|
||
}
|
||
/**
|
||
* @desc [mutator] [setter]
|
||
* @author fenris
|
||
*/
|
||
second_set(second) {
|
||
this.second = second;
|
||
}
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
swap() {
|
||
return (new class_pair(this.second, this.first));
|
||
}
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
transform(transform_first, transform_second) {
|
||
return (new class_pair(transform_first(this.first), transform_second(this.second)));
|
||
}
|
||
/**
|
||
* @desc [accessor] [implementation]
|
||
* @author fenris
|
||
*/
|
||
_clone() {
|
||
return (new class_pair(instance_clone(this.first), instance_clone(this.second)));
|
||
}
|
||
/**
|
||
* @desc [accessor] [implementation]
|
||
* @author fenris
|
||
*/
|
||
_hash() {
|
||
return ("pair_" + instance_hash(this.first) + "_" + instance_hash(this.second) + "");
|
||
}
|
||
/**
|
||
* @desc [accessor] [implementation]
|
||
* @author fenris
|
||
*/
|
||
_collate(pair) {
|
||
return (instance_collate(this.first, pair.first)
|
||
&&
|
||
instance_collate(this.second, pair.second));
|
||
}
|
||
/**
|
||
* @desc [accessor] [implementation]
|
||
* @author fenris
|
||
*/
|
||
_show() {
|
||
return ("(" + instance_show(this.first) + "," + instance_show(this.second) + ")");
|
||
}
|
||
}
|
||
structures.class_pair = class_pair;
|
||
})(structures = lib_plankton.structures || (lib_plankton.structures = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:structures«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:structures« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:structures« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:structures«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var structures;
|
||
(function (structures) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function set_construct(collation, elements = []) {
|
||
let subject = {
|
||
"elements": []
|
||
};
|
||
elements.forEach(element => set_add(collation, subject, element));
|
||
return subject;
|
||
}
|
||
structures.set_construct = set_construct;
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
function set_size(subject) {
|
||
return subject.elements.length;
|
||
}
|
||
structures.set_size = set_size;
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
function set_has(collation, subject, element) {
|
||
return (subject.elements
|
||
.some(element_ => collation(element, element_)));
|
||
}
|
||
structures.set_has = set_has;
|
||
/**
|
||
* @desc [mutator]
|
||
* @author fenris
|
||
*/
|
||
function set_add(collation, subject, element) {
|
||
if (!set_has(collation, subject, element)) {
|
||
subject.elements.push(element);
|
||
}
|
||
}
|
||
structures.set_add = set_add;
|
||
/**
|
||
* @desc [mutator]
|
||
* @author fenris
|
||
*/
|
||
function set_pop(subject) {
|
||
if (subject.elements.length == 0) {
|
||
return lib_plankton.pod.make_empty();
|
||
}
|
||
else {
|
||
return lib_plankton.pod.make_filled(subject.elements.pop());
|
||
}
|
||
}
|
||
structures.set_pop = set_pop;
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
function set_forEach(subject, function_) {
|
||
subject.elements.forEach(element => function_(element));
|
||
}
|
||
structures.set_forEach = set_forEach;
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
function set_map(collation, subject, transformator) {
|
||
return (set_construct(collation, subject.elements.map(element_from => transformator(element_from))));
|
||
}
|
||
structures.set_map = set_map;
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
function set_filter(subject, predicate) {
|
||
return (set_construct((x, y) => false, subject.elements.filter(element => predicate(element))));
|
||
}
|
||
structures.set_filter = set_filter;
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
function set_dump(subject) {
|
||
return subject.elements;
|
||
}
|
||
structures.set_dump = set_dump;
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
function set_subset(collation, subject, object) {
|
||
return (subject.elements
|
||
.every(element => set_has(collation, object, element)));
|
||
}
|
||
structures.set_subset = set_subset;
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
function set_superset(collation, subject, object) {
|
||
return (object.elements
|
||
.every(element => set_has(collation, subject, element)));
|
||
}
|
||
structures.set_superset = set_superset;
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
function set_equals(collation, subject, object) {
|
||
return (set_subset(collation, subject, object)
|
||
&&
|
||
set_superset(collation, subject, object));
|
||
}
|
||
structures.set_equals = set_equals;
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
function set_toString(show_element, subject) {
|
||
return ("{"
|
||
+
|
||
subject.elements.map(element => show_element(element)).join(",")
|
||
+
|
||
"}");
|
||
}
|
||
structures.set_toString = set_toString;
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
function set_empty(subject) {
|
||
return (subject.elements.length == 0);
|
||
}
|
||
structures.set_empty = set_empty;
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
function set_union(collation, subject, object) {
|
||
let result = set_construct(collation, []);
|
||
subject.elements.forEach(element => set_add(collation, result, element));
|
||
object.elements.forEach(element => set_add(collation, result, element));
|
||
return result;
|
||
}
|
||
structures.set_union = set_union;
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
function set_intersection(collation, subject, object) {
|
||
let result = set_construct(collation, []);
|
||
subject.elements.forEach(element => {
|
||
if (set_has(collation, object, element)) {
|
||
set_add(collation, result, element);
|
||
}
|
||
});
|
||
return result;
|
||
}
|
||
structures.set_intersection = set_intersection;
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
function set_difference(collation, subject, object) {
|
||
let result = set_construct(collation, []);
|
||
subject.elements.forEach(element => {
|
||
if (!set_has(collation, object, element)) {
|
||
set_add(collation, result, element);
|
||
}
|
||
});
|
||
return result;
|
||
}
|
||
structures.set_difference = set_difference;
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
function set_symmetric_difference(collation, subject, object) {
|
||
// X $ Y = (X ∪ Y) \ (X ∩ Y)
|
||
return (set_difference(collation, set_union(collation, subject, object), set_intersection(collation, subject, object)));
|
||
}
|
||
structures.set_symmetric_difference = set_symmetric_difference;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function set_union_all(collation, sets) {
|
||
return (sets.reduce((x, y) => ((x == null) ? y : set_union(collation, x, y)), null));
|
||
}
|
||
structures.set_union_all = set_union_all;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function set_intersection_all(collation, sets) {
|
||
return (sets.reduce((x, y) => ((x == null) ? y : set_intersection(collation, x, y)), null));
|
||
}
|
||
structures.set_intersection_all = set_intersection_all;
|
||
})(structures = lib_plankton.structures || (lib_plankton.structures = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:structures«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:structures« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:structures« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:structures«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var structures;
|
||
(function (structures) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class class_set {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
constructor(elements = [], equality = instance_collate /*<type_element>*/) {
|
||
this.equality = equality;
|
||
this.subject = structures.set_construct(equality, elements);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
static from_subject(equality = instance_collate /*<type_element>*/, subject) {
|
||
let set = new class_set([], equality);
|
||
set.subject = subject;
|
||
return set;
|
||
}
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
size() {
|
||
return structures.set_size(this.subject);
|
||
}
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
has(element) {
|
||
return structures.set_has(this.equality, this.subject, element);
|
||
}
|
||
/**
|
||
* @desc [mutator]
|
||
* @author fenris
|
||
*/
|
||
add(element) {
|
||
return structures.set_add(this.equality, this.subject, element);
|
||
}
|
||
/**
|
||
* @desc [mutator]
|
||
* @author fenris
|
||
*/
|
||
pop() {
|
||
return (new lib_plankton.pod.class_pod(structures.set_pop(this.subject)));
|
||
}
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
forEach(function_) {
|
||
return structures.set_forEach(this.subject, function_);
|
||
}
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
map(transformator, equality = instance_collate /*<type_element_>*/) {
|
||
return (class_set.from_subject(equality, structures.set_map(equality, this.subject, transformator)));
|
||
}
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
filter(predicate) {
|
||
return (class_set.from_subject(this.equality, structures.set_filter(this.subject, predicate)));
|
||
}
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
dump() {
|
||
return structures.set_dump(this.subject);
|
||
}
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
subset(set) {
|
||
return structures.set_subset(this.equality, this.subject, set.subject);
|
||
}
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
superset(set) {
|
||
return structures.set_superset(this.equality, this.subject, set.subject);
|
||
}
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
equals(set) {
|
||
return structures.set_equals(this.equality, this.subject, set.subject);
|
||
}
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
toString() {
|
||
return structures.set_toString(instance_show, this.subject);
|
||
}
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
empty() {
|
||
return structures.set_empty(this.subject);
|
||
}
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
union(set) {
|
||
return (class_set.from_subject(this.equality, structures.set_union(this.equality, this.subject, set.subject)));
|
||
}
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
intersection(set) {
|
||
return (class_set.from_subject(this.equality, structures.set_intersection(this.equality, this.subject, set.subject)));
|
||
}
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
difference(set) {
|
||
return (class_set.from_subject(this.equality, structures.set_difference(this.equality, this.subject, set.subject)));
|
||
}
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
symmetric_difference(set) {
|
||
return (class_set.from_subject(this.equality, structures.set_symmetric_difference(this.equality, this.subject, set.subject)));
|
||
}
|
||
/**
|
||
* @desc [accessor] [implementation]
|
||
* @author fenris
|
||
*/
|
||
_collate(set) {
|
||
return structures.set_equals(this.equality, this.subject, set.subject);
|
||
}
|
||
/**
|
||
* @desc [accessor] [implementation]
|
||
* @author fenris
|
||
*/
|
||
_show() {
|
||
return structures.set_toString(instance_show, this.subject);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
static union_all(sets) {
|
||
if (sets.length === 0) {
|
||
let message = "empty union";
|
||
// console.warn("--", message);
|
||
return (new class_set());
|
||
}
|
||
else {
|
||
return (class_set.from_subject(sets[0].equality, structures.set_union_all(sets[0].equality, sets.map(set => set.subject))));
|
||
}
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
static intersection_all(sets) {
|
||
if (sets.length === 0) {
|
||
let message = "empty intersection is not defined";
|
||
throw (new Error(message));
|
||
}
|
||
else {
|
||
return (class_set.from_subject(sets[0].equality, structures.set_intersection_all(sets[0].equality, sets.map(set => set.subject))));
|
||
}
|
||
}
|
||
}
|
||
structures.class_set = class_set;
|
||
})(structures = lib_plankton.structures || (lib_plankton.structures = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:structures«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:structures« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:structures« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:structures«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var structures;
|
||
(function (structures) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function stack_construct() {
|
||
return {
|
||
"elements": []
|
||
};
|
||
}
|
||
structures.stack_construct = stack_construct;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function stack_size(subject) {
|
||
return subject.elements.length;
|
||
}
|
||
structures.stack_size = stack_size;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function stack_scan(subject) {
|
||
if (stack_size(subject) == 0) {
|
||
let message = "empty";
|
||
throw (new Error(message));
|
||
}
|
||
else {
|
||
return subject.elements[subject.elements.length - 1];
|
||
}
|
||
}
|
||
structures.stack_scan = stack_scan;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function stack_take(subject) {
|
||
let element = stack_scan(subject);
|
||
subject.elements.pop();
|
||
return element;
|
||
}
|
||
structures.stack_take = stack_take;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function stack_give(subject, element) {
|
||
subject.elements.push(element);
|
||
}
|
||
structures.stack_give = stack_give;
|
||
})(structures = lib_plankton.structures || (lib_plankton.structures = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:structures«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:structures« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:structures« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:structures«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var structures;
|
||
(function (structures) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class class_stack {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
constructor() {
|
||
this.subject = structures.stack_construct();
|
||
}
|
||
/**
|
||
* @override
|
||
* @author fenris
|
||
*/
|
||
size() {
|
||
return structures.stack_size(this.subject);
|
||
}
|
||
/**
|
||
* @override
|
||
* @author fenris
|
||
*/
|
||
scan() {
|
||
return structures.stack_scan(this.subject);
|
||
}
|
||
/**
|
||
* @override
|
||
* @author fenris
|
||
*/
|
||
take() {
|
||
return structures.stack_take(this.subject);
|
||
}
|
||
/**
|
||
* @override
|
||
* @author fenris
|
||
*/
|
||
give(element) {
|
||
return structures.stack_give(this.subject, element);
|
||
}
|
||
}
|
||
structures.class_stack = class_stack;
|
||
})(structures = lib_plankton.structures || (lib_plankton.structures = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:structures«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:structures« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:structures« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:structures«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var structures;
|
||
(function (structures) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function queue_construct() {
|
||
return {
|
||
"elements": []
|
||
};
|
||
}
|
||
structures.queue_construct = queue_construct;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function queue_size(subject) {
|
||
return subject.elements.length;
|
||
}
|
||
structures.queue_size = queue_size;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function queue_scan(subject) {
|
||
if (queue_size(subject) == 0) {
|
||
let message = "empty";
|
||
throw (new Error(message));
|
||
}
|
||
else {
|
||
return subject.elements[0];
|
||
}
|
||
}
|
||
structures.queue_scan = queue_scan;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function queue_take(subject) {
|
||
let element = queue_scan(subject);
|
||
subject.elements.shift();
|
||
return element;
|
||
}
|
||
structures.queue_take = queue_take;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function queue_give(subject, element) {
|
||
subject.elements.push(element);
|
||
}
|
||
structures.queue_give = queue_give;
|
||
})(structures = lib_plankton.structures || (lib_plankton.structures = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:structures«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:structures« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:structures« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:structures«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var structures;
|
||
(function (structures) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class class_queue {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
constructor() {
|
||
this.subject = structures.queue_construct();
|
||
}
|
||
/**
|
||
* @override
|
||
* @author fenris
|
||
*/
|
||
size() {
|
||
return structures.queue_size(this.subject);
|
||
}
|
||
/**
|
||
* @override
|
||
* @author fenris
|
||
*/
|
||
scan() {
|
||
return structures.queue_scan(this.subject);
|
||
}
|
||
/**
|
||
* @override
|
||
* @author fenris
|
||
*/
|
||
take() {
|
||
return structures.queue_take(this.subject);
|
||
}
|
||
/**
|
||
* @override
|
||
* @author fenris
|
||
*/
|
||
give(element) {
|
||
return structures.queue_give(this.subject, element);
|
||
}
|
||
}
|
||
structures.class_queue = class_queue;
|
||
})(structures = lib_plankton.structures || (lib_plankton.structures = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:structures«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:structures« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:structures« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:structures«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var structures;
|
||
(function (structures) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function simplemap_construct() {
|
||
return {
|
||
"memory": {}
|
||
};
|
||
}
|
||
structures.simplemap_construct = simplemap_construct;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function simplemap_has(subject, key) {
|
||
return (key in subject.memory);
|
||
}
|
||
structures.simplemap_has = simplemap_has;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function simplemap_get_safe(subject, key) {
|
||
if (key in subject.memory) {
|
||
return lib_plankton.pod.make_filled(subject.memory[key]);
|
||
}
|
||
else {
|
||
return lib_plankton.pod.make_empty();
|
||
}
|
||
}
|
||
structures.simplemap_get_safe = simplemap_get_safe;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function simplemap_get(subject, key, fallback = lib_plankton.pod.make_empty()) {
|
||
if (key in subject.memory) {
|
||
return subject.memory[key];
|
||
}
|
||
else {
|
||
if (!lib_plankton.pod.is_filled(fallback)) {
|
||
throw (new Error("key not found"));
|
||
}
|
||
else {
|
||
return lib_plankton.pod.cull(fallback);
|
||
}
|
||
}
|
||
}
|
||
structures.simplemap_get = simplemap_get;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function simplemap_set(subject, key, value) {
|
||
subject.memory[key] = value;
|
||
}
|
||
structures.simplemap_set = simplemap_set;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function simplemap_delete(subject, key) {
|
||
delete subject.memory[key];
|
||
}
|
||
structures.simplemap_delete = simplemap_delete;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function simplemap_clear(subject) {
|
||
// subject.memory = {};
|
||
Object.keys(subject.memory).forEach(key => { delete subject.memory[key]; });
|
||
}
|
||
structures.simplemap_clear = simplemap_clear;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function simplemap_forEach(subject, function_) {
|
||
Object.keys(subject.memory).forEach(key => {
|
||
let value = subject.memory[key];
|
||
function_(value, key);
|
||
});
|
||
}
|
||
structures.simplemap_forEach = simplemap_forEach;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function simplemap_from_object(object) {
|
||
let subject = simplemap_construct();
|
||
Object.keys(object).forEach((key) => {
|
||
let value = object[key];
|
||
subject.memory[key] = value;
|
||
});
|
||
return subject;
|
||
}
|
||
structures.simplemap_from_object = simplemap_from_object;
|
||
})(structures = lib_plankton.structures || (lib_plankton.structures = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:structures«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:structures« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:structures« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:structures«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var structures;
|
||
(function (structures) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class class_simplemap extends structures.class_mapbase {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
static make() {
|
||
const subject = structures.simplemap_construct();
|
||
return (new class_simplemap(subject));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
static from_object(object) {
|
||
return (new class_simplemap(structures.simplemap_from_object(object)));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
* @desc [constructor]
|
||
*/
|
||
constructor(subject = structures.simplemap_construct()) {
|
||
super();
|
||
this.subject = subject;
|
||
}
|
||
/**
|
||
* @author fenris
|
||
* @implementation
|
||
*/
|
||
has(key) {
|
||
return structures.simplemap_has(this.subject, key);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
* @implementation
|
||
*/
|
||
get(key, fallback = lib_plankton.pod.class_pod.empty()) {
|
||
return structures.simplemap_get(this.subject, key, fallback.tear());
|
||
}
|
||
/**
|
||
* @author fenris
|
||
* @implementation
|
||
*/
|
||
set(key, value) {
|
||
return structures.simplemap_set(this.subject, key, value);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
* @implementation
|
||
*/
|
||
delete(key) {
|
||
return structures.simplemap_delete(this.subject, key);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
* @implementation
|
||
*/
|
||
forEach(procedure) {
|
||
return structures.simplemap_forEach(this.subject, procedure);
|
||
}
|
||
}
|
||
structures.class_simplemap = class_simplemap;
|
||
})(structures = lib_plankton.structures || (lib_plankton.structures = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:structures«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:structures« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:structures« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:structures«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var structures;
|
||
(function (structures) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function hashmap_construct(hashing, pairs) {
|
||
const subject = {
|
||
"core": structures.simplemap_construct(),
|
||
"hashing": hashing,
|
||
};
|
||
pairs.forEach((pair) => {
|
||
hashmap_set(subject, pair.key, pair.value);
|
||
});
|
||
return subject;
|
||
}
|
||
structures.hashmap_construct = hashmap_construct;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function hashmap_has(subject, key) {
|
||
const key_ = subject.hashing(key);
|
||
return structures.simplemap_has(subject.core, key_);
|
||
}
|
||
structures.hashmap_has = hashmap_has;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function hashmap_get(subject, key, fallback = lib_plankton.pod.make_empty()) {
|
||
/*
|
||
we have to adjust the fallback argument, so that it can be used in our underlying simplemap core
|
||
therefore we pack the value together with any key as dummy
|
||
*/
|
||
const fallback_ = lib_plankton.pod.propagate(fallback, (value) => ({
|
||
"key": key,
|
||
"value": value
|
||
}));
|
||
const key_ = subject.hashing(key);
|
||
return (structures.simplemap_get(subject.core, key_, fallback_)
|
||
.value);
|
||
}
|
||
structures.hashmap_get = hashmap_get;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function hashmap_set(subject, key, value) {
|
||
const key_ = subject.hashing(key);
|
||
return (structures.simplemap_set(subject.core, key_, { "key": key, "value": value }));
|
||
}
|
||
structures.hashmap_set = hashmap_set;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function hashmap_delete(subject, key) {
|
||
const key_ = subject.hashing(key);
|
||
return (structures.simplemap_delete(subject.core, key_));
|
||
}
|
||
structures.hashmap_delete = hashmap_delete;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function hashmap_clear(subject) {
|
||
return structures.simplemap_clear(subject.core);
|
||
}
|
||
structures.hashmap_clear = hashmap_clear;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function hashmap_forEach(subject, procedure) {
|
||
return (structures.simplemap_forEach(subject.core, ({ "key": key, "value": value }, key_) => {
|
||
procedure(value, key);
|
||
}));
|
||
}
|
||
structures.hashmap_forEach = hashmap_forEach;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function hashmap_dump(subject) {
|
||
let result = [];
|
||
hashmap_forEach(subject, (value, key) => {
|
||
result.push({
|
||
"key": key,
|
||
"value": value,
|
||
});
|
||
});
|
||
return result;
|
||
}
|
||
structures.hashmap_dump = hashmap_dump;
|
||
})(structures = lib_plankton.structures || (lib_plankton.structures = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:structures«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:structures« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:structures« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:structures«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var structures;
|
||
(function (structures) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class class_hashmap extends structures.class_mapbase {
|
||
/**
|
||
* @author fenris
|
||
* @desc [constructor]
|
||
*/
|
||
constructor(hashing = instance_hash, pairs = []) {
|
||
super();
|
||
this.subject = structures.hashmap_construct(hashing, pairs);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
* @implementation
|
||
*/
|
||
has(key) {
|
||
return structures.hashmap_has(this.subject, key);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
* @implementation
|
||
*/
|
||
get(key, fallback = lib_plankton.pod.class_pod.empty()) {
|
||
return structures.hashmap_get(this.subject, key, fallback.tear());
|
||
}
|
||
/**
|
||
* @author fenris
|
||
* @implementation
|
||
*/
|
||
set(key, value) {
|
||
return structures.hashmap_set(this.subject, key, value);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
* @implementation
|
||
*/
|
||
delete(key) {
|
||
return structures.hashmap_delete(this.subject, key);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
* @implementation
|
||
*/
|
||
forEach(procedure) {
|
||
return structures.hashmap_forEach(this.subject, procedure);
|
||
}
|
||
}
|
||
structures.class_hashmap = class_hashmap;
|
||
})(structures = lib_plankton.structures || (lib_plankton.structures = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:structures«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:structures« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:structures« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:structures«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var structures;
|
||
(function (structures) {
|
||
/**
|
||
*/
|
||
function collatemap_construct() {
|
||
return {
|
||
"pairs": [],
|
||
};
|
||
}
|
||
structures.collatemap_construct = collatemap_construct;
|
||
/**
|
||
*/
|
||
function collatemap_has(collation, subject, key) {
|
||
return subject.pairs.some((pair) => collation(key, pair.key));
|
||
}
|
||
structures.collatemap_has = collatemap_has;
|
||
/**
|
||
* @todo use .find
|
||
*/
|
||
function collatemap_get(collation, subject, key, fallback) {
|
||
let value;
|
||
const found = (subject.pairs
|
||
.some((pair) => {
|
||
if (collation(key, pair.key)) {
|
||
value = pair.value;
|
||
return true;
|
||
}
|
||
else {
|
||
return false;
|
||
}
|
||
}));
|
||
if (found) {
|
||
return value;
|
||
}
|
||
else {
|
||
if (!lib_plankton.pod.is_filled(fallback)) {
|
||
throw (new Error("key not found"));
|
||
}
|
||
else {
|
||
return lib_plankton.pod.cull(fallback);
|
||
}
|
||
}
|
||
}
|
||
structures.collatemap_get = collatemap_get;
|
||
/**
|
||
*/
|
||
function collatemap_set(collation, subject, key, value) {
|
||
const found = (subject.pairs
|
||
.some((pair) => {
|
||
if (collation(key, pair.key)) {
|
||
pair.value = value;
|
||
return true;
|
||
}
|
||
else {
|
||
return false;
|
||
}
|
||
}));
|
||
if (found) {
|
||
// nothing
|
||
}
|
||
else {
|
||
subject.pairs.push({
|
||
"key": key,
|
||
"value": value
|
||
});
|
||
}
|
||
}
|
||
structures.collatemap_set = collatemap_set;
|
||
/**
|
||
*/
|
||
function collatemap_delete(collation, subject, key) {
|
||
let index;
|
||
const found = (subject.pairs
|
||
.some((pair, index_) => {
|
||
if (collation(key, pair.key)) {
|
||
index = index_;
|
||
return true;
|
||
}
|
||
else {
|
||
return false;
|
||
}
|
||
}));
|
||
if (found) {
|
||
subject.pairs.splice(index, 1);
|
||
}
|
||
else {
|
||
// do nothing
|
||
}
|
||
}
|
||
structures.collatemap_delete = collatemap_delete;
|
||
/**
|
||
*/
|
||
function collatemap_forEach(
|
||
// collation : type_collation<type_key>,
|
||
subject, function_) {
|
||
subject.pairs
|
||
.forEach((pair) => {
|
||
function_(pair.value, pair.key);
|
||
});
|
||
}
|
||
structures.collatemap_forEach = collatemap_forEach;
|
||
})(structures = lib_plankton.structures || (lib_plankton.structures = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:structures«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:structures« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:structures« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:structures«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var structures;
|
||
(function (structures) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class class_collatemap extends structures.class_mapbase {
|
||
/**
|
||
* @author fenris
|
||
* @desc [constructor]
|
||
*/
|
||
constructor(collation = instance_collate) {
|
||
super();
|
||
this.subject = structures.collatemap_construct();
|
||
this.collation = collation;
|
||
}
|
||
/**
|
||
* @author fenris
|
||
* @implementation
|
||
*/
|
||
has(key) {
|
||
return structures.collatemap_has(this.collation, this.subject, key);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
* @implementation
|
||
*/
|
||
get(key, fallback = lib_plankton.pod.class_pod.empty()) {
|
||
return structures.collatemap_get(this.collation, this.subject, key, fallback.tear());
|
||
}
|
||
/**
|
||
* @author fenris
|
||
* @implementation
|
||
*/
|
||
set(key, value) {
|
||
return structures.collatemap_set(this.collation, this.subject, key, value);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
* @implementation
|
||
*/
|
||
delete(key) {
|
||
return structures.collatemap_delete(this.collation, this.subject, key);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
* @implementation
|
||
*/
|
||
forEach(procedure) {
|
||
return structures.collatemap_forEach(this.subject, procedure);
|
||
}
|
||
}
|
||
structures.class_collatemap = class_collatemap;
|
||
/**
|
||
* @author fenris
|
||
* @deprecated
|
||
*/
|
||
structures.class_map = class_collatemap;
|
||
})(structures = lib_plankton.structures || (lib_plankton.structures = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:structures«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:structures« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:structures« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:structures«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var structures;
|
||
(function (structures) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class class_graph {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
constructor(equality = null, nodes = [], edges = []) {
|
||
if (equality == null) {
|
||
// equality = ((node1, node2) => lib_plankton.trait.call("collatable", "collate", {"kind": "auto"}, {"first": node1, "second": node2}));
|
||
equality = instance_collate /*<type_node>*/;
|
||
}
|
||
this.equality = equality;
|
||
this.nodes = nodes;
|
||
this.edges = edges;
|
||
}
|
||
/**
|
||
* @desc [accessor] [getter]
|
||
* @author fenris
|
||
*/
|
||
nodes_get() {
|
||
return this.nodes;
|
||
}
|
||
/**
|
||
* @desc [mutator]
|
||
* @author fenris
|
||
*/
|
||
add_node(node) {
|
||
this.nodes.push(node);
|
||
}
|
||
/**
|
||
* @desc [accessor] [getter]
|
||
* @author fenris
|
||
*/
|
||
edges_get() {
|
||
return this.edges;
|
||
}
|
||
/**
|
||
* @desc [mutator]
|
||
* @author fenris
|
||
*/
|
||
add_edge(edge) {
|
||
this.edges.push(edge);
|
||
}
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
has(node) {
|
||
return this.nodes.some(node_ => this.equality(node, node_));
|
||
}
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
outgoing(node) {
|
||
return this.edges.filter(edge => this.equality(edge.from, node));
|
||
}
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
incoming(node) {
|
||
return this.edges.filter(edge => this.equality(edge.to, node));
|
||
}
|
||
/**
|
||
* @desc [accessor]
|
||
* @author fenris
|
||
*/
|
||
without(pivot) {
|
||
return (new class_graph(this.equality, this.nodes.filter(node => (!this.equality(node, pivot))), this.edges.filter(edge => ((!this.equality(edge.from, pivot)) && (!this.equality(edge.to, pivot))))));
|
||
}
|
||
/**
|
||
* @desc [accessor] returns the topologic sorting of the nodes (if it exists)
|
||
* @author fenris
|
||
*/
|
||
topsort() {
|
||
let graph = this;
|
||
if (graph.nodes.length == 0) {
|
||
return [];
|
||
}
|
||
else {
|
||
let pivot;
|
||
let found = graph.nodes.some(node => {
|
||
let count = graph.edges.filter(edge => this.equality(edge.to, node)).length;
|
||
if (count == 0) {
|
||
pivot = node;
|
||
return true;
|
||
}
|
||
else {
|
||
// console.info("'" + String(node) + "' has " + count.toString() + " incoming edges");
|
||
return false;
|
||
}
|
||
});
|
||
if (found) {
|
||
return [pivot].concat(graph.without(pivot).topsort());
|
||
}
|
||
else {
|
||
throw (new Error("circular dependencies found"));
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* @desc [accessor] returns the reduced version of a graph representing an order relation (implicit transitivity)
|
||
* @author fenris
|
||
*/
|
||
hasse() {
|
||
return (new class_graph(this.equality, this.nodes, this.edges.filter((edge) => {
|
||
let reachable = (this.outgoing(edge.from)
|
||
.map((edge_) => edge_.to)
|
||
.map((node) => this.outgoing(node).map((edge_) => edge_.to))
|
||
.reduce((x, y) => x.concat(y), []));
|
||
return (!reachable.some(node => this.equality(node, edge.to)));
|
||
})));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
output_dot({ "extract_id": extract_id = null, "extract_label": extract_label = null, "rotate": rotate = false, } = {}) {
|
||
let index = node => {
|
||
let i = -1;
|
||
let found = this.nodes.some((node_, i_) => {
|
||
if (this.equality(node, node_)) {
|
||
i = i_;
|
||
return true;
|
||
}
|
||
else {
|
||
return false;
|
||
}
|
||
});
|
||
return i;
|
||
};
|
||
if (extract_id == null) {
|
||
// instance_hash
|
||
extract_id = (node => index(node).toFixed(0));
|
||
}
|
||
if (extract_label == null) {
|
||
extract_label = instance_show;
|
||
}
|
||
let nodeid = (node) => {
|
||
return ("node_" + extract_id(node));
|
||
};
|
||
return ({
|
||
"common": {
|
||
"fontname": "Monospace",
|
||
"rankdir": (rotate ? "LR" : "TB"),
|
||
},
|
||
"nodes": {
|
||
"head": {
|
||
"fontname": "Monospace",
|
||
"style": "filled",
|
||
"fillcolor": "0.35+0.6+0.8",
|
||
},
|
||
"list": this.nodes_get()
|
||
.map((node, index) => {
|
||
return {
|
||
"id": nodeid(node),
|
||
"attributes": {
|
||
"label": extract_label(node),
|
||
}
|
||
};
|
||
}),
|
||
},
|
||
"edges": {
|
||
"head": {
|
||
"fontname": "Monospace"
|
||
},
|
||
"list": this.edges_get()
|
||
.map((edge, index) => {
|
||
return {
|
||
"id_from": nodeid(edge.from),
|
||
"id_to": nodeid(edge.to),
|
||
"attributes": {}
|
||
};
|
||
}),
|
||
}
|
||
});
|
||
}
|
||
}
|
||
structures.class_graph = class_graph;
|
||
})(structures = lib_plankton.structures || (lib_plankton.structures = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:structures«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:structures« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:structures« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:structures«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var structures;
|
||
(function (structures) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
structures.relation_le = "le";
|
||
structures.relation_ge = "ge";
|
||
structures.relation_lt = "lt";
|
||
structures.relation_gt = "gt";
|
||
structures.relation_eq = "eq";
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function binnode_construct(data) {
|
||
return {
|
||
"data": data,
|
||
"left": null,
|
||
"right": null,
|
||
"depth": 1,
|
||
};
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function binnode_isdef(subject) {
|
||
return (!(subject === null));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function binnode_child_get(subject, left) {
|
||
if (left) {
|
||
return subject.left;
|
||
}
|
||
else {
|
||
return subject.right;
|
||
}
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function binnode_child_set(subject, left, value) {
|
||
if (left) {
|
||
subject.left = value;
|
||
}
|
||
else {
|
||
subject.right = value;
|
||
}
|
||
}
|
||
/**
|
||
* @author fenris
|
||
* @todo remove later on
|
||
*/
|
||
function binnode_update_depth(subject) {
|
||
subject.depth = (1
|
||
+
|
||
Math.max((binnode_isdef(subject.left) ? subject.left.depth : 0), (binnode_isdef(subject.right) ? subject.right.depth : 0)));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
* @todo remove later
|
||
*/
|
||
function binnode_depth(subject) {
|
||
return (1
|
||
+
|
||
Math.max((binnode_isdef(subject.left) ? binnode_depth(subject.left) : 0), (binnode_isdef(subject.right) ? binnode_depth(subject.right) : 0)));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
* @todo remove later on
|
||
*/
|
||
function binnode_check_depths(subject) {
|
||
return ((binnode_isdef(subject.left) ? binnode_check_depths(subject.left) : true)
|
||
&&
|
||
(binnode_isdef(subject.right) ? binnode_check_depths(subject.right) : true)
|
||
&&
|
||
(subject.depth === binnode_depth(subject)));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function binnode_imbalance(subject) {
|
||
if (true) {
|
||
return ((binnode_isdef(subject.right) ? subject.right.depth : 0)
|
||
-
|
||
(binnode_isdef(subject.left) ? subject.left.depth : 0));
|
||
}
|
||
else {
|
||
return ((binnode_isdef(subject.right) ? binnode_depth(subject.right) : 0)
|
||
-
|
||
(binnode_isdef(subject.left) ? binnode_depth(subject.left) : 0));
|
||
}
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function binnode_insert(compare, subject, data) {
|
||
let node;
|
||
const left = compare(data, subject.data);
|
||
if (binnode_child_get(subject, left) == null) {
|
||
node = binnode_construct(data);
|
||
binnode_child_set(subject, left, node);
|
||
}
|
||
else {
|
||
node = binnode_insert(compare, binnode_child_get(subject, left), data);
|
||
}
|
||
binnode_update_depth(subject);
|
||
return node;
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function binnode_update_parent(subject, parent, child) {
|
||
if (binnode_isdef(parent)) {
|
||
if (parent.left === subject) {
|
||
parent.left = child;
|
||
}
|
||
else if (parent.right === subject) {
|
||
parent.right = child;
|
||
}
|
||
else {
|
||
console.warn("-- updating parent failed :/");
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function binnode_drag(subject, left, parent = null) {
|
||
let child = binnode_child_get(subject, !left);
|
||
let grandchild = binnode_child_get(child, left);
|
||
binnode_child_set(subject, !left, grandchild);
|
||
binnode_child_set(child, left, subject);
|
||
binnode_update_parent(subject, parent, child);
|
||
return child;
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function binnode_rebalance(subject, parent = null) {
|
||
// rebalance children first
|
||
{
|
||
if (binnode_isdef(subject.left)) {
|
||
binnode_rebalance(subject.left, subject);
|
||
if (binnode_isdef(parent))
|
||
binnode_update_depth(parent);
|
||
}
|
||
if (binnode_isdef(subject.right)) {
|
||
binnode_rebalance(subject.right, subject);
|
||
if (binnode_isdef(parent))
|
||
binnode_update_depth(parent);
|
||
}
|
||
}
|
||
// now rebalance the current node
|
||
{
|
||
const imbalance = binnode_imbalance(subject);
|
||
if (Math.abs(imbalance) >= 2) {
|
||
const left = (imbalance < 0);
|
||
let child = binnode_child_get(subject, left);
|
||
const imbalance_ = binnode_imbalance(child);
|
||
if (imbalance * imbalance_ < 0) {
|
||
// sub dragging
|
||
let child_ = binnode_drag(child, left, subject);
|
||
binnode_update_depth(binnode_child_get(child_, left));
|
||
binnode_update_depth(child_);
|
||
}
|
||
// core dragging
|
||
let subject_ = binnode_drag(subject, !left, parent);
|
||
binnode_update_depth(subject);
|
||
binnode_update_depth(subject_);
|
||
if (parent != null)
|
||
binnode_update_depth(parent);
|
||
return subject_;
|
||
}
|
||
else {
|
||
return subject;
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* @author fenris
|
||
* @desc see misc/foo.py for some interesting facts explaining the handlers
|
||
* @desc lists all nodes that match the given piece of the data with the given relation
|
||
*/
|
||
function binnode_search(compare, subject, data, relation = "eq") {
|
||
const x = subject.data;
|
||
const y = data;
|
||
const situation_le = compare(x, y);
|
||
const situation_ge = compare(y, x);
|
||
const situation_lt = (situation_le && (!situation_ge));
|
||
const situation_gt = ((!situation_le) && situation_ge);
|
||
const situation_eq = (situation_le && situation_ge);
|
||
// recursive call
|
||
const deepen = (left) => {
|
||
const child = binnode_child_get(subject, left);
|
||
if (binnode_isdef(child)) {
|
||
return binnode_search(compare, child, data, relation);
|
||
}
|
||
else {
|
||
return [];
|
||
}
|
||
};
|
||
/*
|
||
handlers that describe how the search is to be executed;
|
||
if "subject", the current node is added to the search results (~ situation)
|
||
if "left", the left subtree is regarded as well
|
||
if "right", the right subtree is regarded as well
|
||
*/
|
||
const handlers = {
|
||
"lt": {
|
||
"subject": (situation_lt),
|
||
"left": (true),
|
||
"right": (situation_lt),
|
||
},
|
||
"le": {
|
||
"subject": (situation_le),
|
||
"left": (true),
|
||
"right": (situation_lt),
|
||
},
|
||
"eq": {
|
||
"subject": (situation_eq),
|
||
"left": (!situation_lt),
|
||
"right": (situation_lt),
|
||
},
|
||
"ge": {
|
||
"subject": (situation_ge),
|
||
"left": (!situation_lt),
|
||
"right": (true),
|
||
},
|
||
"gt": {
|
||
"subject": (situation_gt),
|
||
"left": (situation_gt),
|
||
"right": (true),
|
||
},
|
||
};
|
||
if (relation in handlers) {
|
||
let result = [];
|
||
const handler = handlers[relation];
|
||
if (handler.subject) {
|
||
result = result.concat([subject]);
|
||
}
|
||
if (handler.left) {
|
||
result = result.concat(deepen(true));
|
||
}
|
||
if (handler.right) {
|
||
result = result.concat(deepen(false));
|
||
}
|
||
return result;
|
||
}
|
||
else {
|
||
const message = `unhandled relation '${relation}'`;
|
||
throw (new Error(message));
|
||
}
|
||
}
|
||
/**
|
||
* @author fenris
|
||
* @desc returns the first found node, which matches the given data or "null" if not found
|
||
*/
|
||
function binnode_find(compare, subject, data) {
|
||
const le = compare(data, subject.data);
|
||
const ge = compare(subject.data, data);
|
||
if (le && ge) {
|
||
return subject;
|
||
}
|
||
else {
|
||
const child = binnode_child_get(subject, le);
|
||
return ((binnode_isdef(child))
|
||
? binnode_find(compare, child, data)
|
||
: null);
|
||
}
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function binnode_traverse(subject) {
|
||
return ([]
|
||
.concat((binnode_isdef(subject.left) ? binnode_traverse(subject.left) : []))
|
||
.concat([subject.data])
|
||
.concat((binnode_isdef(subject.right) ? binnode_traverse(subject.right) : [])));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function binnode_show(show_data, subject, depth = 0) {
|
||
const indent = (n, sequence = " ") => sequence["repeat"](n);
|
||
let str = "";
|
||
{
|
||
str += indent(depth);
|
||
str += show_data(subject.data);
|
||
str += (" " + "[" + binnode_imbalance(subject).toFixed(0) + "]");
|
||
str += (" " + "{" + binnode_depth(subject).toFixed(0) + "/" + subject.depth.toFixed(0) + "}");
|
||
str += "\n";
|
||
}
|
||
if (binnode_isdef(subject.left) || binnode_isdef(subject.right)) {
|
||
// left
|
||
{
|
||
if (binnode_isdef(subject.left)) {
|
||
str += binnode_show(show_data, subject.left, depth + 1);
|
||
}
|
||
else {
|
||
str += (indent(depth + 1) + "~" + "\n");
|
||
}
|
||
}
|
||
// right
|
||
{
|
||
if (binnode_isdef(subject.right)) {
|
||
str += binnode_show(show_data, subject.right, depth + 1);
|
||
}
|
||
else {
|
||
str += (indent(depth + 1) + "~" + "\n");
|
||
}
|
||
}
|
||
}
|
||
return str;
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function bintree_construct() {
|
||
return {
|
||
"root": null,
|
||
};
|
||
}
|
||
structures.bintree_construct = bintree_construct;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function bintree_depth(subject) {
|
||
return ((binnode_isdef(subject.root))
|
||
? binnode_depth(subject.root)
|
||
: 0);
|
||
}
|
||
structures.bintree_depth = bintree_depth;
|
||
/**
|
||
* @author fenris
|
||
* @todo remove later on
|
||
*/
|
||
function bintree_check_depths(subject) {
|
||
return ((binnode_isdef(subject.root))
|
||
? binnode_check_depths(subject.root)
|
||
: true);
|
||
}
|
||
structures.bintree_check_depths = bintree_check_depths;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function bintree_insert(compare, subject, data, rebalance = true) {
|
||
// basic insertion
|
||
{
|
||
if (binnode_isdef(subject.root)) {
|
||
binnode_insert(compare, subject.root, data);
|
||
}
|
||
else {
|
||
subject.root = binnode_construct(data);
|
||
}
|
||
}
|
||
// rebalancing
|
||
{
|
||
if (rebalance) {
|
||
subject.root = binnode_rebalance(subject.root);
|
||
}
|
||
}
|
||
}
|
||
structures.bintree_insert = bintree_insert;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function bintree_search(compare, subject, data, relation = undefined) {
|
||
const binnodes = ((binnode_isdef(subject.root))
|
||
? binnode_search(compare, subject.root, data, relation)
|
||
: []);
|
||
return binnodes.map(binnode => binnode.data);
|
||
}
|
||
structures.bintree_search = bintree_search;
|
||
/**
|
||
* @author fenris
|
||
* @deprecated only used for AVL-Tree-Index atm.
|
||
*/
|
||
function bintree_find(compare, subject, data) {
|
||
const binnode = ((binnode_isdef(subject.root))
|
||
? binnode_find(compare, subject.root, data)
|
||
: null);
|
||
if (binnode == null) {
|
||
const message = "not found";
|
||
throw (new Error(message));
|
||
}
|
||
else {
|
||
return binnode.data;
|
||
}
|
||
}
|
||
structures.bintree_find = bintree_find;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function bintree_traverse(subject) {
|
||
return ((binnode_isdef(subject.root))
|
||
? binnode_traverse(subject.root)
|
||
: []);
|
||
}
|
||
structures.bintree_traverse = bintree_traverse;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function bintree_show(show_data, subject) {
|
||
return ((binnode_isdef(subject.root))
|
||
? binnode_show(show_data, subject.root)
|
||
: "--");
|
||
}
|
||
structures.bintree_show = bintree_show;
|
||
/**
|
||
* @author fenris
|
||
* @todo tidy up or remove
|
||
*/
|
||
function binnode_gather(subject, result = { "nodes": [], "edges": [], "lastid": 0 }) {
|
||
result.lastid += 1;
|
||
const node = { "id": result.lastid, "subject": subject };
|
||
result.nodes.push(node);
|
||
if (binnode_isdef(subject.left)) {
|
||
// result.lastid += 1;
|
||
const node_ = { "id": result.lastid + 1, "subject": subject.left };
|
||
result.edges.push({ "from": node, "to": node_ });
|
||
result = binnode_gather(subject.left, result);
|
||
}
|
||
if (binnode_isdef(subject.right)) {
|
||
// result.lastid += 1;
|
||
const node_ = { "id": result.lastid + 1, "subject": subject.right };
|
||
result.edges.push({ "from": node, "to": node_ });
|
||
result = binnode_gather(subject.right, result);
|
||
}
|
||
return result;
|
||
}
|
||
/**
|
||
* @author fenris
|
||
* @todo tidy up or remove
|
||
*/
|
||
function bintree_to_graph(subject) {
|
||
const gathering = binnode_gather(subject.root);
|
||
const graph = new structures.class_graph((x, y) => (x.data == y.data), gathering.nodes, gathering.edges);
|
||
return graph;
|
||
}
|
||
structures.bintree_to_graph = bintree_to_graph;
|
||
})(structures = lib_plankton.structures || (lib_plankton.structures = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:structures«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:structures« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:structures« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:structures«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var structures;
|
||
(function (structures) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class class_bintree {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
constructor(compare = instance_compare) {
|
||
this.subject = structures.bintree_construct();
|
||
this.compare = compare;
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
depth() {
|
||
return structures.bintree_depth(this.subject);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
insert(data, rebalance = true) {
|
||
return structures.bintree_insert(this.compare, this.subject, data, rebalance);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
delete(data) {
|
||
let message = "not implemented";
|
||
throw (new Error(message));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
search(relation, data) {
|
||
return structures.bintree_search(this.compare, this.subject, data, relation);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
traverse() {
|
||
return structures.bintree_traverse(this.subject);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
show() {
|
||
return structures.bintree_show(instance_show /*<type_data>*/, this.subject);
|
||
}
|
||
}
|
||
structures.class_bintree = class_bintree;
|
||
})(structures = lib_plankton.structures || (lib_plankton.structures = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:json«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:json« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:json« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:json«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var json;
|
||
(function (json) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function encode(source, options = {}) {
|
||
options = Object.assign({
|
||
"formatted": false,
|
||
}, options);
|
||
return JSON.stringify(source, undefined, (options.formatted ? "\t" : undefined));
|
||
}
|
||
json.encode = encode;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function decode(target) {
|
||
return JSON.parse(target);
|
||
}
|
||
json.decode = decode;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function implementation_code() {
|
||
return {
|
||
"encode": x => encode(x),
|
||
"decode": decode,
|
||
};
|
||
}
|
||
json.implementation_code = implementation_code;
|
||
})(json = lib_plankton.json || (lib_plankton.json = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:json«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:json« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:json« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:json«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var json;
|
||
(function (json) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class class_json {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
constructor() {
|
||
}
|
||
/**
|
||
* @implementation
|
||
* @author fenris
|
||
*/
|
||
encode(x) {
|
||
return json.encode(x);
|
||
}
|
||
/**
|
||
* @implementation
|
||
* @author fenris
|
||
*/
|
||
decode(x) {
|
||
return json.decode(x);
|
||
}
|
||
}
|
||
json.class_json = class_json;
|
||
})(json = lib_plankton.json || (lib_plankton.json = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:date«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:date« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:date« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:date«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_et;
|
||
(function (lib_et) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function div(x, y) {
|
||
return Math.floor(x / y);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function mod(x, y) {
|
||
return (x - (y * div(x, y)));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function json_encode(obj) {
|
||
return JSON.stringify(obj);
|
||
}
|
||
/**
|
||
* @desc the maximum of a regular UNIX-timestamp: 2^31-1; one second is cut
|
||
* @author fenris
|
||
*/
|
||
const _modulus = 0x7FFFFFFF;
|
||
/**
|
||
* @desc add (e1,s1) (e2,s2) = (e1+e2+((s1+s2) div m),(s1+s2) mod m)
|
||
* @author fenris
|
||
*/
|
||
function add(et1, et2) {
|
||
let era = (et1.era + et2.era + div(et1.stamp + et2.stamp, _modulus));
|
||
let stamp = mod(et1.stamp + et2.stamp, _modulus);
|
||
return { "era": era, "stamp": stamp };
|
||
}
|
||
/**
|
||
* @desc neutral = (0,0)
|
||
*/
|
||
function neutral() {
|
||
return { "era": 0, "stamp": 0 };
|
||
}
|
||
/**
|
||
* @desc invert (e,s) = (-1-e,m-s)
|
||
*/
|
||
function invert(et) {
|
||
let era = (-1 - et.era);
|
||
let stamp = (_modulus - et.stamp);
|
||
return { "era": era, "stamp": stamp };
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function part(et1, et2) {
|
||
return add(et1, invert(et2));
|
||
}
|
||
lib_et.part = part;
|
||
/**
|
||
* @desc less
|
||
* @author fenris
|
||
*/
|
||
function before(reference, et) {
|
||
let et_ = part(et, reference);
|
||
return ((et_.era >= 0) && (et_.stamp > 0));
|
||
}
|
||
lib_et.before = before;
|
||
/**
|
||
* @desc greater
|
||
* @author fenris
|
||
*/
|
||
function after(reference, et) {
|
||
let et_ = part(reference, et);
|
||
return ((et_.era >= 0) && (et_.stamp > 0));
|
||
}
|
||
lib_et.after = after;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function between(begin, end, et) {
|
||
return (before(begin, et)
|
||
&&
|
||
after(end, et));
|
||
}
|
||
lib_et.between = between;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function intersect(begin1, end1, begin2, end2) {
|
||
return ((between(begin1, end1, begin2)
|
||
||
|
||
between(begin1, end1, end2))
|
||
||
|
||
(between(begin2, end2, begin1)
|
||
||
|
||
between(begin2, end2, end1)));
|
||
}
|
||
lib_et.intersect = intersect;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function move(base, span) {
|
||
return add(base, span);
|
||
}
|
||
lib_et.move = move;
|
||
/**
|
||
* @desc currified version of "move"
|
||
* @author fenris
|
||
*/
|
||
function move_(span) {
|
||
return (base => move(base, span));
|
||
}
|
||
lib_et.move_ = move_;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function from_timestamp(timestamp) {
|
||
let era = div(timestamp, _modulus);
|
||
let stamp = mod(timestamp, _modulus);
|
||
let et = { "era": era, "stamp": stamp };
|
||
return et;
|
||
}
|
||
lib_et.from_timestamp = from_timestamp;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function to_timestamp(et) {
|
||
if (et.era != 0) {
|
||
const message = "case (era <> 0) not properly implemented";
|
||
console.warn(message + "; well ... i'll do my very best ...");
|
||
// throw (new Error(message));
|
||
}
|
||
let timestamp = ((et.era * _modulus) + et.stamp);
|
||
return timestamp;
|
||
}
|
||
lib_et.to_timestamp = to_timestamp;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function from_jsdate(jsdate) {
|
||
const timestamp = Math.floor(jsdate.getTime() / 1000);
|
||
const et = from_timestamp(timestamp);
|
||
return et;
|
||
}
|
||
lib_et.from_jsdate = from_jsdate;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function to_jsdate(et) {
|
||
const timestamp = to_timestamp(et);
|
||
const jsdate = (new Date(timestamp * 1000));
|
||
return jsdate;
|
||
}
|
||
lib_et.to_jsdate = to_jsdate;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function from_components(components) {
|
||
const timestamp = Math.floor(Date.UTC((components.year), (components.month - 1), (components.day), (components.hour || 0), (components.minute || 0), (components.second || 0))
|
||
/
|
||
1000);
|
||
const et = from_timestamp(timestamp);
|
||
return et;
|
||
}
|
||
lib_et.from_components = from_components;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function to_components(et) {
|
||
const jsdate = to_jsdate(et);
|
||
const components = {
|
||
"year": jsdate.getUTCFullYear(),
|
||
"month": jsdate.getUTCMonth() + 1,
|
||
"day": jsdate.getUTCDate(),
|
||
"hour": jsdate.getUTCHours(),
|
||
"minute": jsdate.getUTCMinutes(),
|
||
"second": jsdate.getUTCSeconds(),
|
||
};
|
||
return components;
|
||
}
|
||
lib_et.to_components = to_components;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function now() {
|
||
let timestamp = Math.floor(Date.now() / 1000);
|
||
let et = from_timestamp(timestamp);
|
||
return et;
|
||
}
|
||
lib_et.now = now;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function to_string(et) {
|
||
// return (json_encode(et) + " ~ " + json_encode(to_components(et)));
|
||
return to_jsdate(et).toUTCString();
|
||
}
|
||
lib_et.to_string = to_string;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function to_string_ywd(et) {
|
||
// return (json_encode(et) + " ~ " + json_encode(to_components(et)));
|
||
return to_jsdate(et).toUTCString();
|
||
}
|
||
lib_et.to_string_ywd = to_string_ywd;
|
||
/**
|
||
* @desc retrieve week of year
|
||
* @author fenris
|
||
*/
|
||
function get_woy(et) {
|
||
let jsdate = to_jsdate(et);
|
||
let begin_of_year = new Date(jsdate.getFullYear(), 0, 1, 12, 0, 0);
|
||
let day_of_week = begin_of_year.getDay();
|
||
let overhang = (day_of_week >= 4);
|
||
let factor = (1000 * 60 * 60 * 24);
|
||
let days = ((jsdate.getTime() - begin_of_year.getTime()) / factor);
|
||
let week = (Math.ceil((days + day_of_week) / 7) - (overhang ? 1 : 0));
|
||
return week;
|
||
}
|
||
lib_et.get_woy = get_woy;
|
||
/**
|
||
* @desc retrieve day of week
|
||
* @author fenris
|
||
*/
|
||
function get_dow(et) {
|
||
let jsdate = to_jsdate(et);
|
||
let dow = (mod(jsdate.getDay() - 1, 7) + 1);
|
||
return dow;
|
||
}
|
||
lib_et.get_dow = get_dow;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function trunc_minute(et = now()) {
|
||
let components = to_components(et);
|
||
let components_ = {
|
||
"year": components.year,
|
||
"month": components.month,
|
||
"day": components.day,
|
||
"hour": components.hour,
|
||
"minute": components.minute,
|
||
"second": 0
|
||
};
|
||
let et_ = from_components(components_);
|
||
return et_;
|
||
}
|
||
lib_et.trunc_minute = trunc_minute;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function trunc_hour(et = now()) {
|
||
let components = to_components(et);
|
||
let components_ = {
|
||
"year": components.year,
|
||
"month": components.month,
|
||
"day": components.day,
|
||
"hour": components.hour,
|
||
"minute": 0,
|
||
"second": 0
|
||
};
|
||
let et_ = from_components(components_);
|
||
return et_;
|
||
}
|
||
lib_et.trunc_hour = trunc_hour;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function trunc_day(et = now()) {
|
||
let components = to_components(et);
|
||
let components_ = {
|
||
"year": components.year,
|
||
"month": components.month,
|
||
"day": components.day,
|
||
"hour": 0,
|
||
"minute": 0,
|
||
"second": 0
|
||
};
|
||
let et_ = from_components(components_);
|
||
return et_;
|
||
}
|
||
lib_et.trunc_day = trunc_day;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function trunc_month(et = now()) {
|
||
let components = to_components(et);
|
||
let components_ = {
|
||
"year": components.year,
|
||
"month": components.month,
|
||
"day": 0,
|
||
"hour": 0,
|
||
"minute": 0,
|
||
"second": 0
|
||
};
|
||
let et_ = from_components(components_);
|
||
return et_;
|
||
}
|
||
lib_et.trunc_month = trunc_month;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function trunc_year(et = now()) {
|
||
let components = to_components(et);
|
||
let components_ = {
|
||
"year": components.year,
|
||
"month": 0,
|
||
"day": 0,
|
||
"hour": 0,
|
||
"minute": 0,
|
||
"second": 0
|
||
};
|
||
let et_ = from_components(components_);
|
||
return et_;
|
||
}
|
||
lib_et.trunc_year = trunc_year;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function trunc_week(et = now()) {
|
||
let et_ = trunc_day(et);
|
||
while (to_jsdate(et_).getDay() > 1) {
|
||
et_ = add(et_, span_day(-1));
|
||
}
|
||
return et_;
|
||
}
|
||
lib_et.trunc_week = trunc_week;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function span_second(seconds = 1) {
|
||
return from_timestamp(seconds);
|
||
}
|
||
lib_et.span_second = span_second;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function span_minute(minutes = 1) {
|
||
return span_second(minutes * 60);
|
||
}
|
||
lib_et.span_minute = span_minute;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function span_hour(hours = 1) {
|
||
return span_minute(hours * 60);
|
||
}
|
||
lib_et.span_hour = span_hour;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function span_day(days = 1) {
|
||
return span_hour(days * 24);
|
||
}
|
||
lib_et.span_day = span_day;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function span_week(weeks = 1) {
|
||
return span_day(weeks * 7);
|
||
}
|
||
lib_et.span_week = span_week;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function span_year(years = 1) {
|
||
return span_second(Math.floor(years * 365.25 * 24 * 60 * 60));
|
||
}
|
||
lib_et.span_year = span_year;
|
||
})(lib_et || (lib_et = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:date«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:date« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:date« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:date«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_et;
|
||
(function (lib_et) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class class_et {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
constructor(subject) {
|
||
this.subject = subject;
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
move(et) {
|
||
return (new class_et(lib_et.move(this.subject, et.subject)));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
before(et) {
|
||
return lib_et.before(et.subject, this.subject);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
after(et) {
|
||
return lib_et.after(et.subject, this.subject);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
between(et1, et2) {
|
||
return lib_et.between(et1.subject, et2.subject, this.subject);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
trunc_minute() {
|
||
return (new class_et(lib_et.trunc_minute(this.subject)));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
trunc_hour() {
|
||
return (new class_et(lib_et.trunc_hour(this.subject)));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
trunc_day() {
|
||
return (new class_et(lib_et.trunc_day(this.subject)));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
trunc_month() {
|
||
return (new class_et(lib_et.trunc_month(this.subject)));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
trunc_year() {
|
||
return (new class_et(lib_et.trunc_year(this.subject)));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
trunc_week() {
|
||
return (new class_et(lib_et.trunc_week(this.subject)));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
static now() {
|
||
return (new class_et(lib_et.now()));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
static span_second(count = 1) {
|
||
return (new class_et(lib_et.span_second(count)));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
static span_minute(count = 1) {
|
||
return (new class_et(lib_et.span_minute(count)));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
static span_hour(count = 1) {
|
||
return (new class_et(lib_et.span_hour(count)));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
static span_day(count = 1) {
|
||
return (new class_et(lib_et.span_day(count)));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
static span_week(count = 1) {
|
||
return (new class_et(lib_et.span_week(count)));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
static span_year(count = 1) {
|
||
return (new class_et(lib_et.span_year(count)));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
static from_timestamp(timestamp) {
|
||
return (new class_et(lib_et.from_timestamp(timestamp)));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
to_timestamp() {
|
||
return lib_et.to_timestamp(this.subject);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
static from_jsdate(jsdate) {
|
||
return (new class_et(lib_et.from_jsdate(jsdate)));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
to_jsdate() {
|
||
return lib_et.to_jsdate(this.subject);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
static from_components(components) {
|
||
return (new class_et(lib_et.from_components(components)));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
to_components() {
|
||
return lib_et.to_components(this.subject);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
get_woy() {
|
||
return lib_et.get_woy(this.subject);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
get_dow() {
|
||
return lib_et.get_dow(this.subject);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
to_string() {
|
||
return lib_et.to_string(this.subject);
|
||
}
|
||
}
|
||
lib_et.class_et = class_et;
|
||
})(lib_et || (lib_et = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:date«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:date« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:date« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:date«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
/**
|
||
* @author neuc
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var date;
|
||
(function (date_1) {
|
||
/**
|
||
* @author neu3no, fenris
|
||
*/
|
||
var _days = [
|
||
"Sunday",
|
||
"Monday",
|
||
"Tuesday",
|
||
"Wednesday",
|
||
"Thursday",
|
||
"Friday",
|
||
"Saturday"
|
||
];
|
||
/**
|
||
* @author neu3no, fenris
|
||
*/
|
||
var _months = [
|
||
"January",
|
||
"February",
|
||
"March",
|
||
"April",
|
||
"May",
|
||
"June",
|
||
"July",
|
||
"August",
|
||
"September",
|
||
"October",
|
||
"November",
|
||
"December"
|
||
];
|
||
/**
|
||
* @author neu3no, fenris
|
||
*/
|
||
var _segments = {
|
||
"%a": (date => _days[date.getDay()].slice(0, 3)),
|
||
"%A": (date => _days[date.getDay()]),
|
||
"%b": (date => _days[date.getMonth()].slice(0, 3)),
|
||
"%B": (date => _days[date.getMonth()]),
|
||
"%c": (date => date.toLocaleString()),
|
||
"%C": (date => Math.floor((date.getFullYear()) / 100).toString()),
|
||
"%d": (date => lib_plankton.string.sprintf("%02d", [date.getDate()])),
|
||
"%D": (date => parse("%m/%d/%y", date)),
|
||
"%e": (date => lib_plankton.string.sprintf("%2d", [date.getDate()])),
|
||
"%F": (date => parse("%Y-%m-%d", date)),
|
||
"%g": (date => lib_plankton.string.sprintf("%02d", [date.getFullYear() % 1000])),
|
||
"%G": (date => date.getFullYear().toString()),
|
||
"%h": (date => parse("%b", date)),
|
||
"%H": (date => lib_plankton.string.sprintf("%02d", [date.getHours()])),
|
||
"%I": (date => lib_plankton.string.sprintf("%02d", [((date.getHours() > 12) ? (date.getHours() - 12) : date.getHours())])),
|
||
"%j": (date => lib_plankton.string.sprintf("%03d", [helper_dayOfYear(date)])),
|
||
"%m": (date => lib_plankton.string.sprintf("%02d", [date.getMonth() + 1])),
|
||
"%M": (date => lib_plankton.string.sprintf("%02d", [date.getMinutes()])),
|
||
"%n": (date => "\n"),
|
||
"%p": (date => ((date.getHours() > 12) ? "PM" : "AM")),
|
||
"%r": (date => parse("%I:%M:%S %p", date)),
|
||
"%R": (date => parse("%H:%M", date)),
|
||
"%S": (date => date.getSeconds().toString()),
|
||
"%t": (date => "\t"),
|
||
"%T": (date => parse("%H:%M:%S", date)),
|
||
"%u": (date => lib_plankton.string.sprintf("%02d", [((date.getDay() === 0) ? 7 : date.getDay())])),
|
||
"%U": (date => lib_plankton.string.sprintf("%02d", [helper_englishWeekOfYear(date)])),
|
||
"%V": (date => lib_plankton.string.sprintf("%02d", [helper_weekOfYear(date)])),
|
||
"%w": (date => lib_plankton.string.sprintf("%02d", [date.getDay().toString()])),
|
||
"%W": (date => parse("%w", date)),
|
||
"%x": (date => parse("%m/%d/%G", date)),
|
||
"%X": (date => parse("%T", date)),
|
||
"%y": (date => parse("%g", date)),
|
||
"%Y": (date => parse("%G", date)),
|
||
"%z": (date => date.getTimezoneOffset().toString()),
|
||
"%Z": (date => date.toUTCString().split(' ').pop()),
|
||
"%%": (date => "%"),
|
||
};
|
||
/**
|
||
* @author neu3no, fenris
|
||
*/
|
||
var _currentDate = (new Date(Date.now()));
|
||
/**
|
||
* @author neu3no, fenris
|
||
*/
|
||
function set_days(day_names) {
|
||
_days = day_names;
|
||
}
|
||
date_1.set_days = set_days;
|
||
/**
|
||
* @author neu3no, fenris
|
||
*/
|
||
function set_months(month_names) {
|
||
_months = month_names;
|
||
}
|
||
date_1.set_months = set_months;
|
||
/**
|
||
* @desc source: https://stackoverflow.com/questions/8619879/javascript-calculate-the-day-of-the-year-1-366
|
||
* @author neu3no, fenris
|
||
*/
|
||
function helper_dayOfYear(date) {
|
||
let start = new Date(date.getFullYear(), 0, 0);
|
||
let diff = (date.getTime() - start.getTime());
|
||
let oneDay = (1000 * 60 * 60 * 24);
|
||
return Math.floor(diff / oneDay);
|
||
}
|
||
/**
|
||
* @desc source: http://weeknumber.net/how-to/javascript
|
||
* @author neu3no, fenris
|
||
*/
|
||
function helper_weekOfYear(date_) {
|
||
let date = new Date(date_.getTime());
|
||
date.setHours(0, 0, 0, 0);
|
||
// Thursday in current week decides the year.
|
||
date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7);
|
||
// January 4 is always in week 1.
|
||
let week1 = new Date(date.getFullYear(), 0, 4);
|
||
// Adjust to Thursday in week 1 and count number of weeks from date to week1.
|
||
return (1
|
||
+
|
||
Math.round((((date.getTime() - week1.getTime()) / 86400000)
|
||
-
|
||
3
|
||
+
|
||
(week1.getDay() + 6) % 7)
|
||
/
|
||
7));
|
||
}
|
||
/**
|
||
* @author neu3no, fenris
|
||
*/
|
||
function helper_englishWeekOfYear(date) {
|
||
let nr = helper_weekOfYear(date);
|
||
if (date.getDay() === 0) {
|
||
nr = nr - 1;
|
||
}
|
||
return nr;
|
||
}
|
||
/**
|
||
* @desc week of year
|
||
* @param {Date} date
|
||
* @return {int}
|
||
* @author fenris
|
||
*/
|
||
function get_week(date) {
|
||
let begin_of_year = new Date(date.getFullYear(), 0, 1, 12, 0, 0);
|
||
let day_of_week = begin_of_year.getDay();
|
||
let overhang = (day_of_week >= 4);
|
||
let factor = (1000 * 60 * 60 * 24);
|
||
let days = ((date.getTime() - begin_of_year.getTime()) / factor);
|
||
let week = (Math.ceil((days + day_of_week) / 7) - (overhang ? 1 : 0));
|
||
return week;
|
||
}
|
||
date_1.get_week = get_week;
|
||
/**
|
||
* @author neu3no, fenris
|
||
*/
|
||
function set_currentDate(date) {
|
||
_currentDate = date;
|
||
}
|
||
date_1.set_currentDate = set_currentDate;
|
||
/**
|
||
* @author neu3no, fenris
|
||
*/
|
||
function parse(format, date = _currentDate) {
|
||
let ret = format;
|
||
let re = new RegExp("%[a-z]", "gi");
|
||
let match;
|
||
while (match = re.exec(format)) {
|
||
ret = ret.replace(match[0], parse_segment(match[0], date));
|
||
}
|
||
return ret;
|
||
}
|
||
date_1.parse = parse;
|
||
/**
|
||
* @author neu3no, fenris
|
||
*/
|
||
function parse_segment(segment, date = _currentDate) {
|
||
if (!(segment in _segments)) {
|
||
let message = ("unknown format argument '" + segment + "'");
|
||
throw (new Error(message));
|
||
}
|
||
else {
|
||
return _segments[segment](date);
|
||
}
|
||
}
|
||
/**
|
||
* @author neu3no, fenris
|
||
*/
|
||
function locale_date(date = new Date(), ignore_error = false) {
|
||
if (!(date instanceof Date)) {
|
||
if (!ignore_error) {
|
||
throw new SyntaxError("date must be instance of Date");
|
||
}
|
||
else {
|
||
console.warn("'" + date + "' seems not to be instance of Date; try to force convert.");
|
||
let tmp = date;
|
||
date = new Date(tmp);
|
||
if ((date.toString() === "Invalid Date")
|
||
||
|
||
(!(date < new Date(0)) && !(date > new Date(0)))) {
|
||
console.warn("conversion didn't work, returning default value");
|
||
return "Ø";
|
||
}
|
||
}
|
||
}
|
||
let conf = (
|
||
/*
|
||
global_config.get_value("date")
|
||
||
|
||
*/
|
||
{
|
||
"use_locale_date": true,
|
||
"format_string": "%d.%m.%Y"
|
||
});
|
||
if (conf.use_locale_date) {
|
||
return date.toLocaleDateString();
|
||
}
|
||
else {
|
||
return strftime.parse(conf.format_string, date);
|
||
}
|
||
}
|
||
date_1.locale_date = locale_date;
|
||
/**
|
||
*/
|
||
function now() {
|
||
return Math.floor(Date.now() / 1000);
|
||
}
|
||
date_1.now = now;
|
||
/**
|
||
*/
|
||
function from_components(components) {
|
||
return Math.floor(new Date(Date.parse(lib_string.coin("{{year}}-{{month}}-{{day}}T{{hour}}:{{minute}}:{{second}}.{{milliseconds}}{{timezone_offset}}", {
|
||
"year": components.year.toFixed(0).padStart(4, "0"),
|
||
"month": components.month.toFixed(0).padStart(2, "0"),
|
||
"day": components.day.toFixed(0).padStart(2, "0"),
|
||
"hour": components.hour.toFixed(0).padStart(2, "0"),
|
||
"minute": components.minute.toFixed(0).padStart(2, "0"),
|
||
"second": components.second.toFixed(0).padStart(2, "0"),
|
||
"milliseconds": (0).toFixed(0).padStart(3, "0"),
|
||
"timezone_offset": lib_string.coin("{{sign}}{{amount}}:00", {
|
||
"sign": ((components.timezone_offset < 0) ? "-" : "+"),
|
||
"amount": Math.abs(components.timezone_offset).toFixed(0).padStart(2, "0"),
|
||
}),
|
||
}))).getTime()
|
||
/
|
||
1000);
|
||
}
|
||
date_1.from_components = from_components;
|
||
/**
|
||
*/
|
||
function to_components(unixtimestamp) {
|
||
const date_object = new Date(unixtimestamp * 1000);
|
||
const date_string = date_object.toISOString();
|
||
return {
|
||
"timezone_offset": 0,
|
||
"year": parseInt(date_string.slice(0, 4)),
|
||
"month": parseInt(date_string.slice(5, 7)),
|
||
"day": parseInt(date_string.slice(8, 10)),
|
||
"hour": parseInt(date_string.slice(11, 13)),
|
||
"minute": parseInt(date_string.slice(14, 16)),
|
||
"second": parseInt(date_string.slice(17, 19)),
|
||
};
|
||
}
|
||
date_1.to_components = to_components;
|
||
/**
|
||
*/
|
||
function get_timestamp_from_year_and_week_and_day(year, week, day) {
|
||
const d = (1 + ((week - 1) * 7));
|
||
const date_raw = new Date(year, 0, d);
|
||
return (Math.round(date_raw.getTime() / 1000)
|
||
+
|
||
(60 * 60 * 24 * (day - date_raw.getDay() + 1)));
|
||
}
|
||
date_1.get_timestamp_from_year_and_week_and_day = get_timestamp_from_year_and_week_and_day;
|
||
})(date = lib_plankton.date || (lib_plankton.date = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
var strftime = lib_plankton.date;
|
||
/*
|
||
This file is part of »bacterio-plankton:ical«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:ical« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:ical« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:ical«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var ical;
|
||
(function (ical) {
|
||
/**
|
||
*/
|
||
// type type_timestamp = string;
|
||
/**
|
||
*/
|
||
let enum_class;
|
||
(function (enum_class) {
|
||
enum_class["public"] = "public";
|
||
enum_class["private"] = "private";
|
||
enum_class["confidential"] = "confidential";
|
||
})(enum_class = ical.enum_class || (ical.enum_class = {}));
|
||
;
|
||
/**
|
||
*/
|
||
let enum_event_status;
|
||
(function (enum_event_status) {
|
||
enum_event_status["tentative"] = "tentative";
|
||
enum_event_status["confirmed"] = "confirmed";
|
||
enum_event_status["cancelled"] = "cancelled";
|
||
})(enum_event_status = ical.enum_event_status || (ical.enum_event_status = {}));
|
||
;
|
||
/**
|
||
*/
|
||
let enum_transp;
|
||
(function (enum_transp) {
|
||
enum_transp["opaque"] = "opaque";
|
||
enum_transp["transparent"] = "transparent";
|
||
})(enum_transp = ical.enum_transp || (ical.enum_transp = {}));
|
||
;
|
||
})(ical = lib_plankton.ical || (lib_plankton.ical = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:ical«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:ical« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:ical« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:ical«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var ical;
|
||
(function (ical) {
|
||
/**
|
||
*/
|
||
function date_decode(date_encoded) {
|
||
return {
|
||
"year": parseInt(date_encoded.slice(0, 4)),
|
||
"month": parseInt(date_encoded.slice(4, 6)),
|
||
"day": parseInt(date_encoded.slice(6, 8)),
|
||
};
|
||
}
|
||
/**
|
||
*/
|
||
function time_decode(time_encoded) {
|
||
return {
|
||
"hour": parseInt(time_encoded.slice(0, 2)),
|
||
"minute": parseInt(time_encoded.slice(2, 4)),
|
||
"second": parseInt(time_encoded.slice(4, 6)),
|
||
"utc": ((time_encoded.length >= 7) && (time_encoded[6] === "Z"))
|
||
};
|
||
}
|
||
/**
|
||
*/
|
||
function datetime_decode(datetime_encoded) {
|
||
const parts = datetime_encoded.split("T", 2);
|
||
return {
|
||
"date": date_decode(parts[0]),
|
||
"time": ((parts.length >= 2) ? time_decode(parts[1]) : null),
|
||
};
|
||
}
|
||
/**
|
||
*/
|
||
let enum_decode_state_label;
|
||
(function (enum_decode_state_label) {
|
||
enum_decode_state_label["expect_vcalendar_begin"] = "expect_vcalendar_begin";
|
||
enum_decode_state_label["expect_vcalendar_property"] = "expect_vcalendar_property";
|
||
enum_decode_state_label["expect_vevent_property"] = "expect_vevent_property";
|
||
enum_decode_state_label["done"] = "done";
|
||
})(enum_decode_state_label || (enum_decode_state_label = {}));
|
||
;
|
||
/**
|
||
*/
|
||
function class_encode(class_) {
|
||
switch (class_) {
|
||
case ical.enum_class.private: {
|
||
return "PRIVATE";
|
||
break;
|
||
}
|
||
case ical.enum_class.public: {
|
||
return "PUBLIC";
|
||
break;
|
||
}
|
||
case ical.enum_class.confidential: {
|
||
return "CONFIDENTIAL";
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
*/
|
||
function class_decode(class_encoded) {
|
||
return {
|
||
"PRIVATE": ical.enum_class.private,
|
||
"PUBLIC": ical.enum_class.public,
|
||
"CONFIDENTIAL": ical.enum_class.confidential,
|
||
}[class_encoded];
|
||
}
|
||
/**
|
||
*/
|
||
function event_status_encode(event_status) {
|
||
switch (event_status) {
|
||
case ical.enum_event_status.tentative: {
|
||
return "TENTATIVE";
|
||
break;
|
||
}
|
||
case ical.enum_event_status.confirmed: {
|
||
return "CONFIRMED";
|
||
break;
|
||
}
|
||
case ical.enum_event_status.cancelled: {
|
||
return "CANCELLED";
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
*/
|
||
function event_status_decode(event_status_encoded) {
|
||
return {
|
||
"TENTATIVE": ical.enum_event_status.tentative,
|
||
"CONFIRMED": ical.enum_event_status.confirmed,
|
||
"CANCELLED": ical.enum_event_status.cancelled,
|
||
}[event_status_encoded];
|
||
}
|
||
/**
|
||
*/
|
||
function transp_encode(transp) {
|
||
switch (transp) {
|
||
case ical.enum_transp.opaque: {
|
||
return "OPAQUE";
|
||
break;
|
||
}
|
||
case ical.enum_transp.transparent: {
|
||
return "TRANSPARENT";
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
*/
|
||
function transp_decode(transp_encoded) {
|
||
return {
|
||
"OPAQUE": ical.enum_transp.opaque,
|
||
"TRANSPARENT": ical.enum_transp.transparent,
|
||
}[transp_encoded];
|
||
}
|
||
/**
|
||
*/
|
||
function datetime_to_unixtimestamp(datetime) {
|
||
if ((datetime.time !== null) && (!datetime.time.utc)) {
|
||
throw (new Error("can not convert not utc time values"));
|
||
}
|
||
else {
|
||
return lib_plankton.date.from_components({
|
||
"timezone_offset": 0,
|
||
"year": datetime.date.year,
|
||
"month": datetime.date.month,
|
||
"day": datetime.date.day,
|
||
"hour": ((datetime.time === null) ? 0 : datetime.time.hour),
|
||
"minute": ((datetime.time === null) ? 0 : datetime.time.minute),
|
||
"second": ((datetime.time === null) ? 0 : datetime.time.second),
|
||
});
|
||
}
|
||
}
|
||
ical.datetime_to_unixtimestamp = datetime_to_unixtimestamp;
|
||
/**
|
||
* @see https://www.rfc-editor.org/rfc/rfc5545
|
||
* @see https://icalendar.org/iCalendar-RFC-5545/
|
||
* @todo implement edge cases
|
||
*/
|
||
function ics_decode(ics, options = {}) {
|
||
options = Object.assign({
|
||
"debug": false,
|
||
}, options);
|
||
// preprocessing
|
||
const lines = ics.split("\r\n");
|
||
let content_lines = [];
|
||
let content_line_buffer = null;
|
||
lines.forEach(line => {
|
||
if (line.trim() === "") {
|
||
// do nothing
|
||
}
|
||
else {
|
||
const is_folding = ((line.length >= 2)
|
||
&&
|
||
((line[0] === " ")
|
||
||
|
||
(line[0] === "\t"))
|
||
/*
|
||
&&
|
||
! (
|
||
(line[1] === " ")
|
||
||
|
||
(line[1] === "\t")
|
||
)
|
||
*/
|
||
);
|
||
if (is_folding) {
|
||
content_line_buffer += line.slice(1);
|
||
}
|
||
else {
|
||
if (content_line_buffer === null) {
|
||
// do nothing
|
||
}
|
||
else {
|
||
content_lines.push(content_line_buffer);
|
||
}
|
||
content_line_buffer = line;
|
||
}
|
||
}
|
||
});
|
||
const instructions = content_lines.map((content_line) => {
|
||
const parts = content_line.split(":");
|
||
const parts_left = parts[0].split(";");
|
||
return {
|
||
"command": parts_left[0],
|
||
"parameters": Object.fromEntries(parts_left.slice(1).map(x => x.split("=", 2))),
|
||
"value": (parts.slice(1).join(":")
|
||
.split(";")
|
||
.map(x => x.replace(new RegExp("\\\\,", "g"), ","))),
|
||
};
|
||
});
|
||
// core
|
||
let state = {
|
||
"label": enum_decode_state_label.expect_vcalendar_begin,
|
||
"vcalendar": null,
|
||
"vevent": null,
|
||
};
|
||
instructions.forEach((instruction) => {
|
||
if (options.debug) {
|
||
console.info(JSON.stringify({ "instruction": instruction, "state": state }, undefined, "\t"));
|
||
}
|
||
switch (state.label) {
|
||
default: {
|
||
throw (new Error("unhandled state label: " + state.label));
|
||
break;
|
||
}
|
||
case enum_decode_state_label.expect_vcalendar_begin: {
|
||
switch (instruction.command) {
|
||
default: {
|
||
throw (new Error("unexpected instruction key: " + instruction.command));
|
||
break;
|
||
}
|
||
case "BEGIN": {
|
||
switch (instruction.value[0]) {
|
||
default: {
|
||
throw (new Error("unexpected instruction value: " + instruction.value[0]));
|
||
break;
|
||
}
|
||
case "VCALENDAR": {
|
||
state = {
|
||
"label": enum_decode_state_label.expect_vcalendar_property,
|
||
"vcalendar": {
|
||
"version": "",
|
||
"prodid": "",
|
||
"vevents": [],
|
||
},
|
||
"vevent": null,
|
||
};
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case enum_decode_state_label.expect_vcalendar_property: {
|
||
switch (instruction.command) {
|
||
case "VERSION": {
|
||
state = {
|
||
"label": enum_decode_state_label.expect_vcalendar_property,
|
||
"vcalendar": Object.assign(state.vcalendar, Object.fromEntries([["version", instruction.value[0]]])),
|
||
"vevent": state.vevent,
|
||
};
|
||
break;
|
||
}
|
||
case "PRODID": {
|
||
state = {
|
||
"label": enum_decode_state_label.expect_vcalendar_property,
|
||
"vcalendar": Object.assign(state.vcalendar, Object.fromEntries([["prodid", instruction.value[0]]])),
|
||
"vevent": state.vevent,
|
||
};
|
||
break;
|
||
}
|
||
case "METHOD": {
|
||
state = {
|
||
"label": enum_decode_state_label.expect_vcalendar_property,
|
||
"vcalendar": Object.assign(state.vcalendar, Object.fromEntries([["method", instruction.value[0]]])),
|
||
"vevent": state.vevent,
|
||
};
|
||
break;
|
||
}
|
||
case "BEGIN": {
|
||
const object = instruction.value[0];
|
||
switch (object) {
|
||
default: {
|
||
throw (new Error("unhandled object: " + object));
|
||
break;
|
||
}
|
||
case "VCALENDAR": {
|
||
throw (new Error("unexpected object: " + object));
|
||
break;
|
||
}
|
||
case "VEVENT": {
|
||
state = {
|
||
"label": enum_decode_state_label.expect_vevent_property,
|
||
"vcalendar": state.vcalendar,
|
||
"vevent": {
|
||
"uid": "",
|
||
"dtstamp": {
|
||
"date": { "year": 2000, "month": 0, "day": 0 },
|
||
"time": { "hour": 0, "minute": 0, "second": 0, "utc": true },
|
||
},
|
||
},
|
||
};
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case "END": {
|
||
const object = instruction.value[0];
|
||
switch (object) {
|
||
default: {
|
||
throw (new Error("unhandled object: " + object));
|
||
break;
|
||
}
|
||
case "VCALENDAR": {
|
||
state = {
|
||
"label": enum_decode_state_label.done,
|
||
"vcalendar": state.vcalendar,
|
||
"vevent": state.vevent,
|
||
};
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
default: {
|
||
if (instruction.command.startsWith("X-")) {
|
||
const key = instruction.command.slice(2).toLowerCase();
|
||
const value = instruction.value.join(";");
|
||
state = {
|
||
"label": enum_decode_state_label.expect_vcalendar_property,
|
||
"vcalendar": Object.assign(state.vcalendar, {
|
||
"x_props": Object.assign((state.vcalendar.x_props ?? {}), Object.fromEntries([[key, value]]))
|
||
}),
|
||
"vevent": state.vevent,
|
||
};
|
||
}
|
||
else {
|
||
console.info({ "instruction": instruction, "state": state });
|
||
throw (new Error("unhandled instruction key: " + instruction.command));
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case enum_decode_state_label.expect_vevent_property: {
|
||
switch (instruction.command) {
|
||
case "UID": {
|
||
state = {
|
||
"label": enum_decode_state_label.expect_vevent_property,
|
||
"vcalendar": state.vcalendar,
|
||
"vevent": Object.assign(state.vevent, Object.fromEntries([["uid", instruction.value[0]]])),
|
||
};
|
||
break;
|
||
}
|
||
case "DTSTART": {
|
||
state = {
|
||
"label": enum_decode_state_label.expect_vevent_property,
|
||
"vcalendar": state.vcalendar,
|
||
"vevent": Object.assign(state.vevent, Object.fromEntries([
|
||
[
|
||
"dtstart",
|
||
{
|
||
"tzid": instruction.parameters["tzid"],
|
||
"value": datetime_decode(instruction.value[0]),
|
||
}
|
||
]
|
||
])),
|
||
};
|
||
break;
|
||
}
|
||
case "DTEND": {
|
||
state = {
|
||
"label": enum_decode_state_label.expect_vevent_property,
|
||
"vcalendar": state.vcalendar,
|
||
"vevent": Object.assign(state.vevent, Object.fromEntries([
|
||
[
|
||
"dtend",
|
||
{
|
||
"tzid": instruction.parameters["tzid"],
|
||
"value": datetime_decode(instruction.value[0]),
|
||
}
|
||
]
|
||
])),
|
||
};
|
||
break;
|
||
}
|
||
case "DTSTAMP": {
|
||
state = {
|
||
"label": enum_decode_state_label.expect_vevent_property,
|
||
"vcalendar": state.vcalendar,
|
||
"vevent": Object.assign(state.vevent, Object.fromEntries([
|
||
[
|
||
"dtstamp",
|
||
datetime_decode(instruction.value[0])
|
||
]
|
||
])),
|
||
};
|
||
break;
|
||
}
|
||
case "SEQUENCE": {
|
||
state = {
|
||
"label": enum_decode_state_label.expect_vevent_property,
|
||
"vcalendar": state.vcalendar,
|
||
"vevent": Object.assign(state.vevent, Object.fromEntries([["sequence", parseInt(instruction.value[0])]])),
|
||
};
|
||
break;
|
||
}
|
||
case "TRANSP": {
|
||
state = {
|
||
"label": enum_decode_state_label.expect_vevent_property,
|
||
"vcalendar": state.vcalendar,
|
||
"vevent": Object.assign(state.vevent, Object.fromEntries([["transp", transp_decode(instruction.value[0])]])),
|
||
};
|
||
break;
|
||
}
|
||
case "SUMMARY": {
|
||
state = {
|
||
"label": enum_decode_state_label.expect_vevent_property,
|
||
"vcalendar": state.vcalendar,
|
||
"vevent": Object.assign(state.vevent, Object.fromEntries([["summary", instruction.value[0]]])),
|
||
};
|
||
break;
|
||
}
|
||
case "CLASS": {
|
||
state = {
|
||
"label": enum_decode_state_label.expect_vevent_property,
|
||
"vcalendar": state.vcalendar,
|
||
"vevent": Object.assign(state.vevent, Object.fromEntries([["class", class_decode(instruction.value[0])]])),
|
||
};
|
||
break;
|
||
}
|
||
case "STATUS": {
|
||
state = {
|
||
"label": enum_decode_state_label.expect_vevent_property,
|
||
"vcalendar": state.vcalendar,
|
||
"vevent": Object.assign(state.vevent, Object.fromEntries([["status", event_status_decode(instruction.value[0])]])),
|
||
};
|
||
break;
|
||
}
|
||
case "DESCRIPTION": {
|
||
state = {
|
||
"label": enum_decode_state_label.expect_vevent_property,
|
||
"vcalendar": state.vcalendar,
|
||
"vevent": Object.assign(state.vevent, Object.fromEntries([["description", instruction.value[0]]])),
|
||
};
|
||
break;
|
||
}
|
||
case "CATEGORIES": {
|
||
state = {
|
||
"label": enum_decode_state_label.expect_vevent_property,
|
||
"vcalendar": state.vcalendar,
|
||
"vevent": Object.assign(state.vevent, Object.fromEntries([["categories", instruction.value[0].split(",")]])),
|
||
};
|
||
break;
|
||
}
|
||
case "CREATED": {
|
||
state = {
|
||
"label": enum_decode_state_label.expect_vevent_property,
|
||
"vcalendar": state.vcalendar,
|
||
"vevent": Object.assign(state.vevent, Object.fromEntries([
|
||
[
|
||
"created",
|
||
{
|
||
"value": datetime_decode(instruction.value[0]),
|
||
}
|
||
]
|
||
])),
|
||
};
|
||
break;
|
||
}
|
||
case "LOCATION": {
|
||
state = {
|
||
"label": enum_decode_state_label.expect_vevent_property,
|
||
"vcalendar": state.vcalendar,
|
||
"vevent": Object.assign(state.vevent, Object.fromEntries([["location", instruction.value[0]]])),
|
||
};
|
||
break;
|
||
}
|
||
case "URL": {
|
||
state = {
|
||
"label": enum_decode_state_label.expect_vevent_property,
|
||
"vcalendar": state.vcalendar,
|
||
"vevent": Object.assign(state.vevent, Object.fromEntries([["url", instruction.value[0]]])),
|
||
};
|
||
break;
|
||
}
|
||
case "LAST-MODIFIED": {
|
||
state = {
|
||
"label": enum_decode_state_label.expect_vevent_property,
|
||
"vcalendar": state.vcalendar,
|
||
"vevent": Object.assign(state.vevent, Object.fromEntries([
|
||
[
|
||
"last_modified",
|
||
{
|
||
"value": datetime_decode(instruction.value[0]),
|
||
}
|
||
]
|
||
])),
|
||
};
|
||
break;
|
||
}
|
||
case "ATTENDEE": {
|
||
state = {
|
||
"label": enum_decode_state_label.expect_vevent_property,
|
||
"vcalendar": state.vcalendar,
|
||
"vevent": Object.assign(state.vevent, Object.fromEntries([["attendee", instruction.value[0]]])),
|
||
};
|
||
break;
|
||
}
|
||
case "BEGIN": {
|
||
const object = instruction.value[0];
|
||
switch (object) {
|
||
default: {
|
||
throw (new Error("unhandled object: " + object));
|
||
break;
|
||
}
|
||
case "VCALENDAR": {
|
||
throw (new Error("unexpected object: " + object));
|
||
break;
|
||
}
|
||
case "VEVENT": {
|
||
throw (new Error("unexpected object: " + object));
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case "END": {
|
||
const object = instruction.value[0];
|
||
switch (object) {
|
||
default: {
|
||
throw (new Error("unhandled value: " + object));
|
||
break;
|
||
}
|
||
case "VEVENT": {
|
||
state = {
|
||
"label": enum_decode_state_label.expect_vcalendar_property,
|
||
"vcalendar": Object.assign(state.vcalendar, {
|
||
"vevents": state.vcalendar.vevents.concat([state.vevent]),
|
||
}),
|
||
"vevent": null,
|
||
};
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
default: {
|
||
if (instruction.command.startsWith("X-")) {
|
||
const key = instruction.command.slice(2).toLowerCase();
|
||
const value = instruction.value.join(";");
|
||
state = {
|
||
"label": enum_decode_state_label.expect_vevent_property,
|
||
"vcalendar": state.vcalendar,
|
||
"vevent": Object.assign(state.vevent, {
|
||
"x_props": Object.assign((state.vevent.x_props ?? {}), Object.fromEntries([[key, value]]))
|
||
}),
|
||
};
|
||
}
|
||
else {
|
||
console.info({ "instruction": instruction, "state": state });
|
||
throw (new Error("unhandled instruction key: " + instruction.command));
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case enum_decode_state_label.done: {
|
||
console.info({ "instruction": instruction, "state": state });
|
||
throw (new Error("end expected"));
|
||
break;
|
||
}
|
||
}
|
||
});
|
||
return state.vcalendar;
|
||
}
|
||
ical.ics_decode = ics_decode;
|
||
/**
|
||
* @see https://www.rfc-editor.org/rfc/rfc5545
|
||
* @see https://icalendar.org/iCalendar-RFC-5545/
|
||
*/
|
||
function date_encode(date) {
|
||
return lib_plankton.string.coin("{{year}}{{month}}{{day}}", {
|
||
"year": date.year.toFixed(0).padStart(4, "0"),
|
||
"month": date.month.toFixed(0).padStart(2, "0"),
|
||
"day": date.day.toFixed(0).padStart(2, "0"),
|
||
});
|
||
}
|
||
/**
|
||
*/
|
||
function time_encode(time) {
|
||
return lib_plankton.string.coin("{{hour}}{{minute}}{{second}}{{utc}}", {
|
||
"hour": time.hour.toFixed(0).padStart(2, "0"),
|
||
"minute": time.minute.toFixed(0).padStart(2, "0"),
|
||
"second": time.second.toFixed(0).padStart(2, "0"),
|
||
"utc": (time.utc ? "Z" : ""),
|
||
});
|
||
}
|
||
/**
|
||
*/
|
||
function datetime_encode(datetime) {
|
||
return lib_plankton.string.coin("{{date}}T{{time}}", {
|
||
"date": date_encode(datetime.date),
|
||
"time": time_encode(datetime.time),
|
||
});
|
||
}
|
||
/**
|
||
* @todo method
|
||
* @todo add missing fields
|
||
*/
|
||
function ics_encode(vcalendar) {
|
||
let content_lines = [];
|
||
content_lines.push("BEGIN:VCALENDAR");
|
||
content_lines.push(lib_plankton.string.coin("VERSION:{{version}}", { "version": vcalendar.version }));
|
||
content_lines.push(lib_plankton.string.coin("PRODID:{{prodid}}", { "prodid": vcalendar.prodid }));
|
||
content_lines.push(lib_plankton.string.coin("METHOD:{{method}}", { "method": vcalendar.method }));
|
||
vcalendar.vevents.forEach((vevent) => {
|
||
content_lines.push("BEGIN:VEVENT");
|
||
{
|
||
// uid
|
||
content_lines.push(lib_plankton.string.coin("UID:{{uid}}", {
|
||
"uid": vevent.uid,
|
||
}));
|
||
// dtstart
|
||
content_lines.push(lib_plankton.string.coin(
|
||
// "DTSTART;TZID={{tzid}}:{{value}}",
|
||
"DTSTART:{{value}}", {
|
||
"tzid": vevent.dtstart.tzid,
|
||
"value": datetime_encode(vevent.dtstart.value),
|
||
}));
|
||
// dtend
|
||
if (vevent.dtend !== undefined) {
|
||
content_lines.push(lib_plankton.string.coin(
|
||
// "DTEND;TZID={{tzid}}:{{value}}",
|
||
"DTEND:{{value}}", {
|
||
"tzid": vevent.dtend.tzid,
|
||
"value": datetime_encode(vevent.dtend.value),
|
||
}));
|
||
}
|
||
// dtstamp
|
||
content_lines.push(lib_plankton.string.coin("DTSTAMP:{{value}}", {
|
||
"value": datetime_encode(vevent.dtstamp),
|
||
}));
|
||
// class
|
||
if (vevent.class !== undefined) {
|
||
content_lines.push(lib_plankton.string.coin("CLASS:{{class}}", {
|
||
"class": vevent.class,
|
||
}));
|
||
}
|
||
// summary
|
||
content_lines.push(lib_plankton.string.coin("SUMMARY:{{summary}}", {
|
||
"summary": vevent.summary,
|
||
}));
|
||
// description
|
||
if (vevent.description !== undefined) {
|
||
content_lines.push(lib_plankton.string.coin("DESCRIPTION:{{description}}", {
|
||
"description": vevent.description,
|
||
}));
|
||
}
|
||
// location
|
||
if (vevent.location !== undefined) {
|
||
content_lines.push(lib_plankton.string.coin("LOCATION:{{location}}", {
|
||
"location": vevent.location,
|
||
}));
|
||
}
|
||
// geo
|
||
if (vevent.geo !== undefined) {
|
||
content_lines.push(lib_plankton.string.coin("GEO:{{geo_latitude}};{{geo_longitude}}", {
|
||
"geo_latitude": vevent.geo.latitude.toFixed(4),
|
||
"geo_longitude": vevent.geo.longitude.toFixed(4),
|
||
}));
|
||
}
|
||
// url
|
||
if (vevent.url !== undefined) {
|
||
content_lines.push(lib_plankton.string.coin("URL:{{url}}", {
|
||
"url": vevent.url,
|
||
}));
|
||
}
|
||
}
|
||
content_lines.push("END:VEVENT");
|
||
});
|
||
content_lines.push("END:VCALENDAR");
|
||
let lines = [];
|
||
content_lines.forEach((content_line) => {
|
||
const slices = lib_plankton.string.slice(content_line, 75 - 1);
|
||
lines.push(slices[0]);
|
||
slices.slice(1).forEach((slice) => { lines.push(" " + slice); });
|
||
});
|
||
return lines.join("\r\n");
|
||
}
|
||
ical.ics_encode = ics_encode;
|
||
})(ical = lib_plankton.ical || (lib_plankton.ical = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:http«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:http« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:http« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:http«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var http;
|
||
(function (http) {
|
||
/**
|
||
* @author fenris <frass@greenscale.de>
|
||
*/
|
||
let enum_method;
|
||
(function (enum_method) {
|
||
enum_method["options"] = "options";
|
||
enum_method["head"] = "head";
|
||
enum_method["get"] = "get";
|
||
enum_method["delete"] = "delete";
|
||
enum_method["post"] = "post";
|
||
enum_method["put"] = "put";
|
||
enum_method["patch"] = "patch";
|
||
})(enum_method = http.enum_method || (http.enum_method = {}));
|
||
})(http = lib_plankton.http || (lib_plankton.http = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:http«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:http« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:http« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:http«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var http;
|
||
(function (http) {
|
||
/**
|
||
* @author fenris <frass@greenscale.de>
|
||
*/
|
||
const linebreak = "\r\n";
|
||
/**
|
||
* @todo outsource to string module
|
||
*/
|
||
function capitalize(str) {
|
||
return (str[0].toUpperCase() + str.slice(1));
|
||
}
|
||
/**
|
||
* @todo outsource to string module
|
||
*/
|
||
function capitalize_all(str) {
|
||
return str.split("-").map(x => capitalize(x)).join("-");
|
||
}
|
||
/**
|
||
* @author fenris <frass@greenscale.de>
|
||
*/
|
||
function encode_method(method) {
|
||
switch (method) {
|
||
case http.enum_method.get: return "GET";
|
||
case http.enum_method.post: return "POST";
|
||
case http.enum_method.patch: return "PATCH";
|
||
case http.enum_method.put: return "PUT";
|
||
case http.enum_method.delete: return "DELETE";
|
||
case http.enum_method.options: return "OPTIONS";
|
||
case http.enum_method.head: return "HEAD";
|
||
default: throw (new Error("impossible"));
|
||
}
|
||
}
|
||
http.encode_method = encode_method;
|
||
/**
|
||
* @author fenris <frass@greenscale.de>
|
||
*/
|
||
function decode_method(method_raw) {
|
||
switch (method_raw) {
|
||
case "GET": return http.enum_method.get;
|
||
case "POST": return http.enum_method.post;
|
||
case "PATCH": return http.enum_method.patch;
|
||
case "PUT": return http.enum_method.put;
|
||
case "DELETE": return http.enum_method.delete;
|
||
case "OPTIONS": return http.enum_method.options;
|
||
case "HEAD": return http.enum_method.head;
|
||
default: throw (new Error("unhandled method: " + method_raw));
|
||
}
|
||
}
|
||
/**
|
||
* @author fenris <frass@greenscale.de>
|
||
*/
|
||
function get_statustext(statuscode) {
|
||
switch (statuscode) {
|
||
case 100: return "Continue";
|
||
case 101: return "Switching Protocols";
|
||
case 103: return "Early Hints";
|
||
case 200: return "OK";
|
||
case 201: return "Created";
|
||
case 202: return "Accepted";
|
||
case 203: return "Non-Authoritative Information";
|
||
case 204: return "No Content";
|
||
case 205: return "Reset Content";
|
||
case 206: return "Partial Content";
|
||
case 300: return "Multiple Choices";
|
||
case 301: return "Moved Permanently";
|
||
case 302: return "Found";
|
||
case 303: return "See Other";
|
||
case 304: return "Not Modified";
|
||
case 307: return "Temporary Redirect";
|
||
case 308: return "Permanent Redirect";
|
||
case 400: return "Bad Request";
|
||
case 401: return "Unauthorized";
|
||
case 402: return "Payment Required";
|
||
case 403: return "Forbidden";
|
||
case 404: return "Not Found";
|
||
case 405: return "Method Not Allowed";
|
||
case 406: return "Not Acceptable";
|
||
case 407: return "Proxy Authentication Required";
|
||
case 408: return "Request Timeout";
|
||
case 409: return "Conflict";
|
||
case 410: return "Gone";
|
||
case 411: return "Length Required";
|
||
case 412: return "Precondition Failed";
|
||
case 413: return "Payload Too Large";
|
||
case 414: return "URI Too Long";
|
||
case 415: return "Unsupported Media Type";
|
||
case 416: return "Range Not Satisfiable";
|
||
case 417: return "Expectation Failed";
|
||
case 418: return "I'm a teapot";
|
||
case 422: return "Unprocessable Entity";
|
||
case 425: return "Too Early";
|
||
case 426: return "Upgrade Required";
|
||
case 428: return "Precondition Required";
|
||
case 429: return "Too Many Requests";
|
||
case 431: return "Request Header Fields Too Large";
|
||
case 451: return "Unavailable For Legal Reasons";
|
||
case 500: return "Internal Server Error";
|
||
case 501: return "Not Implemented";
|
||
case 502: return "Bad Gateway";
|
||
case 503: return "Service Unavailable";
|
||
case 504: return "Gateway Timeout";
|
||
case 505: return "HTTP Version Not Supported";
|
||
case 506: return "Variant Also Negotiates";
|
||
case 507: return "Insufficient Storage";
|
||
case 508: return "Loop Detected";
|
||
case 510: return "Not Extended";
|
||
case 511: return "Network Authentication";
|
||
default: throw (new Error("unhandled statuscode: " + statuscode.toFixed(0)));
|
||
}
|
||
}
|
||
/**
|
||
* @author fenris <frass@greenscale.de>
|
||
*/
|
||
function encode_request(request) {
|
||
let request_raw = "";
|
||
request_raw += (encode_method(request.method)
|
||
+
|
||
" "
|
||
+
|
||
request.path
|
||
+
|
||
((request.query === null) ? "" : request.query)
|
||
+
|
||
" "
|
||
+
|
||
request.version
|
||
+
|
||
linebreak);
|
||
if (request.host === null) {
|
||
// do nothing
|
||
}
|
||
else {
|
||
request_raw += ("Host: " + request.host + linebreak);
|
||
}
|
||
for (const [key, value] of Object.entries(request.headers)) {
|
||
request_raw += (capitalize_all(key) + ": " + value + linebreak);
|
||
}
|
||
request_raw += linebreak;
|
||
if (request.body === null) {
|
||
// do nothing
|
||
}
|
||
else {
|
||
request_raw += request.body.toString();
|
||
}
|
||
return request_raw;
|
||
}
|
||
http.encode_request = encode_request;
|
||
/**
|
||
* @author fenris <frass@greenscale.de>
|
||
*/
|
||
function decode_request(request_raw) {
|
||
const lines = request_raw.split(linebreak);
|
||
const first = lines.shift();
|
||
const parts = first.split(" ");
|
||
const method = decode_method(parts[0]);
|
||
const path_and_query = parts[1];
|
||
const parts_ = path_and_query.split("?");
|
||
const path = parts_[0];
|
||
const query = ((parts_.length <= 1) ? null : ("?" + parts_.slice(1).join("?")));
|
||
const version = parts[2];
|
||
let headers = {};
|
||
while (true) {
|
||
const line = lines.shift();
|
||
if (line === "") {
|
||
break;
|
||
}
|
||
else {
|
||
const [key, value] = line.split(": ", 2);
|
||
headers[key.toLowerCase()] = value;
|
||
}
|
||
}
|
||
const body = ([http.enum_method.post, http.enum_method.put, http.enum_method.patch].includes(method)
|
||
// @ts-ignore
|
||
? Buffer.from(lines.join(linebreak))
|
||
: null);
|
||
const request = {
|
||
// TODO
|
||
"scheme": "http",
|
||
"host": (headers["host"] ?? null),
|
||
"path": path,
|
||
"version": version,
|
||
"method": method,
|
||
"query": query,
|
||
"headers": headers,
|
||
"body": body,
|
||
};
|
||
return request;
|
||
}
|
||
http.decode_request = decode_request;
|
||
/**
|
||
* @author fenris <frass@greenscale.de>
|
||
*/
|
||
function encode_response(response) {
|
||
let response_raw = "";
|
||
response_raw += (response.version
|
||
+
|
||
" "
|
||
+
|
||
response.status_code.toFixed(0)
|
||
+
|
||
" "
|
||
+
|
||
get_statustext(response.status_code)
|
||
+
|
||
linebreak);
|
||
for (const [key, value] of Object.entries(response.headers)) {
|
||
response_raw += (capitalize_all(key) + ": " + value + linebreak);
|
||
}
|
||
response_raw += linebreak;
|
||
response_raw += response.body;
|
||
return response_raw;
|
||
}
|
||
http.encode_response = encode_response;
|
||
/**
|
||
* @author fenris <frass@greenscale.de>
|
||
*/
|
||
function decode_response(response_raw) {
|
||
const lines = response_raw.split(linebreak);
|
||
const first = lines.shift();
|
||
const first_parts = first.split(" ");
|
||
const version = first_parts[0];
|
||
const status_code = parseInt(first_parts[1]);
|
||
// first_parts.slice(2) ? probably irrelevant
|
||
let headers = {};
|
||
while (true) {
|
||
const line = lines.shift();
|
||
if (line === "") {
|
||
break;
|
||
}
|
||
else {
|
||
const [key, value] = line.split(": ", 2);
|
||
headers[key.toLowerCase()] = value;
|
||
}
|
||
}
|
||
// @ts-ignore
|
||
const body = Buffer.from(lines.join(linebreak));
|
||
const response = {
|
||
// TODO
|
||
"version": version,
|
||
"status_code": status_code,
|
||
"headers": headers,
|
||
"body": body,
|
||
};
|
||
return response;
|
||
}
|
||
http.decode_response = decode_response;
|
||
/**
|
||
* executes an HTTP request
|
||
*
|
||
* @todo define type_signal
|
||
*/
|
||
async function call(request, options = {}) {
|
||
options = Object.assign({
|
||
"timeout": 5.0,
|
||
"follow_redirects": false,
|
||
"implementation": "fetch",
|
||
}, options);
|
||
const target = (request.scheme
|
||
+
|
||
"://"
|
||
+
|
||
request.host
|
||
+
|
||
request.path
|
||
+
|
||
((request.query === null)
|
||
? ""
|
||
: request.query));
|
||
switch (options.implementation) {
|
||
default: {
|
||
return Promise.reject("invalid implementation: " + options.implementation);
|
||
break;
|
||
}
|
||
case "fetch": {
|
||
function core(signal) {
|
||
return (fetch(target, Object.assign({
|
||
"method": ((method => {
|
||
switch (method) {
|
||
case http.enum_method.head: return "HEAD";
|
||
case http.enum_method.options: return "OPTIONS";
|
||
case http.enum_method.get: return "GET";
|
||
case http.enum_method.delete: return "DELETE";
|
||
case http.enum_method.post: return "POST";
|
||
case http.enum_method.put: return "PUT";
|
||
case http.enum_method.patch: return "PATCH";
|
||
}
|
||
})(request.method)),
|
||
"headers": request.headers,
|
||
/*
|
||
"redirect": (
|
||
options.follow_redirects
|
||
?
|
||
"follow"
|
||
:
|
||
"manual"
|
||
),
|
||
*/
|
||
"signal": (signal
|
||
??
|
||
undefined),
|
||
// "keepalive": false,
|
||
}, ((((method => {
|
||
switch (method) {
|
||
case http.enum_method.head: return false;
|
||
case http.enum_method.options: return false;
|
||
case http.enum_method.get: return false;
|
||
case http.enum_method.delete: return false;
|
||
case http.enum_method.post: return true;
|
||
case http.enum_method.put: return true;
|
||
case http.enum_method.patch: return true;
|
||
}
|
||
})(request.method))
|
||
&&
|
||
(request.body !== null))
|
||
? {
|
||
"body": request.body.toString(),
|
||
}
|
||
: {})))
|
||
.catch((reason) => {
|
||
// console.info(reason);
|
||
return Promise.reject(reason);
|
||
})
|
||
.then((response_raw) => (response_raw.text()
|
||
.then((body) => Promise.resolve({
|
||
// TODO
|
||
"version": null,
|
||
"status_code": response_raw.status,
|
||
"headers": ((headers_raw => {
|
||
let headers = {};
|
||
headers_raw.forEach((value, key) => {
|
||
headers[key] = value;
|
||
});
|
||
return headers;
|
||
})(response_raw.headers)),
|
||
"body": body,
|
||
})))));
|
||
}
|
||
function timeout(controller) {
|
||
return (new Promise((resolve, reject) => {
|
||
if (options.timeout === null) {
|
||
// do nothing (neither resolve nor reject ever)
|
||
}
|
||
else {
|
||
setTimeout(() => {
|
||
controller.abort();
|
||
resolve(null);
|
||
}, (options.timeout * 1000));
|
||
}
|
||
}));
|
||
}
|
||
const controller = new AbortController();
|
||
const signal = controller.signal;
|
||
const response = await Promise.race([
|
||
timeout(controller),
|
||
core(signal),
|
||
]);
|
||
if (response === null) {
|
||
throw (new Error("http_request_timeout"));
|
||
}
|
||
else {
|
||
return response;
|
||
}
|
||
break;
|
||
}
|
||
case "http_module": {
|
||
// @ts-ignore
|
||
const nm_http = require("http");
|
||
// @ts-ignore
|
||
const nm_https = require("https");
|
||
return (new Promise((resolve, reject) => {
|
||
const req = ((request.scheme === "https")
|
||
? nm_https
|
||
: nm_http)
|
||
.request(target, {
|
||
"method": request.method,
|
||
"headers": request.headers,
|
||
}, (res) => {
|
||
try {
|
||
let response_body = "";
|
||
res.setEncoding("utf8");
|
||
res.on("data", (chunk) => {
|
||
response_body += chunk;
|
||
});
|
||
res.on("end", () => {
|
||
resolve({
|
||
// TODO
|
||
"version": null,
|
||
"status_code": res.statusCode,
|
||
"headers": res.headers,
|
||
"body": response_body,
|
||
});
|
||
});
|
||
}
|
||
catch (error) {
|
||
reject(error);
|
||
}
|
||
});
|
||
req.on("error", (error) => {
|
||
reject(error);
|
||
});
|
||
req.write(request.body);
|
||
req.end();
|
||
}));
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
http.call = call;
|
||
})(http = lib_plankton.http || (lib_plankton.http = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:http«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:http« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:http« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:http«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var http;
|
||
(function (http) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class class_http_request {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
constructor() {
|
||
}
|
||
/**
|
||
* @implementation
|
||
* @author fenris
|
||
*/
|
||
encode(x) {
|
||
return http.encode_request(x);
|
||
}
|
||
/**
|
||
* @implementation
|
||
* @author fenris
|
||
*/
|
||
decode(x) {
|
||
return http.decode_request(x);
|
||
}
|
||
}
|
||
http.class_http_request = class_http_request;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class class_http_response {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
constructor() {
|
||
}
|
||
/**
|
||
* @implementation
|
||
* @author fenris
|
||
*/
|
||
encode(x) {
|
||
return http.encode_response(x);
|
||
}
|
||
/**
|
||
* @implementation
|
||
* @author fenris
|
||
*/
|
||
decode(x) {
|
||
return http.decode_response(x);
|
||
}
|
||
}
|
||
http.class_http_response = class_http_response;
|
||
})(http = lib_plankton.http || (lib_plankton.http = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:object«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:object« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:object« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:object«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var object;
|
||
(function (object_1) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function fetch(object, fieldname, fallback, escalation) {
|
||
if (fallback === void 0) { fallback = null; }
|
||
if (escalation === void 0) { escalation = 1; }
|
||
if ((fieldname in object) && (object[fieldname] !== undefined)) {
|
||
return object[fieldname];
|
||
}
|
||
else {
|
||
switch (escalation) {
|
||
case 0: {
|
||
return fallback;
|
||
break;
|
||
}
|
||
case 1: {
|
||
var message = ("field '".concat(fieldname, "' not in structure"));
|
||
message += ("; using fallback value '".concat(String(fallback), "'"));
|
||
// console.warn(message);
|
||
return fallback;
|
||
break;
|
||
}
|
||
case 2: {
|
||
var message = ("field '".concat(fieldname, "' not in structure"));
|
||
throw (new Error(message));
|
||
break;
|
||
}
|
||
default: {
|
||
throw (new Error("invalid escalation level ".concat(escalation)));
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
object_1.fetch = fetch;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function map(object_from, transformator) {
|
||
var object_to = {};
|
||
Object.keys(object_from).forEach(function (key) { return (object_to[key] = transformator(object_from[key], key)); });
|
||
return object_to;
|
||
}
|
||
object_1.map = map;
|
||
/**
|
||
* @desc gibt ein Objekt mit bestimmten Einträgen des Eingabe-Objekts zurück
|
||
* @author fenris
|
||
*/
|
||
function filter(object_from, predicate) {
|
||
var object_to = {};
|
||
Object.keys(object_from).forEach(function (key) {
|
||
var value = object_from[key];
|
||
if (predicate(value, key)) {
|
||
object_to[key] = value;
|
||
}
|
||
});
|
||
return object_to;
|
||
}
|
||
object_1.filter = filter;
|
||
/**
|
||
* @desc wandelt ein Array mit Einträgen der Form {key,value} in ein entsprechendes Objekt um
|
||
* @author fenris
|
||
*/
|
||
function from_array(array) {
|
||
var object = {};
|
||
array.forEach(function (entry) { return (object[entry.key] = entry.value); });
|
||
return object;
|
||
}
|
||
object_1.from_array = from_array;
|
||
/**
|
||
* @desc wandelt ein Objekt in ein entsprechendes Array mit Einträgen der Form {key,value} um
|
||
* @author fenris
|
||
*/
|
||
function to_array(object) {
|
||
var array = [];
|
||
Object.keys(object).forEach(function (key) { return array.push({ "key": key, "value": object[key] }); });
|
||
return array;
|
||
}
|
||
object_1.to_array = to_array;
|
||
/**
|
||
* @desc gibt eine Liste von Schlüsseln eines Objekts zurück
|
||
* @author fenris
|
||
*/
|
||
function keys(object) {
|
||
return Object.keys(object);
|
||
}
|
||
object_1.keys = keys;
|
||
/**
|
||
* @desc gibt eine Liste von Werten eines Objekts zurück
|
||
* @author fenris
|
||
*/
|
||
function values(object) {
|
||
return to_array(object).map(function (entry) { return entry.value; });
|
||
}
|
||
object_1.values = values;
|
||
/**
|
||
* @desc liest ein Baum-artiges Objekt an einer bestimmten Stelle aus
|
||
* @author fenris
|
||
*/
|
||
function path_read(object, path, fallback, escalation) {
|
||
if (fallback === void 0) { fallback = null; }
|
||
if (escalation === void 0) { escalation = 1; }
|
||
var steps = ((path.length == 0) ? [] : path.split("."));
|
||
if (steps.length == 0) {
|
||
throw (new Error("empty path"));
|
||
}
|
||
else {
|
||
var position_1 = object;
|
||
var reachable = (position_1 != null) && steps.slice(0, steps.length - 1).every(function (step) {
|
||
position_1 = lib_plankton.object.fetch(position_1, step, null, 0);
|
||
return (position_1 != null);
|
||
});
|
||
if (reachable) {
|
||
return lib_plankton.object.fetch(position_1, steps[steps.length - 1], fallback, escalation);
|
||
}
|
||
else {
|
||
return lib_plankton.object.fetch({}, "_dummy_", fallback, escalation);
|
||
}
|
||
}
|
||
}
|
||
object_1.path_read = path_read;
|
||
/**
|
||
* @desc schreibt einen Wert an eine bestimmte Stelle in einem Baum-artigen Objekt
|
||
* @author fenris
|
||
*/
|
||
function path_write(object, path, value, construct) {
|
||
if (construct === void 0) { construct = true; }
|
||
var steps = ((path.length == 0) ? [] : path.split("."));
|
||
if (steps.length == 0) {
|
||
throw (new Error("empty path"));
|
||
}
|
||
else {
|
||
var position_2 = object;
|
||
var reachable = steps.slice(0, steps.length - 1).every(function (step) {
|
||
var position_ = lib_plankton.object.fetch(position_2, step, null, 0);
|
||
if (position_ == null) {
|
||
if (construct) {
|
||
position_2[step] = {};
|
||
position_2 = position_2[step];
|
||
return true;
|
||
}
|
||
else {
|
||
return false;
|
||
}
|
||
}
|
||
else {
|
||
position_2 = position_;
|
||
return true;
|
||
}
|
||
});
|
||
if (reachable) {
|
||
position_2[steps[steps.length - 1]] = value;
|
||
}
|
||
else {
|
||
var message = ("path '".concat(path, "' does not exist and may not be constructed"));
|
||
throw (new Error(message));
|
||
}
|
||
}
|
||
}
|
||
object_1.path_write = path_write;
|
||
/**
|
||
* @desc prüft ob ein Objekt einem bestimmten Muster entspricht
|
||
* @param {Object} object das zu prüfende Objekt
|
||
* @param {Object} pattern das einzuhaltende Muster
|
||
* @param {Function} connlate eine Funktion zum Feststellen der Gleichheit von Einzelwerten
|
||
* @author fenris
|
||
*/
|
||
function matches(object, pattern, collate) {
|
||
if (collate === void 0) { collate = instance_collate; }
|
||
return Object.keys(pattern).every(function (key) { return collate(pattern[key], object[key]); });
|
||
}
|
||
object_1.matches = matches;
|
||
/**
|
||
* @desc erzeugt eine Projektion eines Baum-artigen Objekts in ein Listen-artiges Objekt
|
||
* @param {string} [separator] welches Zeichen als Trenner zwischen zwei Pfad-Schritten verwendet werden soll
|
||
* @author fenris
|
||
*/
|
||
function flatten(value, separator, key_for_element) {
|
||
if (separator === void 0) { separator = "."; }
|
||
if (key_for_element === void 0) { key_for_element = (function (index) { return ("element_" + index.toFixed(0)); }); }
|
||
var integrate = function (result, key_, value_) {
|
||
if (value_ == null) {
|
||
result[key_] = value_;
|
||
}
|
||
else {
|
||
// primitive Werte direkt übernehmen
|
||
if (typeof (value_) != "object") {
|
||
result[key_] = value_;
|
||
}
|
||
// sonst durch rekursiven Aufruf die flache Variante des Wertes ermitteln und einarbeiten
|
||
else {
|
||
var result_1 = flatten(value_);
|
||
Object.keys(result_1)
|
||
.forEach(function (key__) {
|
||
var value__ = result_1[key__];
|
||
var key_new = (key_ + separator + key__);
|
||
result[key_new] = value__;
|
||
});
|
||
}
|
||
}
|
||
};
|
||
if ((value === null) || (value === undefined)) {
|
||
return null;
|
||
}
|
||
else {
|
||
var result_2 = {};
|
||
if (typeof (value) != "object") {
|
||
result_2["value"] = value;
|
||
}
|
||
else {
|
||
if (value instanceof Array) {
|
||
var array = (value);
|
||
array
|
||
.forEach(function (element, index) {
|
||
integrate(result_2, key_for_element(index), element);
|
||
});
|
||
}
|
||
else {
|
||
var object_2 = (value);
|
||
Object.keys(object_2)
|
||
.forEach(function (key) {
|
||
integrate(result_2, key, object_2[key]);
|
||
});
|
||
}
|
||
}
|
||
return result_2;
|
||
}
|
||
}
|
||
object_1.flatten = flatten;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function clash(x, y, _a) {
|
||
var _b = _a === void 0 ? {} : _a, _c = _b["overwrite"], overwrite = _c === void 0 ? true : _c, _d = _b["hooks"], _e = _d === void 0 ? {} : _d, _f = _e["existing"], hook_existing = _f === void 0 ? null : _f;
|
||
if (hook_existing == null) {
|
||
(function (key, value_old, value_new) { return console.warn("field ".concat(key, " already defined")); });
|
||
}
|
||
var z = {};
|
||
Object.keys(x).forEach(function (key) {
|
||
z[key] = x[key];
|
||
});
|
||
Object.keys(y).forEach(function (key) {
|
||
if (key in z) {
|
||
if (hook_existing != null) {
|
||
hook_existing(key, z[key], y[key]);
|
||
}
|
||
if (overwrite) {
|
||
z[key] = y[key];
|
||
}
|
||
}
|
||
else {
|
||
z[key] = y[key];
|
||
}
|
||
});
|
||
return z;
|
||
}
|
||
object_1.clash = clash;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function patch(core, mantle, deep, path) {
|
||
if (deep === void 0) { deep = true; }
|
||
if (path === void 0) { path = null; }
|
||
if (mantle == null) {
|
||
console.warn("mantle is null; core was", core);
|
||
}
|
||
else {
|
||
Object.keys(mantle).forEach(function (key) {
|
||
var path_ = ((path == null) ? key : "".concat(path, ".").concat(key));
|
||
var value_mantle = mantle[key];
|
||
if (!(key in core)) {
|
||
if ((typeof (value_mantle) == "object") && (value_mantle != null) && deep) {
|
||
if (value_mantle instanceof Array) {
|
||
core[key] = [];
|
||
value_mantle.forEach(function (element) {
|
||
if ((typeof (element) == "object") && (element != null)) {
|
||
var element_ = {};
|
||
patch(element_, element);
|
||
core[key].push(element_);
|
||
}
|
||
else {
|
||
core[key].push(element);
|
||
}
|
||
});
|
||
}
|
||
else {
|
||
core[key] = {};
|
||
patch(core[key], value_mantle, deep, path_);
|
||
}
|
||
}
|
||
else {
|
||
core[key] = value_mantle;
|
||
}
|
||
}
|
||
else {
|
||
var value_core = core[key];
|
||
if (typeof (value_core) == typeof (value_mantle)) {
|
||
if ((typeof (value_mantle) == "object") && (value_mantle != null) && deep) {
|
||
patch(core[key], value_mantle, deep, path_);
|
||
}
|
||
else {
|
||
core[key] = value_mantle;
|
||
}
|
||
}
|
||
else {
|
||
if ((value_core != null) && (value_mantle != null)) {
|
||
var message = "objects have different shapes at path '".concat(path_, "'; core has type '").concat(typeof (value_core), "' and mantle has type '").concat(typeof (value_mantle), "'");
|
||
console.warn(message);
|
||
}
|
||
core[key] = value_mantle;
|
||
// throw (new Error(message));
|
||
}
|
||
}
|
||
});
|
||
}
|
||
}
|
||
object_1.patch = patch;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function patched(core, mantle, deep) {
|
||
if (deep === void 0) { deep = undefined; }
|
||
var result = {};
|
||
patch(result, core, deep);
|
||
patch(result, mantle, deep);
|
||
return result;
|
||
}
|
||
object_1.patched = patched;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function attached(object, key, value) {
|
||
var mantle = {};
|
||
mantle[key] = value;
|
||
return patched(object, mantle, false);
|
||
}
|
||
object_1.attached = attached;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function copy(object) {
|
||
return patched({}, object);
|
||
}
|
||
object_1.copy = copy;
|
||
})(object = lib_plankton.object || (lib_plankton.object = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:markdown«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:markdown« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:markdown« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:markdown«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var markdown;
|
||
(function (markdown) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function code(content) {
|
||
return lib_plankton.string.coin("`{{content}}`", {
|
||
"content": content
|
||
});
|
||
}
|
||
markdown.code = code;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function paragraph(content) {
|
||
return lib_plankton.string.coin("{{content}}\n\n", {
|
||
"content": content
|
||
});
|
||
}
|
||
markdown.paragraph = paragraph;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function sectionhead(level, content) {
|
||
return lib_plankton.string.coin("{{grids}} {{content}}\n\n", {
|
||
"grids": lib_plankton.string.repeat("#", level),
|
||
"content": content
|
||
});
|
||
}
|
||
markdown.sectionhead = sectionhead;
|
||
})(markdown = lib_plankton.markdown || (lib_plankton.markdown = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:api«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:api« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:api« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:api«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var api;
|
||
(function (api) {
|
||
/**
|
||
*/
|
||
let enum_checklevel;
|
||
(function (enum_checklevel) {
|
||
enum_checklevel["none"] = "none";
|
||
enum_checklevel["soft"] = "soft";
|
||
enum_checklevel["hard"] = "hard";
|
||
})(enum_checklevel = api.enum_checklevel || (api.enum_checklevel = {}));
|
||
/**
|
||
*/
|
||
class class_error_permission_denied extends Error {
|
||
}
|
||
api.class_error_permission_denied = class_error_permission_denied;
|
||
})(api = lib_plankton.api || (lib_plankton.api = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:api«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:api« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:api« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:api«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var api;
|
||
(function (api_1) {
|
||
/**
|
||
* @throws Error if the inspection had foundings and the level is high enough
|
||
* @author fenris
|
||
*/
|
||
function validate(level, shape, value, options = {}) {
|
||
options = lib_plankton.object.patched({
|
||
"kind": "value",
|
||
"message_factory": ((kind, findings) => ("malformed " + kind + ": " + findings.join("; "))),
|
||
}, options);
|
||
if (level === api_1.enum_checklevel.none) {
|
||
return value;
|
||
}
|
||
else {
|
||
const inspection = lib_plankton.shape.inspect_flat(shape, value);
|
||
if (inspection.length === 0) {
|
||
return value;
|
||
}
|
||
else {
|
||
const message = options.message_factory(options.kind, inspection);
|
||
switch (level) {
|
||
case api_1.enum_checklevel.soft: {
|
||
console.warn(message);
|
||
return value;
|
||
break;
|
||
}
|
||
case api_1.enum_checklevel.hard:
|
||
default:
|
||
{
|
||
throw (new Error(message));
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function make(title) {
|
||
const api = {
|
||
"title": title,
|
||
"actions": {},
|
||
};
|
||
return api;
|
||
}
|
||
api_1.make = make;
|
||
/**
|
||
* @throws Error if a action with the given name has already been registered
|
||
* @author fenris
|
||
*/
|
||
function register(api, name, options = {}) {
|
||
options = /*lib_plankton.object.patched*/ Object.assign({
|
||
"active": (version) => true,
|
||
"execution": (version, environment, input) => lib_plankton.call.promise_reject("not implemented"),
|
||
"restriction": (version, environment) => true,
|
||
"input_shape": (version) => ({ "kind": "any" }),
|
||
"output_shape": (version) => ({ "kind": "any" }),
|
||
"title": null,
|
||
"description": null,
|
||
}, options);
|
||
if (api.actions.hasOwnProperty(name)) {
|
||
throw (new Error("an action with the name '" + name + "' has already been registered"));
|
||
}
|
||
else {
|
||
const action = {
|
||
"name": name,
|
||
"active": options.active,
|
||
"execution": options.execution,
|
||
"restriction": options.restriction,
|
||
"input_shape": options.input_shape,
|
||
"output_shape": options.output_shape,
|
||
"title": options.title,
|
||
"description": options.description,
|
||
};
|
||
api.actions[name] = action;
|
||
}
|
||
}
|
||
api_1.register = register;
|
||
/**
|
||
* @throws Error if not found
|
||
* @author fenris
|
||
*/
|
||
function get_action(api, name) {
|
||
if (api.actions.hasOwnProperty(name)) {
|
||
const action = api.actions[name];
|
||
return action;
|
||
}
|
||
else {
|
||
throw (new Error("no action with name '" + name + "'"));
|
||
}
|
||
}
|
||
api_1.get_action = get_action;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function call(api, name, options = {}) {
|
||
options = /*lib_plankton.object.patched*/ Object.assign({
|
||
"version": null,
|
||
"input": null,
|
||
"environment": {},
|
||
"checklevel_restriction": api_1.enum_checklevel.hard,
|
||
"checklevel_input": api_1.enum_checklevel.soft,
|
||
"checklevel_output": api_1.enum_checklevel.soft,
|
||
}, options);
|
||
return (lib_plankton.call.promise_resolve(undefined)
|
||
// get action
|
||
.then(() => lib_plankton.call.promise_resolve(get_action(api, name)))
|
||
.then((action) => (lib_plankton.call.promise_resolve(undefined)
|
||
// check permission
|
||
.then(() => {
|
||
let conf;
|
||
switch (options.checklevel_restriction) {
|
||
case api_1.enum_checklevel.none: {
|
||
conf = {
|
||
"actual_check": false,
|
||
"escalate": false,
|
||
};
|
||
break;
|
||
}
|
||
case api_1.enum_checklevel.soft: {
|
||
conf = {
|
||
"actual_check": true,
|
||
"escalate": false,
|
||
};
|
||
break;
|
||
}
|
||
default:
|
||
case api_1.enum_checklevel.hard: {
|
||
conf = {
|
||
"actual_check": true,
|
||
"escalate": true,
|
||
};
|
||
break;
|
||
}
|
||
}
|
||
return ((conf.actual_check
|
||
? action.restriction(options.version, options.environment)
|
||
: Promise.resolve(true))
|
||
.then((valid) => {
|
||
if (!valid) {
|
||
if (conf.escalate) {
|
||
return Promise.reject(new api_1.class_error_permission_denied());
|
||
}
|
||
else {
|
||
lib_plankton.log.warning("api_permission_missing", {
|
||
"version": options.version,
|
||
"environment": options.environment,
|
||
"action_name": action.name,
|
||
});
|
||
return Promise.resolve(null);
|
||
}
|
||
}
|
||
else {
|
||
return Promise.resolve(null);
|
||
}
|
||
}));
|
||
})
|
||
// validate and adjust input
|
||
.then(() => lib_plankton.call.promise_resolve(validate(options.checklevel_input, action.input_shape(options.version), options.input, {
|
||
"kind": "input",
|
||
})))
|
||
// execute
|
||
.then((input) => action.execution(options.version, options.environment, options.input))
|
||
// validate output
|
||
.then((output) => lib_plankton.call.promise_resolve(validate(options.checklevel_output, action.output_shape(options.version), output, {
|
||
"kind": "output",
|
||
}))))));
|
||
}
|
||
api_1.call = call;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function generate_documentation_for_action(api, name, options = {}) {
|
||
options = Object.assign({
|
||
"version": null,
|
||
}, options);
|
||
const action = get_action(api, name);
|
||
let result = "";
|
||
if (!action.active(options.version)) {
|
||
// do nothing
|
||
}
|
||
else {
|
||
// name
|
||
{
|
||
result += lib_plankton.markdown.sectionhead(2, lib_plankton.markdown.code(action.name));
|
||
}
|
||
// description
|
||
{
|
||
result += lib_plankton.markdown.sectionhead(3, "Description");
|
||
result += lib_plankton.markdown.paragraph(action.description ?? "-");
|
||
}
|
||
// input shape
|
||
{
|
||
result += lib_plankton.markdown.sectionhead(3, "Input");
|
||
result += lib_plankton.markdown.paragraph(lib_plankton.markdown.code(lib_plankton.shape.show(action.input_shape(options.version))));
|
||
}
|
||
// output shape
|
||
{
|
||
result += lib_plankton.markdown.sectionhead(3, "Output");
|
||
result += lib_plankton.markdown.paragraph(lib_plankton.markdown.code(lib_plankton.shape.show(action.output_shape(options.version))));
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
api_1.generate_documentation_for_action = generate_documentation_for_action;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function generate_documentation(api, options = {}) {
|
||
options = Object.assign({
|
||
"version": null,
|
||
}, options);
|
||
let result = "";
|
||
result += lib_plankton.markdown.paragraph(api.title);
|
||
result += lib_plankton.markdown.sectionhead(1, "Actions");
|
||
// iterate through actions and use "generate_documentation_for_action"
|
||
Object.entries(api.actions)
|
||
.forEach(([action_name, action]) => {
|
||
result += generate_documentation_for_action(api, action_name, {
|
||
"version": options.version,
|
||
});
|
||
});
|
||
return result;
|
||
}
|
||
api_1.generate_documentation = generate_documentation;
|
||
})(api = lib_plankton.api || (lib_plankton.api = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:api«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:api« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:api« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:api«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var api;
|
||
(function (api) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class class_api {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
constructor(subject) {
|
||
this.subject = subject;
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
static create(name) {
|
||
const subject = api.make(name);
|
||
return (new class_api(subject));
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
register(name, options = {}) {
|
||
return api.register(this.subject, name, options);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
call(name, options = {}) {
|
||
return api.call(this.subject, name, options);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
generate_documentation_for_action(name) {
|
||
return api.generate_documentation_for_action(this.subject, name);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
generate_documentation() {
|
||
return api.generate_documentation(this.subject);
|
||
}
|
||
}
|
||
api.class_api = class_api;
|
||
})(api = lib_plankton.api || (lib_plankton.api = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:rest«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:rest« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:rest« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:rest«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
/*
|
||
This file is part of »bacterio-plankton:rest«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:rest« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:rest« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:rest«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var rest;
|
||
(function (rest_1) {
|
||
/**
|
||
*/
|
||
function http_request_method_to_oas(http_request_method) {
|
||
switch (http_request_method) {
|
||
case lib_plankton.http.enum_method.get: return "get";
|
||
case lib_plankton.http.enum_method.post: return "post";
|
||
case lib_plankton.http.enum_method.patch: return "patch";
|
||
case lib_plankton.http.enum_method.head: return "head";
|
||
case lib_plankton.http.enum_method.delete: return "delete";
|
||
case lib_plankton.http.enum_method.options: return "options";
|
||
case lib_plankton.http.enum_method.put: return "put";
|
||
default: throw (new Error("impossible"));
|
||
}
|
||
}
|
||
/**
|
||
*/
|
||
function wildcard_step_decode(step) {
|
||
const matches = (new RegExp("^:(.*)$")).exec(step);
|
||
if ((matches === null) || (matches.length < 2)) {
|
||
return null;
|
||
}
|
||
else {
|
||
return matches[1];
|
||
}
|
||
}
|
||
/**
|
||
*/
|
||
function wildcard_step_encode(name) {
|
||
return (":" + name);
|
||
}
|
||
/**
|
||
*/
|
||
function routenode_iterate(routenode, procedure, steps) {
|
||
procedure(routenode, steps);
|
||
Object.entries(routenode.sub_branch).forEach(([key, value]) => {
|
||
routenode_iterate(value, procedure, steps.concat([key]));
|
||
});
|
||
if (!(routenode.sub_wildcard === null)) {
|
||
routenode_iterate(routenode.sub_wildcard.node, procedure, steps.concat([wildcard_step_encode(routenode.sub_wildcard.name)]));
|
||
}
|
||
}
|
||
/**
|
||
*/
|
||
function routenode_flatten(routenode) {
|
||
let list = [];
|
||
routenode_iterate(routenode, (routenode_, steps) => {
|
||
list.push({ "steps": steps, "node": routenode_ });
|
||
}, []);
|
||
return list;
|
||
}
|
||
/**
|
||
*/
|
||
function routenode_spawn(steps, http_method, operation) {
|
||
let routenode;
|
||
if (steps.length <= 0) {
|
||
routenode = {
|
||
"operations": Object.fromEntries([[http_method, operation]]),
|
||
"sub_branch": {},
|
||
"sub_wildcard": null,
|
||
};
|
||
}
|
||
else {
|
||
const steps_head = steps[0];
|
||
const steps_tail = steps.slice(1);
|
||
const sub = routenode_spawn(steps_tail, http_method, operation);
|
||
const wildcard_name = wildcard_step_decode(steps_head);
|
||
if (wildcard_name === null) {
|
||
// branch
|
||
routenode = {
|
||
"operations": {},
|
||
"sub_branch": Object.fromEntries([[steps_head, sub]]),
|
||
"sub_wildcard": null,
|
||
};
|
||
}
|
||
else {
|
||
// wildcard
|
||
routenode = {
|
||
"operations": {},
|
||
"sub_branch": {},
|
||
"sub_wildcard": { "name": wildcard_name, "node": sub },
|
||
};
|
||
}
|
||
}
|
||
return routenode;
|
||
}
|
||
/**
|
||
*/
|
||
function routenode_path_read(routenode, steps) {
|
||
if (steps.length <= 0) {
|
||
return {
|
||
"steps": [],
|
||
"rest": [],
|
||
"routenode": routenode,
|
||
"parameters": {},
|
||
};
|
||
}
|
||
else {
|
||
const path_head = steps[0];
|
||
const path_tail = steps.slice(1);
|
||
if (path_head in routenode.sub_branch) {
|
||
const result = routenode_path_read(routenode.sub_branch[path_head], path_tail);
|
||
return {
|
||
"steps": [path_head].concat(result.steps),
|
||
"rest": result.rest,
|
||
"routenode": result.routenode,
|
||
"parameters": result.parameters,
|
||
};
|
||
}
|
||
else {
|
||
if (!(routenode.sub_wildcard === null)) {
|
||
const result = routenode_path_read(routenode.sub_wildcard.node, path_tail);
|
||
if (!(routenode.sub_wildcard.name in result.parameters)) {
|
||
// do nothing
|
||
}
|
||
else {
|
||
lib_plankton.log.warning("rest_overwriting_path_parameter", {
|
||
"key": routenode.sub_wildcard.name,
|
||
"value_old": result.parameters[routenode.sub_wildcard.name],
|
||
"value_new": path_head,
|
||
});
|
||
}
|
||
return {
|
||
"steps": [path_head].concat(result.steps),
|
||
"rest": result.rest,
|
||
"routenode": result.routenode,
|
||
"parameters": lib_plankton.object.patched(Object.fromEntries([[routenode.sub_wildcard.name, path_head]]), result.parameters),
|
||
};
|
||
}
|
||
else {
|
||
return {
|
||
"steps": [path_head],
|
||
"rest": path_tail,
|
||
"routenode": routenode,
|
||
"parameters": {},
|
||
};
|
||
}
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
*/
|
||
function routenode_path_write(routenode, steps, http_method, operation, options = {}) {
|
||
options = lib_plankton.object.patched({
|
||
"create": false,
|
||
}, options);
|
||
if (steps.length <= 0) {
|
||
if (!(http_method in routenode.operations)) {
|
||
// do nothing
|
||
}
|
||
else {
|
||
lib_plankton.log.warning("rest_overwriting_action", {
|
||
"http_method": http_method,
|
||
"steps": steps,
|
||
});
|
||
}
|
||
routenode.operations[http_method] = operation;
|
||
}
|
||
else {
|
||
const steps_head = steps[0];
|
||
const steps_tail = steps.slice(1);
|
||
const wildcard_name = wildcard_step_decode(steps_head);
|
||
if (!(wildcard_name === null)) {
|
||
// wildcard
|
||
if (routenode.sub_wildcard === null) {
|
||
if (!options.create) {
|
||
throw (new Error("may not create missing route"));
|
||
}
|
||
else {
|
||
routenode.sub_wildcard = {
|
||
"name": wildcard_name,
|
||
"node": routenode_spawn(steps_tail, http_method, operation),
|
||
};
|
||
}
|
||
}
|
||
else {
|
||
if (!(routenode.sub_wildcard.name === wildcard_name)) {
|
||
/*
|
||
lib_plankton.log.warning(
|
||
"rest_overwriting_wildcard_node",
|
||
{
|
||
"wildcard_name": wildcard_name,
|
||
}
|
||
);
|
||
*/
|
||
throw (new Error("inconsistent wildcard name: '" + routenode.sub_wildcard.name + "' vs. '" + wildcard_name + "'"));
|
||
}
|
||
else {
|
||
// walk
|
||
routenode_path_write(routenode.sub_wildcard.node, steps_tail, http_method, operation, options);
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
if (steps_head in routenode.sub_branch) {
|
||
// walk branch
|
||
routenode_path_write(routenode.sub_branch[steps_head], steps_tail, http_method, operation, options);
|
||
}
|
||
else {
|
||
// add branch
|
||
if (!options.create) {
|
||
throw (new Error("may not create missing route"));
|
||
}
|
||
else {
|
||
routenode.sub_branch[steps_head] = routenode_spawn(steps_tail, http_method, operation);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
*/
|
||
function make(options = {}) {
|
||
options = lib_plankton.object.patched({
|
||
"title": "REST-API",
|
||
"versioning_method": "none",
|
||
"versioning_header_name": "X-Api-Version",
|
||
"versioning_query_key": "version",
|
||
"header_parameters": [],
|
||
"set_access_control_headers": false,
|
||
"authentication": {
|
||
"kind": "none",
|
||
"parameters": {},
|
||
},
|
||
"actions": [],
|
||
}, options);
|
||
const subject = {
|
||
"api": lib_plankton.api.make(options.title),
|
||
"versioning_method": options.versioning_method,
|
||
"versioning_header_name": options.versioning_header_name,
|
||
"versioning_query_key": options.versioning_query_key,
|
||
"routetree": {
|
||
"operations": {},
|
||
"sub_branch": {},
|
||
"sub_wildcard": null,
|
||
},
|
||
"header_parameters": options.header_parameters,
|
||
"set_access_control_headers": options.set_access_control_headers,
|
||
"authentication": options.authentication,
|
||
};
|
||
options.actions.forEach(action_definition => {
|
||
rest.register(subject, action_definition.http_method, action_definition.path, action_definition.options);
|
||
});
|
||
return subject;
|
||
}
|
||
rest_1.make = make;
|
||
/**
|
||
*/
|
||
function register(rest, http_method, path, options) {
|
||
options = lib_plankton.object.patched({
|
||
"active": ((version) => true),
|
||
"execution": ((stuff) => Promise.resolve({ "status_code": 501, "data": null })),
|
||
"restriction": ((stuff) => Promise.resolve(true)),
|
||
"input_schema": ((version) => ({})),
|
||
"output_schema": ((version) => ({})),
|
||
"title": null,
|
||
"description": null,
|
||
"query_parameters": [],
|
||
"request_body_mimetype": "application/json",
|
||
"request_body_decode": ((http_request_body, http_request_header_content_type) => (((http_request_header_content_type !== null)
|
||
&&
|
||
(http_request_header_content_type.startsWith("application/json"))
|
||
&&
|
||
(http_request_body !== null)
|
||
&&
|
||
(http_request_body.toString() !== ""))
|
||
? JSON.parse(http_request_body.toString())
|
||
: ((http_request_body !== null)
|
||
? http_request_body.toString()
|
||
: null))),
|
||
"response_body_mimetype": "application/json",
|
||
// TODO: no "from"?
|
||
"response_body_encode": ((output) => Buffer["from"](JSON.stringify(output))),
|
||
}, options);
|
||
const steps = lib_plankton.string.split(path, "/").slice(1);
|
||
const steps_enriched = ((rest.versioning_method === "path")
|
||
? ["{version}"].concat(steps)
|
||
: steps);
|
||
const action_name = (steps.concat([lib_plankton.http.encode_method(http_method).toLowerCase()])
|
||
.join("_"));
|
||
const operation = {
|
||
"action_name": action_name,
|
||
"query_parameters": options.query_parameters,
|
||
"request_body_mimetype": options.request_body_mimetype,
|
||
"request_body_decode": options.request_body_decode,
|
||
"response_body_mimetype": options.response_body_mimetype,
|
||
"response_body_encode": options.response_body_encode,
|
||
"input_schema": options.input_schema,
|
||
"output_schema": options.output_schema,
|
||
};
|
||
routenode_path_write(rest.routetree, steps_enriched, http_method, operation, {
|
||
"create": true,
|
||
});
|
||
lib_plankton.api.register(rest.api, action_name, {
|
||
"active": options.active,
|
||
"execution": (version, environment, input) => options.execution({
|
||
"version": version,
|
||
"path_parameters": environment.path_parameters,
|
||
"query_parameters": environment.query_parameters,
|
||
"headers": environment.headers,
|
||
"input": input
|
||
}),
|
||
"restriction": (version, environment) => options.restriction({
|
||
"version": version,
|
||
"path_parameters": environment.path_parameters,
|
||
"query_parameters": environment.query_parameters,
|
||
"headers": environment.headers,
|
||
}),
|
||
"title": options.title,
|
||
"description": options.description,
|
||
// TODO
|
||
// "input_shape": options.input_type,
|
||
// "output_shape": options.output_type,
|
||
});
|
||
lib_plankton.log.debug("rest_route_added", {
|
||
"http_method": http_method,
|
||
"path": path,
|
||
// "routetree": rest.routetree,
|
||
});
|
||
}
|
||
rest_1.register = register;
|
||
/**
|
||
* @todo check request body mimetype?
|
||
* @todo check query paramater validity
|
||
*/
|
||
async function call(rest, http_request, options = {}) {
|
||
options = /*lib_plankton.object.patched*/ Object.assign({
|
||
"checklevel_restriction": lib_plankton.api.enum_checklevel.hard,
|
||
"checklevel_input": lib_plankton.api.enum_checklevel.soft,
|
||
"checklevel_output": lib_plankton.api.enum_checklevel.soft,
|
||
}, options);
|
||
lib_plankton.log.info("rest_call", {
|
||
"http_request": {
|
||
"scheme": http_request.scheme,
|
||
"host": http_request.host,
|
||
"path": http_request.path,
|
||
"version": http_request.version,
|
||
"method": http_request.method,
|
||
"query": http_request.query,
|
||
"headers": http_request.headers,
|
||
"body": String(http_request.body),
|
||
}
|
||
});
|
||
// parse target and query parameters
|
||
// const url_stuff : URL = new URL("http://dummy" + http_request.target);
|
||
const path = http_request.path;
|
||
const query_parameters_raw = new URLSearchParams(http_request.query);
|
||
let query_parameters = {};
|
||
for (const [key, value] of query_parameters_raw) {
|
||
query_parameters[key] = value;
|
||
}
|
||
const steps = lib_plankton.string.split(path, "/").slice(1);
|
||
if (steps.length <= 0) {
|
||
throw (new Error("empty path"));
|
||
}
|
||
else {
|
||
// resolve
|
||
const stuff = routenode_path_read(rest.routetree, steps);
|
||
const allowed_methods = (Object.keys(stuff.routenode.operations)
|
||
.map(x => lib_plankton.http.encode_method(x))
|
||
.join(", "));
|
||
// get version
|
||
let version;
|
||
switch (rest.versioning_method) {
|
||
case "none": {
|
||
version = null;
|
||
break;
|
||
}
|
||
case "path": {
|
||
version = stuff.parameters["version"];
|
||
// delete stuff.parameters["version"];
|
||
break;
|
||
}
|
||
case "header": {
|
||
version = http_request.headers[rest.versioning_header_name];
|
||
// delete http_request.headers[rest.versioning_header_name];
|
||
break;
|
||
}
|
||
case "query": {
|
||
version = query_parameters[rest.versioning_query_key];
|
||
// delete query_parameters[rest.versioning_query_key];
|
||
break;
|
||
}
|
||
default: {
|
||
throw (new Error("unhandled versioning method: " + rest.versioning_method));
|
||
break;
|
||
}
|
||
}
|
||
const additional_response_headers = (rest.set_access_control_headers
|
||
? {
|
||
"Access-Control-Allow-Headers": (([
|
||
"Content-Type",
|
||
"X-Api-Key",
|
||
]
|
||
.concat((rest.versioning_header_name !== null)
|
||
? [rest.versioning_header_name]
|
||
: [])
|
||
.concat((rest.authentication.kind === "key_header")
|
||
? [rest.authentication.parameters["name"]]
|
||
: []))
|
||
.join(", ")),
|
||
"Access-Control-Allow-Origin": "*",
|
||
"Access-Control-Allow-Methods": allowed_methods,
|
||
}
|
||
: {});
|
||
if (stuff.rest.length > 0) {
|
||
return {
|
||
"version": "HTTP/1.1",
|
||
"status_code": 404,
|
||
"headers": {},
|
||
"body": null,
|
||
};
|
||
}
|
||
else {
|
||
if (http_request.method === lib_plankton.http.enum_method.options) {
|
||
return {
|
||
"version": "HTTP/1.1",
|
||
"status_code": 200,
|
||
"headers": Object.assign({}, additional_response_headers),
|
||
"body": null,
|
||
};
|
||
}
|
||
else {
|
||
if (!(http_request.method in stuff.routenode.operations)) {
|
||
if (Object.keys(stuff.routenode.operations).length <= 0) {
|
||
return {
|
||
"version": "HTTP/1.1",
|
||
"status_code": 404,
|
||
"headers": Object.assign({}, additional_response_headers),
|
||
"body": null,
|
||
};
|
||
}
|
||
else {
|
||
return {
|
||
"version": "HTTP/1.1",
|
||
"status_code": 405,
|
||
"headers": Object.assign({
|
||
"Allow": allowed_methods,
|
||
}, additional_response_headers),
|
||
"body": null,
|
||
};
|
||
}
|
||
}
|
||
else {
|
||
// call
|
||
let result;
|
||
let error;
|
||
const operation = stuff.routenode.operations[http_request.method];
|
||
const stuff_ = {
|
||
"version": version,
|
||
"headers": http_request.headers,
|
||
"path_parameters": stuff.parameters,
|
||
"query_parameters": query_parameters,
|
||
"input": ((http_request.body === null)
|
||
? null
|
||
: operation.request_body_decode(http_request.body, (http_request.headers["Content-Type"]
|
||
??
|
||
http_request.headers["content-type"]
|
||
??
|
||
null))),
|
||
};
|
||
/*
|
||
const allowed : boolean = (
|
||
(operation.restriction === null)
|
||
? true
|
||
: operation.restriction(stuff_)
|
||
);
|
||
*/
|
||
let response;
|
||
/*
|
||
if (! allowed) {
|
||
lib_plankton.log.error(
|
||
"rest_access_denied",
|
||
{
|
||
"http_request": {
|
||
"target": http_request.target,
|
||
"method": http_request.method,
|
||
"headers": http_request.headers,
|
||
"body": (
|
||
(http_request.body === null)
|
||
? null
|
||
: lib_plankton.string.limit(http_request.body.toString(), {"length": 200})
|
||
),
|
||
},
|
||
}
|
||
);
|
||
response = {
|
||
"version": "HTTP/1.1",
|
||
"status_code": 403,
|
||
"headers": Object.assign(
|
||
{
|
||
},
|
||
additional_response_headers
|
||
),
|
||
"body": Buffer["from"]("forbidden"),
|
||
};
|
||
}
|
||
else*/ {
|
||
try {
|
||
result = await lib_plankton.api.call(rest.api, operation.action_name, {
|
||
"version": stuff_.version,
|
||
"environment": {
|
||
"headers": stuff_.headers,
|
||
"path_parameters": stuff_.path_parameters,
|
||
"query_parameters": stuff_.query_parameters,
|
||
},
|
||
"input": stuff_.input,
|
||
"checklevel_restriction": options.checklevel_restriction,
|
||
"checklevel_input": options.checklevel_input,
|
||
"checklevel_output": options.checklevel_output,
|
||
});
|
||
error = null;
|
||
}
|
||
catch (error_) {
|
||
result = null;
|
||
error = error_;
|
||
}
|
||
if ((result === null) || (error !== null)) {
|
||
if (error instanceof lib_plankton.api.class_error_permission_denied) {
|
||
response = {
|
||
"version": "HTTP/1.1",
|
||
"status_code": 403,
|
||
"headers": Object.assign({}, additional_response_headers),
|
||
"body": null,
|
||
};
|
||
}
|
||
else {
|
||
lib_plankton.log.error("rest_execution_failed", {
|
||
"http_request": {
|
||
"version": http_request.version,
|
||
"scheme": http_request.scheme,
|
||
"method": http_request.method,
|
||
"path": http_request.path,
|
||
"query": http_request.query,
|
||
"headers": http_request.headers,
|
||
"body": ((http_request.body === null)
|
||
? null
|
||
: lib_plankton.string.limit(http_request.body.toString(), { "length": 200 })),
|
||
},
|
||
"error": {
|
||
"message": error.toString(),
|
||
"file_name": error.fileName,
|
||
"line_number": error.lineNumber,
|
||
"stack": error.stack,
|
||
},
|
||
});
|
||
response = {
|
||
"version": "HTTP/1.1",
|
||
"status_code": 500,
|
||
"headers": Object.assign({}, additional_response_headers),
|
||
"body": Buffer["from"]("internal error"),
|
||
};
|
||
}
|
||
}
|
||
else {
|
||
// encode
|
||
response = {
|
||
"version": "HTTP/1.1",
|
||
"status_code": result.status_code,
|
||
"headers": Object.assign({
|
||
"Content-Type": operation.response_body_mimetype,
|
||
}, additional_response_headers),
|
||
"body": operation.response_body_encode(result.data),
|
||
};
|
||
}
|
||
}
|
||
return response;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
rest_1.call = call;
|
||
/**
|
||
* @see https://swagger.io/specification/#openrest-object
|
||
*/
|
||
function to_oas(rest, options = {}) {
|
||
options = lib_plankton.object.patched({
|
||
"version": null,
|
||
"servers": [],
|
||
}, options);
|
||
const subject = rest;
|
||
const version = (options.version ?? "-");
|
||
return {
|
||
"openapi": "3.0.3",
|
||
"info": {
|
||
"version": version,
|
||
"title": (rest.api.title ?? "API"),
|
||
// "description": (rest.api.description ?? undefined),
|
||
},
|
||
"servers": options.servers.map(url => ({ "url": url })),
|
||
"components": {
|
||
"securitySchemes": (((description) => ({
|
||
"none": {},
|
||
"key_header": {
|
||
"default_security_schema": {
|
||
"type": "restKey",
|
||
"in": "header",
|
||
"name": description.parameters["name"],
|
||
},
|
||
},
|
||
}[description.kind]))(rest.authentication)),
|
||
},
|
||
"security": [
|
||
{
|
||
"default_security_schema": [],
|
||
}
|
||
],
|
||
"paths": lib_plankton.call.convey(rest.routetree, [
|
||
routenode_flatten,
|
||
(x) => x.map((entry) => {
|
||
const steps_ = entry.steps;
|
||
const path = lib_plankton.string.join(steps_, "_");
|
||
const key = ((steps_.length <= 0)
|
||
? "/"
|
||
: lib_plankton.string.join([""].concat(steps_
|
||
.map(step => ((wildcard_step_decode(step) !== null)
|
||
? ("{" + wildcard_step_decode(step) + "}")
|
||
: step))), "/"));
|
||
return [
|
||
key,
|
||
lib_plankton.call.convey(entry.node.operations, [
|
||
x => Object.entries(x),
|
||
(pairs) => pairs.map(([http_method, operation]) => ([
|
||
http_request_method_to_oas(http_method),
|
||
{
|
||
"operationId": (http_request_method_to_oas(http_method)
|
||
+
|
||
"_"
|
||
+
|
||
path),
|
||
"summary": (operation.title
|
||
??
|
||
[""].concat(steps_).join(" ")),
|
||
"description": (lib_plankton.api.get_action(rest.api, operation.action_name).description
|
||
??
|
||
"(missing)"),
|
||
"parameters": [].concat(
|
||
// header parameters
|
||
rest.header_parameters.map(header_parameter => ({
|
||
"name": header_parameter.name,
|
||
"in": "header",
|
||
"required": header_parameter.required,
|
||
"schema": {
|
||
"type": "string",
|
||
},
|
||
"description": (header_parameter.description ?? undefined),
|
||
})),
|
||
// path parameters
|
||
lib_plankton.call.convey(steps_, [
|
||
x => x.map(y => wildcard_step_decode(y)),
|
||
x => x.filter(y => (!(y === null))),
|
||
x => x.map(y => ({
|
||
"name": y,
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string",
|
||
},
|
||
})),
|
||
]),
|
||
// query parameters
|
||
operation.query_parameters.map((query_parameter) => ({
|
||
"name": query_parameter.name,
|
||
"in": "query",
|
||
"required": query_parameter.required,
|
||
"schema": {
|
||
"type": "string",
|
||
},
|
||
"description": (query_parameter.description ?? undefined),
|
||
}))),
|
||
"requestBody": (([
|
||
lib_plankton.http.enum_method.get,
|
||
lib_plankton.http.enum_method.head,
|
||
lib_plankton.http.enum_method.delete,
|
||
].includes(http_method))
|
||
? undefined
|
||
: {
|
||
"content": Object.fromEntries([
|
||
[
|
||
operation.request_body_mimetype,
|
||
{
|
||
"schema": operation.input_schema(options.version),
|
||
}
|
||
]
|
||
])
|
||
}),
|
||
"responses": {
|
||
"default": {
|
||
"description": "",
|
||
"content": Object.fromEntries([
|
||
[
|
||
operation.response_body_mimetype,
|
||
{
|
||
"schema": operation.output_schema(options.version),
|
||
}
|
||
]
|
||
]),
|
||
}
|
||
},
|
||
}
|
||
])),
|
||
(pairs) => Object.fromEntries(pairs),
|
||
]),
|
||
];
|
||
}),
|
||
x => x.filter(y => (Object.keys(y[1]).length > 0)),
|
||
x => Object.fromEntries(x),
|
||
])
|
||
};
|
||
}
|
||
rest_1.to_oas = to_oas;
|
||
})(rest = lib_plankton.rest || (lib_plankton.rest = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:server«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:server« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:server« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:server«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var server;
|
||
(function (server) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function make(handle, options = {}) {
|
||
options = Object.assign({
|
||
"host": "::",
|
||
"port": 9999,
|
||
"threshold": 0.25,
|
||
}, options);
|
||
return {
|
||
"host": options.host,
|
||
"port": options.port,
|
||
"threshold": options.threshold,
|
||
"handle": handle,
|
||
"serverobj": undefined,
|
||
};
|
||
}
|
||
server.make = make;
|
||
/**
|
||
* @author fenris
|
||
* @deprecated
|
||
*/
|
||
function make_old(port, handle) {
|
||
return make(handle, {
|
||
"host": "::",
|
||
"port": port,
|
||
"threshold": 0.25,
|
||
});
|
||
}
|
||
server.make_old = make_old;
|
||
/**
|
||
* @author fenris
|
||
* @see https://nodejs.org/api/net.html#serverlistenport-host-backlog-callback
|
||
*/
|
||
function start(subject) {
|
||
const net = require("net");
|
||
return (new Promise((resolve, reject) => {
|
||
// @ts-ignore
|
||
let input_chunks = [];
|
||
subject.serverobj = net.createServer({
|
||
"allowHalfOpen": false,
|
||
}, (socket) => {
|
||
let timeout_handler = null;
|
||
let ended = false;
|
||
const process_input = function () {
|
||
// @ts-ignore
|
||
const input = Buffer.concat(input_chunks);
|
||
/*
|
||
const metadata : type_metadata = {
|
||
"ip_address": socket.remoteAddress,
|
||
};
|
||
*/
|
||
lib_plankton.log.debug("server_process_input", {
|
||
"input": input,
|
||
});
|
||
(subject.handle(input /*, metadata*/)
|
||
.then((output) => {
|
||
lib_plankton.log.debug("server_writing", {
|
||
"output": output,
|
||
});
|
||
socket.write(output);
|
||
socket.end();
|
||
})
|
||
.catch((error) => {
|
||
lib_plankton.log.warning("server_handle_failed", {
|
||
"error": error.toString(),
|
||
});
|
||
// socket.write("");
|
||
socket.end();
|
||
})
|
||
.then(() => {
|
||
input_chunks = [];
|
||
}));
|
||
};
|
||
const timeout_stop = function () {
|
||
if (timeout_handler === null) {
|
||
// do nothing
|
||
}
|
||
else {
|
||
lib_plankton.log.debug("server_timeout_cancelling");
|
||
clearTimeout(timeout_handler);
|
||
timeout_handler = null;
|
||
}
|
||
};
|
||
const timeout_start = function () {
|
||
if (subject.threshold === null) {
|
||
process_input();
|
||
}
|
||
else {
|
||
if (timeout_handler === null) {
|
||
timeout_handler = setTimeout(() => {
|
||
lib_plankton.log.debug("server_timeout_reached");
|
||
timeout_handler = null;
|
||
process_input();
|
||
}, (subject.threshold * 1000));
|
||
}
|
||
else {
|
||
lib_plankton.log.warning("server_timeout_already_started");
|
||
// do nothing
|
||
}
|
||
}
|
||
};
|
||
lib_plankton.log.info("server_client connected", {});
|
||
socket.on("data", (input_chunk_raw) => {
|
||
lib_plankton.log.debug("server_reading_chunk", {
|
||
"chunk_raw": input_chunk_raw,
|
||
});
|
||
timeout_stop();
|
||
const input_chunk = ((input_chunk_raw instanceof Buffer)
|
||
?
|
||
input_chunk_raw
|
||
:
|
||
// @ts-ignore
|
||
Buffer.from(input_chunk_raw));
|
||
input_chunks.push(input_chunk);
|
||
timeout_start();
|
||
});
|
||
socket.on("end", () => {
|
||
if (!ended) {
|
||
lib_plankton.log.info("server_client_disconnected", {});
|
||
ended = true;
|
||
timeout_stop();
|
||
}
|
||
else {
|
||
lib_plankton.log.info("server_socket_already_ended");
|
||
// do nothing
|
||
}
|
||
});
|
||
});
|
||
subject.serverobj.on("error", (error) => {
|
||
// throw error;
|
||
process.stderr.write("net_error: " + String(error) + "\n\n");
|
||
});
|
||
subject.serverobj.listen(subject.port, subject.host, 511, () => {
|
||
lib_plankton.log.info("server_listenting", {
|
||
"host": subject.host,
|
||
"port": subject.port,
|
||
});
|
||
resolve(undefined);
|
||
});
|
||
}));
|
||
}
|
||
server.start = start;
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function kill(subject) {
|
||
subject.serverobj.close();
|
||
lib_plankton.log.info("server_stopped", {});
|
||
}
|
||
server.kill = kill;
|
||
})(server = lib_plankton.server || (lib_plankton.server = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:server«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:server« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:server« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:server«. If not, see <common://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var server;
|
||
(function (server) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class class_server {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
constructor(handle, options = {}) {
|
||
options = Object.assign({
|
||
"host": "::",
|
||
"port": 9999,
|
||
}, options);
|
||
this.subject = server.make(handle, {
|
||
"host": options.host,
|
||
"port": options.port,
|
||
});
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
start() {
|
||
return server.start(this.subject);
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
kill() {
|
||
return server.kill(this.subject);
|
||
}
|
||
}
|
||
server.class_server = class_server;
|
||
})(server = lib_plankton.server || (lib_plankton.server = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
var lib_server = lib_plankton.server;
|
||
/*
|
||
This file is part of »bacterio-plankton:args«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:args« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:args« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:args«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var args;
|
||
(function (args) {
|
||
/**
|
||
*/
|
||
var enum_environment;
|
||
(function (enum_environment) {
|
||
enum_environment["cli"] = "cli";
|
||
enum_environment["url"] = "url";
|
||
})(enum_environment = args.enum_environment || (args.enum_environment = {}));
|
||
;
|
||
/**
|
||
*/
|
||
var enum_kind;
|
||
(function (enum_kind) {
|
||
enum_kind["positional"] = "positional";
|
||
enum_kind["volatile"] = "volatile";
|
||
})(enum_kind = args.enum_kind || (args.enum_kind = {}));
|
||
;
|
||
/**
|
||
*/
|
||
var enum_type;
|
||
(function (enum_type) {
|
||
enum_type["boolean"] = "boolean";
|
||
enum_type["integer"] = "int";
|
||
enum_type["float"] = "float";
|
||
enum_type["string"] = "string";
|
||
})(enum_type = args.enum_type || (args.enum_type = {}));
|
||
;
|
||
/**
|
||
*/
|
||
var enum_mode;
|
||
(function (enum_mode) {
|
||
enum_mode["replace"] = "replace";
|
||
enum_mode["accumulate"] = "accumulate";
|
||
})(enum_mode = args.enum_mode || (args.enum_mode = {}));
|
||
;
|
||
})(args = lib_plankton.args || (lib_plankton.args = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:args«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:args« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:args« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:args«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var args;
|
||
(function (args) {
|
||
/*
|
||
export enum_mode {
|
||
replace = "replace",
|
||
accumulate = "accumulate",
|
||
};
|
||
*/
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
var class_argument = /** @class */ (function () {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function class_argument(_a) {
|
||
var name = _a["name"], _b = _a["type"], type = _b === void 0 ? args.enum_type.string : _b, _c = _a["kind"], kind = _c === void 0 ? args.enum_kind.positional : _c, _d = _a["mode"], mode = _d === void 0 ? args.enum_mode.replace : _d, _e = _a["default"], default_ = _e === void 0 ? null : _e, _f = _a["info"], info = _f === void 0 ? null : _f, _g = _a["parameters"], parameters = _g === void 0 ? {} : _g, _h = _a["hidden"], hidden = _h === void 0 ? false : _h;
|
||
this.name = name;
|
||
this.type = type;
|
||
this.kind = kind;
|
||
this.mode = mode;
|
||
this.default_ = default_;
|
||
this.info = info;
|
||
this.parameters = parameters;
|
||
this.hidden = hidden;
|
||
if (!this.check()) {
|
||
throw (new Error("invalid argument-setup"));
|
||
}
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class_argument.positional = function (_a) {
|
||
var name = _a["name"], _b = _a["type"], type = _b === void 0 ? args.enum_type.string : _b, _c = _a["mode"], mode = _c === void 0 ? args.enum_mode.replace : _c, _d = _a["default"], default_ = _d === void 0 ? null : _d, _e = _a["info"], info = _e === void 0 ? null : _e, _f = _a["hidden"], hidden = _f === void 0 ? false : _f, index = _a["index"];
|
||
return (new class_argument({
|
||
"name": name,
|
||
"kind": args.enum_kind.positional,
|
||
"type": type,
|
||
"mode": mode,
|
||
"default": default_,
|
||
"info": info,
|
||
"hidden": hidden,
|
||
"parameters": {
|
||
"index": index
|
||
}
|
||
}));
|
||
};
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class_argument.volatile = function (_a) {
|
||
var name = _a["name"], _b = _a["type"], type = _b === void 0 ? args.enum_type.string : _b, _c = _a["mode"], mode = _c === void 0 ? args.enum_mode.replace : _c, _d = _a["default"], default_ = _d === void 0 ? null : _d, _e = _a["info"], info = _e === void 0 ? null : _e, _f = _a["hidden"], hidden = _f === void 0 ? false : _f, indicators_short = _a["indicators_short"], indicators_long = _a["indicators_long"];
|
||
return (new class_argument({
|
||
"name": name,
|
||
"kind": args.enum_kind.volatile,
|
||
"type": type,
|
||
"mode": mode,
|
||
"default": default_,
|
||
"info": info,
|
||
"hidden": hidden,
|
||
"parameters": {
|
||
"indicators_short": indicators_short,
|
||
"indicators_long": indicators_long
|
||
}
|
||
}));
|
||
};
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class_argument.prototype.check = function () {
|
||
var _this = this;
|
||
return [
|
||
function () { return ((!(_this.kind == args.enum_kind.volatile))
|
||
||
|
||
(("indicators_long" in _this.parameters)
|
||
&&
|
||
(_this.parameters["indicators_long"]["length"] >= 0))); },
|
||
].every(function (condition) { return condition(); });
|
||
};
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class_argument.prototype.name_get = function () {
|
||
return this.name;
|
||
};
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class_argument.prototype.kind_get = function () {
|
||
return this.kind;
|
||
};
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class_argument.prototype.type_get = function () {
|
||
return this.type;
|
||
};
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class_argument.prototype.mode_get = function () {
|
||
return this.mode;
|
||
};
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class_argument.prototype.default_get = function () {
|
||
return this.default_;
|
||
};
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class_argument.prototype.parameters_get = function () {
|
||
return this.parameters;
|
||
};
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class_argument.prototype.hidden_get = function () {
|
||
return this.hidden;
|
||
};
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class_argument.prototype.toString = function () {
|
||
return "<".concat(this.name, ">");
|
||
};
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class_argument.prototype.indicator_main = function () {
|
||
if (this.kind === args.enum_kind.volatile) {
|
||
return this.parameters["indicators_long"][0];
|
||
}
|
||
else {
|
||
return null;
|
||
}
|
||
};
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class_argument.prototype.pattern_value = function () {
|
||
switch (this.type) {
|
||
case args.enum_type.boolean: {
|
||
return "false|true";
|
||
break;
|
||
}
|
||
case args.enum_type.integer: {
|
||
return "[0-9]+";
|
||
break;
|
||
}
|
||
case args.enum_type.float: {
|
||
return "\\d*(?:\\.\\d+)?";
|
||
break;
|
||
}
|
||
case args.enum_type.string: {
|
||
return "\\S+";
|
||
break;
|
||
}
|
||
default: {
|
||
throw (new Error("unhandled type ".concat(this.type)));
|
||
break;
|
||
}
|
||
}
|
||
};
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class_argument.prototype.extract = function (raw) {
|
||
switch (this.type) {
|
||
case args.enum_type.boolean: {
|
||
return (raw != "false");
|
||
break;
|
||
}
|
||
case args.enum_type.integer: {
|
||
return parseInt(raw);
|
||
break;
|
||
}
|
||
case args.enum_type.float: {
|
||
return parseFloat(raw);
|
||
break;
|
||
}
|
||
case args.enum_type.string: {
|
||
return raw;
|
||
break;
|
||
}
|
||
default: {
|
||
throw (new Error("unhandled type ".concat(this.type)));
|
||
break;
|
||
}
|
||
}
|
||
};
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class_argument.prototype.assign = function (data, target, raw) {
|
||
var value = this.extract(raw);
|
||
switch (this.mode) {
|
||
case args.enum_mode.replace: {
|
||
data[target] = value;
|
||
break;
|
||
}
|
||
case args.enum_mode.accumulate: {
|
||
/*
|
||
if (! (this.name in data)) {
|
||
data[this.name] = [];
|
||
}
|
||
*/
|
||
data[target].push(value);
|
||
break;
|
||
}
|
||
default: {
|
||
throw (new Error("unhandled mode ".concat(this.mode)));
|
||
}
|
||
}
|
||
};
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class_argument.prototype.make = function (data, target) {
|
||
var value = data[target];
|
||
return value.toString();
|
||
};
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class_argument.prototype.generate_help = function () {
|
||
var _this = this;
|
||
var _a, _b, _c, _d;
|
||
var output = "";
|
||
{
|
||
switch (this.kind) {
|
||
case args.enum_kind.positional: {
|
||
var line = "";
|
||
line += "\t";
|
||
line += "<".concat(this.name, ">");
|
||
line += "\n";
|
||
output += line;
|
||
}
|
||
case args.enum_kind.volatile: {
|
||
var line = "";
|
||
line += "\t";
|
||
if (this.type === args.enum_type.boolean) {
|
||
line += ([]
|
||
.concat(((_a = this.parameters["indicators_short"]) !== null && _a !== void 0 ? _a : []).map(function (indicator) { return ("-" + indicator); }))
|
||
.concat(((_b = this.parameters["indicators_long"]) !== null && _b !== void 0 ? _b : []).map(function (indicator) { return ("--" + indicator); }))
|
||
.join(" | "));
|
||
}
|
||
else {
|
||
line += ([]
|
||
.concat(((_c = this.parameters["indicators_short"]) !== null && _c !== void 0 ? _c : []).map(function (indicator) { return ("-" + indicator + " " + ("<" + _this.name + ">")); }))
|
||
.concat(((_d = this.parameters["indicators_long"]) !== null && _d !== void 0 ? _d : []).map(function (indicator) { return ("--" + indicator + "=" + ("<" + _this.name + ">")); }))
|
||
.join(" | "));
|
||
}
|
||
line += "\n";
|
||
output += line;
|
||
}
|
||
}
|
||
}
|
||
{
|
||
var line = "";
|
||
line += "\t\t";
|
||
var infotext = ((this.info == null) ? "(no info available)" : this.info);
|
||
line += infotext;
|
||
if ((this.type != "boolean") && (this.default_ != null)) {
|
||
line += "; default: ".concat(this.default_.toString());
|
||
}
|
||
line += "\n";
|
||
output += line;
|
||
}
|
||
return output;
|
||
};
|
||
return class_argument;
|
||
}());
|
||
args.class_argument = class_argument;
|
||
})(args = lib_plankton.args || (lib_plankton.args = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|
||
/*
|
||
This file is part of »bacterio-plankton:args«.
|
||
|
||
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||
<info@greenscale.de>
|
||
|
||
»bacterio-plankton:args« is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
»bacterio-plankton:args« is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with »bacterio-plankton:args«. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
var lib_plankton;
|
||
(function (lib_plankton) {
|
||
var args;
|
||
(function (args) {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
var settings = {
|
||
"environment": {
|
||
"cli": {
|
||
"symbols": {
|
||
"delimiter": " ",
|
||
"prefix": "--",
|
||
"assignment": "="
|
||
}
|
||
},
|
||
"url": {
|
||
"symbols": {
|
||
"delimiter": "&",
|
||
"prefix": "",
|
||
"assignment": "="
|
||
}
|
||
}
|
||
}
|
||
};
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
args.verbosity = 0;
|
||
/**
|
||
* @author fenris
|
||
* @todo check validity
|
||
*/
|
||
var class_handler = /** @class */ (function () {
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
function class_handler(arguments_) {
|
||
this.arguments_ = arguments_;
|
||
}
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class_handler.prototype.filter = function (kind) {
|
||
var arguments_ = {};
|
||
for (var _i = 0, _a = Object.entries(this.arguments_); _i < _a.length; _i++) {
|
||
var _b = _a[_i], name = _b[0], argument = _b[1];
|
||
if (argument.kind_get() == kind) {
|
||
arguments_[name] = argument;
|
||
}
|
||
}
|
||
return arguments_;
|
||
};
|
||
/**
|
||
* @author fenris
|
||
*/
|
||
class_handler.prototype.read = function (environment, input, data) {
|
||
var _this = this;
|
||
if (data === void 0) { data = {}; }
|
||
switch (environment) {
|
||
case args.enum_environment.cli:
|
||
case args.enum_environment.url: {
|
||
// default values
|
||
{
|
||
for (var _i = 0, _a = Object.entries(this.arguments_); _i < _a.length; _i++) {
|
||
var _b = _a[_i], name = _b[0], argument = _b[1];
|
||
data[name] = argument.default_get();
|
||
}
|
||
}
|
||
// preprocessing
|
||
{
|
||
// short indicators (lil hacky ...)
|
||
{
|
||
if (environment == args.enum_environment.cli) {
|
||
for (var _c = 0, _d = Object.entries(this.filter(args.enum_kind.volatile)); _c < _d.length; _c++) {
|
||
var _e = _d[_c], name = _e[0], argument = _e[1];
|
||
// console.info(argument.parameters_get()["indicators_short"].join("|"));
|
||
var pattern_from = "";
|
||
{
|
||
pattern_from += "(?:^|".concat(settings["environment"][environment]["symbols"]["delimiter"], ")");
|
||
pattern_from += "-".concat(argument.parameters_get()["indicators_short"].join("|"));
|
||
pattern_from += "(?:$|".concat(settings["environment"][environment]["symbols"]["delimiter"], ")");
|
||
}
|
||
var pattern_to = "";
|
||
{
|
||
pattern_to += settings["environment"][environment]["symbols"]["delimiter"];
|
||
pattern_to += settings["environment"][environment]["symbols"]["prefix"];
|
||
pattern_to += argument.indicator_main();
|
||
if (argument.type_get() == args.enum_type.boolean) {
|
||
pattern_to += settings["environment"][environment]["symbols"]["delimiter"];
|
||
}
|
||
else {
|
||
pattern_to += settings["environment"][environment]["symbols"]["assignment"];
|
||
}
|
||
}
|
||
var result = input.replace(new RegExp(pattern_from, "g"), pattern_to);
|
||
lib_plankton.log.debug("lib_args:read:replacing", {
|
||
"pattern_from": pattern_from,
|
||
"pattern_to": pattern_to,
|
||
"input": input,
|
||
"result": result
|
||
});
|
||
input = result;
|
||
}
|
||
}
|
||
}
|
||
lib_plankton.log.debug("lib_args:read:current_input", {
|
||
"input": input
|
||
});
|
||
}
|
||
// parsing
|
||
{
|
||
var parts = input
|
||
.split(settings["environment"][environment]["symbols"]["delimiter"])
|
||
.filter(function (x) { return (x != ""); });
|
||
var index_expected_1 = 0;
|
||
parts.forEach(function (part) {
|
||
lib_plankton.log.debug("lib_args:read:analyzing", {
|
||
"part": part
|
||
});
|
||
var found = [
|
||
function () {
|
||
lib_plankton.log.debug("lib_args:read:probing_as_volatile", {
|
||
"part": part
|
||
});
|
||
for (var _i = 0, _a = Object.entries(_this.filter(args.enum_kind.volatile)); _i < _a.length; _i++) {
|
||
var _b = _a[_i], name = _b[0], argument = _b[1];
|
||
lib_plankton.log.debug("lib_args:read:probing_as_volatile:trying", {
|
||
"part": part,
|
||
"argument": argument.toString()
|
||
});
|
||
var pattern = "";
|
||
{
|
||
var pattern_front = "";
|
||
pattern_front += "".concat(settings["environment"][environment]["symbols"]["prefix"]);
|
||
pattern_front += "(?:".concat(argument.parameters_get()["indicators_long"].join("|"), ")");
|
||
pattern += pattern_front;
|
||
}
|
||
{
|
||
var pattern_back = "";
|
||
pattern_back += "".concat(settings["environment"][environment]["symbols"]["assignment"]);
|
||
pattern_back += "(".concat(argument.pattern_value(), ")");
|
||
if (argument.type_get() == args.enum_type.boolean) {
|
||
pattern_back = "(?:".concat(pattern_back, ")?");
|
||
}
|
||
pattern += pattern_back;
|
||
}
|
||
lib_plankton.log.debug("lib_args:read:probing_as_volatile:pattern", {
|
||
"pattern": pattern
|
||
});
|
||
var regexp = new RegExp(pattern);
|
||
var matching = regexp.exec(part);
|
||
lib_plankton.log.debug("lib_args:read:probing_as_volatile:matching", {
|
||
"matching": matching
|
||
});
|
||
if (matching == null) {
|
||
// do nothing
|
||
}
|
||
else {
|
||
argument.assign(data, name, matching[1]);
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
},
|
||
function () {
|
||
lib_plankton.log.debug("lib_args:read:probing_as_positional", {
|
||
"part": part
|
||
});
|
||
var positional = _this.filter(args.enum_kind.positional);
|
||
for (var _i = 0, _a = Object.entries(positional); _i < _a.length; _i++) {
|
||
var _b = _a[_i], name = _b[0], argument = _b[1];
|
||
if (argument.parameters_get()['index'] !== index_expected_1) {
|
||
// do nothing
|
||
}
|
||
else {
|
||
lib_plankton.log.debug("lib_args:read:probing_as_positional:trying", {
|
||
"part": part,
|
||
"argument": argument.toString()
|
||
});
|
||
var pattern = "";
|
||
{
|
||
var pattern_back = "";
|
||
pattern_back += "(".concat(argument.pattern_value(), ")");
|
||
pattern += pattern_back;
|
||
}
|
||
lib_plankton.log.debug("lib_args:read:probing_as_positional:pattern", {
|
||
"pattern": pattern
|
||
});
|
||
var regexp = new RegExp(pattern);
|
||
var matching = regexp.exec(part);
|
||
lib_plankton.log.debug("lib_args:read:probing_as_positional:matching", {
|
||
"matching": matching
|
||
});
|
||
if (matching == null) {
|
||
return false;
|
||
}
|
||
else {
|
||
argument.assign(data, name, matching[1]);
|
||
index_expected_1 += 1;
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
},
|
||
].some(function (x) { return x(); });
|
||
if (!found) {
|
||
lib_plankton.log.warning("lib_args:read:could_not_parse", {
|
||
"part": part
|
||
});
|
||
}
|
||
});
|
||
}
|
||
return data;
|
||
break;
|
||
}
|
||
default: {
|
||
throw (new Error("unhandled environment ".concat(environment)));
|
||
break;
|
||
}
|
||
}
|
||
};
|
||
/**
|
||
* @author fenris
|
||
* @todo handle if the data object doesn't have the required field or the type is wrong or sth.
|
||
*/
|
||
class_handler.prototype.write = function (environment, data) {
|
||
switch (environment) {
|
||
case args.enum_environment.cli: {
|
||
return (([]
|
||
.concat(Object.entries(this.filter(args.enum_kind.volatile)).map(function (_a) {
|
||
var name = _a[0], argument = _a[1];
|
||
var values;
|
||
switch (argument.mode_get()) {
|
||
case args.enum_mode.replace: {
|
||
values = [data[argument.name_get()]];
|
||
break;
|
||
}
|
||
case args.enum_mode.accumulate: {
|
||
values = data[argument.name_get()];
|
||
break;
|
||
}
|
||
}
|
||
return (values
|
||
.map(function (value) { return ((settings["environment"][environment]["symbols"]["prefix"]
|
||
+
|
||
argument.parameters_get()["indicators_long"][0])
|
||
+
|
||
(settings["environment"][environment]["symbols"]["assignment"]
|
||
+
|
||
value.toString())); })
|
||
.join(" "));
|
||
}))
|
||
.concat(Object.entries(this.filter(args.enum_kind.positional)).map(function (_a) {
|
||
var name = _a[0], argument = _a[1];
|
||
var raw = "";
|
||
{
|
||
var raw_back = "";
|
||
raw_back += argument.make(data, name);
|
||
raw += raw_back;
|
||
}
|
||
return raw;
|
||
})))
|
||
.join(settings["environment"][environment]["symbols"]["delimiter"]));
|
||
break;
|
||
}
|
||
default: {
|
||
throw (new Error("unhandled environment ".concat(environment)));
|
||
break;
|
||
}
|
||
}
|
||
};
|
||
/**
|
||
* @desc manpage-like info-sheet
|
||
* @author fenris
|
||
*/
|
||
class_handler.prototype.generate_help = function (_a) {
|
||
var _b = _a["programname"], programname = _b === void 0 ? null : _b, _c = _a["author"], author = _c === void 0 ? null : _c, _d = _a["description"], description = _d === void 0 ? null : _d, _e = _a["executable"], executable = _e === void 0 ? null : _e;
|
||
var environment = args.enum_environment.cli;
|
||
var output = "";
|
||
{
|
||
var section = "";
|
||
{
|
||
var line = "";
|
||
line += "";
|
||
line += "INFO";
|
||
line += "\n";
|
||
section += line;
|
||
}
|
||
{
|
||
var line = "";
|
||
line += "\t";
|
||
line += "".concat(programname, " -- ").concat(description);
|
||
line += "\n";
|
||
section += line;
|
||
}
|
||
section += "\n";
|
||
output += section;
|
||
}
|
||
{
|
||
if (author != null) {
|
||
var section = "";
|
||
{
|
||
var line = "";
|
||
line += "";
|
||
line += "AUTHOR";
|
||
line += "\n";
|
||
section += line;
|
||
}
|
||
{
|
||
var line = "";
|
||
line += "\t";
|
||
line += "".concat(author);
|
||
line += "\n";
|
||
section += line;
|
||
}
|
||
section += "\n";
|
||
output += section;
|
||
}
|
||
}
|
||
{
|
||
var section = "";
|
||
{
|
||
var line = "";
|
||
line += "";
|
||
line += "SYNOPSIS";
|
||
line += "\n";
|
||
section += line;
|
||
}
|
||
{
|
||
var line = "";
|
||
line += "\t";
|
||
line += executable;
|
||
line += settings["environment"][environment]["symbols"]["delimiter"];
|
||
line += Object.entries(this.filter(args.enum_kind.positional))
|
||
.map(function (_a) {
|
||
var name = _a[0], argument = _a[1];
|
||
var part = "";
|
||
part += "<".concat(argument.name_get(), ">");
|
||
return part;
|
||
})
|
||
.join(settings["environment"][environment]["symbols"]["delimiter"]);
|
||
line += settings["environment"][environment]["symbols"]["delimiter"];
|
||
line += Object.entries(this.filter(args.enum_kind.volatile))
|
||
.filter(function (_a) {
|
||
var name = _a[0], argument = _a[1];
|
||
return (!argument.hidden_get());
|
||
})
|
||
.map(function (_a) {
|
||
var name = _a[0], argument = _a[1];
|
||
var part = "";
|
||
// part += settings["environment"][environment]["symbols"]["prefix"];
|
||
part += "-";
|
||
part += argument.parameters_get()["indicators_short"][0];
|
||
if (argument.type_get() != "boolean") {
|
||
/*
|
||
part += settings["environment"][environment]["symbols"]["assignment"];
|
||
part += `<${argument.name_get()}>`;
|
||
*/
|
||
part += " ";
|
||
part += "<".concat(argument.name_get(), ">");
|
||
}
|
||
part = "[".concat(part, "]");
|
||
return part;
|
||
})
|
||
.join(settings["environment"][environment]["symbols"]["delimiter"]);
|
||
line += "\n";
|
||
section += line;
|
||
}
|
||
section += "\n";
|
||
output += section;
|
||
}
|
||
{
|
||
var section = "";
|
||
{
|
||
var line = "";
|
||
line += "";
|
||
line += "OPTIONS";
|
||
line += "\n";
|
||
section += line;
|
||
}
|
||
{
|
||
section += (Object.entries(this.arguments_)
|
||
.filter(function (_a) {
|
||
var name = _a[0], argument = _a[1];
|
||
return (!argument.hidden_get());
|
||
})
|
||
.map(function (_a) {
|
||
var name = _a[0], argument = _a[1];
|
||
return argument.generate_help();
|
||
})
|
||
.join("\n"));
|
||
}
|
||
section += "\n";
|
||
output += section;
|
||
}
|
||
return output;
|
||
};
|
||
return class_handler;
|
||
}());
|
||
args.class_handler = class_handler;
|
||
})(args = lib_plankton.args || (lib_plankton.args = {}));
|
||
})(lib_plankton || (lib_plankton = {}));
|