From b2eeb3f1fe3237f156ec1c4bfa2aec3c18ed8cbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Fra=C3=9F?= Date: Thu, 3 Apr 2025 11:47:47 +0000 Subject: [PATCH 1/2] [task-193] [int] --- misc/conf-example.json | 2 +- source/logic/backend.ts | 57 ++++++++ source/pages/invite_handle/logic.ts | 155 ++++++++++++++++++++++ source/pages/invite_handle/structure.html | 19 +++ source/pages/invite_handle/style.css | 15 +++ tools/makefile | 7 +- 6 files changed, 252 insertions(+), 3 deletions(-) create mode 100644 source/pages/invite_handle/logic.ts create mode 100644 source/pages/invite_handle/structure.html create mode 100644 source/pages/invite_handle/style.css diff --git a/misc/conf-example.json b/misc/conf-example.json index 5eb6264..9a3665c 100644 --- a/misc/conf-example.json +++ b/misc/conf-example.json @@ -2,7 +2,7 @@ "backend": { "scheme": "http", "host": "localhost", - "port": 7979, + "port": 4916, "path_base": "" } } diff --git a/source/logic/backend.ts b/source/logic/backend.ts index ec1eb96..01446a9 100644 --- a/source/logic/backend.ts +++ b/source/logic/backend.ts @@ -485,4 +485,61 @@ namespace _espe.backend ); } + + /** + */ + export async function invite_examine( + key : string + ) : Promise< + { + membership_number_mode : int; + membership_number_value : (null | string); + name_mode : int; + name_value : string; + email_address_mode : int; + email_address_value : (null | string); + groups_mode : int; + groups_value : Array; + } + > + { + return abstract_call( + "GET", + lib_plankton.string.coin( + "/invite/examine?key={{key}}", + { + "key": key + } + ) + ); + } + + + /** + */ + export async function invite_accept( + key : string, + data : { + membership_number_value : string; + name_value : string; + email_address_value : (null | string); + groups_value : Array; + } + ) : Promise + { + return abstract_call( + "POST", + "/invite/accept", + { + "data": { + "key": key, + "membership_number_value": data.membership_number_value, + "name_value": data.name_value, + "email_address_value": data.email_address_value, + "groups_value": data.groups_value, + } + } + ); + } + } diff --git a/source/pages/invite_handle/logic.ts b/source/pages/invite_handle/logic.ts new file mode 100644 index 0000000..2e7062e --- /dev/null +++ b/source/pages/invite_handle/logic.ts @@ -0,0 +1,155 @@ +/* +Espe | Ein schlichtes Werkzeug zur Mitglieder-Verwaltung | Frontend +Copyright (C) 2024 Christian Fraß + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public +License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later +version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program. If not, see +. + */ + +lib_plankton.zoo_page.register( + "invite_handle", + async (parameters, target_element) => { + // parameters + const key : string = parameters["key"]; + + target_element.appendChild(template_request("invite_handle")); + + /** + * @todo invite_handle-title + */ + + const data : { + membership_number_mode : int; + membership_number_value : (null | string); + name_mode : int; + name_value : string; + email_address_mode : int; + email_address_value : (null | string); + groups_mode : int; + groups_value : Array; + } = await _espe.backend.invite_examine(key); + + const form = new lib_plankton.zoo_form.class_form< + { + membership_number_value : (null | string); + name_value : string; + email_address_value : (null | string); + groups_value : Array; + }, + { + membership_number_value : string; + name_value : string; + email_address_value : string; + groups_value : Array; + } + >( + value => ({ + "membership_number_value": (value.membership_number_value ?? ""), + "name_value": value.name_value, + "email_address_value": (value.email_address_value ?? ""), + "groups_value": value.groups_value, + }), + representation => ({ + "membership_number_value": representation.membership_number_value, + "name_value": representation.name_value, + "email_address_value": representation.email_address_value, + "groups_value": representation.groups_value, + }), + new lib_plankton.zoo_input.class_input_group( + [ + { + "name": "name_value", + "input": new lib_plankton.zoo_input.class_input_text( + { + "read_only": (data.name_mode <= 1), + } + ), + /** + * @todo translate + */ + "label": "Name", + }, + { + "name": "membership_number_value", + "input": new lib_plankton.zoo_input.class_input_text( + { + "read_only": (data.membership_number_mode <= 1), + } + ), + /** + * @todo translate + */ + "label": "Mitgliedsnummer", + }, + { + "name": "email_address_value", + "input": new lib_plankton.zoo_input.class_input_text( + { + "read_only": (data.email_address_mode <= 1), + } + ), + /** + * @todo translate + */ + "label": "E-Mail-Adresse", + }, + { + "name": "groups_value", + "input": new lib_plankton.zoo_input.class_input_list( + () => new lib_plankton.zoo_input.class_input_text(), + { + /** + * @todo does not work yet + */ + // "read_only": (data.groups_mode <= 1), + } + ), + /** + * @todo translate + */ + "label": "Gruppen", + }, + ] + ), + [ + { + "label": "Senden", + "procedure": async (get_value, get_representation) => { + const value = await get_value(); + await _espe.backend.invite_accept( + key, + { + "membership_number_value": value.membership_number_value, + "name_value": value.name_value, + "email_address_value": value.email_address_value, + "groups_value": value.groups_value, + } + ); + /** + * @todo redirect + */ + /* + lib_plankton.zoo_page.set({"name": "view", "parameters": {"id": id}}); + */ + }, + } + ] + ); + await form.setup(target_element.querySelector(".invite_handle-form") as HTMLElement); + await form.input_write( + { + "membership_number_value": data.membership_number_value, + "name_value": data.name_value, + "email_address_value": data.email_address_value, + "groups_value": data.groups_value, + } + ); + } +); diff --git a/source/pages/invite_handle/structure.html b/source/pages/invite_handle/structure.html new file mode 100644 index 0000000..7abba5e --- /dev/null +++ b/source/pages/invite_handle/structure.html @@ -0,0 +1,19 @@ + + + diff --git a/source/pages/invite_handle/style.css b/source/pages/invite_handle/style.css new file mode 100644 index 0000000..791713b --- /dev/null +++ b/source/pages/invite_handle/style.css @@ -0,0 +1,15 @@ +/* +Espe | Ein schlichtes Werkzeug zur Mitglieder-Verwaltung | Frontend +Copyright (C) 2024 Christian Fraß + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public +License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later +version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program. If not, see +. + */ + diff --git a/tools/makefile b/tools/makefile index 24dfef8..9968b9b 100644 --- a/tools/makefile +++ b/tools/makefile @@ -47,6 +47,7 @@ ${dir_temp}/logic-unlinked.js: \ ${dir_source}/pages/register/logic.ts \ ${dir_source}/pages/password_change_init/logic.ts \ ${dir_source}/pages/password_change_exec/logic.ts \ + ${dir_source}/pages/invite_handle/logic.ts \ ${dir_source}/logic/main.ts @ ${cmd_log} "logic | compile …" @ ${cmd_mkdir} $(dir $@) @@ -68,7 +69,8 @@ ${dir_build}/style.css: \ ${dir_source}/pages/view/style.css \ ${dir_source}/pages/register/style.css \ ${dir_source}/pages/password_change_init/style.css \ - ${dir_source}/pages/password_change_exec/style.css + ${dir_source}/pages/password_change_exec/style.css \ + ${dir_source}/pages/invite_handle/style.css @ ${cmd_log} "style …" @ ${cmd_mkdir} $(dir $@) @ ${cmd_cat} $^ > $@ @@ -83,7 +85,8 @@ ${dir_build}/index.html: \ ${dir_source}/pages/view/structure.html \ ${dir_source}/pages/register/structure.html \ ${dir_source}/pages/password_change_init/structure.html \ - ${dir_source}/pages/password_change_exec/structure.html + ${dir_source}/pages/password_change_exec/structure.html \ + ${dir_source}/pages/invite_handle/structure.html @ ${cmd_log} "structure …" @ ${cmd_mkdir} $(dir $@) @ tools/make-index $^ > $@ -- 2.39.5 From 76a2d7dff4ebbc4d942ae9398fedbf2fe7f3721e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Fra=C3=9F?= Date: Sat, 12 Apr 2025 10:19:59 +0000 Subject: [PATCH 2/2] [task-193] [int] --- lib/plankton/plankton.d.ts | 1034 +++-- lib/plankton/plankton.js | 3380 +++++++++++++---- source/data/localization/deu.loc.json | 4 +- source/data/localization/eng.loc.json | 4 +- source/logic/backend.ts | 35 +- source/logic/main.ts | 5 + source/pages/invite_handle/logic.ts | 73 +- source/pages/invite_list/logic.ts | 81 + .../style.css => invite_list/structure.html} | 11 +- source/pages/list/logic.ts | 2 +- source/pages/view/style.css | 15 - source/style/style.css | 19 +- tools/makefile | 5 +- 13 files changed, 3577 insertions(+), 1091 deletions(-) create mode 100644 source/pages/invite_list/logic.ts rename source/pages/{invite_handle/style.css => invite_list/structure.html} (80%) diff --git a/lib/plankton/plankton.d.ts b/lib/plankton/plankton.d.ts index 883b649..1598f00 100644 --- a/lib/plankton/plankton.d.ts +++ b/lib/plankton/plankton.d.ts @@ -6,29 +6,6 @@ type int = number; * @author fenris */ type float = number; -/** - * @author fenris - */ -type type_date = { - year: int; - month: int; - day: int; -}; -/** - * @author fenris - */ -type type_time = { - hour: int; - minute: int; - second: int; -}; -/** - * @author fenris - */ -type type_datetimeobject = { - date: type_date; - time: type_time; -}; declare class Buffer { constructor(x: string, modifier?: string); toString(modifier?: string): string; @@ -247,6 +224,12 @@ declare namespace lib_plankton.base { /** */ function object_merge(core: Record, mantle: Record): Record; + /** + */ + function buffer_show(buffer: Buffer, { "block_size": option_block_size, "break_char": option_break_char, }?: { + block_size?: int; + break_char?: string; + }): string; } declare module lib_plankton.pod { /** @@ -297,7 +280,10 @@ declare module lib_plankton.pod { */ class class_pod { private subject; - private constructor(); + constructor(subject: type_pod); + tear(): type_pod; + static empty(): class_pod; + static filled(value: type_value): class_pod; is_empty(): boolean; is_filled(): boolean; cull(): type_value; @@ -372,36 +358,6 @@ declare namespace lib_plankton.call { */ function promise_delay(promise: type_promise, delay: int): type_promise; } -declare namespace lib_plankton.call { - /** - */ - class CancellablePromise extends Promise { - /** - */ - private cancelled; - /** - */ - private interval; - /** - */ - private subject; - /** - */ - constructor(executor: ((resolve: any, reject: any) => void)); - /** - */ - private clear; - /** - */ - then(onfulfilled?: ((value: type_result) => (type_next_resolved | PromiseLike)), onrejected?: ((reason: any) => (type_next_rejected | PromiseLike))): Promise; - /** - */ - catch(x: any): Promise; - /** - */ - cancel(): void; - } -} /** * initializer might be obsolete, since promises are reusable after having been resolved or rejected */ @@ -565,25 +521,25 @@ declare namespace lib_plankton.call { * @param {Object} args * @author fenris */ - function args2list(args: any): Array; + export function args2list(args: any): Array; /** * just the empty function; useful for some callbacks etc. * * @author fenris */ - function nothing(): void; + export function nothing(): void; /** * just the identity; useful for some callbacks etc.; defined as function instead of const for using type parameters * * @author fenris */ - function id(x: type_value): type_value; + export function id(x: type_value): type_value; /** * just the identity; useful for some callbacks etc. * * @author fenris */ - function const_(x: type_value): ((y: any) => type_value); + export function const_(x: type_value): ((y: any) => type_value); /** * composes two functions (i.e. returns a function that return the result of the successive execution of both input-functions) * @@ -591,7 +547,7 @@ declare namespace lib_plankton.call { * @param {function} function_g * @author fenris */ - function compose(function_f: ((type_x: any) => type_y), function_g: ((type_y: any) => type_z)): ((value: type_x) => type_z); + export function compose(function_f: ((type_x: any) => type_y), function_g: ((type_y: any) => type_z)): ((value: type_x) => type_z); /** * transforms a function with sequential input to a function with leveled input; example: add(2,3) = curryfy(add)(2)(3) * @@ -599,27 +555,46 @@ declare namespace lib_plankton.call { * @return {function} the currified version of the in put function * @author fenris */ - function curryfy(f: Function): Function; + export function curryfy(f: Function): Function; /** * @author fenris */ - function convey(value: any, functions: Array): any; + export function convey(value: any, functions: Array): any; + /** + */ + class class_value_wrapper { + /** + */ + private value; + /** + */ + constructor(value: type_value); + /** + */ + convey(function_: ((value: type_value) => type_value_result)): class_value_wrapper; + /** + */ + cull(): type_value; + } + /** + */ + export function wrap(value: type_value): class_value_wrapper; /** * @author fenris */ - function timeout(procedure: (() => void), delay_in_seconds: float): int; + export function timeout(procedure: (() => void), delay_in_seconds: float): int; /** * Promise version of "setTimeout" * * @author fenris */ - function defer(seconds: float, action: (() => type_result)): Promise; + export function defer(seconds: float, action: (() => type_result)): Promise; /** * a definition for a value being "defined" * * @author neuc */ - function is_def(obj: type_value, options?: { + export function is_def(obj: type_value, options?: { null_is_valid?: boolean; }): boolean; /** @@ -627,7 +602,7 @@ declare namespace lib_plankton.call { * * @author neuc */ - function def_val(value: any, default_value: any, options?: { + export function def_val(value: any, default_value: any, options?: { type?: (null | string); null_is_valid?: boolean; }): any; @@ -638,7 +613,7 @@ declare namespace lib_plankton.call { * @return {function} * @author fenris */ - function attribute(name: string): ((object: type_object) => type_attribute); + export function attribute(name: string): ((object: type_object) => type_attribute); /** * provides a method of a class as a regular function; useful for processing lists of objects * @@ -646,48 +621,33 @@ declare namespace lib_plankton.call { * @return {function} * @author fenris */ - function method(name: string): ((object: type_object) => type_output); + export function method(name: string): ((object: type_object) => type_output); /** * @author fenris */ - type type_coproduct = { + export type type_coproduct = { kind: string; data?: any; }; /** * @author fenris */ - function distinguish(coproduct: type_coproduct, handlers: Record type_output)>, options?: { + export function distinguish(coproduct: type_coproduct, handlers: Record type_output)>, options?: { fallback?: (null | ((coproduct?: type_coproduct) => type_output)); }): type_output; /** - * for rate_limit_check - * - * @author fenris */ - type type_mana_snapshot = { - timestamp: float; - value: float; + export function try_catch_wrap(get_value: (() => type_value)): { + value: (null | type_value); + error: (null | any); }; /** - * 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 */ - function rate_limit_check(setup: { - capacity: float; - regeneration_rate: float; - get_snapshot: (() => Promise<(null | type_mana_snapshot)>); - set_snapshot: ((snapshot: type_mana_snapshot) => Promise); - update_snapshot: ((timestamp: float, value_increment: float) => Promise); - }, heft: float): Promise<{ - granted: boolean; - seconds: (null | float); + export function try_catch_wrap_async(get_value: (() => Promise)): Promise<{ + value: (null | type_value); + error: (null | any); }>; + export {}; } declare namespace lib_plankton.file { /** @@ -900,13 +860,26 @@ declare namespace lib_plankton.code { } declare namespace lib_plankton.json { /** - * @author fenris */ - function encode(x: any, formatted?: boolean): string; + type type_source = any; + /** + */ + type type_target = string; /** * @author fenris */ - function decode(x: string): any; + export function encode(source: type_source, options?: { + formatted?: boolean; + }): type_target; + /** + * @author fenris + */ + export function decode(target: type_target): type_source; + /** + * @author fenris + */ + export function implementation_code(): lib_plankton.code.type_code; + export {}; } declare namespace lib_plankton.json { /** @@ -960,6 +933,16 @@ declare namespace lib_plankton.base64 { decode(x: string): string; } } +declare namespace lib_plankton.email { + /** + */ + function send(smtp_credentials: { + host: string; + port: int; + username: string; + password: string; + }, sender: string, receivers: Array, subject: string, content: string): Promise; +} declare namespace lib_plankton.log { /** */ @@ -970,124 +953,265 @@ declare namespace lib_plankton.log { warning = 3, error = 4 } - /** - */ - function level_order(level1: enum_level, level2: enum_level): boolean; - /** - */ - function level_show(level: enum_level): string; /** */ type type_entry = { level: enum_level; incident: string; - details: Record; + tags: Array; + details: any; }; + /** + */ + type type_channel_description = lib_plankton.call.type_coproduct; + /** + */ + type type_channel_logic = { + send: ((entry: type_entry) => void); + }; + /** + */ + type type_logger_data = Array; + /** + */ + type type_logger_logic = Array; + /** + */ + type type_format_definition = ({ + kind: "jsonl"; + data: { + structured: boolean; + }; + } | { + kind: "human_readable"; + data: {}; + }); +} +declare namespace lib_plankton.log { + /** + */ + function level_order(level1: enum_level, level2: enum_level): boolean; + /** + */ + function level_show(level: enum_level, { "abbreviated": option_abbreviated, }?: { + abbreviated?: boolean; + }): string; + /** + */ + function level_decode(level_string: string): enum_level; +} +declare namespace lib_plankton.log { + /** + * @todo use label + */ + function get_logger_logic(logger_data: type_logger_data): type_logger_logic; + /** + */ + function format_entry(format_definition: type_format_definition, entry: type_entry): string; + /** + */ + function parse_format_definition(format_definition_raw: any): type_format_definition; +} +declare namespace lib_plankton.log.channel.filtered { + /** + */ + type type_predicate = ((entry: type_entry) => boolean); + /** + */ + type type_subject = { + /** + * @todo check if it has to be logic + */ + core: type_channel_logic; + predicate: type_predicate; + }; + /** + */ + function predicate_incident(substring: string): type_predicate; + /** + */ + function predicate_level(threshold: enum_level): type_predicate; + /** + */ + function predicate_tag(tag: string): type_predicate; + /** + * combines other predicates in disjunctive normal form + */ + function predicate_complex(definition: Array>): type_predicate; + /** + */ + function send(subject: type_subject, entry: type_entry): void; + /** + */ + function logic(subject: type_subject): type_channel_logic; +} +declare namespace lib_plankton.log.channel.minlevel { + /** + */ + type type_subject = { + /** + * @todo check if it has to be logic + */ + core: type_channel_logic; + threshold: enum_level; + }; + /** + */ + function send(subject: type_subject, entry: type_entry): void; + /** + */ + function logic(subject: type_subject): type_channel_logic; } /** - * @deprecated - * @todo remove + * output for writing log entries to web console */ -declare namespace lib_plankton.log { - function level_push(level: int): void; - function level_pop(): void; - function indent_push(indent: int): void; - function indent_pop(): void; - function indent_inc(): void; - function indent_dec(): void; +declare namespace lib_plankton.log.channel.console_ { /** - * @author fenris */ - function write({ "message": message, "type": type, "prefix": prefix, "level": level, "indent": indent, }: { - message?: string; - type?: string; - prefix?: string; - level?: int; - indent?: int; + type type_subject = {}; + /** + * @todo tags + */ + function send(subject: type_subject, entry: type_entry): void; + /** + */ + function logic(subject: type_subject): type_channel_logic; +} +declare namespace lib_plankton.log { + /** + */ + function get_channel_logic(channel_description: type_channel_description): type_channel_logic; +} +declare namespace lib_plankton.log { + /** + */ + function default_logger(): type_logger_data; +} +declare namespace lib_plankton.log { + /** + */ + function set_main_logger(logger_data: type_logger_data): void; + /** + * consumes a log entry, i.e. sends it to all channels + */ + function send_(logger: type_logger_logic, entry: type_entry): void; + /** + * [convenience] + * + * @todo rename to "send" + */ + function debug_(logger: type_logger_logic, incident: string, { "tags": option_tags, "details": option_details, }?: { + tags?: Array; + details?: any; }): void; -} -declare namespace lib_plankton.log { /** + * [convenience] + * + * @todo rename to "info" */ - abstract class class_channel { - /** - */ - abstract add(entry: type_entry): void; - } -} -declare namespace lib_plankton.log { + function info_(logger: type_logger_logic, incident: string, { "tags": option_tags, "details": option_details, }?: { + tags?: Array; + details?: any; + }): void; /** - * output for writing log entries to web console + * [convenience] + * + * @todo rename to "notice" */ - class class_channel_console extends class_channel { - /** - */ - add(entry: type_entry): void; - } -} -declare namespace lib_plankton.log { + function notice_(logger: type_logger_logic, incident: string, { "tags": option_tags, "details": option_details, }?: { + tags?: Array; + details?: any; + }): void; /** - * decorator for filtering out log entries below a certain level threshold + * [convenience] + * + * @todo rename to "warning" */ - class class_channel_minlevel extends class_channel { - /** - */ - private core; - /** - */ - private threshold; - /** - */ - constructor(core: class_channel, threshold: enum_level); - /** - */ - add(entry: type_entry): void; - } -} -declare namespace lib_plankton.log { + function warning_(logger: type_logger_logic, incident: string, { "tags": option_tags, "details": option_details, }?: { + tags?: Array; + details?: any; + }): void; /** + * [convenience] + * + * @todo rename to "error" */ - function channel_make(description: { - kind: string; - data?: { - [key: string]: any; - }; - }): class_channel; + function error_(logger: type_logger_logic, incident: string, { "tags": option_tags, "details": option_details, }?: { + tags?: Array; + details?: any; + }): void; /** + * [convenience] */ - type type_configuration = Array; + function _send(entry: type_entry): void; /** + * [convenience] */ - function conf_default(): type_configuration; -} -declare namespace lib_plankton.log { + function _debug(incident: string, { "tags": option_tags, "details": option_details, }?: { + tags?: Array; + details?: any; + }): void; /** - * pushes a new configuration on the stack and activates it + * [convenience] */ - function conf_push(channels: type_configuration): void; + function _info(incident: string, { "tags": option_tags, "details": option_details, }?: { + tags?: Array; + details?: any; + }): void; /** - * pops the current active configuration from the stack + * [convenience] */ - function conf_pop(): void; + function _notice(incident: string, { "tags": option_tags, "details": option_details, }?: { + tags?: Array; + details?: any; + }): void; /** - * consumes a log entry, i.e. sends it to the currently active outputs + * [convenience] */ - function add(entry: type_entry): void; + function _warning(incident: string, { "tags": option_tags, "details": option_details, }?: { + tags?: Array; + details?: any; + }): void; /** + * [convenience] */ - function debug(incident: string, details?: Record): void; + function _error(incident: string, { "tags": option_tags, "details": option_details, }?: { + tags?: Array; + details?: any; + }): void; /** + * [convenience] + * + * @deprecated use ._debug instead! */ - function info(incident: string, details?: Record): void; + function debug(incident: string, details?: any, tags?: Array): void; /** + * [convenience] + * + * @deprecated use ._info instead! */ - function notice(incident: string, details?: Record): void; + function info(incident: string, details?: any, tags?: Array): void; /** + * [convenience] + * + * @deprecated use ._notice instead! */ - function warning(incident: string, details?: Record): void; + function notice(incident: string, details?: any, tags?: Array): void; /** + * [convenience] + * + * @deprecated use ._warning instead! */ - function error(incident: string, details?: Record): void; + function warning(incident: string, details?: any, tags?: Array): void; + /** + * [convenience] + * + * @deprecated use ._error instead! + */ + function error(incident: string, details?: any, tags?: Array): void; } declare var plain_text_to_html: (text: string) => string; /** @@ -1125,7 +1249,7 @@ declare namespace lib_plankton.string { * @return {Array} * @author fenris */ - function split(chain: string, separator?: string): Array; + function split(chain: string, separator: string): Array; /** * @author neu3no */ @@ -1211,6 +1335,9 @@ declare namespace lib_plankton.string { /** */ function slice(str: string, size: int): Array; + /** + */ + function capitalize(str: string): string; } /** * @deprecated @@ -1254,114 +1381,105 @@ declare var make_logger: (prefix: any, current_loglevel: any) => (obj: any, lvl: declare namespace lib_plankton.object { /** * @author fenris + * @deprecated use the "??" operator instead */ - function fetch(object: Object, fieldname: string, fallback?: type_value, escalation?: int): type_value; + function fetch(object: Object, fieldname: string, options?: { + fallback?: type_value; + escalate?: boolean; + }): type_value; /** - * @author fenris */ - function map(object_from: { - [key: string]: type_from; - }, transformator: (value_from: type_from, key?: string) => type_to): { - [key: string]: type_to; - }; + function map(object_from: Record, transformator: ((value_from: type_from, key?: string) => type_to)): Record; /** - * @desc gibt ein Objekt mit bestimmten Einträgen des Eingabe-Objekts zurück - * @author fenris + * gibt ein Objekt mit bestimmten Einträgen des Eingabe-Objekts zurück */ - function filter(object_from: { - [key: string]: type_value; - }, predicate: (value_from: type_value, key?: string) => boolean): { - [key: string]: type_value; - }; + function filter(object_from: Record, predicate: ((value_from: type_value, key?: string) => boolean)): Record; /** - * @desc wandelt ein Array mit Einträgen der Form {key,value} in ein entsprechendes Objekt um - * @author fenris + * wandelt ein Array mit Einträgen der Form {key,value} in ein entsprechendes Objekt um + * + * @deprecated use Object.fromEntries instead! */ function from_array(array: Array<{ key: string; value: type_value; - }>): { - [key: string]: type_value; - }; + }>): Record; /** - * @desc wandelt ein Objekt in ein entsprechendes Array mit Einträgen der Form {key,value} um - * @author fenris + * wandelt ein Objekt in ein entsprechendes Array mit Einträgen der Form {key,value} um + * + * @deprecated use Object.entries insetad! */ - function to_array(object: { - [key: string]: type_value; - }): Array<{ + function to_array(object: Record): Array<{ key: string; value: type_value; }>; /** - * @desc gibt eine Liste von Schlüsseln eines Objekts zurück - * @author fenris + * gibt eine Liste von Schlüsseln eines Objekts zurück + * + * @deprecated use Object.keys instead! */ - function keys(object: { - [key: string]: any; - }): Array; + function keys(object: Record): Array; /** - * @desc gibt eine Liste von Werten eines Objekts zurück - * @author fenris + * gibt eine Liste von Werten eines Objekts zurück + * + * @deprecated use Object.values instead! */ - function values(object: { - [key: string]: type_value; - }): Array; + function values(object: Record): Array; /** - * @desc liest ein Baum-artiges Objekt an einer bestimmten Stelle aus - * @author fenris + * liest ein Baum-artiges Objekt an einer bestimmten Stelle aus */ - function path_read(object: Object, path: string, fallback?: type_value, escalation?: int): type_value; + function path_read(object: Object, path: string, options?: { + fallback?: type_value; + escalate?: boolean; + }): type_value; /** - * @desc schreibt einen Wert an eine bestimmte Stelle in einem Baum-artigen Objekt - * @author fenris + * schreibt einen Wert an eine bestimmte Stelle in einem Baum-artigen Objekt */ function path_write(object: Object, path: string, value: type_value, construct?: boolean): void; /** - * @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 + * prüft ob ein Objekt einem bestimmten Muster entspricht + * + * @deprecated not very useful */ - function matches(object: Object, pattern: Object, collate?: typeof instance_collate): boolean; + function matches(object: Record, pattern: Record, options?: { + collate?: ((value_pattern: type_value_pattern, value_object: type_value_object) => boolean); + }): boolean; /** - * @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 + * erzeugt eine Projektion eines Baum-artigen Objekts in ein Listen-artiges Objekt */ - function flatten(value: any, separator?: string, key_for_element?: (index: int) => string): Object; + function flatten(value: any, options?: { + separator?: string; + key_for_array_element?: ((index: int) => string); + }): Record; /** - * @author fenris + * @deprecated use Object.assign instead! */ - function clash(x: { - [key: string]: any; - }, y: { - [key: string]: any; - }, { "overwrite": overwrite, "hooks": { "existing": hook_existing, }, }?: { + function clash(x: Record, y: Record, options?: { overwrite?: boolean; hooks?: { - existing?: (key?: string, value_old?: any, value_new?: any) => void; + existing?: ((key?: string, value_old?: any, value_new?: any) => void); }; - }): { - [key: string]: any; - }; + }): Record; + /** + * @deprecated use Object.assign instead! + */ + function patch(core: (null | Record), mantle: (null | Record), options?: { + deep?: boolean; + path?: (null | string); + }): void; + /** + * @deprecated use Object.assign instead! + */ + function patched(core: Record, mantle: Record, options?: { + deep?: boolean; + }): Record; + /** + * @deprecated use Object.assign instead! + */ + function attached(object: Record, key: string, value: any): Record; /** * @author fenris */ - function patch(core: Object, mantle: Object, deep?: boolean, path?: string): void; - /** - * @author fenris - */ - function patched(core: Object, mantle: Object, deep?: boolean): Object; - /** - * @author fenris - */ - function attached(object: Object, key: string, value: any): Object; - /** - * @author fenris - */ - function copy(object: Object): Object; + function copy(object: Record): Record; } declare namespace lib_plankton.translate { /** @@ -1490,6 +1608,7 @@ declare namespace lib_plankton.database { type type_description_insert = { table_name: string; values: Record; + returning?: (null | string); }; /** */ @@ -1534,6 +1653,7 @@ declare namespace lib_plankton.database { * @author fenris */ type type_database = { + wrap_name: ((name: string) => string); query_free_get: ((query: type_query) => Promise); query_free_put: ((query: type_query) => Promise); query_free_set: ((query: type_query) => Promise); @@ -1706,7 +1826,7 @@ declare namespace lib_plankton.storage.memory { clear(): Promise; write(key: any, value: any): Promise; delete(key: any): Promise; - read(key: any): Promise>; + read(key: any): Promise; search(term: any): Promise<{ key: string; preview: string; @@ -1774,6 +1894,301 @@ declare namespace lib_plankton.storage.localstorage { }[]>; } } +declare namespace lib_plankton.map { + /** + */ + type type_pair = { + key: type_key; + value: type_value; + }; + /** + * @author fenris + */ + type type_map = { + size: (() => int); + has: ((key: type_key) => boolean); + get: ((key: type_key, fallback?: lib_plankton.pod.type_pod) => type_value); + set: ((key: type_key, value: type_value) => void); + delete: ((key: type_key) => void); + iterate: ((procedure: ((value: type_value, key?: type_key) => void)) => void); + }; +} +declare namespace lib_plankton.map { + /** + */ + function clear(map: type_map): void; + /** + */ + function keys(map: type_map): Array; + /** + */ + function values(map: type_map): Array; + /** + */ + function dump(map: type_map): Array>; + /** + */ + function show(map: type_map, options?: { + show_key?: ((key: type_key) => string); + show_value?: ((value: type_value) => string); + }): string; +} +declare namespace lib_plankton.map.simplemap { + /** + */ + type type_subject = { + data: Record; + }; + /** + */ + function make(options?: { + data?: Record; + }): type_subject; + /** + */ + function size(subject: type_subject): int; + /** + */ + function has(subject: type_subject, key: string): boolean; + /** + */ + function get_safe(subject: type_subject, key: string): lib_plankton.pod.type_pod; + /** + */ + function get(subject: type_subject, key: string, fallback?: lib_plankton.pod.type_pod): type_value; + /** + */ + function set(subject: type_subject, key: string, value: type_value): void; + /** + */ + function delete_(subject: type_subject, key: string): void; + /** + */ + function iterate(subject: type_subject, procedure: ((value?: type_value, key?: string) => void)): void; + /** + */ + function implementation_map(subject: type_subject): type_map; +} +declare namespace lib_plankton.map.hashmap { + /** + * we base the hashmap on a simplemap, whos keys are the hashes and whos values are the key/value-pairs + */ + type type_subject = { + hashing: ((key: type_key) => string); + core: lib_plankton.map.simplemap.type_subject>; + }; + /** + */ + function make(hashing: ((key: type_key) => string), options?: { + pairs?: Array>; + }): type_subject; + /** + */ + function size(subject: type_subject): int; + /** + */ + function has(subject: type_subject, key: type_key): boolean; + /** + */ + function get(subject: type_subject, key: type_key, fallback?: lib_plankton.pod.type_pod): type_value; + /** + */ + function set(subject: type_subject, key: type_key, value: type_value): void; + /** + */ + function delete_(subject: type_subject, key: type_key): void; + /** + */ + function iterate(subject: type_subject, procedure: ((value?: type_value, key?: type_key) => void)): void; + /** + */ + function implementation_map(subject: type_subject): type_map; +} +declare namespace lib_plankton.map.collatemap { + /** + */ + type type_collation = ((key1: type_key, key2: type_key) => boolean); + /** + */ + export type type_subject = { + collation: type_collation; + pairs: Array>; + }; + /** + */ + export function make(collation: type_collation, options?: { + pairs?: Array>; + }): type_subject; + /** + */ + export function size(subject: type_subject): int; + /** + */ + export function has(subject: type_subject, key: type_key): boolean; + /** + * @todo use .find + */ + export function get(subject: type_subject, key: type_key, fallback?: lib_plankton.pod.type_pod): type_value; + /** + */ + export function set(subject: type_subject, key: type_key, value: type_value): void; + /** + */ + export function delete_(subject: type_subject, key: type_key): void; + /** + */ + export function iterate(subject: type_subject, function_: ((value?: type_value, key?: type_key) => void)): void; + /** + */ + export function implementation_map(subject: type_subject): type_map; + export {}; +} +declare namespace lib_plankton.pit { + /** + */ + type type_date = { + year: int; + month: int; + day: int; + }; + /** + */ + type type_ywd = { + year: int; + week: int; + day: int; + }; + /** + */ + type type_time = { + hour: int; + minute: int; + second: int; + }; + /** + */ + type type_datetime = { + timezone_shift: int; + date: type_date; + time: (null | type_time); + }; + /** + */ + type type_pit = int; +} +declare namespace lib_plankton.pit { + /** + * @todo complete + */ + function timezone_name_to_timezone_shift(timezone_name: string): int; + /** + */ + function date_object_get_week_of_year(date: Date): int; + /** + */ + function to_unix_timestamp(pit: type_pit): int; + /** + */ + function from_unix_timestamp(unix_timestamp: int): type_pit; + /** + */ + function to_date_object(pit: type_pit): Date; + /** + * @todo test + */ + function to_datetime(pit: type_pit, { "timezone_shift": option_timezone_shift, }?: { + timezone_shift?: int; + }): type_datetime; + /** + */ + function from_datetime(datetime: type_datetime): type_pit; + /** + */ + function is_before(pit: type_pit, reference: type_pit): boolean; + /** + */ + function is_between(pit: type_pit, reference_left: type_pit, reference_right: type_pit): boolean; + /** + */ + function shift_day(pit: type_pit, increment: int): type_pit; + /** + */ + function shift_week(pit: type_pit, increment: int): type_pit; + /** + */ + function trunc_week(pit: type_pit): type_pit; + /** + */ + function now(): type_pit; + /** + * @param year year according to specified timezone shift + * @param week week according to specified timezone shift + * @return the begin of the week (monday, 00:00) + */ + function from_ywd(ywd: type_ywd, { "timezone_shift": option_timezone_shift, }?: { + timezone_shift?: int; + }): type_pit; + /** + * @todo timezone + */ + function to_ywd(pit: type_pit, { "timezone_shift": option_timezone_shift, }?: { + timezone_shift?: int; + }): type_ywd; + /** + * computes the point in time for switching to central european summer time + * + * @todo write tests + */ + function cest_switch_on(year: int): type_pit; + /** + * computes the point in time for switching away from central european summer time + * + * @todo write tests + */ + function cest_switch_off(year: int): type_pit; + /** + */ + function timezone_shift_ce(pit: type_pit): int; + /** + * [convenience] + */ + function to_datetime_ce(pit: type_pit): type_datetime; + /** + */ + function datetime_translate(datetime: type_datetime, timezone_shift: int): type_datetime; + /** + * [convenience] + */ + function datetime_translate_ce(datetime: type_datetime): type_datetime; + /** + */ + function timezone_shift_format(timezone_shift: int): string; + /** + */ + function date_format(date: type_date): string; + /** + */ + function time_format(time: type_time, { "show_seconds": option_show_seconds, }?: { + show_seconds?: boolean; + }): string; + /** + * @todo show timezone + */ + function datetime_format(datetime: (null | type_datetime), { "timezone_indicator": option_timezone_indicator, "show_timezone": option_show_timezone, "adjust_to_ce": option_adjust_to_ce, "omit_date": option_omit_date, }?: { + timezone_indicator?: string; + show_timezone?: boolean; + adjust_to_ce?: boolean; + omit_date?: boolean; + }): string; + /** + */ + function timespan_format(from: type_datetime, to: (null | type_datetime), { "timezone_indicator": option_timezone_indicator, "show_timezone": option_show_timezone, "adjust_to_ce": option_adjust_to_ce, "omit_date": option_omit_date, }?: { + timezone_indicator?: string; + show_timezone?: boolean; + adjust_to_ce?: boolean; + omit_date?: boolean; + }): string; +} declare namespace lib_plankton.zoo_input { /** * @author fenris @@ -1821,6 +2236,40 @@ declare namespace lib_plankton.zoo_input { write(value: type_value_outer): Promise; } } +declare namespace lib_plankton.zoo_input { + /** + * @author fenris + */ + class class_input_soft implements interface_input<(null | type_value_core)> { + /** + */ + private core; + /** + */ + private dom_set; + /** + */ + private dom_wrapper; + /** + */ + constructor(core: interface_input, options?: {}); + /** + */ + private toggle; + /** + * [implementation] + */ + setup(parent: HTMLElement): Promise; + /** + * [implementation] + */ + read(): Promise<(null | type_value_core)>; + /** + * [implementation] + */ + write(value: (null | type_value_core)): Promise; + } +} declare namespace lib_plankton.zoo_input { /** * @author fenris @@ -1942,7 +2391,7 @@ declare namespace lib_plankton.zoo_input { /** * @author fenris */ - class class_input_date implements interface_input<(null | type_date)> { + class class_input_date implements interface_input<(null | lib_plankton.pit.type_date)> { /** */ private required; @@ -1961,11 +2410,11 @@ declare namespace lib_plankton.zoo_input { /** * [implementation] */ - read(): Promise<(null | type_date)>; + read(): Promise<(null | lib_plankton.pit.type_date)>; /** * [implementation] */ - write(value: (null | type_date)): Promise; + write(value: (null | lib_plankton.pit.type_date)): Promise; } } declare namespace lib_plankton.zoo_input { @@ -2111,6 +2560,9 @@ declare namespace lib_plankton.zoo_input { * @author fenris */ export class class_input_list implements interface_input> { + /** + */ + private read_only; /** */ private element_input_factory; @@ -2126,6 +2578,7 @@ declare namespace lib_plankton.zoo_input { /** */ constructor(element_input_factory: (() => interface_input), options?: { + read_only?: boolean; translations?: type_translations; }); /** @@ -2206,7 +2659,7 @@ declare namespace lib_plankton.zoo_input { /** * @author fenris */ - class class_input_time implements interface_input<(null | type_time)> { + class class_input_time implements interface_input<(null | lib_plankton.pit.type_time)> { /** */ private dom_input; @@ -2220,11 +2673,11 @@ declare namespace lib_plankton.zoo_input { /** * [implementation] */ - read(): Promise<(null | type_time)>; + read(): Promise<(null | lib_plankton.pit.type_time)>; /** * [implementation] */ - write(value: (null | type_time)): Promise; + write(value: (null | lib_plankton.pit.type_time)): Promise; } } declare namespace lib_plankton.zoo_input { @@ -2257,6 +2710,83 @@ declare namespace lib_plankton.zoo_input { write(value: type_record): Promise; } } +declare namespace lib_plankton.zoo_input { + /** + */ + class class_input_hashmap implements lib_plankton.zoo_input.interface_input> { + /** + */ + private hash_key; + /** + */ + private core; + /** + */ + constructor(hash_key: ((key: type_key) => string), key_input_factory: (() => lib_plankton.zoo_input.interface_input), value_input_factory: (() => lib_plankton.zoo_input.interface_input)); + /** + * [implementation] + */ + setup(parent: HTMLElement): Promise; + /** + * [implementation] + */ + read(): Promise>; + /** + * [implementation] + */ + write(map: lib_plankton.map.type_map): Promise; + } +} +declare namespace lib_plankton.zoo_input { + /** + */ + class class_input_datetime implements interface_input { + /** + */ + private core; + /** + */ + constructor(options?: { + label_timezone_shift?: string; + label_date?: string; + label_time?: string; + }); + /** + */ + setup(parent: HTMLElement): Promise; + /** + */ + read(): Promise; + /** + */ + write(value: lib_plankton.pit.type_datetime): Promise; + } +} +declare namespace lib_plankton.zoo_input { + /** + * for central europe with daylight saving time feature + */ + class class_input_datetime_central_europe implements interface_input { + /** + */ + private core; + /** + */ + constructor(options?: { + label_date?: string; + label_time?: string; + }); + /** + */ + setup(parent: HTMLElement): Promise; + /** + */ + read(): Promise; + /** + */ + write(value: lib_plankton.pit.type_datetime): Promise; + } +} declare namespace lib_plankton.zoo_form { /** */ diff --git a/lib/plankton/plankton.js b/lib/plankton/plankton.js index 3a89377..0217965 100644 --- a/lib/plankton/plankton.js +++ b/lib/plankton/plankton.js @@ -1,22 +1,7 @@ -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-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:base« is free software: you can redistribute it and/or modify @@ -36,7 +21,7 @@ along with »bacterio-plankton:base«. If not, see »bacterio-plankton:base« is free software: you can redistribute it and/or modify @@ -77,7 +62,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:base«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:base« is free software: you can redistribute it and/or modify @@ -123,7 +108,7 @@ along with »bacterio-plankton:base«. If not, see »bacterio-plankton:base« is free software: you can redistribute it and/or modify @@ -267,7 +252,7 @@ function instance_show(value) { /* This file is part of »bacterio-plankton:base«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:base« is free software: you can redistribute it and/or modify @@ -286,11 +271,11 @@ along with »bacterio-plankton:base«. If not, see this.actions[id](information)); } - }; + } /** * @author frac */ - class_observer.prototype.rollout = function () { - var _this = this; - this.buffer.forEach(function (information) { return _this.notify(information, false); }); + rollout() { + this.buffer.forEach(information => this.notify(information, false)); this.buffer = []; - }; - return class_observer; -}()); + } +} /** * @author frac */ @@ -378,7 +358,7 @@ export interface interface_writeable { /* This file is part of »bacterio-plankton:base«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:base« is free software: you can redistribute it and/or modify @@ -397,27 +377,42 @@ along with »bacterio-plankton:base«. If not, see x.toString()).join(",") + "]")); + } +} +/* +This file is part of »bacterio-plankton:base«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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 . + */ var lib_plankton; (function (lib_plankton) { var base; @@ -427,9 +422,8 @@ var lib_plankton; * * @author fenris */ - function get_current_timestamp(rounded) { - if (rounded === void 0) { rounded = false; } - var x = (Date.now() / 1000); + function get_current_timestamp(rounded = false) { + const x = (Date.now() / 1000); return (rounded ? Math.round(x) : x); ; } @@ -440,12 +434,30 @@ var lib_plankton; return Object.assign(core, mantle); } base.object_merge = object_merge; + /** + */ + function buffer_show(buffer, { "block_size": option_block_size = 20, "break_char": option_break_char = "\n", } = {}) { + let output = ""; + let count = 0; + // @ts-ignore + for (const entry of buffer) { + count = ((count + 1) % option_block_size); + output += ((typeof (entry) === "string") + ? + entry.charCodeAt(0) + : + entry).toString(16).toUpperCase().padStart(2, "0"); + output += ((count === 0) ? option_break_char : " "); + } + return output; + } + base.buffer_show = buffer_show; })(base = lib_plankton.base || (lib_plankton.base = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:pod«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:pod« is free software: you can redistribute it and/or modify @@ -549,7 +561,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:pod«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:pod« is free software: you can redistribute it and/or modify @@ -573,6 +585,9 @@ var lib_plankton; */ 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); } @@ -587,7 +602,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:call«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:call« is free software: you can redistribute it and/or modify @@ -749,90 +764,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:call«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -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-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:call« is free software: you can redistribute it and/or modify @@ -999,7 +931,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:call«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:call« is free software: you can redistribute it and/or modify @@ -1170,7 +1102,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:call«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:call« is free software: you can redistribute it and/or modify @@ -1261,7 +1193,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:call«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:call« is free software: you can redistribute it and/or modify @@ -1374,6 +1306,31 @@ var lib_plankton; return result; } call.convey = convey; + /** + */ + class class_value_wrapper { + /** + */ + constructor(value) { + this.value = value; + } + /** + */ + convey(function_) { + return (new class_value_wrapper(function_(this.value))); + } + /** + */ + cull() { + return this.value; + } + } + /** + */ + function wrap(value) { + return (new class_value_wrapper(value)); + } + call.wrap = wrap; /** * @author fenris */ @@ -1480,69 +1437,42 @@ var lib_plankton; } 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, - }); + function try_catch_wrap(get_value) { + try { + return { + "value": get_value(), + "error": 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, - }); - } + catch (error) { + return { + "value": null, + "error": error, + }; } } - call.rate_limit_check = rate_limit_check; + call.try_catch_wrap = try_catch_wrap; + /** + */ + function try_catch_wrap_async(get_value) { + return (get_value() + .then((value) => Promise.resolve({ + "value": value, + "error": null, + })) + .catch((reason) => Promise.resolve({ + "value": null, + "error": reason, + }))); + } + call.try_catch_wrap_async = try_catch_wrap_async; })(call = lib_plankton.call || (lib_plankton.call = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:file«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:file« is free software: you can redistribute it and/or modify @@ -1647,7 +1577,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:code«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:code« is free software: you can redistribute it and/or modify @@ -1666,7 +1596,7 @@ along with »bacterio-plankton:code«. If not, see »bacterio-plankton:code« is free software: you can redistribute it and/or modify @@ -1685,7 +1615,7 @@ along with »bacterio-plankton:code«. If not, see »bacterio-plankton:code« is free software: you can redistribute it and/or modify @@ -1724,7 +1654,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:code«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:code« is free software: you can redistribute it and/or modify @@ -1778,7 +1708,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:code«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:code« is free software: you can redistribute it and/or modify @@ -1821,7 +1751,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:code«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:code« is free software: you can redistribute it and/or modify @@ -1876,7 +1806,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:code«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:code« is free software: you can redistribute it and/or modify @@ -1926,7 +1856,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:code«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:code« is free software: you can redistribute it and/or modify @@ -1978,7 +1908,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:code«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:code« is free software: you can redistribute it and/or modify @@ -2038,7 +1968,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:code«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:code« is free software: you can redistribute it and/or modify @@ -2089,7 +2019,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:json«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:json« is free software: you can redistribute it and/or modify @@ -2112,23 +2042,36 @@ var lib_plankton; /** * @author fenris */ - function encode(x, formatted = false) { - return JSON.stringify(x, undefined, formatted ? "\t" : undefined); + 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(x) { - return JSON.parse(x); + 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-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:json« is free software: you can redistribute it and/or modify @@ -2178,7 +2121,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:base64«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:base64« is free software: you can redistribute it and/or modify @@ -2217,7 +2160,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:base64«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:base64« is free software: you can redistribute it and/or modify @@ -2264,25 +2207,81 @@ var lib_plankton; base64.class_base64 = class_base64; })(base64 = lib_plankton.base64 || (lib_plankton.base64 = {})); })(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 __()); - }; -})(); +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' + + +»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 . + */ +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 () { + return __generator(this, function (_a) { + return [2 /*return*/, Promise.reject(new Error("not implemented"))]; + }); + }); + } + email.send = send; + })(email = lib_plankton.email || (lib_plankton.email = {})); +})(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:log«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:log« is free software: you can redistribute it and/or modify @@ -2313,6 +2312,31 @@ var lib_plankton; enum_level[enum_level["error"] = 4] = "error"; })(enum_level = log.enum_level || (log.enum_level = {})); ; + })(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' + + +»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 . + */ +var lib_plankton; +(function (lib_plankton) { + var log; + (function (log) { /** */ function level_order(level1, level2) { @@ -2321,282 +2345,33 @@ var lib_plankton; 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)"; + function level_show(level, _a) { + var _b = _a === void 0 ? {} : _a, _c = _b["abbreviated"], option_abbreviated = _c === void 0 ? false : _c; + if (option_abbreviated) { + switch (level) { + case log.enum_level.debug: return "DBG"; + case log.enum_level.info: return "INF"; + case log.enum_level.notice: return "NTC"; + case log.enum_level.warning: return "WRN"; + case log.enum_level.error: return "ERR"; + default: return "(unknown)"; + } + } + else { + switch (level) { + case log.enum_level.debug: return "debug"; + case log.enum_level.info: return "info"; + case log.enum_level.notice: return "notice"; + case log.enum_level.warning: return "warning"; + case log.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-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -/** - * @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-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -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-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var log; - (function (log) { - /** - * output for writing log entries to web console - */ - var class_channel_console = /** @class */ (function (_super) { - __extends(class_channel_console, _super); - function class_channel_console() { - return _super !== null && _super.apply(this, arguments) || this; - } - /** - */ - class_channel_console.prototype.add = function (entry) { - var _a; - var renderers = (_a = {}, - _a[log.enum_level.debug] = { - "renderer": function (i, d) { return console.log(i, d); }, - "show_level": true - }, - _a[log.enum_level.info] = { - "renderer": function (i, d) { return console.info(i, d); }, - "show_level": false - }, - _a[log.enum_level.notice] = { - "renderer": function (i, d) { return console.log(i, d); }, - "show_level": true - }, - _a[log.enum_level.warning] = { - "renderer": function (i, d) { return console.warn(i, d); }, - "show_level": false - }, - _a[log.enum_level.error] = { - "renderer": function (i, d) { return console.error(i, d); }, - "show_level": false - }, - _a); - var setting = renderers[entry.level]; - setting.renderer(((setting.show_level - ? ("[" + log.level_show(entry.level) + "]" + " ") - : "") - + - ("" + entry.incident + "")), entry.details); - }; - return class_channel_console; - }(log.class_channel)); - log.class_channel_console = class_channel_console; - })(log = lib_plankton.log || (lib_plankton.log = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:log«. - -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -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-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var log; - (function (log) { - /** - */ - function translate_level(level_string) { + function level_decode(level_string) { return { "debug": log.enum_level.debug, "info": log.enum_level.info, @@ -2605,36 +2380,318 @@ var lib_plankton; "error": log.enum_level.error }[level_string]; } - /** - */ - function channel_make(description) { - var _a; - switch (description.kind) { - default: { - throw (new Error("unhandled log channel kind: " + description.kind)); - break; - } - case "console": { - return (new log.class_channel_minlevel(new log.class_channel_console(), translate_level((_a = description.data["threshold"]) !== null && _a !== void 0 ? _a : "debug"))); - break; - } - } - } - log.channel_make = channel_make; - /** - */ - function conf_default() { - return [ - new log.class_channel_minlevel(new log.class_channel_console(), log.enum_level.notice), - ]; - } - log.conf_default = conf_default; + log.level_decode = level_decode; })(log = lib_plankton.log || (lib_plankton.log = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:log«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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 . + */ +var lib_plankton; +(function (lib_plankton) { + var log; + (function (log) { + /** + * @todo use label + */ + function get_logger_logic(logger_data) { + return logger_data.map(function (channel_description) { return lib_plankton.log.get_channel_logic(channel_description); }); + } + log.get_logger_logic = get_logger_logic; + /** + */ + function format_entry(format_definition, entry) { + switch (format_definition.kind) { + case "jsonl": { + var now = Date.now(); + var timestamp = (now / 1000); + var datetime = (new Date(now)).toISOString(); + return (JSON.stringify({ + "datetime_timestamp": Math.round(timestamp), + "datetime_string": datetime /*.slice(0, 19)*/, + "level_numeric": entry.level, + "level_name": log.level_show(entry.level, { "abbreviated": false }), + "tags": entry.tags, + "incident": entry.incident, + "details": entry.details + }, undefined, (format_definition.data.structured + ? + "\t" + : + undefined))); + break; + } + case "human_readable": { + var parts = []; + parts.push(("<" + (new Date(Date.now())).toISOString() /*.slice(0, 19)*/ + ">")); + parts.push(("[" + log.level_show(entry.level, { "abbreviated": true }) + "]")); + for (var _i = 0, _a = entry.tags; _i < _a.length; _i++) { + var tag = _a[_i]; + parts.push(("{" + tag + "}")); + } + parts.push(entry.incident); + (entry.details !== null) && parts.push((": " + JSON.stringify(entry.details, undefined, undefined))); + return (parts.join(" ")); + break; + } + default: { + throw (new Error("unhandled format kind: " + format_definition["kind"])); + break; + } + } + } + log.format_entry = format_entry; + /** + */ + function parse_format_definition(format_definition_raw) { + return lib_plankton.call.distinguish((format_definition_raw !== null && format_definition_raw !== void 0 ? format_definition_raw : { + "kind": "human_readable", + "data": {} + }), { + "jsonl": function (_a) { + var structured = _a["structured"]; + return ({ + "kind": "jsonl", + "data": { + "structured": (structured !== null && structured !== void 0 ? structured : false) + } + }); + }, + "human_readable": function (data_) { return ({ + "kind": "human_readable", + "data": {} + }); } + }); + } + log.parse_format_definition = parse_format_definition; + })(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' + + +»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 . + */ +var lib_plankton; +(function (lib_plankton) { + var log; + (function (log) { + var channel; + (function (channel) { + var filtered; + (function (filtered) { + /** + */ + function predicate_incident(substring) { + return (function (entry) { return entry.incident.includes(substring); }); + } + filtered.predicate_incident = predicate_incident; + /** + */ + function predicate_level(threshold) { + return (function (entry) { return log.level_order(threshold, entry.level); }); + } + filtered.predicate_level = predicate_level; + /** + */ + function predicate_tag(tag) { + return (function (entry) { return entry.tags.includes(tag); }); + } + filtered.predicate_tag = predicate_tag; + /** + * combines other predicates in disjunctive normal form + */ + function predicate_complex(definition) { + return (function (entry) { return definition.some(function (clause) { return clause.every(function (literal) { return (literal.item(entry) + === + literal.mode); }); }); }); + } + filtered.predicate_complex = predicate_complex; + /** + */ + function send(subject, entry) { + if (!subject.predicate(entry)) { + // do nothing + } + else { + subject.core.send(entry); + } + } + filtered.send = send; + /** + */ + function logic(subject) { + return { + "send": function (entry) { return send(subject, entry); } + }; + } + filtered.logic = logic; + })(filtered = channel.filtered || (channel.filtered = {})); + })(channel = log.channel || (log.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' + + +»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 . + */ +var lib_plankton; +(function (lib_plankton) { + var log; + (function (log) { + var channel; + (function (channel) { + var minlevel; + (function (minlevel) { + /** + */ + function to_filter_subject(subject) { + return { + "core": subject.core, + "predicate": lib_plankton.log.channel.filtered.predicate_level(subject.threshold) + }; + } + /** + */ + function send(subject, entry) { + lib_plankton.log.channel.filtered.send(to_filter_subject(subject), entry); + } + minlevel.send = send; + /** + */ + function logic(subject) { + return { + "send": function (entry) { return send(subject, entry); } + }; + } + minlevel.logic = logic; + })(minlevel = channel.minlevel || (channel.minlevel = {})); + })(channel = log.channel || (log.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' + + +»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 . + */ +/** + * output for writing log entries to web console + */ +var lib_plankton; +(function (lib_plankton) { + var log; + (function (log) { + var channel; + (function (channel) { + var console_; + (function (console_) { + /** + * @todo tags + */ + function send(subject, entry) { + var _a; + var renderers = (_a = {}, + _a[log.enum_level.debug] = { + "renderer": function (i, d) { return console.log(i, d); }, + "show_level": true + }, + _a[log.enum_level.info] = { + "renderer": function (i, d) { return console.info(i, d); }, + "show_level": true + }, + _a[log.enum_level.notice] = { + "renderer": function (i, d) { return console.warn(i, d); }, + "show_level": true + }, + _a[log.enum_level.warning] = { + "renderer": function (i, d) { return console.warn(i, d); }, + "show_level": true + }, + _a[log.enum_level.error] = { + "renderer": function (i, d) { return console.error(i, d); }, + "show_level": true + }, + _a); + var setting = renderers[entry.level]; + setting.renderer(((setting.show_level + ? ("[" + log.level_show(entry.level) + "]" + " ") + : "") + + + ("" + entry.incident + "")), entry.details); + } + console_.send = send; + /** + */ + function logic(subject) { + return { + "send": function (entry) { return send(subject, entry); } + }; + } + console_.logic = logic; + })(console_ = channel.console_ || (channel.console_ = {})); + })(channel = log.channel || (log.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' »bacterio-plankton:log« is free software: you can redistribute it and/or modify @@ -2656,82 +2713,367 @@ var lib_plankton; (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 + function get_channel_logic(channel_description) { + switch (channel_description.kind) { + default: { + throw (new Error("unhandled log channel kind: " + channel_description.kind)); + break; + } + case "filtered": { + return lib_plankton.log.channel.filtered.logic({ + "core": get_channel_logic(channel_description.data.core), + "predicate": lib_plankton.log.channel.filtered.predicate_complex(channel_description.data.predicate.map(function (clause_raw) { return clause_raw.map(function (literal_raw) { + var _a; + return ({ + "mode": ((_a = literal_raw["mode"]) !== null && _a !== void 0 ? _a : true), + "item": lib_plankton.call.distinguish(literal_raw["item"], { + "incident": function (_a) { + var substring = _a["substring"]; + if (substring === undefined) { + throw (new Error("required parameter missing: substring")); + } + else { + return lib_plankton.log.channel.filtered.predicate_incident(substring); + } + }, + "level": function (_a) { + var threshold = _a["threshold"]; + if (threshold === undefined) { + throw (new Error("required parameter missing: threshold")); + } + else { + return lib_plankton.log.channel.filtered.predicate_level(log.level_decode(threshold)); + } + }, + "tag": function (_a) { + var value = _a["value"]; + if (value === undefined) { + throw (new Error("required parameter missing: value")); + } + else { + return lib_plankton.log.channel.filtered.predicate_tag(value); + } + } + }, { + "fallback": function () { return function (entry) { return true; }; } + }) + }); + }); })) + }); + break; + } + case "minlevel": { + return lib_plankton.log.channel.minlevel.logic({ + "core": get_channel_logic(channel_description.data.core), + "threshold": log.level_decode(channel_description.data.threshold) + }); + break; + } + case "console": { + return lib_plankton.log.channel.console_.logic({}); + break; + } } } - log.conf_pop = conf_pop; + log.get_channel_logic = get_channel_logic; + })(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' + + +»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 . + */ +var lib_plankton; +(function (lib_plankton) { + var log; + (function (log) { /** - * makes the logging system ready */ - function setup() { - if (_channel_stack === null) { - _channel_stack = []; - conf_push(log.conf_default()); - } - else { - // do nothing - } + function default_logger() { + return [ + { + "kind": "minlevel", + "data": { + "core": { + "kind": "console", + "data": {} + }, + "threshold": "info" + } + }, + ]; + } + log.default_logger = default_logger; + })(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' + + +»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 . + */ +var lib_plankton; +(function (lib_plankton) { + var log; + (function (log) { + /** + */ + var _main_logger_data = null; + /** + */ + function set_main_logger(logger_data) { + _main_logger_data = logger_data; + } + log.set_main_logger = set_main_logger; + /** + */ + function get_main_logger() { + return (_main_logger_data !== null && _main_logger_data !== void 0 ? _main_logger_data : log.default_logger()); } /** - * 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); }); + function get_main_logger_logic() { + return lib_plankton.log.get_logger_logic(get_main_logger()); } - log.add = add; /** + * consumes a log entry, i.e. sends it to all channels */ - function debug(incident, details) { - if (details === void 0) { details = {}; } - add({ "level": log.enum_level.debug, "incident": incident, "details": details }); + function send_(logger, entry) { + logger.forEach(function (channel) { return channel.send(entry); }); + } + log.send_ = send_; + /** + * [convenience] + * + * @todo rename to "send" + */ + function debug_(logger, incident, _a) { + var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d; + send_(logger, { + "level": log.enum_level.debug, + "incident": incident, + "tags": option_tags, + "details": option_details + }); + } + log.debug_ = debug_; + /** + * [convenience] + * + * @todo rename to "info" + */ + function info_(logger, incident, _a) { + var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d; + send_(logger, { + "level": log.enum_level.info, + "incident": incident, + "tags": option_tags, + "details": option_details + }); + } + log.info_ = info_; + /** + * [convenience] + * + * @todo rename to "notice" + */ + function notice_(logger, incident, _a) { + var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d; + send_(logger, { + "level": log.enum_level.notice, + "incident": incident, + "tags": option_tags, + "details": option_details + }); + } + log.notice_ = notice_; + /** + * [convenience] + * + * @todo rename to "warning" + */ + function warning_(logger, incident, _a) { + var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d; + send_(logger, { + "level": log.enum_level.warning, + "incident": incident, + "tags": option_tags, + "details": option_details + }); + } + log.warning_ = warning_; + /** + * [convenience] + * + * @todo rename to "error" + */ + function error_(logger, incident, _a) { + var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d; + send_(logger, { + "level": log.enum_level.error, + "incident": incident, + "tags": option_tags, + "details": option_details + }); + } + log.error_ = error_; + /** + * [convenience] + */ + function _send(entry) { + send_(get_main_logger_logic(), entry); + } + log._send = _send; + /** + * [convenience] + */ + function _debug(incident, _a) { + var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d; + debug_(get_main_logger_logic(), incident, { + "tags": option_tags, + "details": option_details + }); + } + log._debug = _debug; + /** + * [convenience] + */ + function _info(incident, _a) { + var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d; + info_(get_main_logger_logic(), incident, { + "tags": option_tags, + "details": option_details + }); + } + log._info = _info; + /** + * [convenience] + */ + function _notice(incident, _a) { + var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d; + notice_(get_main_logger_logic(), incident, { + "tags": option_tags, + "details": option_details + }); + } + log._notice = _notice; + /** + * [convenience] + */ + function _warning(incident, _a) { + var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d; + warning_(get_main_logger_logic(), incident, { + "tags": option_tags, + "details": option_details + }); + } + log._warning = _warning; + /** + * [convenience] + */ + function _error(incident, _a) { + var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d; + error_(get_main_logger_logic(), incident, { + "tags": option_tags, + "details": option_details + }); + } + log._error = _error; + /** + * [convenience] + * + * @deprecated use ._debug instead! + */ + function debug(incident, details, tags) { + if (details === void 0) { details = null; } + if (tags === void 0) { tags = []; } + _debug(incident, { + "details": details, + "tags": tags + }); } log.debug = debug; /** + * [convenience] + * + * @deprecated use ._info instead! */ - function info(incident, details) { - if (details === void 0) { details = {}; } - add({ "level": log.enum_level.info, "incident": incident, "details": details }); + function info(incident, details, tags) { + if (details === void 0) { details = null; } + if (tags === void 0) { tags = []; } + _info(incident, { + "details": details, + "tags": tags + }); } log.info = info; /** + * [convenience] + * + * @deprecated use ._notice instead! */ - function notice(incident, details) { - if (details === void 0) { details = {}; } - add({ "level": log.enum_level.notice, "incident": incident, "details": details }); + function notice(incident, details, tags) { + if (details === void 0) { details = null; } + if (tags === void 0) { tags = []; } + _notice(incident, { + "details": details, + "tags": tags + }); } log.notice = notice; /** + * [convenience] + * + * @deprecated use ._warning instead! */ - function warning(incident, details) { - if (details === void 0) { details = {}; } - add({ "level": log.enum_level.warning, "incident": incident, "details": details }); + function warning(incident, details, tags) { + if (details === void 0) { details = null; } + if (tags === void 0) { tags = []; } + _warning(incident, { + "details": details, + "tags": tags + }); } log.warning = warning; /** + * [convenience] + * + * @deprecated use ._error instead! */ - function error(incident, details) { - if (details === void 0) { details = {}; } - add({ "level": log.enum_level.error, "incident": incident, "details": details }); + function error(incident, details, tags) { + if (details === void 0) { details = null; } + if (tags === void 0) { tags = []; } + _error(incident, { + "details": details, + "tags": tags + }); } log.error = error; })(log = lib_plankton.log || (lib_plankton.log = {})); @@ -2739,7 +3081,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:string«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:string« is free software: you can redistribute it and/or modify @@ -2898,7 +3240,7 @@ var make_eml_body = (function () { /* This file is part of »bacterio-plankton:string«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:string« is free software: you can redistribute it and/or modify @@ -2945,6 +3287,7 @@ var lib_plankton; */ function generate(prefix = "string_") { if (index_is > index_max) { + lib_plankton.log.error("plankton.string.generate.out_of_valid_indices", null); throw (new Error("[string_generate] out of valid indices")); } else { @@ -2971,7 +3314,7 @@ var lib_plankton; * @return {Array} * @author fenris */ - function split(chain, separator = " ") { + function split(chain, separator) { if (chain.length == 0) { return []; } @@ -3175,11 +3518,16 @@ var lib_plankton; 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, - }); + /* + lib_plankton.log.debug( + "lib_plankton.string.coin", + { + "key": key, + "regex": regexp_argument.toString(), + "value": value, + } + ); + */ str = str.replace(regexp_argument, value); } } @@ -3187,11 +3535,16 @@ var lib_plankton; { 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, - }); + /* + lib_plankton.log.debug( + "lib_plankton.string.coin", + { + "key": key, + "regex": regexp_argument.toString(), + "value": value, + } + ); + */ str = str.replace(regexp_argument, value); } }); @@ -3235,6 +3588,12 @@ var lib_plankton; return slices; } string.slice = slice; + /** + */ + function capitalize(str) { + return (str[0].toUpperCase() + str.slice(1)); + } + string.capitalize = capitalize; })(string = lib_plankton.string || (lib_plankton.string = {})); })(lib_plankton || (lib_plankton = {})); /** @@ -3259,7 +3618,7 @@ var lib_string; /* This file is part of »bacterio-plankton:string«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:string« is free software: you can redistribute it and/or modify @@ -3523,7 +3882,7 @@ var printf = lib_plankton.string.printf; /* This file is part of »bacterio-plankton:string«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:string« is free software: you can redistribute it and/or modify @@ -3655,7 +4014,7 @@ var make_logger = (function () { /* This file is part of »bacterio-plankton:object«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:object« is free software: you can redistribute it and/or modify @@ -3677,128 +4036,136 @@ var lib_plankton; (function (object_1) { /** * @author fenris + * @deprecated use the "??" operator instead */ - 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)) { + function fetch(object, fieldname, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "fallback": null, + "escalation": 1 + }, options); + 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; - } + if (!options.escalate) { + return options.fallback; + } + else { + throw (new Error("field '" + fieldname + "' not in structure")); } } } 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; + return (Object.fromEntries(Object.entries(object_from) + .map(function (_a) { + var key = _a[0], value = _a[1]; + return ([key, transformator(value, key)]); + }))); } object_1.map = map; /** - * @desc gibt ein Objekt mit bestimmten Einträgen des Eingabe-Objekts zurück - * @author fenris + * gibt ein Objekt mit bestimmten Einträgen des Eingabe-Objekts zurück */ 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; + return (Object.fromEntries(Object.entries(object_from) + .filter(function (_a) { + var key = _a[0], value = _a[1]; + return predicate(value, key); + }))); } object_1.filter = filter; /** - * @desc wandelt ein Array mit Einträgen der Form {key,value} in ein entsprechendes Objekt um - * @author fenris + * wandelt ein Array mit Einträgen der Form {key,value} in ein entsprechendes Objekt um + * + * @deprecated use Object.fromEntries instead! */ function from_array(array) { - var object = {}; - array.forEach(function (entry) { return (object[entry.key] = entry.value); }); - return object; + return (Object.fromEntries(array + .map(function (_a) { + var key = _a["key"], value = _a["value"]; + return ([key, value]); + }))); } object_1.from_array = from_array; /** - * @desc wandelt ein Objekt in ein entsprechendes Array mit Einträgen der Form {key,value} um - * @author fenris + * wandelt ein Objekt in ein entsprechendes Array mit Einträgen der Form {key,value} um + * + * @deprecated use Object.entries insetad! */ function to_array(object) { - var array = []; - Object.keys(object).forEach(function (key) { return array.push({ "key": key, "value": object[key] }); }); - return array; + return (Object.entries(object) + .map(function (_a) { + var key = _a[0], value = _a[1]; + return ({ "key": key, "value": value }); + })); } object_1.to_array = to_array; /** - * @desc gibt eine Liste von Schlüsseln eines Objekts zurück - * @author fenris + * gibt eine Liste von Schlüsseln eines Objekts zurück + * + * @deprecated use Object.keys instead! */ function keys(object) { return Object.keys(object); } object_1.keys = keys; /** - * @desc gibt eine Liste von Werten eines Objekts zurück - * @author fenris + * gibt eine Liste von Werten eines Objekts zurück + * + * @deprecated use Object.values instead! */ function values(object) { - return to_array(object).map(function (entry) { return entry.value; }); + return Object.values(object); } object_1.values = values; /** - * @desc liest ein Baum-artiges Objekt an einer bestimmten Stelle aus - * @author fenris + * liest ein Baum-artiges Objekt an einer bestimmten Stelle aus */ - function path_read(object, path, fallback, escalation) { - if (fallback === void 0) { fallback = null; } - if (escalation === void 0) { escalation = 1; } + function path_read(object, path, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "fallback": null, + "escalate": false + }, options); 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); - }); + var reachable = ((position_1 != null) + && + (steps.slice(0, steps.length - 1) + .every(function (step) { + position_1 = lib_plankton.object.fetch(position_1, step, { + "fallback": null, + "escalate": false + }); + return (position_1 != null); + }))); if (reachable) { - return lib_plankton.object.fetch(position_1, steps[steps.length - 1], fallback, escalation); + return lib_plankton.object.fetch(position_1, steps[steps.length - 1], { + "fallback": options.fallback, + "escalate": options.escalate + }); } else { - return lib_plankton.object.fetch({}, "_dummy_", fallback, escalation); + return lib_plankton.object.fetch({}, "_dummy_", { + "fallback": options.fallback, + "escalate": options.escalate + }); } } } object_1.path_read = path_read; /** - * @desc schreibt einen Wert an eine bestimmte Stelle in einem Baum-artigen Objekt - * @author fenris + * schreibt einen Wert an eine bestimmte Stelle in einem Baum-artigen Objekt */ function path_write(object, path, value, construct) { if (construct === void 0) { construct = true; } @@ -3809,7 +4176,10 @@ var lib_plankton; 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); + var position_ = lib_plankton.object.fetch(position_2, step, { + "fallback": null, + "escalate": false + }); if (position_ == null) { if (construct) { position_2[step] = {}; @@ -3829,99 +4199,111 @@ var lib_plankton; 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)); + throw (new Error("path '" + path + "' does not exist and may not be constructed")); } } } 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 + * prüft ob ein Objekt einem bestimmten Muster entspricht + * + * @deprecated not very useful */ - 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]); }); + function matches(object, pattern, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "collate": instance_collate + }, options); + return (Object.entries(pattern) + .every(function (_a) { + var key = _a[0], value = _a[1]; + return options.collate(value, 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 + * erzeugt eine Projektion eines Baum-artigen Objekts in ein Listen-artiges Objekt */ - 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_; + function flatten(value, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "separator": ".", + "key_for_array_element": (function (index) { return ("element_" + index.toFixed(0)); }) + }, options); + var integrate = function (result, key, value) { + if (value == null) { + result[key] = value; } else { // primitive Werte direkt übernehmen - if (typeof (value_) != "object") { - result[key_] = value_; + 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__; + var result_ = flatten(value, { + "separator": options.separator, + "key_for_array_element": options.key_for_array_element + }); + Object.entries(result_).forEach(function (_a) { + var key_ = _a[0], value_ = _a[1]; + result[(key + options.separator + key_)] = value_; }); } } }; - if ((value === null) || (value === undefined)) { + if ((value === null) + || + (value === undefined)) { return null; } else { - var result_2 = {}; + var result_1 = {}; if (typeof (value) != "object") { - result_2["value"] = value; + result_1["value"] = value; } else { if (value instanceof Array) { - var array = (value); - array - .forEach(function (element, index) { - integrate(result_2, key_for_element(index), element); + value.forEach(function (element, index) { + integrate(result_1, options.key_for_array_element(index), element); }); } else { - var object_2 = (value); - Object.keys(object_2) - .forEach(function (key) { - integrate(result_2, key, object_2[key]); + Object.entries(value).forEach(function (_a) { + var key = _a[0], value = _a[1]; + integrate(result_1, key, value); }); } } - return result_2; + return result_1; } } object_1.flatten = flatten; /** - * @author fenris + * @deprecated use Object.assign instead! */ - 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")); }); - } + function clash(x, y, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "overwrite": true, + "hooks": { + "existing": function (key, value_old, value_new) { + lib_plankton.log.warning("object_clash_field_already_defined", { + "key": key + }); + } + } + }, options); 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 (options.hooks.existing != null) { + options.hooks.existing(key, z[key], y[key]); } - if (overwrite) { + if (options.overwrite) { z[key] = y[key]; } } @@ -3933,24 +4315,39 @@ var lib_plankton; } object_1.clash = clash; /** - * @author fenris + * @deprecated use Object.assign instead! */ - function patch(core, mantle, deep, path) { - if (deep === void 0) { deep = true; } - if (path === void 0) { path = null; } + function patch(core, mantle, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "deep": true, + "path": null + }, options); if (mantle == null) { - console.warn("mantle is null; core was", core); + lib_plankton.log.warning("object_patch_mantle_is_null", { + "core": core + }); } else { Object.keys(mantle).forEach(function (key) { - var path_ = ((path == null) ? key : "".concat(path, ".").concat(key)); + var path_ = ((options.path == null) + ? + key + : + (options.path + "." + key)); var value_mantle = mantle[key]; if (!(key in core)) { - if ((typeof (value_mantle) == "object") && (value_mantle != null) && deep) { + if ((typeof (value_mantle) == "object") + && + (value_mantle != null) + && + options.deep) { if (value_mantle instanceof Array) { core[key] = []; value_mantle.forEach(function (element) { - if ((typeof (element) == "object") && (element != null)) { + if ((typeof (element) == "object") + && + (element != null)) { var element_ = {}; patch(element_, element); core[key].push(element_); @@ -3962,7 +4359,10 @@ var lib_plankton; } else { core[key] = {}; - patch(core[key], value_mantle, deep, path_); + patch(core[key], value_mantle, { + "deep": options.deep, + "path": path_ + }); } } else { @@ -3972,17 +4372,29 @@ var lib_plankton; 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_); + if ((typeof (value_mantle) == "object") + && + (value_mantle != null) + && + options.deep) { + patch(core[key], value_mantle, { + "deep": options.deep, + "path": 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); + if ((value_core != null) + && + (value_mantle != null)) { + lib_plankton.log.warning("object_path_different_shapes", { + "path": path_, + "core_type": typeof (value_core), + "mantle_type": typeof (value_mantle) + }); } core[key] = value_mantle; // throw (new Error(message)); @@ -3993,23 +4405,26 @@ var lib_plankton; } object_1.patch = patch; /** - * @author fenris + * @deprecated use Object.assign instead! */ - function patched(core, mantle, deep) { - if (deep === void 0) { deep = undefined; } + function patched(core, mantle, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "deep": true + }, options); var result = {}; - patch(result, core, deep); - patch(result, mantle, deep); + patch(result, core, { "deep": options.deep }); + patch(result, mantle, { "deep": options.deep }); return result; } object_1.patched = patched; /** - * @author fenris + * @deprecated use Object.assign instead! */ function attached(object, key, value) { var mantle = {}; mantle[key] = value; - return patched(object, mantle, false); + return patched(object, mantle, { "deep": false }); } object_1.attached = attached; /** @@ -4024,7 +4439,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:translate«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:translate« is free software: you can redistribute it and/or modify @@ -4122,7 +4537,9 @@ var lib_plankton; function feed(package_) { let identifier = package_.meta.identifier; if (identifier in _packages) { - lib_plankton.object.patch(_packages[identifier].tree, package_.tree, true); + lib_plankton.object.patch(_packages[identifier].tree, package_.tree, { + "deep": true, + }); } else { if (translate._verbosity >= 2) { @@ -4289,7 +4706,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:translate«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:translate« is free software: you can redistribute it and/or modify @@ -4367,7 +4784,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:database«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:database« is free software: you can redistribute it and/or modify @@ -4403,7 +4820,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:storage«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:storage« is free software: you can redistribute it and/or modify @@ -4422,7 +4839,7 @@ along with »bacterio-plankton:storage«. If not, see »bacterio-plankton:storage« is free software: you can redistribute it and/or modify @@ -4441,7 +4858,7 @@ along with »bacterio-plankton:storage«. If not, see »bacterio-plankton:storage« is free software: you can redistribute it and/or modify @@ -4551,7 +4968,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:storage«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:storage« is free software: you can redistribute it and/or modify @@ -4595,7 +5012,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:storage«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:storage« is free software: you can redistribute it and/or modify @@ -4720,7 +5137,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:storage«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:storage« is free software: you can redistribute it and/or modify @@ -4767,9 +5184,1072 @@ var lib_plankton; })(storage = lib_plankton.storage || (lib_plankton.storage = {})); })(lib_plankton || (lib_plankton = {})); /* +This file is part of »bacterio-plankton:map«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:map« 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:map« 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:map«. If not, see . + */ +/* +This file is part of »bacterio-plankton:map«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:map« 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:map« 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:map«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var map; + (function (map_1) { + /** + */ + function clear(map) { + map.iterate(function (value, key) { + map["delete"](key); + }); + } + map_1.clear = clear; + /** + */ + function keys(map) { + var keys = []; + map.iterate(function (value, key) { + keys.push(key); + }); + return keys; + } + map_1.keys = keys; + /** + */ + function values(map) { + var values = []; + map.iterate(function (value, key) { + values.push(value); + }); + return values; + } + map_1.values = values; + /** + */ + function dump(map) { + var pairs = []; + map.iterate(function (value, key) { + pairs.push({ "key": key, "value": value }); + }); + return pairs; + } + map_1.dump = dump; + /** + */ + function show(map, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "show_key": instance_show, + "show_value": instance_show + }, options); + return ("[" + + + (dump(map) + .map(function (_a) { + var key = _a["key"], value = _a["value"]; + return (options.show_key(key) + + + " -> " + + + options.show_value(value)); + }) + .join(", ")) + + + "]"); + } + map_1.show = show; + })(map = lib_plankton.map || (lib_plankton.map = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:map«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:map« 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:map« 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:map«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var map; + (function (map) { + var simplemap; + (function (simplemap) { + /** + */ + function make(options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "data": {} + }, options); + return { + "data": options.data + }; + } + simplemap.make = make; + /** + */ + function size(subject) { + return Object.keys(subject.data).length; + } + simplemap.size = size; + /** + */ + function has(subject, key) { + return (key in subject.data); + } + simplemap.has = has; + /** + */ + function get_safe(subject, key) { + if (key in subject.data) { + return lib_plankton.pod.make_filled(subject.data[key]); + } + else { + return lib_plankton.pod.make_empty(); + } + } + simplemap.get_safe = get_safe; + /** + */ + function get(subject, key, fallback) { + if (fallback === void 0) { fallback = lib_plankton.pod.make_empty(); } + if (key in subject.data) { + return subject.data[key]; + } + else { + if (!lib_plankton.pod.is_filled(fallback)) { + throw (new Error("key not found")); + } + else { + return lib_plankton.pod.cull(fallback); + } + } + } + simplemap.get = get; + /** + */ + function set(subject, key, value) { + subject.data[key] = value; + } + simplemap.set = set; + /** + */ + function delete_(subject, key) { + delete subject.data[key]; + } + simplemap.delete_ = delete_; + /** + */ + function iterate(subject, procedure) { + Object.entries(subject.data).forEach(function (_a) { + var key = _a[0], value = _a[1]; + procedure(value, key); + }); + } + simplemap.iterate = iterate; + /** + */ + function implementation_map(subject) { + return { + "size": function () { return size(subject); }, + "has": function (key) { return has(subject, key); }, + "get": function (key, fallback) { return get(subject, key, fallback); }, + "set": function (key, value) { return set(subject, key, value); }, + "delete": function (key) { return delete_(subject, key); }, + "iterate": function (function_) { return iterate(subject, function_); } + }; + } + simplemap.implementation_map = implementation_map; + })(simplemap = map.simplemap || (map.simplemap = {})); + })(map = lib_plankton.map || (lib_plankton.map = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:map«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:map« 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:map« 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:map«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var map; + (function (map) { + var hashmap; + (function (hashmap) { + /** + */ + function make(hashing, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "pairs": [] + }, options); + var subject = { + "hashing": hashing, + "core": lib_plankton.map.simplemap.make({}) + }; + options.pairs.forEach(function (pair) { + set(subject, pair.key, pair.value); + }); + return subject; + } + hashmap.make = make; + /** + */ + function size(subject) { + return lib_plankton.map.simplemap.size(subject.core); + } + hashmap.size = size; + /** + */ + function has(subject, key) { + return lib_plankton.map.simplemap.has(subject.core, subject.hashing(key)); + } + hashmap.has = has; + /** + */ + function get(subject, key, fallback) { + if (fallback === void 0) { 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 + */ + return (lib_plankton.map.simplemap.get(subject.core, subject.hashing(key), lib_plankton.pod.propagate(fallback, function (value) { return ({ + "key": key, + "value": value + }); })) + .value); + } + hashmap.get = get; + /** + */ + function set(subject, key, value) { + var key_ = subject.hashing(key); + return (lib_plankton.map.simplemap.set(subject.core, key_, { "key": key, "value": value })); + } + hashmap.set = set; + /** + */ + function delete_(subject, key) { + return (lib_plankton.map.simplemap.delete_(subject.core, subject.hashing(key))); + } + hashmap.delete_ = delete_; + /** + */ + function iterate(subject, procedure) { + return (lib_plankton.map.simplemap.iterate(subject.core, function (_a, key_) { + var key = _a["key"], value = _a["value"]; + procedure(value, key); + })); + } + hashmap.iterate = iterate; + /** + */ + function implementation_map(subject) { + return { + "size": function () { return size(subject); }, + "has": function (key) { return has(subject, key); }, + "get": function (key, fallback) { return get(subject, key, fallback); }, + "set": function (key, value) { return set(subject, key, value); }, + "delete": function (key) { return delete_(subject, key); }, + "iterate": function (procedure) { return iterate(subject, procedure); } + }; + } + hashmap.implementation_map = implementation_map; + })(hashmap = map.hashmap || (map.hashmap = {})); + })(map = lib_plankton.map || (lib_plankton.map = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:map«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:map« 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:map« 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 +3GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:map«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var map; + (function (map) { + var collatemap; + (function (collatemap) { + /** + */ + function make(collation, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "pairs": [] + }, options); + var subject = { + "collation": collation, + "pairs": [] + }; + options.pairs.forEach(function (pair) { + set(subject, pair.key, pair.value); + }); + return subject; + } + collatemap.make = make; + /** + */ + function size(subject) { + return subject.pairs.length; + } + collatemap.size = size; + /** + */ + function has(subject, key) { + return (subject.pairs.some(function (pair) { return subject.collation(key, pair.key); })); + } + collatemap.has = has; + /** + * @todo use .find + */ + function get(subject, key, fallback) { + var value; + var found = (subject.pairs + .some(function (pair) { + if (subject.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); + } + } + } + collatemap.get = get; + /** + */ + function set(subject, key, value) { + var found = (subject.pairs + .some(function (pair) { + if (subject.collation(key, pair.key)) { + // pair.value = value; + return true; + } + else { + return false; + } + })); + if (found) { + // nothing + } + else { + subject.pairs.push({ + "key": key, + "value": value + }); + } + } + collatemap.set = set; + /** + */ + function delete_(subject, key) { + var index; + var found = (subject.pairs + .some(function (pair, index_) { + if (subject.collation(key, pair.key)) { + index = index_; + return true; + } + else { + return false; + } + })); + if (found) { + subject.pairs.splice(index, 1); + } + else { + // do nothing + } + } + collatemap.delete_ = delete_; + /** + */ + function iterate(subject, function_) { + subject.pairs + .forEach(function (pair) { + function_(pair.value, pair.key); + }); + } + collatemap.iterate = iterate; + /** + */ + function implementation_map(subject) { + return { + "size": function () { return size(subject); }, + "has": function (key) { return has(subject, key); }, + "get": function (key, fallback) { return get(subject, key, fallback); }, + "set": function (key, value) { return set(subject, key, value); }, + "delete": function (key) { return delete_(subject, key); }, + "iterate": function (function_) { return iterate(subject, function_); } + }; + } + collatemap.implementation_map = implementation_map; + })(collatemap = map.collatemap || (map.collatemap = {})); + })(map = lib_plankton.map || (lib_plankton.map = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:pit«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:pit« 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:pit« 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:pit«. If not, see . + */ +/* +This file is part of »bacterio-plankton:pit«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:pit« 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:pit« 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:pit«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var pit; + (function (pit_1) { + /** + * @todo complete + */ + function timezone_name_to_timezone_shift(timezone_name) { + const map = { + "UTC": 0, + "CET": +1, + "CEST": +2, + }; + if (!(timezone_name in map)) { + throw (new Error("unhandled timezone: " + timezone_name)); + } + else { + return map[timezone_name]; + } + } + pit_1.timezone_name_to_timezone_shift = timezone_name_to_timezone_shift; + /** + */ + function date_object_get_week_of_year(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)); + } + pit_1.date_object_get_week_of_year = date_object_get_week_of_year; + /** + */ + function to_unix_timestamp(pit) { + return pit; + } + pit_1.to_unix_timestamp = to_unix_timestamp; + /** + */ + function from_unix_timestamp(unix_timestamp) { + return unix_timestamp; + } + pit_1.from_unix_timestamp = from_unix_timestamp; + /** + */ + function to_date_object(pit) { + return (new Date(pit * 1000)); + } + pit_1.to_date_object = to_date_object; + /** + */ + function from_date_object(date_object) { + return Math.round(date_object.getTime() / 1000); + } + /** + * @todo test + */ + function to_datetime(pit, { "timezone_shift": option_timezone_shift = 0, } = {}) { + return lib_plankton.call.convey(pit, [ + to_date_object, + (x) => x.getTime(), + (x) => (x + ((option_timezone_shift * (60 * 60)) * 1000)), + (x) => new Date(x), + x => x.toISOString(), + x => ({ + "timezone_shift": option_timezone_shift, + "date": { + "year": parseInt(x.slice(0, 4)), + "month": parseInt(x.slice(5, 7)), + "day": parseInt(x.slice(8, 10)), + }, + "time": { + "hour": parseInt(x.slice(11, 13)), + "minute": parseInt(x.slice(14, 16)), + "second": parseInt(x.slice(17, 19)), + }, + }) + ]); + } + pit_1.to_datetime = to_datetime; + /** + */ + function from_datetime(datetime) { + return lib_plankton.call.convey(datetime, [ + (x) => lib_plankton.string.coin("{{year}}-{{month}}-{{day}}T{{hour}}:{{minute}}:{{second}}.000+{{shift}}", { + "year": x.date.year.toFixed(0).padStart(4, "0"), + "month": x.date.month.toFixed(0).padStart(2, "0"), + "day": x.date.day.toFixed(0).padStart(2, "0"), + "hour": ((x.time !== null) ? x.time.hour : 0).toFixed(0).padStart(2, "0"), + "minute": ((x.time !== null) ? x.time.minute : 0).toFixed(0).padStart(2, "0"), + "second": ((x.time !== null) ? x.time.second : 0).toFixed(0).padStart(2, "0"), + "shift": (x.timezone_shift.toFixed(0).padStart(2, "0") + ":00"), + }), + x => (new Date(x)), + from_date_object, + ]); + } + pit_1.from_datetime = from_datetime; + /** + */ + function is_before(pit, reference) { + return (pit < reference); + } + pit_1.is_before = is_before; + /** + */ + function is_after(pit, reference) { + return (pit > reference); + } + /** + */ + function is_between(pit, reference_left, reference_right) { + return (is_after(pit, reference_left) + && + is_before(pit, reference_right)); + } + pit_1.is_between = is_between; + /** + */ + function shift_hour(pit, increment) { + return (pit + (60 * 60 * increment)); + } + /** + */ + function shift_day(pit, increment) { + return (pit + (60 * 60 * 24 * increment)); + } + pit_1.shift_day = shift_day; + /** + */ + function shift_week(pit, increment) { + return (pit + (60 * 60 * 24 * 7 * increment)); + } + pit_1.shift_week = shift_week; + /** + */ + function shift_year(pit, increment) { + return (pit + (60 * 60 * 24 * 365 * increment)); + } + /** + */ + function trunc_minute(pit) { + const datetime_input = to_datetime(pit); + const datetime_output = { + "timezone_shift": 0, + "date": { + "year": datetime_input.date.year, + "month": datetime_input.date.month, + "day": datetime_input.date.day, + }, + "time": { + "hour": ((datetime_input.time === null) + ? + 0 + : + datetime_input.time.hour), + "minute": ((datetime_input.time === null) + ? + 0 + : + datetime_input.time.minute), + "second": 0, + }, + }; + return from_datetime(datetime_output); + } + /** + */ + function trunc_hour(pit) { + const datetime_input = to_datetime(pit); + const datetime_output = { + "timezone_shift": 0, + "date": { + "year": datetime_input.date.year, + "month": datetime_input.date.month, + "day": datetime_input.date.day, + }, + "time": { + "hour": ((datetime_input.time === null) + ? + 0 + : + datetime_input.time.hour), + "minute": 0, + "second": 0, + }, + }; + return from_datetime(datetime_output); + } + /** + */ + function trunc_day(pit) { + const datetime_input = to_datetime(pit); + const datetime_output = { + "timezone_shift": 0, + "date": { + "year": datetime_input.date.year, + "month": datetime_input.date.month, + "day": datetime_input.date.day, + }, + "time": { + "hour": 0, + "minute": 0, + "second": 0, + }, + }; + return from_datetime(datetime_output); + } + /** + */ + function trunc_week(pit) { + const date_object = to_date_object(pit); + return lib_plankton.call.convey(date_object.getDay(), [ + (x) => ((x === 0) ? 7 : x), + (x) => (x - 1), + (x) => shift_day(pit, (-x)), + trunc_day + ]); + } + pit_1.trunc_week = trunc_week; + /** + */ + function trunc_month(pit) { + const datetime_input = to_datetime(pit); + const datetime_output = { + "timezone_shift": 0, + "date": { + "year": datetime_input.date.year, + "month": datetime_input.date.month, + "day": 1, + }, + "time": { + "hour": 0, + "minute": 0, + "second": 0, + }, + }; + return from_datetime(datetime_output); + } + /** + */ + function trunc_year(pit) { + const datetime_input = to_datetime(pit); + const datetime_output = { + "timezone_shift": 0, + "date": { + "year": datetime_input.date.year, + "month": 1, + "day": 1, + }, + "time": { + "hour": 0, + "minute": 0, + "second": 0, + }, + }; + return from_datetime(datetime_output); + } + /** + */ + function now() { + return from_date_object(new Date(Date.now())); + } + pit_1.now = now; + /** + * @param year year according to specified timezone shift + * @param week week according to specified timezone shift + * @return the begin of the week (monday, 00:00) + */ + function from_ywd(ywd, { "timezone_shift": option_timezone_shift = 0, } = {}) { + return lib_plankton.call.convey({ + "timezone_shift": option_timezone_shift, + "date": { + "year": ywd.year, + "month": 1, + "day": 1, + }, + "time": { + "hour": 0, + "minute": 0, + "second": 0 + } + }, [ + from_datetime, + (x) => shift_week(x, (ywd.week - 1)), + trunc_week, + (x) => shift_day(x, (ywd.day - 1)), + ]); + } + pit_1.from_ywd = from_ywd; + /** + * @todo timezone + */ + function to_ywd(pit, { "timezone_shift": option_timezone_shift = 0, } = {}) { + return lib_plankton.call.convey(pit, [ + to_date_object, + x => ({ + "year": x.getFullYear(), + "week": date_object_get_week_of_year(x), + "day": ((day => (day <= 0) ? 7 : day)(x.getDay())), + }) + ]); + } + pit_1.to_ywd = to_ywd; + /** + * computes the point in time for switching to central european summer time + * + * @todo write tests + */ + function cest_switch_on(year) { + return lib_plankton.call.convey(year, [ + (x) => ({ + "timezone_shift": 0, + "date": { + "year": x, + "month": 4, + "day": 1, + }, + "time": { + "hour": 2, + "minute": 0, + "second": 0 + }, + }), + from_datetime, + trunc_week, + x => shift_day(x, -1), + ]); + } + pit_1.cest_switch_on = cest_switch_on; + /** + * computes the point in time for switching away from central european summer time + * + * @todo write tests + */ + function cest_switch_off(year) { + return lib_plankton.call.convey(year, [ + (x) => ({ + "timezone_shift": 0, + "date": { + "year": x, + "month": 11, + "day": 1, + }, + "time": { + "hour": 1, + "minute": 0, + "second": 0 + }, + }), + from_datetime, + trunc_week, + x => shift_day(x, -1), + ]); + } + pit_1.cest_switch_off = cest_switch_off; + /** + */ + function timezone_shift_ce(pit) { + const year = to_datetime(pit).date.year; + return (is_between(pit, cest_switch_on(year), cest_switch_off(year)) + ? +2 + : +1); + } + pit_1.timezone_shift_ce = timezone_shift_ce; + /** + * [convenience] + */ + function to_datetime_ce(pit) { + return to_datetime(pit, { + "timezone_shift": timezone_shift_ce(pit), + }); + } + pit_1.to_datetime_ce = to_datetime_ce; + /** + */ + function datetime_translate(datetime, timezone_shift) { + if (datetime.timezone_shift === timezone_shift) { + return datetime; + } + else { + const pit = from_datetime(datetime); + const pit_shifted = shift_hour(pit, (timezone_shift - datetime.timezone_shift)); + const datetime_shifted = to_datetime(pit_shifted); + return { + "timezone_shift": timezone_shift, + "date": datetime_shifted.date, + "time": ((datetime.time === null) + ? + null + : datetime_shifted.time) + }; + } + } + pit_1.datetime_translate = datetime_translate; + /** + * [convenience] + */ + function datetime_translate_ce(datetime) { + return datetime_translate(datetime, timezone_shift_ce(from_datetime(datetime))); + } + pit_1.datetime_translate_ce = datetime_translate_ce; + /** + */ + function timezone_shift_format(timezone_shift) { + return lib_plankton.string.coin("{{sign}}{{value}}", { + "sign": ((timezone_shift === 0) + ? + " " + : + ((timezone_shift > 0) + ? + "+" + : + "-")), + "value": Math.abs(timezone_shift).toFixed(0), + }); + } + pit_1.timezone_shift_format = timezone_shift_format; + /** + */ + function date_format(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"), + }); + } + pit_1.date_format = date_format; + /** + */ + function time_format(time, { "show_seconds": option_show_seconds = false, } = {}) { + return lib_plankton.string.coin((option_show_seconds + ? + "{{hour}}:{{minute}}:{{seconds}}" + : + "{{hour}}:{{minute}}"), { + "hour": time.hour.toFixed(0).padStart(2, "0"), + "minute": time.minute.toFixed(0).padStart(2, "0"), + "second": time.second.toFixed(0).padStart(2, "0"), + }); + } + pit_1.time_format = time_format; + /** + * @todo show timezone + */ + function datetime_format(datetime, { "timezone_indicator": option_timezone_indicator = "", "show_timezone": option_show_timezone = false, "adjust_to_ce": option_adjust_to_ce = false, "omit_date": option_omit_date = false, } = {}) { + if (datetime === null) { + return "-"; + } + else { + const datetime_adjusted = (option_adjust_to_ce + ? + to_datetime_ce(from_datetime(datetime)) + : + datetime); + return lib_plankton.string.coin("{{macro_date_and_time}}{{macro_timezone}}", { + "macro_date_and_time": ([ + // date + (option_omit_date + ? + null + : + date_format(datetime_adjusted.date)), + // time + ((datetime_adjusted.time === null) + ? + null + : + time_format(datetime_adjusted.time)), + ] + .filter(x => (x !== null)) + .join(", ")), + "macro_timezone": (option_show_timezone + ? + lib_plankton.string.coin(" [{{timezone_indicator}}{{timezone_value}}]", { + "timezone_indicator": option_timezone_indicator, + "timezone_value": timezone_shift_format(datetime_adjusted.timezone_shift), + }) + : + ""), + }); + } + } + pit_1.datetime_format = datetime_format; + /** + */ + function timespan_format(from, to, { "timezone_indicator": option_timezone_indicator = "", "show_timezone": option_show_timezone = false, "adjust_to_ce": option_adjust_to_ce = false, "omit_date": option_omit_date = false, } = {}) { + const from_adjusted = (option_adjust_to_ce + ? + datetime_translate_ce(from) + : + from); + const to_adjusted = ((to === null) + ? + null + : + (option_adjust_to_ce + ? + datetime_translate_ce(to) + : + to)); + return lib_plankton.string.coin("{{from}}{{to_macro}}{{macro_timezone}}", { + "from": datetime_format(from_adjusted, { + "show_timezone": false, + "adjust_to_ce": false, + "omit_date": option_omit_date, + }), + "to_macro": ((to_adjusted === null) + ? + "" + : + lib_plankton.string.coin(" - {{to}}", { + "to": datetime_format(to_adjusted, { + "omit_date": ((from_adjusted.date.year === to_adjusted.date.year) + && + (from_adjusted.date.month === to_adjusted.date.month) + && + (from_adjusted.date.day === to_adjusted.date.day)) + }), + })), + "macro_timezone": (option_show_timezone + ? + lib_plankton.string.coin(" [{{timezone_indicator}}{{timezone_value}}]", { + "timezone_indicator": option_timezone_indicator, + "timezone_value": timezone_shift_format(from_adjusted.timezone_shift), + }) + : + ""), + }); + } + pit_1.timespan_format = timespan_format; + })(pit = lib_plankton.pit || (lib_plankton.pit = {})); +})(lib_plankton || (lib_plankton = {})); +/* This file is part of »bacterio-plankton:zoo-input«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify @@ -4788,7 +6268,7 @@ along with »bacterio-plankton:zoo-input«. If not, see »bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify @@ -4846,7 +6326,110 @@ var lib_plankton; /* This file is part of »bacterio-plankton:zoo-input«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:zoo-input« 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:zoo-input« 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:zoo-input«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var zoo_input; + (function (zoo_input) { + /** + * @author fenris + */ + class class_input_soft { + /** + */ + constructor(core, options = {}) { + options = Object.assign({}, options); + this.core = core; + this.dom_set = null; + this.dom_wrapper = null; + } + /** + */ + toggle(also_element, mode) { + if (also_element) { + this.dom_set.checked = mode; + } + else { + // do nothing + } + this.dom_wrapper.classList.toggle("plankton_input_soft_inactive", (!mode)); + } + /** + * [implementation] + */ + async setup(parent) { + let dom_container = document.createElement("div"); + dom_container.classList.add("plankton_input_soft_container"); + { + // set + { + this.dom_set = document.createElement("input"); + this.dom_set.setAttribute("type", "checkbox"); + this.dom_set.classList.add("plankton_input_soft_setter"); + dom_container.appendChild(this.dom_set); + } + // core + { + this.dom_wrapper = document.createElement("div"); + this.dom_wrapper.classList.add("plankton_input_soft_core_wrapper"); + dom_container.appendChild(this.dom_wrapper); + await this.core.setup(this.dom_wrapper); + } + } + this.dom_set.addEventListener("change", (event) => { + this.toggle(false, event.target.checked); + }); + parent.appendChild(dom_container); + this.toggle(true, false); + return Promise.resolve(undefined); + } + /** + * [implementation] + */ + read() { + if (!this.dom_set.checked) { + return Promise.resolve(null); + } + else { + return this.core.read(); + } + } + /** + * [implementation] + */ + write(value) { + if (value === null) { + this.toggle(true, false); + return Promise.resolve(undefined); + } + else { + this.toggle(true, true); + return this.core.write(value); + } + } + } + zoo_input.class_input_soft = class_input_soft; + })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:zoo-input«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify @@ -4908,7 +6491,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:zoo-input«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify @@ -5005,7 +6588,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:zoo-input«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify @@ -5063,7 +6646,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:zoo-input«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify @@ -5120,7 +6703,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:zoo-input«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify @@ -5216,7 +6799,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:zoo-input«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify @@ -5299,7 +6882,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:zoo-input«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify @@ -5378,7 +6961,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:zoo-input«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify @@ -5442,7 +7025,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:zoo-input«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify @@ -5526,7 +7109,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:zoo-input«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify @@ -5554,6 +7137,7 @@ var lib_plankton; */ constructor(element_input_factory, options = {}) { options = Object.assign({ + "read_only": false, "translations": { "add": "add", "remove": "remove", @@ -5562,6 +7146,7 @@ var lib_plankton; this.element_input_factory = element_input_factory; this.elements = []; this.elements_container_dom = null; + this.read_only = options.read_only; this.translations = options.translations; } /** @@ -5587,6 +7172,9 @@ var lib_plankton; remover_dom.classList.add("plankton_input_list_button"); remover_dom.classList.add("plankton_input_list_element_remover"); remover_dom.setAttribute("title", this.translations.remove); + if (this.read_only) { + remover_dom.setAttribute("disabled", "disabled"); + } remover_dom.textContent = "x"; remover_dom.addEventListener("click", (event) => { event.preventDefault(); @@ -5630,6 +7218,9 @@ var lib_plankton; adder_dom.classList.add("plankton_input_list_button"); adder_dom.classList.add("plankton_input_list_adder"); adder_dom.setAttribute("title", this.translations.add); + if (this.read_only) { + adder_dom.setAttribute("disabled", "disabled"); + } adder_dom.textContent = "+"; adder_dom.addEventListener("click", (event) => { event.preventDefault(); @@ -5673,7 +7264,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:zoo-input«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify @@ -5731,7 +7322,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:zoo-input«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify @@ -5800,7 +7391,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:zoo-input«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify @@ -5880,7 +7471,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:zoo-input«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify @@ -5921,7 +7512,7 @@ var lib_plankton; async setup(parent) { let dom_group = document.createElement("div"); dom_group.classList.add("plankton_input_group"); - await Promise.all(this.fields.map(async (field) => { + for await (const field of this.fields) { let dom_field = document.createElement("div"); dom_field.classList.add("plankton_input_group_field"); dom_field.setAttribute("rel", field.name); @@ -5957,8 +7548,8 @@ var lib_plankton; field.input.setup(dom_field), ]); dom_group.appendChild(dom_field); - return Promise.resolve(undefined); - })); + // return Promise.resolve(undefined); + } parent.appendChild(dom_group); return Promise.resolve(undefined); } @@ -5985,9 +7576,252 @@ var lib_plankton; })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {})); })(lib_plankton || (lib_plankton = {})); /* +This file is part of »bacterio-plankton:zoo-input«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:zoo-input« 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:zoo-input« 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:zoo-input«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var zoo_input; + (function (zoo_input) { + /** + */ + class class_input_hashmap { + /** + */ + constructor(hash_key, key_input_factory, value_input_factory) { + this.hash_key = hash_key; + this.core = new lib_plankton.zoo_input.class_input_list(() => new lib_plankton.zoo_input.class_input_group([ + { + "name": "key", + "input": key_input_factory(), + }, + { + "name": "value", + "input": value_input_factory(), + }, + ])); + } + /** + * [implementation] + */ + setup(parent) { + return this.core.setup(parent); + } + /** + * [implementation] + */ + async read() { + const pairs = await this.core.read(); + const map = lib_plankton.map.hashmap.implementation_map(lib_plankton.map.hashmap.make(this.hash_key, { + "pairs": pairs + })); + return Promise.resolve(map); + } + /** + * [implementation] + */ + async write(map) { + const pairs = lib_plankton.map.dump(map); + await this.core.write(pairs); + return Promise.resolve(undefined); + } + } + zoo_input.class_input_hashmap = class_input_hashmap; + })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:zoo-input«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:zoo-input« 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:zoo-input« 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:zoo-input«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var zoo_input; + (function (zoo_input) { + /** + */ + class class_input_datetime { + /** + */ + constructor(options = {}) { + options = Object.assign({ + "label_timezone_shift": "", + "label_date": "", + "label_time": "", + }, options); + this.core = new zoo_input.class_input_group([ + { + "name": "timezone_shift", + "input": new zoo_input.class_input_number(), + "label": options.label_timezone_shift, + }, + { + "name": "date", + "input": new zoo_input.class_input_date(), + "label": options.label_date, + }, + { + "name": "time", + "input": new zoo_input.class_input_soft(new zoo_input.class_input_time()), + "label": options.label_time, + }, + ]); + } + /** + */ + setup(parent) { + return this.core.setup(parent); + } + /** + */ + read() { + return this.core.read(); + } + /** + */ + write(value) { + return this.core.write(value); + } + } + zoo_input.class_input_datetime = class_input_datetime; + })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:zoo-input«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:zoo-input« 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:zoo-input« 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:zoo-input«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var zoo_input; + (function (zoo_input) { + /** + * for central europe with daylight saving time feature + */ + class class_input_datetime_central_europe { + /** + */ + constructor(options = {}) { + options = Object.assign({ + "label_date": "", + "label_time": "", + }, options); + this.core = new zoo_input.class_input_group([ + { + "name": "date", + "input": new zoo_input.class_input_date(), + "label": options.label_date, + }, + { + "name": "time", + "input": new zoo_input.class_input_soft(new zoo_input.class_input_time()), + "label": options.label_time, + }, + ]); + } + /** + */ + setup(parent) { + return this.core.setup(parent); + } + /** + */ + async read() { + const datetime_easy = await this.core.read(); + const datetime_cet = { + "timezone_shift": 1, + "date": datetime_easy.date, + "time": datetime_easy.time, + }; + const datetime_cest = { + "timezone_shift": 2, + "date": datetime_easy.date, + "time": datetime_easy.time, + }; + const datetime = (lib_plankton.pit.is_between(lib_plankton.pit.from_datetime(datetime_cet), lib_plankton.pit.cest_switch_on(datetime_easy.date.year), lib_plankton.pit.cest_switch_off(datetime_easy.date.year)) + ? + datetime_cest + : + datetime_cet); + if (datetime_easy.time === null) { + datetime.time = null; + } + else { + // do nothing + } + return Promise.resolve(datetime); + } + /** + */ + async write(value) { + const pit = lib_plankton.pit.from_datetime(value); + const datetime_utc = lib_plankton.pit.to_datetime(pit, { + "timezone_shift": 0, + }); + const datetime_relative = lib_plankton.pit.to_datetime(pit, { + "timezone_shift": (lib_plankton.pit.is_between(lib_plankton.pit.from_datetime(datetime_utc), lib_plankton.pit.cest_switch_on(datetime_utc.date.year), lib_plankton.pit.cest_switch_off(datetime_utc.date.year)) + ? + 2 + : + 1) + }); + const datetime_easy = { + "date": datetime_relative.date, + "time": ((value.time === null) ? null : datetime_relative.time), + }; + return this.core.write(datetime_easy); + } + } + zoo_input.class_input_datetime_central_europe = class_input_datetime_central_europe; + })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {})); +})(lib_plankton || (lib_plankton = {})); +/* This file is part of »bacterio-plankton:zoo-form«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-form« is free software: you can redistribute it and/or modify @@ -6155,7 +7989,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:zoo-form«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-form« is free software: you can redistribute it and/or modify @@ -6244,7 +8078,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:zoo-search«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-search« is free software: you can redistribute it and/or modify @@ -6430,7 +8264,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:zoo-editor«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-editor« is free software: you can redistribute it and/or modify @@ -6867,7 +8701,7 @@ var lib_plankton; /* This file is part of »bacterio-plankton:zoo-page«. -Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-page« is free software: you can redistribute it and/or modify diff --git a/source/data/localization/deu.loc.json b/source/data/localization/deu.loc.json index 13253d4..4e05eb9 100644 --- a/source/data/localization/deu.loc.json +++ b/source/data/localization/deu.loc.json @@ -69,6 +69,8 @@ "page.password_change_exec.flaw.password_lacks_number": "das Passwort muss ein Zahl beinhalten", "page.password_change_exec.flaw.password_lacks_special_character": "das Passwort muss ein Sonderzeichen beinhalten", "page.password_change_exec.flaw.unhandled_error": "da ist etwas schief gelaufen :/", - "page.password_change_exec.status.success": "erledigt" + "page.password_change_exec.status.success": "erledigt", + "page.invite_list.title": "Einladungen", + "page.invite_handle.title": "Einladung" } } diff --git a/source/data/localization/eng.loc.json b/source/data/localization/eng.loc.json index b0f3b47..333b68c 100644 --- a/source/data/localization/eng.loc.json +++ b/source/data/localization/eng.loc.json @@ -69,6 +69,8 @@ "page.password_change_exec.flaw.password_lacks_number": "das Passwort muss ein Zahl beinhalten", "page.password_change_exec.flaw.password_lacks_special_character": "das Passwort muss ein Sonderzeichen beinhalten", "page.password_change_exec.flaw.unhandled_error": "da ist etwas schief gelaufen :/", - "page.password_change_exec.status.success": "done" + "page.password_change_exec.status.success": "done", + "page.invite_list.title": "Invites", + "page.invite_handle.title": "Invite" } } diff --git a/source/logic/backend.ts b/source/logic/backend.ts index 01446a9..e9ca607 100644 --- a/source/logic/backend.ts +++ b/source/logic/backend.ts @@ -485,20 +485,45 @@ namespace _espe.backend ); } - + + /** + */ + export async function invite_list( + ) : Promise< + Array< + { + id : int; + key : string; + expiry : (null | int); + name_value : string; + } + > + > + { + return abstract_call( + "GET", + lib_plankton.string.coin( + "/invite/list", + { + } + ) + ); + } + + /** */ export async function invite_examine( key : string ) : Promise< { - membership_number_mode : int; + membership_number_changeable : boolean; membership_number_value : (null | string); - name_mode : int; + name_changeable : boolean; name_value : string; - email_address_mode : int; + email_address_changeable : boolean; email_address_value : (null | string); - groups_mode : int; + groups_changeable : boolean; groups_value : Array; } > diff --git a/source/logic/main.ts b/source/logic/main.ts index 7ad3adf..b53ada6 100644 --- a/source/logic/main.ts +++ b/source/logic/main.ts @@ -69,6 +69,11 @@ function setup_nav( "label": "Anlegen", "classes": ["logged_in"], }, + { + "location": {"name": "invite_list", "parameters": {}}, + "label": "Einladungen", + "classes": ["logged_in"], + }, { "location": {"name": "logout", "parameters": {}}, "label": "Abmelden", diff --git a/source/pages/invite_handle/logic.ts b/source/pages/invite_handle/logic.ts index 2e7062e..6c253e8 100644 --- a/source/pages/invite_handle/logic.ts +++ b/source/pages/invite_handle/logic.ts @@ -21,18 +21,16 @@ lib_plankton.zoo_page.register( target_element.appendChild(template_request("invite_handle")); - /** - * @todo invite_handle-title - */ + target_element.querySelector(".invite_handle-title").textContent = lib_plankton.translate.get("page.invite_handle.title"); const data : { - membership_number_mode : int; + membership_number_changeable : boolean; membership_number_value : (null | string); - name_mode : int; + name_changeable : boolean; name_value : string; - email_address_mode : int; + email_address_changeable : boolean; email_address_value : (null | string); - groups_mode : int; + groups_changeable : boolean; groups_value : Array; } = await _espe.backend.invite_examine(key); @@ -64,23 +62,11 @@ lib_plankton.zoo_page.register( }), new lib_plankton.zoo_input.class_input_group( [ - { - "name": "name_value", - "input": new lib_plankton.zoo_input.class_input_text( - { - "read_only": (data.name_mode <= 1), - } - ), - /** - * @todo translate - */ - "label": "Name", - }, { "name": "membership_number_value", "input": new lib_plankton.zoo_input.class_input_text( { - "read_only": (data.membership_number_mode <= 1), + "read_only": (! data.membership_number_changeable), } ), /** @@ -88,27 +74,16 @@ lib_plankton.zoo_page.register( */ "label": "Mitgliedsnummer", }, - { - "name": "email_address_value", - "input": new lib_plankton.zoo_input.class_input_text( - { - "read_only": (data.email_address_mode <= 1), - } - ), - /** - * @todo translate - */ - "label": "E-Mail-Adresse", - }, { "name": "groups_value", "input": new lib_plankton.zoo_input.class_input_list( - () => new lib_plankton.zoo_input.class_input_text(), + () => new lib_plankton.zoo_input.class_input_text( + { + "read_only": (! data.groups_changeable), + } + ), { - /** - * @todo does not work yet - */ - // "read_only": (data.groups_mode <= 1), + "read_only": (! data.groups_changeable), } ), /** @@ -116,6 +91,30 @@ lib_plankton.zoo_page.register( */ "label": "Gruppen", }, + { + "name": "name_value", + "input": new lib_plankton.zoo_input.class_input_text( + { + "read_only": (! data.name_changeable), + } + ), + /** + * @todo translate + */ + "label": "Name", + }, + { + "name": "email_address_value", + "input": new lib_plankton.zoo_input.class_input_text( + { + "read_only": (! data.email_address_changeable), + } + ), + /** + * @todo translate + */ + "label": "E-Mail-Adresse", + }, ] ), [ diff --git a/source/pages/invite_list/logic.ts b/source/pages/invite_list/logic.ts new file mode 100644 index 0000000..54772b9 --- /dev/null +++ b/source/pages/invite_list/logic.ts @@ -0,0 +1,81 @@ +/* +Espe | Ein schlichtes Werkzeug zur Mitglieder-Verwaltung | Frontend +Copyright (C) 2024 Christian Fraß + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public +License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later +version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program. If not, see +. + */ + +lib_plankton.zoo_page.register( + "invite_list", + async (parameters, target_element) => { + type type_item = { + id : int; + key : string; + expiry : (null | int); + name_value : string; + }; + + target_element.appendChild(template_request("invite_list")); + + target_element.querySelector(".invite_list-title").textContent = lib_plankton.translate.get("page.invite_list.title"); + + const search : lib_plankton.zoo_search.type_search = lib_plankton.zoo_search.make( + (term) => _espe.backend.invite_list(), + { + "encode_item": (item) => lib_plankton.string.coin( + "[{{id}}] {{name}}: {{key}}", + { + "id": item.id.toFixed(0), + "name": item.name_value, + "key": item.key, + } + ), + "hooks_begin": [ + (term) => { + /** + * @todo + */ + } + ], + "hooks_select": [ + (item) => { + const url : URL = new URL(window.location.toString()); + url.hash = lib_plankton.string.coin( + "#invite_handle,key={{key}}", + { + "key": item.key, + } + ); + console.info(url.toString()); + } + ] + } + ); + lib_plankton.zoo_search.render( + search, + target_element.querySelector(".invite_list-search"), + { + "state": { + "term": "", + } + } + ); + + /* + const data = await _espe.backend.invite_list(); + (target_element.querySelector(".invite_list-data") as HTMLElement).textContent = JSON.stringify( + data, + undefined, + " " + ); + */ + } +); diff --git a/source/pages/invite_handle/style.css b/source/pages/invite_list/structure.html similarity index 80% rename from source/pages/invite_handle/style.css rename to source/pages/invite_list/structure.html index 791713b..c003993 100644 --- a/source/pages/invite_handle/style.css +++ b/source/pages/invite_list/structure.html @@ -1,4 +1,4 @@ -/* + + diff --git a/source/pages/list/logic.ts b/source/pages/list/logic.ts index 5377a8c..cbaab56 100644 --- a/source/pages/list/logic.ts +++ b/source/pages/list/logic.ts @@ -25,7 +25,7 @@ lib_plankton.zoo_page.register( }; }; const term : (null | string) = (parameters["term"] ?? ""); - + target_element.appendChild(template_request("list")); target_element.querySelector(".list-title").textContent = lib_plankton.translate.get("page.list.title"); diff --git a/source/pages/view/style.css b/source/pages/view/style.css index 87593c5..3094704 100644 --- a/source/pages/view/style.css +++ b/source/pages/view/style.css @@ -39,18 +39,3 @@ You should have received a copy of the GNU General Public License along with thi } */ -.plankton_form_actions > * -{ - display: block; - margin: 8px; -} - -section.view .plankton_input_list_element > * -{ - display: inline-block; -} - -section.view .plankton_input_list_element_input -{ - -} diff --git a/source/style/style.css b/source/style/style.css index 716df36..93e0517 100644 --- a/source/style/style.css +++ b/source/style/style.css @@ -30,7 +30,6 @@ html color: hsl(var(--hue), 0%, 100%); } - body { max-width: 960px; @@ -171,6 +170,12 @@ nav > ul > li:hover::after font-weight: bold; } +.plankton_form_actions > * +{ + display: block; + margin: 8px; +} + .plankton_search_item { cursor: pointer; @@ -210,7 +215,6 @@ nav > ul > li:hover::after display: block; } - .plankton_input_enumeration > * { display: block; @@ -236,3 +240,14 @@ nav > ul > li:hover::after { margin-bottom: 8px; } + + +.plankton_input_list_element > * +{ + display: inline-block; +} + +.plankton_input_list_element_input +{ + +} diff --git a/tools/makefile b/tools/makefile index 9968b9b..be17f5f 100644 --- a/tools/makefile +++ b/tools/makefile @@ -47,6 +47,7 @@ ${dir_temp}/logic-unlinked.js: \ ${dir_source}/pages/register/logic.ts \ ${dir_source}/pages/password_change_init/logic.ts \ ${dir_source}/pages/password_change_exec/logic.ts \ + ${dir_source}/pages/invite_list/logic.ts \ ${dir_source}/pages/invite_handle/logic.ts \ ${dir_source}/logic/main.ts @ ${cmd_log} "logic | compile …" @@ -69,8 +70,7 @@ ${dir_build}/style.css: \ ${dir_source}/pages/view/style.css \ ${dir_source}/pages/register/style.css \ ${dir_source}/pages/password_change_init/style.css \ - ${dir_source}/pages/password_change_exec/style.css \ - ${dir_source}/pages/invite_handle/style.css + ${dir_source}/pages/password_change_exec/style.css @ ${cmd_log} "style …" @ ${cmd_mkdir} $(dir $@) @ ${cmd_cat} $^ > $@ @@ -86,6 +86,7 @@ ${dir_build}/index.html: \ ${dir_source}/pages/register/structure.html \ ${dir_source}/pages/password_change_init/structure.html \ ${dir_source}/pages/password_change_exec/structure.html \ + ${dir_source}/pages/invite_list/structure.html \ ${dir_source}/pages/invite_handle/structure.html @ ${cmd_log} "structure …" @ ${cmd_mkdir} $(dir $@) -- 2.39.5