diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..e82584a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,27 @@ +# see https://EditorConfig.org + +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = tab +indent_style = tab +tab_width = 4 +insert_final_newline = true +max_line_length = 80 +trim_trailing_whitespace = true +curly_bracket_next_line = false +indent_brace_style = K&R +spaces_around_operators = true +spaces_around_brackets = false +quote_type = double + +[*.y{,a}ml{,lint}] +indent_style = space +indent_size = 2 + +[*.md] +indent_style = space +indent_size = 2 + diff --git a/conf/example.json b/conf/example.json index 63ec3b1..c63431d 100644 --- a/conf/example.json +++ b/conf/example.json @@ -1,4 +1,6 @@ { - "view_mode": "table", - "timezone_shift": 0 + "version": 1, + "log": [ + {"kind": "stdout", "data": {"threshold": "debug"}} + ] } diff --git a/lib/plankton/plankton.d.ts b/lib/plankton/plankton.d.ts index 28f1eb6..66c3c17 100644 --- a/lib/plankton/plankton.d.ts +++ b/lib/plankton/plankton.d.ts @@ -29,8 +29,11 @@ type type_datetimeobject = { date: type_date; time: type_time; }; +declare var process: any; +declare var require: any; declare class Buffer { constructor(x: string, modifier?: string); + static from(x: string, encoding?: string): any; toString(modifier?: string): string; } declare namespace lib_plankton.base { @@ -692,7 +695,1847 @@ declare namespace lib_plankton.call { seconds: (null | float); }>; } +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 { + /** + */ + enum enum_level { + debug = 0, + info = 1, + notice = 2, + 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; + }; +} +/** + * @deprecated + * @todo remove + */ +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; + /** + * @author fenris + */ + function write({ "message": message, "type": type, "prefix": prefix, "level": level, "indent": indent, }: { + message?: string; + type?: string; + prefix?: string; + level?: int; + indent?: int; + }): void; +} +declare namespace lib_plankton.log { + /** + */ + abstract class class_channel { + /** + */ + abstract add(entry: type_entry): void; + } +} +declare namespace lib_plankton.log { + /** + * output for writing log entries to stdout + */ + class class_channel_stdout extends class_channel { + /** + */ + add(entry: type_entry): void; + } +} +declare namespace lib_plankton.log { + /** + */ + class class_channel_file extends class_channel { + /** + * the path of the log file + */ + private path; + /** + */ + private human_readable; + /** + * [constructor] + */ + constructor(path: string, human_readable: boolean); + /** + */ + add(entry: type_entry): void; + } +} +declare namespace lib_plankton.log { + /** + */ + class class_channel_email extends class_channel { + /** + */ + private smtp_credentials; + /** + */ + private sender; + /** + */ + private receivers; + /** + * [constructor] + */ + constructor(smtp_credentials: { + host: string; + port: int; + username: string; + password: string; + }, sender: string, receivers: Array); + /** + */ + add(entry: type_entry): void; + } +} +declare namespace lib_plankton.log { + /** + * output for desktop notifications via "libnotify" + */ + class class_channel_notify extends class_channel { + /** + */ + add(entry: type_entry): void; + } +} +declare namespace lib_plankton.log { + /** + * decorator for filtering out log entries below a certain level threshold + */ + 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 channel_make(description: { + kind: string; + data?: { + [key: string]: any; + }; + }): class_channel; + /** + */ + type type_configuration = Array; + /** + */ + function conf_default(): type_configuration; +} +declare namespace lib_plankton.log { + /** + * pushes a new configuration on the stack and activates it + */ + function conf_push(channels: type_configuration): void; + /** + * pops the current active configuration from the stack + */ + function conf_pop(): void; + /** + * consumes a log entry, i.e. sends it to the currently active outputs + */ + function add(entry: type_entry): void; + /** + */ + function debug(incident: string, details?: Record): void; + /** + */ + function info(incident: string, details?: Record): void; + /** + */ + function notice(incident: string, details?: Record): void; + /** + */ + function warning(incident: string, details?: Record): void; + /** + */ + function error(incident: string, details?: Record): void; +} +declare namespace lib_plankton.log { +} +declare var plain_text_to_html: (text: string) => string; +/** + * @desc makes a valid + */ +declare var format_sentence: (str: string, rtl?: boolean, caseSense?: boolean) => string; +declare var fill_string_template: (template_string: string, object: any, fabric: Function, delimiter: string, default_string: string, sloppy: boolean) => string; +declare var make_string_template: (_template: string, _fabrics?: Object) => (object: { + [key: string]: string; +}) => string; +declare var make_eml_header: (object: { + [key: string]: string; +}) => string; +declare var make_eml_body: Object; +declare namespace lib_plankton.string { + /** + * @author neuc,frac + */ + function empty(str: string): boolean; + /** + * @desc returns a unique string + * @param {string} prefix an optional prefix for the generated string + * @return {string} + * @author fenris + */ + function generate(prefix?: string): string; + /** + * @author fenris + */ + function join(parts: Array, glue?: string): string; + /** + * @desc splits a string, but returns an empty list, if the string is empty + * @param {string} chain + * @param {string} separator + * @return {Array} + * @author fenris + */ + function split(chain: string, separator?: string): Array; + /** + * @author neu3no + */ + function explode(str: string, needle: string, max: int): Array; + /** + * @desc concats a given word with itself n times + * @param {string} word + * @param {int} + * @return {string} + * @author fenris + */ + function repeat(word: string, count: int): string; + /** + * @desc lengthens a string by repeatedly appending or prepending another string + * @param {string} word the string to pad + * @param {int} length the length, which the result shall have + * @param {string} symbol the string, which will be added (multiple times) + * @param {boolean} [prepend]; whether to prepend (~true) or append (~false); default: false + * @return {string} the padded string + * @author fenris + */ + function pad(word: string, length: int, symbol?: string, mode?: string): string; + /** + * @desc checks if a given string conttains a certain substring + * @param {string} string + * @param {string} part + * @return {boolean} + * @author fenris + */ + function contains(chain: string, part: string): boolean; + /** + * @desc checks if a given string starts with a certain substring + * @param {string} string + * @param {string} part + * @return {boolean} + * @author fenris + */ + function startsWith(chain: string, part: string): boolean; + /** + * @desc checks if a given string ends with a certain substring + * @param {string} string + * @param {string} part + * @return {boolean} + * @author fenris + */ + function endsWith(chain: string, part: string): boolean; + /** + * @desc count the occourrences of a string in a string + * @param string haystack_string the string wich should be examined + * @param string needle_string the string which should be counted + * @author neuc + */ + function count_occourrences(haystack_string: string, needle_string: string, check_escape: boolean): int; + /** + * @author fenris + */ + function replace(str: string, replacements: Array<{ + from: string; + to: string; + }>, options?: {}): string; + /** + * @desc replaces occurences of "{{name}}" in a string by the corresponding values of an argument object + * @author fenris + */ + function coin(str: string, args: { + [id: string]: string; + }, options?: { + legacy?: boolean; + open?: string; + close?: string; + }): string; + /** + * @author fenris + * @deprecated use limit + */ + function cut(str: string, length: int, delimiter?: string): string; + /** + */ + function limit(str: string, options?: { + length?: int; + indicator?: string; + }): string; + /** + */ + function slice(str: string, size: int): Array; +} +/** + * @deprecated + */ +declare namespace lib_string { + const empty: typeof lib_plankton.string.empty; + const generate: typeof lib_plankton.string.generate; + const split: typeof lib_plankton.string.split; + const explode: typeof lib_plankton.string.repeat; + const repeat: typeof lib_plankton.string.repeat; + const pad: typeof lib_plankton.string.pad; + const contains: typeof lib_plankton.string.contains; + const startsWith: typeof lib_plankton.string.startsWith; + const endsWith: typeof lib_plankton.string.endsWith; + const count_occourrences: typeof lib_plankton.string.count_occourrences; + const coin: typeof lib_plankton.string.coin; + const stance: typeof lib_plankton.string.coin; + const cut: typeof lib_plankton.string.cut; +} +declare namespace lib_plankton.string { + /** + * an implementation of c sprintf + * @param {string} string format string + * @param {array} args arguments which should be filled into + * @returns {string} + */ + var sprintf: (input: string, args?: Array, original?: any) => string; + /** + * an implementation of c printf + * @param {string} string format string + * @param {array} args arguments which should be filled into + * @returns {string} + */ + function printf(format: any, args: any): void; +} +declare var sprintf: (input: string, args?: Array, original?: any) => string; +declare var printf: typeof lib_plankton.string.printf; +declare var eml_log: any; +declare var track_exports: any; +declare var make_logger: (prefix: any, current_loglevel: any) => (obj: any, lvl: any) => void; +declare namespace lib_plankton.database { + /** + */ + type type_query = { + template: string; + arguments: Record; + }; + /** + */ + enum enum_type { + boolean = "boolean", + integer = "integer", + string_short = "string_short", + string_medium = "string_medium", + string_long = "string_long", + float = "float" + } + /** + */ + type type_description_create_table = { + name: string; + key_field?: (null | { + name: string; + type?: enum_type; + comment?: (null | string); + auto_increment?: (null | boolean); + description?: (null | string); + }); + data_fields?: Array<{ + name: string; + nullable?: boolean; + type: enum_type; + default?: any; + description?: (null | string); + }>; + constraints?: Array<{ + kind: string; + parameters?: Record; + }>; + description?: (null | string); + }; + /** + */ + type type_description_insert = { + table_name: string; + values: Record; + returning?: (null | string); + }; + /** + */ + type type_description_update = { + table_name: string; + values: Record; + condition?: (null | string); + arguments?: (null | Record); + }; + /** + */ + type type_description_delete = { + table_name: string; + condition?: (null | string); + arguments?: (null | Record); + }; + /** + */ + type type_description_select = { + source: string; + fields?: (null | Array); + condition?: (null | string); + group_by?: (null | string); + having?: (null | string); + order_by?: (null | string); + limit?: (null | int); + arguments?: (null | Record); + }; + /** + * rows + */ + type type_result_get = Array>; + /** + * auto insert id + */ + type type_result_put = (null | int); + /** + * number of affected rows + */ + type type_result_set = int; + /** + * @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); + query_create_table: ((description_create_table: type_description_create_table) => Promise); + query_insert: ((description_insert: type_description_insert) => Promise); + query_update: ((description_update: type_description_update) => Promise); + query_delete: ((description_delete: type_description_delete) => Promise); + query_select: ((description_select: type_description_select) => Promise); + }; + /** + */ + type interface_database = database.type_database; +} +declare namespace lib_plankton.database { + /** + * @todo default case? + */ + function sql_common_value_format(value: any): string; + /** + */ + function sql_common_formulation_create_table(description_create_table: type_description_create_table, options?: { + auto_increment_keyword?: (null | string); + auto_increment_special?: (null | string); + omit_comments?: boolean; + type_map?: Record; + wrap_name?: ((name: string) => string); + }): type_query; + /** + */ + function sql_common_formulation_insert(description_insert: type_description_insert, options?: { + wrap_name?: ((name: string) => string); + set_returning?: boolean; + }): type_query; + /** + */ + function sql_common_formulation_update(description_update: type_description_update, options?: { + wrap_name?: ((name: string) => string); + }): type_query; + /** + */ + function sql_common_formulation_delete(description_delete: type_description_delete, options?: { + wrap_name?: ((name: string) => string); + }): type_query; + /** + */ + function sql_common_formulation_select(description_select: type_description_select, options?: { + wrap_name?: ((name: string) => string); + }): type_query; +} +declare namespace lib_plankton.database { + /** + */ + type type_sqlite_subject = { + path: string; + handle: any; + }; + /** + */ + type type_sqlite_parameters = { + path: string; + }; + /** + */ + function sqlite_make(parameters: type_sqlite_parameters): type_sqlite_subject; + /** + */ + function sqlite_wrap_name(name: string): string; + /** + * @author fenris + */ + function sqlite_query_free_get(subject: type_sqlite_subject, query: type_query): Promise; + /** + * @author fenris + */ + function sqlite_query_free_put(subject: type_sqlite_subject, query: type_query): Promise; + /** + * @author fenris + */ + function sqlite_query_free_set(subject: type_sqlite_subject, query: type_query): Promise; + /** + */ + function sqlite_formulation_create_table(description_create_table: type_description_create_table): type_query; + /** + */ + function sqlite_query_create_table(subject: type_sqlite_subject, description: type_description_create_table): Promise; + /** + */ + function sqlite_formulation_insert(description_insert: type_description_insert): type_query; + /** + */ + function sqlite_query_insert(subject: type_sqlite_subject, description_insert: type_description_insert): Promise; + /** + */ + function sqlite_formulation_update(description_update: type_description_update): type_query; + /** + */ + function sqlite_query_update(subject: type_sqlite_subject, description_update: type_description_update): Promise; + /** + */ + function sqlite_formulation_delete(description_delete: type_description_delete): type_query; + /** + */ + function sqlite_query_delete(subject: type_sqlite_subject, description_delete: type_description_delete): Promise; + /** + */ + function sqlite_formulation_select(description_select: type_description_select): type_query; + /** + */ + function sqlite_query_select(subject: type_sqlite_subject, description_select: type_description_select): Promise>>; + /** + */ + function sqlite_database(parameters: type_sqlite_parameters): type_database; +} +declare namespace lib_plankton.database { + /** + * @author fenris + */ + class class_sqlite implements interface_database { + private subject; + constructor(parameters: type_sqlite_parameters); + wrap_name(name: any): string; + query_free_get(query: any): Promise; + query_free_put(query: any): Promise; + query_free_set(query: any): Promise; + query_create_table(description_create_table: any): Promise; + query_insert(description_insert: any): Promise; + query_update(description_update: any): Promise; + query_delete(description_delete: any): Promise; + query_select(description_select: any): Promise[]>; + } +} +declare namespace lib_plankton.database { + /** + * @todo + */ + type type_postgresql_subject = { + host: string; + port: int; + username: string; + password: string; + schema: string; + pool: (null | any); + }; + /** + * @todo + */ + type type_postgresql_parameters = { + host: string; + port?: int; + username: string; + password: string; + schema: string; + }; + /** + */ + function postgresql_make(parameters: type_postgresql_parameters): type_postgresql_subject; + /** + */ + function postgresql_wrap_name(name: string): string; + /** + * @author fenris + * @see https://node-postgres.com/apis/pool#poolquery + */ + function postgresql_query_free_get(subject: type_postgresql_subject, query: type_query): Promise; + /** + * @author fenris + * @see https://node-postgres.com/apis/pool#poolquery + */ + function postgresql_query_free_put(subject: type_postgresql_subject, query: type_query): Promise; + /** + * @author fenris + * @see https://node-postgres.com/apis/pool#poolquery + */ + function postgresql_query_free_set(subject: type_postgresql_subject, query: type_query): Promise; + /** + */ + function postgresql_formulation_create_table(description_create_table: type_description_create_table): type_query; + /** + */ + function postgresql_query_create_table(subject: type_postgresql_subject, description: type_description_create_table): Promise; + /** + */ + function postgresql_formulation_insert(description_insert: type_description_insert): type_query; + /** + */ + function postgresql_query_insert(subject: type_postgresql_subject, description_insert: type_description_insert): Promise; + /** + */ + function postgresql_formulation_update(description_update: type_description_update): type_query; + /** + */ + function postgresql_query_update(subject: type_postgresql_subject, description_update: type_description_update): Promise; + /** + */ + function postgresql_formulation_delete(description_delete: type_description_delete): type_query; + /** + */ + function postgresql_query_delete(subject: type_postgresql_subject, description_delete: type_description_delete): Promise; + /** + */ + function postgresql_formulation_select(description_select: type_description_select): type_query; + /** + */ + function postgresql_query_select(subject: type_postgresql_subject, description_select: type_description_select): Promise>>; + /** + */ + function postgresql_database(parameters: type_postgresql_parameters): type_database; +} +declare namespace lib_plankton.database { + /** + * @author fenris + */ + class class_postgresql implements interface_database { + private subject; + constructor(parameters: type_postgresql_parameters); + wrap_name(name: any): string; + query_free_get(query: any): Promise; + query_free_put(query: any): Promise; + query_free_set(query: any): Promise; + query_create_table(description_create_table: any): Promise; + query_insert(description_insert: any): Promise; + query_update(description_update: any): Promise; + query_delete(description_delete: any): Promise; + query_select(description_select: any): Promise[]>; + } +} +declare namespace lib_plankton.database { + /** + * @todo + */ + type type_mysql_subject = { + verbose: boolean; + }; + /** + * @todo + */ + type type_mysql_parameters = { + verbose?: boolean; + }; + /** + */ + function mysql_make(parameters: type_mysql_parameters): type_mysql_subject; + /** + */ + function mysql_wrap_name(name: string): string; + /** + * @author fenris + */ + function mysql_query_free_get(subject: type_mysql_subject, query: type_query): Promise; + /** + * @author fenris + */ + function mysql_query_free_put(subject: type_mysql_subject, query: type_query): Promise; + /** + * @author fenris + */ + function mysql_query_free_set(subject: type_mysql_subject, query: type_query): Promise; + /** + */ + function mysql_formulation_create_table(description_create_table: type_description_create_table): type_query; + /** + */ + function mysql_query_create_table(subject: type_mysql_subject, description: type_description_create_table): Promise; + /** + */ + function mysql_formulation_insert(description_insert: type_description_insert): type_query; + /** + */ + function mysql_query_insert(subject: type_mysql_subject, description_insert: type_description_insert): Promise; + /** + */ + function mysql_formulation_update(description_update: type_description_update): type_query; + /** + */ + function mysql_query_update(subject: type_mysql_subject, description_update: type_description_update): Promise; + /** + */ + function mysql_formulation_delete(description_delete: type_description_delete): type_query; + /** + */ + function mysql_query_delete(subject: type_mysql_subject, description_delete: type_description_delete): Promise; + /** + */ + function mysql_formulation_select(description_select: type_description_select): type_query; + /** + */ + function mysql_query_select(subject: type_mysql_subject, description_select: type_description_select): Promise>>; + /** + */ + function mysql_database(parameters: type_mysql_parameters): type_database; +} +declare namespace lib_plankton.database { + /** + * @author fenris + */ + class class_mysql implements interface_database { + private subject; + constructor(parameters: type_mysql_parameters); + wrap_name(name: any): string; + query_free_get(query: any): Promise; + query_free_put(query: any): Promise; + query_free_set(query: any): Promise; + query_create_table(description_create_table: any): Promise; + query_insert(description_insert: any): Promise; + query_update(description_update: any): Promise; + query_delete(description_delete: any): Promise; + query_select(description_select: any): Promise[]>; + } +} +declare namespace lib_plankton.storage { + /** + * implements the idea of a database, which houses datasets (type_value) and manages their access by ids or sth. similar (type_key) + * + * @author fenris + */ + type type_store = { + /** + * shall prepare the storage instance for use + * + * @author fenris + */ + setup(input: type_setup_input): Promise; + /** + * shall insert a new dataset and return its automatically assign key + * + * @author fenris + */ + create(value: type_value): Promise; + /** + * shall modify an existing dataset + * + * @author fenris + */ + update(key: type_key, value: type_value): Promise; + /** + * shall remove an existing dataset + * + * @author fenris + */ + delete(key: type_key): Promise; + /** + * shall get an existing dataset by its key + * + * @author fenris + */ + read(key: type_key): Promise; + /** + * shall list keys and previews of existing datasets, which match a certain search term + * + * @author fenris + */ + search(term?: (null | type_searchterm)): Promise>; + }; + /** + * for class wrappers + */ + type interface_store = type_store; +} +declare namespace lib_plankton.storage { + /** + * implements the idea of a storage without managed keys + * + * @author fenris + */ + type type_chest = { + /** + * shall prepare the storage instance for use + * + * @author fenris + */ + setup(input: type_setup_input): Promise; + /** + * shall remove all items + */ + clear(): Promise; + /** + * shall insert a new or modify an existing dataset and return whether it is new + * + * @author fenris + */ + write(key: type_key, value: type_value): Promise; + /** + * shall remove an existing dataset + * + * @author fenris + */ + delete(key: type_key): Promise; + /** + * shall get an existing dataset by its key + * + * @author fenris + */ + read(key: type_key): Promise; + /** + * shall list keys and previews of existing datasets, which match a certain search term + * + * @author fenris + */ + search(term?: (null | type_searchterm)): Promise>; + }; + /** + * for class wrappers + */ + type interface_chest = type_chest; +} +declare namespace lib_plankton.storage.memory { + /** + * @author fenris + */ + type type_subject = { + data: Record; + }; + /** + */ + type type_parameters = {}; + /** + * @author fenris + */ + function make(parameters: type_parameters): type_subject; + /** + * @author fenris + */ + function clear(subject: type_subject): void; + /** + * @author fenris + */ + function write(subject: type_subject, key: string, value: type_value): boolean; + /** + * @author fenris + */ + function delete_(subject: type_subject, key: string): void; + /** + * @author fenris + */ + function read(subject: type_subject, key: string): type_value; + /** + * @author fenris + */ + function list(subject: type_subject): Array; + /** + * @author fenris + */ + function search(subject: type_subject, term: (null | string)): Array<{ + key: string; + preview: string; + }>; + /** + * @author fenris + */ + function implementation_chest(parameters: type_parameters): type_chest; +} +declare namespace lib_plankton.storage.memory { + /** + * @author fenris + */ + class class_chest implements type_chest { + private subject; + constructor(parameters: type_parameters); + setup(input: any): Promise; + clear(): Promise; + write(key: any, value: any): Promise; + delete(key: any): Promise; + read(key: any): Promise>; + search(term: any): Promise<{ + key: string; + preview: string; + }[]>; + } +} +declare namespace lib_plankton.storage.filesystem { + /** + * @author fenris + */ + type type_subject = { + nodemodule: any; + }; + /** + */ + type type_parameters = {}; + /** + * @author fenris + */ + function make(parameters: type_parameters): type_subject; + /** + */ + function clear(subject: type_subject): Promise; + /** + * @author fenris + */ + function write(subject: type_subject, path: string, content: Buffer): Promise; + /** + * @author fenris + */ + function delete_(subject: type_subject, path: string): Promise; + /** + * @author fenris + */ + function read(subject: type_subject, path: string): Promise; + /** + */ + function implementation_chest(parameters: type_parameters): type_chest; +} +declare namespace lib_plankton.storage.filesystem { + /** + * @author fenris + */ + class class_chest implements type_chest { + private subject; + constructor(parameters: type_parameters); + setup(input: any): Promise; + clear(): Promise; + write(key: any, value: any): Promise; + delete(key: any): Promise; + read(key: any): Promise; + search(searchterm: any): Promise<{ + key: string; + preview: void; + }[]>; + } +} +declare namespace lib_plankton.storage { + /** + */ + type type_sql_table_autokey_search_term = { + expression: string; + arguments: Record; + }; + /** + */ + type type_sql_table_autokey_subject = { + database_implementation: lib_plankton.database.type_database; + table_name: string; + key_name: string; + }; + /** + */ + type type_sql_table_autokey_parameters = { + database_implementation: lib_plankton.database.type_database; + table_name: string; + key_name: string; + }; + /** + */ + function sql_table_autokey_make(parameters: type_sql_table_autokey_parameters): type_sql_table_autokey_subject; + /** + */ + function sql_table_autokey_setup(subject: type_sql_table_autokey_subject, description_create_table: lib_plankton.database.type_description_create_table): Promise; + /** + */ + function sql_table_autokey_create(subject: type_sql_table_autokey_subject, value: Record): Promise; + /** + */ + function sql_table_autokey_update(subject: type_sql_table_autokey_subject, key: int, value: Record): Promise; + /** + */ + function sql_table_autokey_delete(subject: type_sql_table_autokey_subject, key: int): Promise; + /** + */ + function sql_table_autokey_read(subject: type_sql_table_autokey_subject, key: int): Promise>; + /** + * @todo correct preview + */ + function sql_table_autokey_search(subject: type_sql_table_autokey_subject, term: (null | type_sql_table_autokey_search_term)): Promise; + }>>; + /** + */ + function sql_table_autokey_store(parameters: type_sql_table_autokey_parameters): type_store, lib_plankton.database.type_description_create_table, type_sql_table_autokey_search_term, Record>; +} +declare namespace lib_plankton.storage { + /** + * @author fenris + */ + class class_sql_table_autokey implements type_store, lib_plankton.database.type_description_create_table, string, Record> { + private subject; + constructor(parameters: type_sql_table_autokey_parameters); + setup(input: any): Promise; + create(value: any): Promise; + update(key: any, value: any): Promise; + delete(key: any): Promise; + read(key: any): Promise>; + search(term: any): Promise<{ + key: number; + preview: Record; + }[]>; + } +} +declare namespace lib_plankton.storage.sql_table_common { + /** + */ + type type_sql_table_common_search_term = { + expression: string; + arguments: Record; + }; + /** + */ + type type_subject = { + database_implementation: lib_plankton.database.type_database; + table_name: string; + key_names: Array; + }; + /** + */ + type type_parameters = { + database_implementation: lib_plankton.database.type_database; + table_name: string; + key_names: Array; + }; + /** + */ + function make(parameters: type_parameters): type_subject; + /** + */ + function setup(subject: type_subject, description_create_table: lib_plankton.database.type_description_create_table): Promise; + /** + */ + function clear(subject: type_subject): Promise; + /** + * @todo optimize: avoid read + */ + function write(subject: type_subject, key: Array, value: Record): Promise; + /** + */ + function delete_(subject: type_subject, key: Array): Promise; + /** + */ + function read(subject: type_subject, key: Array): Promise>; + /** + * @todo correct preview + */ + function search(subject: type_subject, term: (null | type_sql_table_common_search_term)): Promise; + preview: Record; + }>>; + /** + */ + function chest(parameters: type_parameters): type_chest, Record, lib_plankton.database.type_description_create_table, type_sql_table_common_search_term, Record>; +} +declare namespace lib_plankton.storage.sql_table_common { + /** + * @author fenris + */ + class class_chest implements type_chest, Record, lib_plankton.database.type_description_create_table, type_sql_table_common_search_term, Record> { + private subject; + constructor(parameters: type_parameters); + setup(input: any): Promise; + clear(): Promise; + write(key: any, value: any): Promise; + delete(key: any): Promise; + read(key: any): Promise>; + search(term: any): Promise<{ + key: any[]; + preview: Record; + }[]>; + } +} +declare namespace lib_plankton.shape { + /** + * @todo + */ + type type_jsonschema = any; + /** + * @todo + */ + type type_oas_schema = any; + /** + * @author fenris + */ + type type_inspection = { + flaws: Array; + sub: Array<{ + position: string; + inspection: type_inspection; + }>; + }; + /** + * @author fenris + */ + function inspection_create(): type_inspection; + /** + * @author fenris + */ + function inspection_add(main: type_inspection, flaw: string): void; + /** + * @author fenris + */ + function inspection_extend(main: type_inspection, prefix: string, sub: type_inspection): void; + /** + */ + type type_shape = { + kind: string; + parameters: Record; + }; + /** + * @author fenris + */ + type type_logic = { + inspect: ((sub_inspect: ((shape: type_shape, value: any) => type_inspection), value: any) => type_inspection); + show: ((sub_show: ((shape: type_shape) => string)) => string); + to_typescript_type: ((sub_to_typescript_type: ((shape: type_shape) => string)) => string); + to_jsonschema: ((sub_to_json_schema: ((shape: type_shape) => type_jsonschema)) => type_jsonschema); + to_oas_schema: ((sub_to_oas_schema: ((shape: type_shape) => type_oas_schema)) => type_oas_schema); + example: ((sub_example: ((shape: type_shape) => any)) => any); + }; + /** + */ + function inspect(shape: type_shape, value: any): type_inspection; + /** + */ + function inspect_flat(shape: type_shape, value: any): Array; + /** + */ + function show(shape: type_shape): string; + /** + */ + function to_typescript_type(shape: type_shape): string; + /** + */ + function to_jsonschema(shape: type_shape): type_jsonschema; + /** + */ + function to_oas_schema(shape: type_shape): type_oas_schema; + /** + */ + function example(shape: type_shape): any; + /** + */ + function register(name: string, construct: ((parameters: type_parameters) => type_subject), logic: ((subject: type_subject) => type_logic)): void; +} +declare namespace lib_plankton.shape.any { + /** + */ + type type_subject = {}; + /** + */ + export function make(options?: {}): type_subject; + export {}; +} +declare namespace lib_plankton.shape.null_ { + /** + */ + type type_subject = {}; + /** + */ + export function make(options?: {}): type_subject; + export {}; +} +declare namespace lib_plankton.shape.boolean { + /** + */ + type type_subject = { + soft: boolean; + defaultvalue: lib_plankton.pod.type_pod; + description: lib_plankton.pod.type_pod; + }; + /** + */ + export function make(options?: { + soft?: boolean; + defaultvalue?: (null | boolean); + description?: string; + }): type_subject; + export {}; +} +declare namespace lib_plankton.shape.integer { + /** + */ + type type_subject = { + soft: boolean; + defaultvalue: lib_plankton.pod.type_pod; + description: lib_plankton.pod.type_pod; + minimum: lib_plankton.pod.type_pod; + maximum: lib_plankton.pod.type_pod; + }; + /** + */ + export function make(options?: { + soft?: boolean; + defaultvalue?: (null | int); + description?: string; + minimum?: int; + maximum?: int; + }): type_subject; + export {}; +} +declare namespace lib_plankton.shape.float { + /** + */ + type type_subject = { + soft: boolean; + defaultvalue: lib_plankton.pod.type_pod; + description: lib_plankton.pod.type_pod; + minimum: lib_plankton.pod.type_pod; + maximum: lib_plankton.pod.type_pod; + }; + /** + */ + export function make(options?: { + soft?: boolean; + defaultvalue?: (null | float); + description?: string; + minimum?: float; + maximum?: float; + }): type_subject; + export {}; +} +declare namespace lib_plankton.shape.string { + /** + */ + type type_subject = { + soft: boolean; + defaultvalue: lib_plankton.pod.type_pod; + description: lib_plankton.pod.type_pod; + pattern: lib_plankton.pod.type_pod; + min_length: lib_plankton.pod.type_pod; + max_length: lib_plankton.pod.type_pod; + }; + /** + */ + export function make(options?: { + soft?: boolean; + defaultvalue?: (null | int); + description?: string; + pattern?: string; + min_length?: int; + max_length?: int; + }): type_subject; + export {}; +} +declare namespace lib_plankton.shape.email { + /** + */ + type type_subject = { + core: type_shape; + }; + /** + */ + export function make(options?: { + soft?: boolean; + defaultvalue?: (null | int); + description?: string; + }): type_subject; + export {}; +} +declare namespace lib_plankton.shape.list_ { + /** + */ + type type_subject = { + shape_element: type_shape; + soft: boolean; + defaultvalue: lib_plankton.pod.type_pod; + description: lib_plankton.pod.type_pod; + }; + /** + */ + export function make(shape_element: type_shape, options?: { + soft?: boolean; + defaultvalue?: any; + description?: string; + }): type_subject; + export {}; +} +declare namespace lib_plankton.shape.map { + /** + */ + type type_subject = { + shape_key: type_shape; + shape_value: type_shape; + soft: boolean; + defaultvalue: lib_plankton.pod.type_pod; + description: lib_plankton.pod.type_pod; + }; + /** + */ + export function make(shape_key: type_shape, shape_value: type_shape, options?: { + soft?: boolean; + defaultvalue?: any; + description?: string; + }): type_subject; + export {}; +} +declare namespace lib_plankton.shape.record { + /** + */ + type type_field = { + name: string; + shape: type_shape; + required: boolean; + }; + /** + */ + type type_subject = { + fields: Array; + soft: boolean; + defaultvalue: lib_plankton.pod.type_pod; + description: lib_plankton.pod.type_pod; + }; + /** + */ + export function make(fields_raw: Array<{ + name: string; + shape: type_shape; + required?: boolean; + }>, options?: { + soft?: boolean; + defaultvalue?: any; + description?: string; + }): type_subject; + export {}; +} +declare namespace lib_plankton.code { + /** + * @author fenris + */ + interface interface_code { + /** + * @author fenris + */ + encode(x: type_from): type_to; + /** + * @author fenris + */ + decode(x: type_to): type_from; + } +} +declare namespace lib_plankton.code { + /** + * @author fenris + */ + type type_code = { + /** + * @author fenris + */ + encode: (x: type_from) => type_to; + /** + * @author fenris + */ + decode: (x: type_to) => type_from; + }; +} +declare namespace lib_plankton.code { + /** + * @author fenris + */ + function inverse_encode(decode: (to: type_to) => type_from, to: type_to): type_from; + /** + * @author fenris + */ + function inverse_decode(encode: (from: type_from) => type_to, from: type_from): type_to; +} +declare namespace lib_plankton.code { + /** + * @author fenris + */ + class class_code_inverse implements interface_code { + /** + * @author fenris + */ + protected subject: interface_code; + /** + * @author fenris + */ + constructor(subject: interface_code); + /** + * @implementation + * @author fenris + */ + encode(to: type_to): type_from; + /** + * @implementation + * @author fenris + */ + decode(from: type_from): type_to; + } +} +declare namespace lib_plankton.code { + /** + * @author fenris + */ + function pair_encode(encode_first: (from: type_from) => type_between, encode_second: (between: type_between) => type_to, from: type_from): type_to; + /** + * @author fenris + */ + function pair_decode(decode_first: (between: type_between) => type_from, decode_second: (to: type_to) => type_between, to: type_to): type_from; +} +declare namespace lib_plankton.code { + /** + * @author fenris + */ + class class_code_pair implements interface_code { + /** + * @author fenris + */ + protected first: interface_code; + /** + * @author fenris + */ + protected second: interface_code; + /** + * @author fenris + */ + constructor(first: interface_code, second: interface_code); + /** + * @implementation + * @author fenris + */ + encode(from: type_from): type_to; + /** + * @implementation + * @author fenris + */ + decode(to: type_to): type_from; + } +} +declare namespace lib_plankton.code { + /** + * @author fenris + */ + function chain_encode(encode_links: Array<(from: any) => any>, from: any): any; + /** + * @author fenris + */ + function chain_decode(decode_links: Array<(to: any) => any>, to: any): any; +} +declare namespace lib_plankton.code { + /** + * @author fenris + */ + class class_code_chain implements interface_code { + /** + * @author fenris + */ + protected links: Array>; + /** + * @author fenris + */ + constructor(links: Array>); + /** + * @implementation + * @author fenris + */ + encode(from: any): any; + /** + * @implementation + * @author fenris + */ + decode(to: any): any; + } +} +declare namespace lib_plankton.code { + /** + * @author Christian Fraß + */ + type type_flatten_from = Array<{ + [name: string]: any; + }>; + /** + * @author Christian Fraß + */ + type type_flatten_to = { + keys: Array; + data: Array>; + }; + /** + * @author Christian Fraß + */ + function flatten_encode(from: type_flatten_from, keys?: Array): type_flatten_to; + /** + * @author Christian Fraß + */ + function flatten_decode(to: type_flatten_to): type_flatten_from; +} +declare namespace lib_plankton.code { + /** + * @author fenris + */ + class class_code_flatten implements interface_code { + /** + * @author fenris + */ + constructor(); + /** + * @implementation + * @author fenris + */ + encode(x: type_flatten_from): type_flatten_to; + /** + * @implementation + * @author fenris + */ + decode(x: type_flatten_to): type_flatten_from; + } +} +declare namespace lib_plankton.www_form { + /** + */ + type type_source = Record; + /** + */ + type type_target = string; + /** + * @author fenris + */ + function encode(source: type_source): type_target; + /** + * @author fenris + */ + function decode(target: type_target): type_source; +} +declare namespace lib_plankton.www_form { + /** + * @author fenris + */ + class class_www_form implements lib_plankton.code.interface_code { + /** + * @author fenris + */ + constructor(); + /** + * @implementation + * @author fenris + */ + encode(source: type_source): type_target; + /** + * @implementation + * @author fenris + */ + decode(target: type_target): type_source; + } +} +declare namespace lib_plankton.url { + /** + * @author fenris + */ + type type_url = { + scheme: (null | string); + host: (null | string); + username: (null | string); + password: (null | string); + port: (null | int); + path: (null | string); + query: (null | string); + hash: (null | string); + }; +} +declare namespace lib_plankton.url { + /** + * @author fenris + */ + function encode(url: type_url): string; + /** + * @author fenris + * @todo arguments + */ + function decode(url_raw: string): type_url; + /** + * @author fenris + */ + function implementation_code(): lib_plankton.code.type_code; +} +declare namespace lib_plankton.url { + /** + * @author fenris + */ + class class_url implements lib_plankton.code.interface_code { + /** + * @author fenris + */ + constructor(); + /** + * @implementation + * @author fenris + */ + encode(x: any): string; + /** + * @implementation + * @author fenris + */ + decode(x: string): any; + } +} +declare namespace lib_plankton.random { + /** + * @author fenris + */ + type type_state = { + builtin: boolean; + seed?: int; + }; + /** + * @author fenris + */ + function state_push(state: type_state): void; + /** + * @author fenris + */ + function state_pop(): type_state; + /** + * returns a random floating point number in the interval [0,1[ + * + * @author fenris + */ + function generate_unit(): float; + /** + * returns a random boolean value + * + * @param {float} [probability] the probability for the return-value "true"; default: 0.5 + * @author fenris + */ + function generate_boolean(options?: { + probability?: float; + }): boolean; + /** + * returns a random integer number in the interval [a,b] + * + * @param {int} [minimum] the left side of the halfopen interval (i.e. the smallest included value in the range) + * @param {int} [minimum] the right side of the halfopen interval (i.e. the smallest excluded value in the range) + * @author fenris + */ + function generate_integer(options?: { + minimum?: int; + maximum?: int; + }): int; + var generate_int: typeof generate_integer; + /** + * returns a random floating point number in the given interval + * + * @author fenris + */ + function generate_float(options?: { + minimum?: int; + maximum?: int; + }): float; + /** + * returns a random date + * + * @author fenris + */ + function generate_date(options?: { + minimum?: Date; + maximum?: Date; + }): Date; + /** + * @author fenris + */ + function generate_hexdigit(): string; + /** + * generates a random string with an optional prefix + * + * @author fenris + */ + function generate_string(options?: { + length?: int; + }): string; + /** + * chooses a value randomly from a list of values with weights (a higher weight means a higher probability to be chosen) + * + * @author fenris + */ + function choose_weighted(sets: Array<{ + weight: float; + value: type_value; + }>): type_value; + /** + * chooses a value randomly from a list of values with equal probabilities + * + * @author fenris + */ + function choose_uniformly(values: Array): type_value; + /** + * @author fenris + */ + function shuffle(list: Array): Array; + /** + * @author fenris + */ + function generate_vowel(): string; + /** + * @author fenris + */ + function generate_halfvowel(): string; + /** + * @author fenris + */ + function generate_consonant(): string; + /** + * @author fenris + */ + function generate_letter(): string; + /** + * @author fenris + */ + function generate_syllable(): string; + /** + * @author fenris + */ + function generate_word(options?: { + syllable_count_minimum?: int; + syllable_count_maximum?: int; + }): string; + /** + * @author fenris + */ + function generate_text(options?: { + word_count?: int; + }): string; + /** + * @author fenris + */ + function generate_city(): string; + /** + * @author fenris + */ + function generate_street(): string; + /** + * @author fenris + */ + function generate_guid(options?: { + with_braces?: boolean; + }): string; + /** + * @author fenris + */ + function generate_url(): string; + /** + * @author fenris + */ + function generate_email_address(): string; + /** + * @author fenris + */ + function generate_telephone_number(): string; + /** + * @author fenris + */ + function generate_time(): any; + /** + * @author fenris + * @deprecated + * @todo remove + */ + function generate_for_shape(shape: any): any; + /** + * @author fenris + */ +} +declare namespace lib_plankton.session { + /** + */ + type type_session = { + key: string; + name: string; + expiry: int; + data: any; + }; + /** + */ + function begin(name: string, options?: { + lifetime?: int; + data?: any; + }): Promise; + /** + */ + function get(key: string): Promise; + /** + */ + function end(key: string): Promise; + /** + */ + function setup(options?: { + key_length?: int; + key_max_attempts?: int; + default_lifetime?: int; + data_chest?: lib_plankton.storage.type_chest; + clear?: boolean; + }): Promise; +} declare namespace lib_plankton.file { + /** + * @author fenris + */ + function exists(path: string): Promise; /** * @author fenris */ @@ -700,23 +2543,24 @@ declare namespace lib_plankton.file { /** * @author fenris */ - function write(path: string, content: string): Promise; + function read_buffer(path: string): Promise; /** * @author fenris */ - function blob_read_text(blob: Blob): lib_plankton.call.type_promise; + function read_stdin(): Promise; /** * @author fenris */ - function blob_read_arraybuffer(blob: Blob): lib_plankton.call.type_promise; + function write(path: string, content: string, options?: { + encoding?: string; + }): Promise; /** * @author fenris */ - function blob_read_dataurl(blob: Blob): lib_plankton.call.type_promise; + function write_buffer(path: string, content: Buffer, options?: {}): Promise; /** - * @author fenris */ - function blob_write_text(text: string): lib_plankton.call.type_promise; + function delete_(path: string): Promise; } declare namespace lib_plankton.structures { /** @@ -1757,189 +3601,6 @@ declare namespace lib_plankton.structures { show(): string; } } -declare namespace lib_plankton.code { - /** - * @author fenris - */ - interface interface_code { - /** - * @author fenris - */ - encode(x: type_from): type_to; - /** - * @author fenris - */ - decode(x: type_to): type_from; - } -} -declare namespace lib_plankton.code { - /** - * @author fenris - */ - type type_code = { - /** - * @author fenris - */ - encode: (x: type_from) => type_to; - /** - * @author fenris - */ - decode: (x: type_to) => type_from; - }; -} -declare namespace lib_plankton.code { - /** - * @author fenris - */ - function inverse_encode(decode: (to: type_to) => type_from, to: type_to): type_from; - /** - * @author fenris - */ - function inverse_decode(encode: (from: type_from) => type_to, from: type_from): type_to; -} -declare namespace lib_plankton.code { - /** - * @author fenris - */ - class class_code_inverse implements interface_code { - /** - * @author fenris - */ - protected subject: interface_code; - /** - * @author fenris - */ - constructor(subject: interface_code); - /** - * @implementation - * @author fenris - */ - encode(to: type_to): type_from; - /** - * @implementation - * @author fenris - */ - decode(from: type_from): type_to; - } -} -declare namespace lib_plankton.code { - /** - * @author fenris - */ - function pair_encode(encode_first: (from: type_from) => type_between, encode_second: (between: type_between) => type_to, from: type_from): type_to; - /** - * @author fenris - */ - function pair_decode(decode_first: (between: type_between) => type_from, decode_second: (to: type_to) => type_between, to: type_to): type_from; -} -declare namespace lib_plankton.code { - /** - * @author fenris - */ - class class_code_pair implements interface_code { - /** - * @author fenris - */ - protected first: interface_code; - /** - * @author fenris - */ - protected second: interface_code; - /** - * @author fenris - */ - constructor(first: interface_code, second: interface_code); - /** - * @implementation - * @author fenris - */ - encode(from: type_from): type_to; - /** - * @implementation - * @author fenris - */ - decode(to: type_to): type_from; - } -} -declare namespace lib_plankton.code { - /** - * @author fenris - */ - function chain_encode(encode_links: Array<(from: any) => any>, from: any): any; - /** - * @author fenris - */ - function chain_decode(decode_links: Array<(to: any) => any>, to: any): any; -} -declare namespace lib_plankton.code { - /** - * @author fenris - */ - class class_code_chain implements interface_code { - /** - * @author fenris - */ - protected links: Array>; - /** - * @author fenris - */ - constructor(links: Array>); - /** - * @implementation - * @author fenris - */ - encode(from: any): any; - /** - * @implementation - * @author fenris - */ - decode(to: any): any; - } -} -declare namespace lib_plankton.code { - /** - * @author Christian Fraß - */ - type type_flatten_from = Array<{ - [name: string]: any; - }>; - /** - * @author Christian Fraß - */ - type type_flatten_to = { - keys: Array; - data: Array>; - }; - /** - * @author Christian Fraß - */ - function flatten_encode(from: type_flatten_from, keys?: Array): type_flatten_to; - /** - * @author Christian Fraß - */ - function flatten_decode(to: type_flatten_to): type_flatten_from; -} -declare namespace lib_plankton.code { - /** - * @author fenris - */ - class class_code_flatten implements interface_code { - /** - * @author fenris - */ - constructor(); - /** - * @implementation - * @author fenris - */ - encode(x: type_flatten_from): type_flatten_to; - /** - * @implementation - * @author fenris - */ - decode(x: type_flatten_to): type_flatten_from; - } -} declare namespace lib_plankton.json { /** */ @@ -1984,1400 +3645,6 @@ declare namespace lib_plankton.json { decode(x: string): any; } } -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 { - /** - */ - enum enum_level { - debug = 0, - info = 1, - notice = 2, - 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; - }; -} -/** - * @deprecated - * @todo remove - */ -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; - /** - * @author fenris - */ - function write({ "message": message, "type": type, "prefix": prefix, "level": level, "indent": indent, }: { - message?: string; - type?: string; - prefix?: string; - level?: int; - indent?: int; - }): void; -} -declare namespace lib_plankton.log { - /** - */ - abstract class class_channel { - /** - */ - abstract add(entry: type_entry): void; - } -} -declare namespace lib_plankton.log { - /** - * output for writing log entries to web console - */ - class class_channel_console extends class_channel { - /** - */ - add(entry: type_entry): void; - } -} -declare namespace lib_plankton.log { - /** - * decorator for filtering out log entries below a certain level threshold - */ - 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 channel_make(description: { - kind: string; - data?: { - [key: string]: any; - }; - }): class_channel; - /** - */ - type type_configuration = Array; - /** - */ - function conf_default(): type_configuration; -} -declare namespace lib_plankton.log { - /** - * pushes a new configuration on the stack and activates it - */ - function conf_push(channels: type_configuration): void; - /** - * pops the current active configuration from the stack - */ - function conf_pop(): void; - /** - * consumes a log entry, i.e. sends it to the currently active outputs - */ - function add(entry: type_entry): void; - /** - */ - function debug(incident: string, details?: Record): void; - /** - */ - function info(incident: string, details?: Record): void; - /** - */ - function notice(incident: string, details?: Record): void; - /** - */ - function warning(incident: string, details?: Record): void; - /** - */ - function error(incident: string, details?: Record): void; -} -declare namespace lib_plankton.log { -} -declare namespace lib_plankton.args { - /** - */ - enum enum_environment { - cli = "cli", - url = "url" - } - /** - */ - enum enum_kind { - positional = "positional", - volatile = "volatile" - } - /** - */ - enum enum_type { - boolean = "boolean", - integer = "int", - float = "float", - string = "string" - } - /** - */ - enum enum_mode { - replace = "replace", - accumulate = "accumulate" - } -} -declare namespace lib_plankton.args { - /** - * @author fenris - */ - class class_argument { - /** - * @author fenris - */ - protected name: string; - /** - * @author fenris - */ - protected kind: enum_kind; - /** - * @author fenris - */ - protected type: enum_type; - /** - * @author fenris - */ - protected mode: enum_mode; - /** - * @author fenris - */ - protected default_: any; - /** - * @author fenris - */ - protected info: string; - /** - * @author fenris - */ - protected parameters: Object; - /** - * @author fenris - */ - protected hidden: boolean; - /** - * @author fenris - */ - constructor({ "name": name, "type": type, "kind": kind, "mode": mode, "default": default_, "info": info, "parameters": parameters, "hidden": hidden, }: { - name: string; - type?: enum_type; - kind?: enum_kind; - mode?: enum_mode; - default?: any; - info?: string; - parameters?: Object; - hidden?: boolean; - }); - /** - * @author fenris - */ - static positional({ "name": name, "type": type, "mode": mode, "default": default_, "info": info, "hidden": hidden, "index": index, }: { - name: string; - type?: enum_type; - mode?: enum_mode; - default?: any; - info?: string; - hidden?: boolean; - index: int; - }): class_argument; - /** - * @author fenris - */ - static volatile({ "name": name, "type": type, "mode": mode, "default": default_, "info": info, "hidden": hidden, "indicators_short": indicators_short, "indicators_long": indicators_long, }: { - name: string; - type?: enum_type; - mode?: enum_mode; - default?: any; - info?: string; - hidden?: boolean; - indicators_short: Array; - indicators_long: Array; - }): class_argument; - /** - * @author fenris - */ - check(): boolean; - /** - * @author fenris - */ - name_get(): string; - /** - * @author fenris - */ - kind_get(): enum_kind; - /** - * @author fenris - */ - type_get(): enum_type; - /** - * @author fenris - */ - mode_get(): enum_mode; - /** - * @author fenris - */ - default_get(): any; - /** - * @author fenris - */ - parameters_get(): Object; - /** - * @author fenris - */ - hidden_get(): boolean; - /** - * @author fenris - */ - toString(): string; - /** - * @author fenris - */ - indicator_main(): string; - /** - * @author fenris - */ - pattern_value(): string; - /** - * @author fenris - */ - extract(raw: string): any; - /** - * @author fenris - */ - assign(data: Object, target: string, raw: string): void; - /** - * @author fenris - */ - make(data: Object, target: string): string; - /** - * @author fenris - */ - generate_help(): string; - } -} -declare namespace lib_plankton.args { - /** - * @author fenris - */ - var verbosity: int; - /** - * @author fenris - * @todo check validity - */ - class class_handler { - /** - * @author fenris - */ - protected arguments_: { - [name: string]: class_argument; - }; - /** - * @author fenris - */ - constructor(arguments_: { - [name: string]: class_argument; - }); - /** - * @author fenris - */ - filter(kind: enum_kind): { - [name: string]: class_argument; - }; - /** - * @author fenris - */ - read(environment: enum_environment, input: string, data?: { - [name: string]: any; - }): { - [name: string]: any; - }; - /** - * @author fenris - * @todo handle if the data object doesn't have the required field or the type is wrong or sth. - */ - write(environment: enum_environment, data: { - [name: string]: any; - }): string; - /** - * @desc manpage-like info-sheet - * @author fenris - */ - generate_help({ "programname": programname, "author": author, "description": description, "executable": executable, }: { - programname?: string; - author?: string; - description?: string; - executable?: string; - }): string; - } -} -declare var plain_text_to_html: (text: string) => string; -/** - * @desc makes a valid - */ -declare var format_sentence: (str: string, rtl?: boolean, caseSense?: boolean) => string; -declare var fill_string_template: (template_string: string, object: any, fabric: Function, delimiter: string, default_string: string, sloppy: boolean) => string; -declare var make_string_template: (_template: string, _fabrics?: Object) => (object: { - [key: string]: string; -}) => string; -declare var make_eml_header: (object: { - [key: string]: string; -}) => string; -declare var make_eml_body: Object; -declare namespace lib_plankton.string { - /** - * @author neuc,frac - */ - function empty(str: string): boolean; - /** - * @desc returns a unique string - * @param {string} prefix an optional prefix for the generated string - * @return {string} - * @author fenris - */ - function generate(prefix?: string): string; - /** - * @author fenris - */ - function join(parts: Array, glue?: string): string; - /** - * @desc splits a string, but returns an empty list, if the string is empty - * @param {string} chain - * @param {string} separator - * @return {Array} - * @author fenris - */ - function split(chain: string, separator?: string): Array; - /** - * @author neu3no - */ - function explode(str: string, needle: string, max: int): Array; - /** - * @desc concats a given word with itself n times - * @param {string} word - * @param {int} - * @return {string} - * @author fenris - */ - function repeat(word: string, count: int): string; - /** - * @desc lengthens a string by repeatedly appending or prepending another string - * @param {string} word the string to pad - * @param {int} length the length, which the result shall have - * @param {string} symbol the string, which will be added (multiple times) - * @param {boolean} [prepend]; whether to prepend (~true) or append (~false); default: false - * @return {string} the padded string - * @author fenris - */ - function pad(word: string, length: int, symbol?: string, mode?: string): string; - /** - * @desc checks if a given string conttains a certain substring - * @param {string} string - * @param {string} part - * @return {boolean} - * @author fenris - */ - function contains(chain: string, part: string): boolean; - /** - * @desc checks if a given string starts with a certain substring - * @param {string} string - * @param {string} part - * @return {boolean} - * @author fenris - */ - function startsWith(chain: string, part: string): boolean; - /** - * @desc checks if a given string ends with a certain substring - * @param {string} string - * @param {string} part - * @return {boolean} - * @author fenris - */ - function endsWith(chain: string, part: string): boolean; - /** - * @desc count the occourrences of a string in a string - * @param string haystack_string the string wich should be examined - * @param string needle_string the string which should be counted - * @author neuc - */ - function count_occourrences(haystack_string: string, needle_string: string, check_escape: boolean): int; - /** - * @author fenris - */ - function replace(str: string, replacements: Array<{ - from: string; - to: string; - }>, options?: {}): string; - /** - * @desc replaces occurences of "{{name}}" in a string by the corresponding values of an argument object - * @author fenris - */ - function coin(str: string, args: { - [id: string]: string; - }, options?: { - legacy?: boolean; - open?: string; - close?: string; - }): string; - /** - * @author fenris - * @deprecated use limit - */ - function cut(str: string, length: int, delimiter?: string): string; - /** - */ - function limit(str: string, options?: { - length?: int; - indicator?: string; - }): string; - /** - */ - function slice(str: string, size: int): Array; -} -/** - * @deprecated - */ -declare namespace lib_string { - const empty: typeof lib_plankton.string.empty; - const generate: typeof lib_plankton.string.generate; - const split: typeof lib_plankton.string.split; - const explode: typeof lib_plankton.string.repeat; - const repeat: typeof lib_plankton.string.repeat; - const pad: typeof lib_plankton.string.pad; - const contains: typeof lib_plankton.string.contains; - const startsWith: typeof lib_plankton.string.startsWith; - const endsWith: typeof lib_plankton.string.endsWith; - const count_occourrences: typeof lib_plankton.string.count_occourrences; - const coin: typeof lib_plankton.string.coin; - const stance: typeof lib_plankton.string.coin; - const cut: typeof lib_plankton.string.cut; -} -declare namespace lib_plankton.string { - /** - * an implementation of c sprintf - * @param {string} string format string - * @param {array} args arguments which should be filled into - * @returns {string} - */ - var sprintf: (input: string, args?: Array, original?: any) => string; - /** - * an implementation of c printf - * @param {string} string format string - * @param {array} args arguments which should be filled into - * @returns {string} - */ - function printf(format: any, args: any): void; -} -declare var sprintf: (input: string, args?: Array, original?: any) => string; -declare var printf: typeof lib_plankton.string.printf; -declare var eml_log: any; -declare var track_exports: any; -declare var make_logger: (prefix: any, current_loglevel: any) => (obj: any, lvl: any) => void; -declare namespace lib_plankton.complex { - /** - * @author fenris - */ - type type_complex = { - rea: float; - ima: float; - }; - /** - * erstellt eine komplexe Zahl anhand ihrer kartesianischen Koordinaten - * - * @author fenris - */ - function make_cartesian(rea_: float, ima_: float): type_complex; - /** - * erstellt eine komplexe Zahl anhand ihrer Polar-Koordinaten - * - * @author fenris - */ - function make_polar(abs: float, arg: float): type_complex; - /** - * alias zu "make_cartesian" - * - * @author fenris - */ - function make(rea_: float, ima_: float): type_complex; - /** - * erstellt die komplexe Null - * - * @author fenris - */ - function nul(): type_complex; - /** - * erstellt die komplexe Eins - * - * @author fenris - */ - function one(): type_complex; - /** - * gibt den Real-Teil einer komplexen Zahl zurück - * - * @author fenris - */ - function rea(x: type_complex): float; - /** - * gibt den Imaginär-Teil einer komplexen Zahl zurück - * - * @author fenris - */ - function ima(x: type_complex): float; - /** - * gibt die konjugierte komplexe Zahl zurück - * - * @author fenris - */ - function con(x: type_complex): type_complex; - /** - * gibt den Betrag einer komplexen Zahl zurück - * - * @author fenris - */ - function abs(x: type_complex): float; - /** - * gibt das Argument einer komplexen Zahl zurück (auf dem Hauptzweig des komplexen Logarithmus) - * - * @author fenris - */ - function arg(x: type_complex): float; - /** - * gibt eine skalierte komplexe Zahl zurück (das Produkt mit einer reellen Zahl) - * - * @author fenris - */ - function scl(x: type_complex, s: float): type_complex; - /** - * errechnet die Summe zweier komplexer Zahl - * - * @author fenris - */ - function add(x: type_complex, y: type_complex): type_complex; - /** - * gibt die additiv inverse, also negierte komplexe Zahl zurück - * - * @author fenris - */ - function neg(x: type_complex): type_complex; - /** - * ermittelt die Differenz zweier komplexer Zahlen - * - * @author fenris - */ - function sub(x: type_complex, y: type_complex): type_complex; - /** - * ermittelt das Produkt zweier komplexer Zahlen - * - * @author fenris - */ - function mul(x: type_complex, y: type_complex): type_complex; - /** - * ermittelt die multiplikativ inverse komplexe Zahl, also den Kehrwert - * - * @author fenris - */ - function inv(x: type_complex): type_complex; - /** - * ermittelt den Quotienten zweier komplexer Zahlen - * - * @author fenris - */ - function div(x: type_complex, y: type_complex): type_complex; - /** - * ermittelt die natürliche Potenz einer komplexen Zahl - * - * @author fenris - */ - function npow(x: type_complex, n: int): type_complex; - /** - * ermittelt die natürliche Potenz einer komplexen Zahl - * - * @author fenris - * @deprecated use "npow" instead - * @todo remove - */ - function exp(x: type_complex, n: int): type_complex; - /** - * ermittelt die Potenz zweier komplexer Zahlen - * - * @author fenris - * @todo Probleme der komplexen Exponentiation berücksichtigen - */ - function pow(x: type_complex, y: type_complex): type_complex; - /** - * gibt die n-ten komplexen Einheits-Wurzeln zurück ({x ∈ C | x^n = 1}) - * - * @author fenris - */ - function unitroots(n: int): Array; - /** - * {x ∈ C | x^n = y} - * - * @author fenris - */ - function normroots(n: int, y: type_complex): Array; - /** - * ermittelt ob zwei komplexe Zahlen gleich sind - * - * @author fenris - */ - function equ(x: type_complex, y: type_complex, threshold?: float): boolean; - /** - * gibt eine textuelle Repräsentation einer komplexen Zahl zurück - * - * @author fenris - */ - function str(x: type_complex): string; -} -declare namespace lib_plankton.complex { - /** - * @author fenris - */ - class class_complex { - /** - * @author fenris - */ - private subject; - /** - * @author fenris - */ - private constructor(); - /** - * @author fenris - */ - private static _cram; - /** - * @author fenris - */ - private static _tear; - /** - * @author fenris - */ - static make_cartesian(rea: float, ima: float): class_complex; - /** - * @author fenris - */ - static make_polar(abs: float, arg: float): class_complex; - /** - * @author fenris - */ - static make(rea: float, ima: float): class_complex; - /** - * @author fenris - */ - static nul(): class_complex; - /** - * @author fenris - */ - static one(): class_complex; - /** - * @author fenris - */ - con(): class_complex; - /** - * @author fenris - */ - abs(): float; - /** - * @author fenris - */ - arg(): float; - /** - * @author fenris - */ - scl(s: float): class_complex; - /** - * @author fenris - */ - add(other: class_complex): class_complex; - /** - * @author fenris - */ - neg(): class_complex; - /** - * @author fenris - */ - sub(other: class_complex): class_complex; - /** - * @author fenris - */ - mul(other: class_complex): class_complex; - /** - * @author fenris - */ - inv(): class_complex; - /** - * @author fenris - */ - div(other: class_complex): class_complex; - /** - * @author fenris - */ - exp(n: int): class_complex; - /** - * @author fenris - */ - pow(other: class_complex): class_complex; - /** - * @author fenris - */ - equ(other: class_complex): boolean; - /** - * @author fenris - */ - str(): string; - /** - * @author fenris - */ - toString(): string; - } -} -declare namespace lib_plankton.math { - /** - * @desc golden ratio (e.g. for generating colors) - * @author fenris - */ - const phi: float; - /** - * @author fenris - */ - const e: float; - /** - * @author fenris - */ - const pi: float; - /** - * @author fenris - */ - const tau: float; -} -declare namespace lib_plankton.math { - /** - * @author fenris - */ - function clamp(x: number, a?: number, b?: number): number; - /** - * @desc the mathematical sign-function - * @return {int} an element of {-1,0,+1} - * @author fenris - */ - function sgn(x: number): int; - /** - * @desc integer division - * @author fenris - */ - function div(x: float, y: float): float; - /** - * @desc real modulo operator - * @author fenris - */ - function mod(x: float, y: float): float; - /** - * @desc computes "x^y mod z" via square-and-multiply - * @param {int} base ("x") - * @param {int} exponent ("y") - * @param {int} modulus ("z") - * @return {int} - * @author fenris - * @todo handle invalid cases (e.g. "z < 1") - * @todo implement iteratively - */ - function modpow(base: int, exponent: int, modulus: int): int; - /** - * @desc determines if two integers are coprime, i.e. that they don't have a common divisor greater than 1 - * @author fenris - * @todo write function "gcdx" and base on it - */ - function coprime(x: int, y: int): boolean; - /** - * @desc extended euclidean algorithm for computing multiplicative inverse elements - * @param {int} modulus - * @param {int} element - * @author fenris - * @todo write function "gcdx" and base on it - * @todo handle more invalid cases - */ - function inv(modulus: int, element: int, positive?: boolean): int; - /** - * @author fenris - */ - function interpolate_linear(x: number, y: number, t?: number): number; - /** - * @desc kind of the inverse of linear interpolation; i.e. to find the coefficient "t" for given values x, y and - * their presumed interpolation v - * @author fenris - */ - function appoint_linear(x: number, y: number, v: number): number; - /** - * continued fraction decomposition - */ - function cfd(x: float, n?: int): Array; -} -declare namespace lib_plankton.math { - /** - * @author fenris - */ - type type_relationparameters = { - symbol?: string; - name?: string; - predicate?: (value: type_value, reference: type_value) => boolean; - }; - /** - * @author fenris - */ - class class_relation implements interface_showable, interface_hashable, interface_collatable> { - /** - * @author fenris - */ - protected id: string; - /** - * @author fenris - */ - protected symbol: string; - /** - * @author fenris - */ - protected name: string; - /** - * @author fenris - */ - protected predicate: (value: type_value, reference: type_value) => boolean; - /** - * @author fenris - */ - check(value: type_value, reference: type_value): boolean; - /** - * @author fenris - */ - constructor(id: string, { "symbol": symbol, "name": name, "predicate": predicate, }: type_relationparameters); - /** - * @author fenris - */ - id_get(): string; - /** - * @author fenris - */ - symbol_get(): string; - /** - * @author fenris - */ - name_get(): string; - /** - * @desc [accessor] [implementation] - * @author fenris - */ - _show(): string; - /** - * @desc [accessor] [implementation] - * @author fenris - */ - _hash(): string; - /** - * @desc [accessor] [implementation] - * @author fenris - */ - _collate(relation: class_relation): boolean; - /** - * @author fenris - */ - toString(): string; - /** - * @author fenris - */ - protected static pool(): { - [id: string]: type_relationparameters; - }; - /** - * @author fenris - */ - static get(id: string): class_relation; - /** - * @author fenris - */ - static available(): Array; - } - /** - * @author fenris - */ - class class_filtrationitem implements interface_showable { - /** - * @author fenris - */ - protected extract: (dataset: Object) => type_value; - /** - * @author fenris - */ - protected relation: class_relation; - /** - * @author fenris - */ - protected reference: type_value; - /** - * @author fenris - */ - constructor({ "extract": extract, "relation": relation, "reference": reference, }: { - extract: (dataset: Object) => type_value; - relation: class_relation; - reference: type_value; - }); - /** - * @author fenris - */ - check(dataset: Object): boolean; - /** - * @desc [implementation] - * @author fenris - */ - _show(): string; - /** - * @author fenris - */ - toString(): string; - } - /** - * @desc disjunctive normal form - * @author fenris - */ - class class_filtration implements interface_showable { - /** - * @author fenris - */ - protected clauses: Array>>; - /** - * @author fenris - */ - constructor(clauses: Array>>); - /** - * @author fenris - */ - check(dataset: Object): boolean; - /** - * @author fenris - */ - use(datasets: Array): Array; - /** - * @desc [implementation] - * @author fenris - */ - _show(): string; - /** - * @author fenris - */ - toString(): string; - } - /** - * @author fenris - * @deprecated - */ - function comparator_to_relation(comparator: (x: type_value, y: type_value) => int): (x: type_value, y: type_value) => boolean; - /** - * @author fenris - * @deprecated - */ - function relation_to_comparator(relation: (x: type_value, y: type_value) => boolean): (x: type_value, y: type_value) => int; -} -declare module lib_calculus { - /** - * @class Calculus - * @desc Ensure precision of mathematical operations - */ - class Calculus { - /** @desc only for typescript - */ - private NORM; - /** - * @constructor - * @þaram {number} norm - */ - constructor(norm?: number); - /** - * normalize - * @param {number} value - * @return {number} - */ - normalize(value: number): number; - /** - * denormalize - * @param {number} value - * @return {number} - */ - denormalize(value: number): number; - } -} -declare namespace lib_plankton.math { - /** - * {x ∈ C | 0 = ax³ + bx² + cx + d} - * - * @author fenris - */ - function cubic_solve(a: lib_plankton.complex.type_complex, b: lib_plankton.complex.type_complex, c: lib_plankton.complex.type_complex, d: lib_plankton.complex.type_complex): Array; - /** - * {x ∈ C | 0 = ax³ + bx² + cx + d} - * - * @author fenris - */ - function cubic_solve_real(a: float, b: float, c: float, d: float): Array; -} -declare namespace lib_plankton.color { - /** - * @author fenris - */ - type type_model_hsv = { - hue: float; - saturation: float; - value: float; - }; - /** - * @author fenris - */ - type type_model_hsl = { - hue: float; - saturation: float; - lightness: float; - }; - /** - * @author fenris - */ - type type_model_rgb = { - red: float; - green: float; - blue: float; - }; - /** - * @author fenris - */ - type type_color = { - model: type_model_rgb; - }; -} -declare namespace lib_plankton.color { - /** - */ - function make_hsv({ "hue": hue, "saturation": saturation, "value": value }: { - hue?: float; - saturation?: float; - value?: float; - }): type_color; - /** - */ - function make_hsl(model_hsl: type_model_hsl): type_color; - /** - */ - function make_rgb(model_rgb: type_model_rgb): type_color; - /** - */ - function to_hsv(color: type_color): type_model_hsv; - /** - */ - function to_hsl(color: type_color): type_model_hsl; - /** - */ - function to_rgb(color: type_color): type_model_rgb; - /** - */ - function to_cmyk(color: type_color): type_model_rgb; - /** - */ - function add(color1: type_color, color2: type_color): type_color; - /** - */ - function multiply(color1: type_color, color2: type_color): type_color; - /** - * @todo blend through other model? - */ - function blend(color1: type_color, color2: type_color, strength?: float): type_color; - /** - */ - function mix(color1: type_color, color2: type_color, { "strength1": option_strength1, "strength2": option_strength2, }?: { - strength1?: float; - strength2?: float; - }): type_color; - /** - */ - function output_rgb(color: type_color): string; - /** - */ - function output_hex(color: type_color): string; - /** - */ - function output_dot(color: type_color): string; - /** - */ - function give_generic(n: int, { "offset": option_offset, "saturation": option_saturation, "value": option_value, }: { - offset?: float; - saturation?: float; - value?: float; - }): type_color; - /** - */ - function give_gray({ "value": option_value, }: { - value?: float; - }): type_color; - /** - */ - function give_black(): type_color; - /** - */ - function give_white(): type_color; - /** - */ - function give_red({ "saturation": option_saturation, "value": option_value, }?: { - saturation?: float; - value?: float; - }): type_color; - /** - */ - function give_green({ "saturation": option_saturation, "value": option_value, }?: { - saturation?: float; - value?: float; - }): type_color; - /** - */ - function give_blue({ "saturation": option_saturation, "value": option_value, }?: { - saturation?: float; - value?: float; - }): type_color; - /** - */ - function give_yellow({ "saturation": option_saturation, "value": option_value, }?: { - saturation?: float; - value?: float; - }): type_color; - /** - */ - function give_cyan({ "saturation": option_saturation, "value": option_value, }?: { - saturation?: float; - value?: float; - }): type_color; - /** - */ - function give_magenta({ "saturation": option_saturation, "value": option_value, }?: { - saturation?: float; - value?: float; - }): type_color; -} -declare namespace lib_plankton.color { - /** - * @author fenris - */ - class class_color { - /** - * @author fenris - */ - private subject; - /** - * @author fenris - */ - protected constructor(subject: type_color); - /** - * @author fenris - */ - private static _cram; - /** - * @author fenris - */ - private static _tear; - /** - * @author fenris - */ - static make_hsv({ "hue": hue, "saturation": saturation, "value": value }: { - hue?: float; - saturation?: float; - value?: float; - }): class_color; - /** - * @author fenris - */ - blend(color: class_color, strength?: float): class_color; - /** - * @author fenris - */ - output_rgb(): string; - /** - * @author fenris - */ - output_hex(): string; - /** - * @author fenris - */ - output_dot(): string; - /** - * @author fenris - */ - static give_generic({ "n": n, "offset": offset, "saturation": saturation, "value": value, }: { - n: int; - offset?: float; - saturation?: float; - value?: float; - }): class_color; - static generic(x: any): class_color; - /** - * @author fenris - */ - static give_gray(value?: float): class_color; - /** - * @author fenris - */ - static give_black(): class_color; - /** - * @author fenris - */ - static give_white(): class_color; - /** - * @author fenris - */ - static give_red({ "saturation": saturation, "value": value, }?: { - saturation?: float; - value?: float; - }): class_color; - /** - * @author fenris - */ - static give_green({ "saturation": saturation, "value": value, }?: { - saturation?: float; - value?: float; - }): class_color; - /** - * @author fenris - */ - static give_blue({ "saturation": saturation, "value": value, }?: { - saturation?: float; - value?: float; - }): class_color; - /** - * @author fenris - */ - static give_yellow({ "saturation": saturation, "value": value, }?: { - saturation?: float; - value?: float; - }): class_color; - /** - * @author fenris - */ - static give_cyan({ "saturation": saturation, "value": value, }?: { - saturation?: float; - value?: float; - }): class_color; - /** - * @author fenris - */ - static give_magenta({ "saturation": saturation, "value": value, }?: { - saturation?: float; - value?: float; - }): class_color; - } -} -/** - * @author fenris - */ -declare namespace lib_plankton.xml { - /** - * @author fenris - */ - abstract class class_node { - /** - * @author fenris - */ - abstract compile(depth?: int): string; - } - /** - * @author fenris - */ - class class_node_text extends class_node { - /** - * @author fenris - */ - protected content: string; - /** - * @author fenris - */ - constructor(content: string); - /** - * @author fenris - */ - compile(depth?: int): string; - } - /** - * @author fenris - */ - class class_node_comment extends class_node { - /** - * @author fenris - */ - protected content: string; - /** - * @author fenris - */ - constructor(content: string); - /** - * @author fenris - */ - compile(depth?: int): string; - } - /** - * @author fenris - */ - class class_node_complex extends class_node { - /** - * @author fenris - */ - protected name: string; - /** - * @author fenris - */ - protected attributes: { - [key: string]: string; - }; - /** - * @author fenris - */ - protected children: Array; - /** - * @author fenris - */ - constructor(name: string, attributes?: { - [key: string]: string; - }, children?: any[]); - /** - * @author fenris - */ - compile(depth?: int): string; - } -} declare module lib_et { /** * @desc type of extended timestamp @@ -3995,54 +4262,732 @@ declare namespace lib_plankton.http { decode(x: string): type_response; } } -declare namespace lib_plankton.url { +declare namespace lib_plankton.object { /** * @author fenris */ - type type_url = { - scheme: (null | string); - host: (null | string); - username: (null | string); - password: (null | string); - port: (null | int); - path: (null | string); - query: (null | string); - hash: (null | string); + function fetch(object: Object, fieldname: string, fallback?: type_value, escalation?: int): 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; }; + /** + * @desc gibt ein Objekt mit bestimmten Einträgen des Eingabe-Objekts zurück + * @author fenris + */ + function filter(object_from: { + [key: string]: type_value; + }, predicate: (value_from: type_value, key?: string) => boolean): { + [key: string]: type_value; + }; + /** + * @desc wandelt ein Array mit Einträgen der Form {key,value} in ein entsprechendes Objekt um + * @author fenris + */ + function from_array(array: Array<{ + key: string; + value: type_value; + }>): { + [key: string]: type_value; + }; + /** + * @desc wandelt ein Objekt in ein entsprechendes Array mit Einträgen der Form {key,value} um + * @author fenris + */ + function to_array(object: { + [key: string]: type_value; + }): Array<{ + key: string; + value: type_value; + }>; + /** + * @desc gibt eine Liste von Schlüsseln eines Objekts zurück + * @author fenris + */ + function keys(object: { + [key: string]: any; + }): Array; + /** + * @desc gibt eine Liste von Werten eines Objekts zurück + * @author fenris + */ + function values(object: { + [key: string]: type_value; + }): Array; + /** + * @desc liest ein Baum-artiges Objekt an einer bestimmten Stelle aus + * @author fenris + */ + function path_read(object: Object, path: string, fallback?: type_value, escalation?: int): type_value; + /** + * @desc schreibt einen Wert an eine bestimmte Stelle in einem Baum-artigen Objekt + * @author fenris + */ + 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 + */ + function matches(object: Object, pattern: Object, collate?: typeof instance_collate): 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 + */ + function flatten(value: any, separator?: string, key_for_element?: (index: int) => string): Object; + /** + * @author fenris + */ + function clash(x: { + [key: string]: any; + }, y: { + [key: string]: any; + }, { "overwrite": overwrite, "hooks": { "existing": hook_existing, }, }?: { + overwrite?: boolean; + hooks?: { + existing?: (key?: string, value_old?: any, value_new?: any) => void; + }; + }): { + [key: string]: any; + }; + /** + * @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; } -declare namespace lib_plankton.url { +declare namespace lib_plankton.markdown { /** * @author fenris */ - function encode(url: type_url): string; - /** - * @author fenris - * @todo arguments - */ - function decode(url_raw: string): type_url; + function code(content: string): string; /** * @author fenris */ - function implementation_code(): lib_plankton.code.type_code; + function paragraph(content: string): string; + /** + * @author fenris + */ + function sectionhead(level: int, content: string): string; } -declare namespace lib_plankton.url { +declare namespace lib_plankton.api { + /** + */ + enum enum_checklevel { + none = "none", + soft = "soft", + hard = "hard" + } /** * @author fenris */ - class class_url implements lib_plankton.code.interface_code { - /** - * @author fenris - */ - constructor(); - /** - * @implementation - * @author fenris - */ - encode(x: any): string; - /** - * @implementation - * @author fenris - */ - decode(x: string): any; + type type_action = { + name: string; + active: ((version: (null | string)) => boolean); + execution: ((version: (null | string), environment: any, input: any) => Promise); + restriction: ((version: (null | string), environment: any) => Promise); + input_shape: ((version: (null | string)) => lib_plankton.shape.type_shape); + output_shape: ((version: (null | string)) => lib_plankton.shape.type_shape); + title: (null | string); + description: (null | string); + }; + /** + * @author fenris + */ + type type_api = { + title: string; + actions: Record; + }; + /** + */ + class class_error_permission_denied extends Error { + } +} +declare namespace lib_plankton.api { + /** + * @author fenris + */ + function make(title: string): type_api; + /** + * @throws Error if a action with the given name has already been registered + * @author fenris + */ + function register(api: type_api, name: string, options?: { + active?: ((version: (null | string)) => boolean); + execution?: ((version: (null | string), environment: any, input: any) => Promise); + restriction?: ((version: (null | string), input: any) => Promise); + input_shape?: ((version: (null | string)) => lib_plankton.shape.type_shape); + output_shape?: ((version: (null | string)) => lib_plankton.shape.type_shape); + title?: (null | string); + description?: (null | string); + }): void; + /** + * @throws Error if not found + * @author fenris + */ + function get_action(api: type_api, name: string): type_action; + /** + * @author fenris + */ + function call(api: type_api, name: string, options?: { + version?: (null | string); + input?: any; + environment?: Record; + checklevel_restriction?: enum_checklevel; + checklevel_input?: enum_checklevel; + checklevel_output?: enum_checklevel; + }): Promise; + /** + * @author fenris + */ + function generate_documentation_for_action(api: type_api, name: string, options?: { + version?: (null | string); + }): string; + /** + * @author fenris + */ + function generate_documentation(api: type_api, options?: { + version?: (null | string); + }): string; +} +declare namespace lib_plankton.api { + /** + * @author fenris + */ + class class_api { + /** + * @author fenris + */ + private subject; + /** + * @author fenris + */ + private constructor(); + /** + * @author fenris + */ + static create(name: string): class_api; + /** + * @author fenris + */ + register(name: string, options?: { + active?: ((version: (null | string)) => boolean); + execution?: ((version: (null | string), environment: any, input: any) => lib_plankton.call.type_promise); + restriction?: ((version: (null | string), input: any) => Promise); + input_shape?: ((version: (null | string)) => lib_plankton.shape.type_shape); + output_shape?: ((version: (null | string)) => lib_plankton.shape.type_shape); + title?: (null | string); + description?: (null | string); + }): void; + /** + * @author fenris + */ + call(name: string, options?: { + version?: (null | string); + input?: any; + environment?: Record; + checklevel_restriction?: enum_checklevel; + checklevel_input?: enum_checklevel; + checklevel_output?: enum_checklevel; + }): lib_plankton.call.type_promise; + /** + * @author fenris + */ + generate_documentation_for_action(name: string): string; + /** + * @author fenris + */ + generate_documentation(): string; + } +} +declare namespace lib_plankton.rest { + /** + */ + type type_oas_schema = ({} | { + nullable: boolean; + } | { + type: "boolean"; + nullable?: boolean; + enum?: Array; + } | { + type: "integer"; + nullable?: boolean; + enum?: Array; + } | { + type: "number"; + nullable?: boolean; + enum?: Array; + } | { + type: "string"; + nullable?: boolean; + enum?: Array; + } | { + type: "array"; + nullable?: boolean; + items: type_oas_schema; + } | { + type: "object"; + nullable?: boolean; + additionalProperties?: (false | type_oas_schema); + properties: Record; + required: Array; + }); + /** + */ + type type_execution = ((stuff: { + version: (null | string); + headers: Record; + path_parameters: Record; + query_parameters: Record; + input: (null | type_input); + }) => Promise<{ + status_code: int; + data: type_output; + }>); + /** + */ + type type_restriction = ((stuff: { + version: (null | string); + headers: Record; + path_parameters: Record; + query_parameters: Record; + }) => Promise); + /** + */ + type type_operation = { + action_name: string; + query_parameters: Array<{ + name: string; + description: (null | string); + required: boolean; + }>; + request_body_mimetype: string; + request_body_decode: ((http_request_body: Buffer, http_request_header_content_type: (null | string)) => any); + response_body_mimetype: string; + response_body_encode: ((output: any) => Buffer); + input_schema: ((version: (null | string)) => type_oas_schema); + output_schema: ((version: (null | string)) => type_oas_schema); + }; + /** + */ + type type_routenode = { + operations: Record>; + sub_branch: Record; + sub_wildcard: (null | { + name: string; + node: type_routenode; + }); + }; + /** + */ + type type_rest = { + api: lib_plankton.api.type_api; + routetree: type_routenode; + versioning_method: ("none" | "path" | "header" | "query"); + versioning_header_name: (null | string); + versioning_query_key: (null | string); + header_parameters: Array<{ + name: string; + description: (null | string); + required: boolean; + }>; + set_access_control_headers: boolean; + authentication: ({ + kind: "none"; + parameters: {}; + } | { + kind: "key_header"; + parameters: { + name: string; + }; + }); + }; +} +declare namespace lib_plankton.rest { + /** + */ + function make(options?: { + title?: (null | string); + versioning_method?: ("none" | "path" | "header" | "query"); + versioning_header_name?: (null | string); + versioning_query_key?: (null | string); + header_parameters?: Array<{ + name: string; + description: (null | string); + required: boolean; + }>; + set_access_control_headers?: boolean; + authentication?: ({ + kind: "none"; + parameters: {}; + } | { + kind: "key_header"; + parameters: { + name: string; + }; + }); + actions?: Array<{ + http_method: lib_plankton.http.enum_method; + path: string; + options: { + active?: ((version: string) => boolean); + restriction?: (null | type_restriction); + execution?: type_execution; + title?: (null | string); + description?: (null | string); + query_parameters?: Array<{ + name: string; + description: (null | string); + required: boolean; + }>; + input_schema?: ((version: string) => type_oas_schema); + output_schema?: ((version: string) => type_oas_schema); + request_body_mimetype?: string; + request_body_decode?: ((http_request_body: Buffer, http_request_header_content_type: (null | string)) => any); + response_body_mimetype?: string; + response_body_encode?: ((output: any) => Buffer); + }; + }>; + }): type_rest; + /** + */ + function register(rest: type_rest, http_method: lib_plankton.http.enum_method, path: string, options: { + active?: ((version: string) => boolean); + restriction?: (null | type_restriction); + execution?: type_execution; + title?: (null | string); + description?: (null | string); + query_parameters?: Array<{ + name: string; + description: (null | string); + required: boolean; + }>; + input_schema?: ((version: (null | string)) => type_oas_schema); + output_schema?: ((version: (null | string)) => type_oas_schema); + request_body_mimetype?: string; + request_body_decode?: ((http_request_body: Buffer, http_request_header_content_type: (null | string)) => any); + response_body_mimetype?: string; + response_body_encode?: ((output: any) => Buffer); + }): void; + /** + * @todo check request body mimetype? + * @todo check query paramater validity + */ + function call(rest: type_rest, http_request: lib_plankton.http.type_request, options?: { + checklevel_restriction?: lib_plankton.api.enum_checklevel; + checklevel_input?: lib_plankton.api.enum_checklevel; + checklevel_output?: lib_plankton.api.enum_checklevel; + }): Promise; + /** + * @see https://swagger.io/specification/#openrest-object + */ + function to_oas(rest: type_rest, options?: { + version?: (null | string); + servers?: Array; + }): any; +} +declare namespace lib_plankton.server { + /** + * @author fenris + */ + type type_metadata = { + ip_address: string; + }; + /** + * @author fenris + */ + type type_subject = { + host: string; + port: int; + threshold: (null | float); + handle: ((input: Buffer, metadata?: type_metadata) => Promise); + serverobj: any; + }; + /** + * @author fenris + */ + function make(handle: ((input: string, metadata?: type_metadata) => Promise), options?: { + host?: string; + port?: int; + threshold?: (null | float); + }): type_subject; + /** + * @author fenris + * @deprecated + */ + function make_old(port: int, handle: ((input: string, metadata?: type_metadata) => Promise)): type_subject; + /** + * @author fenris + * @see https://nodejs.org/api/net.html#serverlistenport-host-backlog-callback + */ + function start(subject: type_subject): Promise; + /** + * @author fenris + */ + function kill(subject: type_subject): void; +} +declare namespace lib_plankton.server { + /** + * @author fenris + */ + class class_server { + /** + * @author fenris + */ + protected subject: type_subject; + /** + * @author fenris + */ + constructor(handle: ((input: Buffer, metadata?: type_metadata) => Promise), options?: { + host?: string; + port?: int; + }); + /** + * @author fenris + */ + start(): Promise; + /** + * @author fenris + */ + kill(): void; + } +} +declare var lib_server: typeof lib_plankton.server; +declare namespace lib_plankton.args { + /** + */ + enum enum_environment { + cli = "cli", + url = "url" + } + /** + */ + enum enum_kind { + positional = "positional", + volatile = "volatile" + } + /** + */ + enum enum_type { + boolean = "boolean", + integer = "int", + float = "float", + string = "string" + } + /** + */ + enum enum_mode { + replace = "replace", + accumulate = "accumulate" + } +} +declare namespace lib_plankton.args { + /** + * @author fenris + */ + class class_argument { + /** + * @author fenris + */ + protected name: string; + /** + * @author fenris + */ + protected kind: enum_kind; + /** + * @author fenris + */ + protected type: enum_type; + /** + * @author fenris + */ + protected mode: enum_mode; + /** + * @author fenris + */ + protected default_: any; + /** + * @author fenris + */ + protected info: string; + /** + * @author fenris + */ + protected parameters: Object; + /** + * @author fenris + */ + protected hidden: boolean; + /** + * @author fenris + */ + constructor({ "name": name, "type": type, "kind": kind, "mode": mode, "default": default_, "info": info, "parameters": parameters, "hidden": hidden, }: { + name: string; + type?: enum_type; + kind?: enum_kind; + mode?: enum_mode; + default?: any; + info?: string; + parameters?: Object; + hidden?: boolean; + }); + /** + * @author fenris + */ + static positional({ "name": name, "type": type, "mode": mode, "default": default_, "info": info, "hidden": hidden, "index": index, }: { + name: string; + type?: enum_type; + mode?: enum_mode; + default?: any; + info?: string; + hidden?: boolean; + index: int; + }): class_argument; + /** + * @author fenris + */ + static volatile({ "name": name, "type": type, "mode": mode, "default": default_, "info": info, "hidden": hidden, "indicators_short": indicators_short, "indicators_long": indicators_long, }: { + name: string; + type?: enum_type; + mode?: enum_mode; + default?: any; + info?: string; + hidden?: boolean; + indicators_short: Array; + indicators_long: Array; + }): class_argument; + /** + * @author fenris + */ + check(): boolean; + /** + * @author fenris + */ + name_get(): string; + /** + * @author fenris + */ + kind_get(): enum_kind; + /** + * @author fenris + */ + type_get(): enum_type; + /** + * @author fenris + */ + mode_get(): enum_mode; + /** + * @author fenris + */ + default_get(): any; + /** + * @author fenris + */ + parameters_get(): Object; + /** + * @author fenris + */ + hidden_get(): boolean; + /** + * @author fenris + */ + toString(): string; + /** + * @author fenris + */ + indicator_main(): string; + /** + * @author fenris + */ + pattern_value(): string; + /** + * @author fenris + */ + extract(raw: string): any; + /** + * @author fenris + */ + assign(data: Object, target: string, raw: string): void; + /** + * @author fenris + */ + make(data: Object, target: string): string; + /** + * @author fenris + */ + generate_help(): string; + } +} +declare namespace lib_plankton.args { + /** + * @author fenris + */ + var verbosity: int; + /** + * @author fenris + * @todo check validity + */ + class class_handler { + /** + * @author fenris + */ + protected arguments_: { + [name: string]: class_argument; + }; + /** + * @author fenris + */ + constructor(arguments_: { + [name: string]: class_argument; + }); + /** + * @author fenris + */ + filter(kind: enum_kind): { + [name: string]: class_argument; + }; + /** + * @author fenris + */ + read(environment: enum_environment, input: string, data?: { + [name: string]: any; + }): { + [name: string]: any; + }; + /** + * @author fenris + * @todo handle if the data object doesn't have the required field or the type is wrong or sth. + */ + write(environment: enum_environment, data: { + [name: string]: any; + }): string; + /** + * @desc manpage-like info-sheet + * @author fenris + */ + generate_help({ "programname": programname, "author": author, "description": description, "executable": executable, }: { + programname?: string; + author?: string; + description?: string; + executable?: string; + }): string; } } diff --git a/lib/plankton/plankton.js b/lib/plankton/plankton.js index bc36cbe..ba2cbb8 100644 --- a/lib/plankton/plankton.js +++ b/lib/plankton/plankton.js @@ -53,14 +53,6 @@ You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:base«. If not, see . */ ; -/* -declare class console { - static log(...args : any[]) : void; - static info(...args : any[]) : void; - static warn(...args : any[]) : void; - static error(...args : any[]) : void; -}; - */ var lib_plankton; (function (lib_plankton) { var base; @@ -69,7 +61,7 @@ var lib_plankton; * @author fenris */ function environment() { - return "web"; + return "node"; } base.environment = environment; })(base = lib_plankton.base || (lib_plankton.base = {})); @@ -1561,6 +1553,6885 @@ var lib_plankton; call.rate_limit_check = rate_limit_check; })(call = lib_plankton.call || (lib_plankton.call = {})); })(lib_plankton || (lib_plankton = {})); +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +/* +This file is part of »bacterio-plankton:email«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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 () { + var nm_nodemailer, transporter, info; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + nm_nodemailer = require("nodemailer"); + transporter = nm_nodemailer.createTransport({ + "host": smtp_credentials.host, + "port": smtp_credentials.port, + "secure": false, + "auth": { + "user": smtp_credentials.username, + "pass": smtp_credentials.password + }, + "debug": true + }); + return [4 /*yield*/, transporter.sendMail({ + "from": sender, + "to": receivers.join(", "), + "subject": subject, + "text": content + })]; + case 1: + info = _a.sent(); + return [2 /*return*/]; + } + }); + }); + } + email.send = send; + })(email = lib_plankton.email || (lib_plankton.email = {})); +})(lib_plankton || (lib_plankton = {})); +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +/* +This file is part of »bacterio-plankton:log«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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 enum_level; + (function (enum_level) { + enum_level[enum_level["debug"] = 0] = "debug"; + enum_level[enum_level["info"] = 1] = "info"; + enum_level[enum_level["notice"] = 2] = "notice"; + enum_level[enum_level["warning"] = 3] = "warning"; + enum_level[enum_level["error"] = 4] = "error"; + })(enum_level = log.enum_level || (log.enum_level = {})); + ; + /** + */ + function level_order(level1, level2) { + return (level1 <= level2); + } + log.level_order = level_order; + /** + */ + function level_show(level) { + switch (level) { + case enum_level.debug: return "debug"; + case enum_level.info: return "info"; + case enum_level.notice: return "notice"; + case enum_level.warning: return "warning"; + case enum_level.error: return "error"; + default: return "(unknown)"; + } + } + log.level_show = level_show; + })(log = lib_plankton.log || (lib_plankton.log = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:log«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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-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 class_channel = /** @class */ (function () { + function class_channel() { + } + return class_channel; + }()); + log.class_channel = class_channel; + })(log = lib_plankton.log || (lib_plankton.log = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:log«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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 stdout + */ + var class_channel_stdout = /** @class */ (function (_super) { + __extends(class_channel_stdout, _super); + function class_channel_stdout() { + return _super !== null && _super.apply(this, arguments) || this; + } + /** + */ + class_channel_stdout.prototype.add = function (entry) { + process.stdout.write(("<" + (new Date(Date.now())).toISOString().slice(0, 19) + ">") + + + " " + + + ("[" + log.level_show(entry.level) + "]") + + + " " + + + ("" + entry.incident + "") + + + ": " + + + JSON.stringify(entry.details, undefined, " ") + + + "\n"); + }; + return class_channel_stdout; + }(log.class_channel)); + log.class_channel_stdout = class_channel_stdout; + })(log = lib_plankton.log || (lib_plankton.log = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:log«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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_file = /** @class */ (function (_super) { + __extends(class_channel_file, _super); + /** + * [constructor] + */ + function class_channel_file(path, human_readable) { + var _this = _super.call(this) || this; + _this.path = path; + _this.human_readable = human_readable; + return _this; + } + /** + */ + class_channel_file.prototype.add = function (entry) { + var _this = this; + var nm_fs = require("fs"); + var line = (this.human_readable + ? (("<" + (new Date(Date.now())).toISOString().slice(0, 19) + ">") + + + " " + + + ("[" + log.level_show(entry.level) + "]") + + + " " + + + ("" + entry.incident + "") + + + ": " + + + JSON.stringify(entry.details, undefined, " ") + + + "\n") + : (JSON.stringify({ + "timestamp": lib_plankton.base.get_current_timestamp(), + "level_number": entry.level, + "level_name": log.level_show(entry.level), + "incident": entry.incident, + "details": entry.details + }) + + + "\n")); + nm_fs.writeFile(this.path, line, { + "flag": "a+" + }, function (error) { + if (error !== null) { + process.stderr.write('-- [plankton] could not add log entry to file ' + _this.path + "\n"); + } + else { + // do nothing + } + }); + }; + return class_channel_file; + }(log.class_channel)); + log.class_channel_file = class_channel_file; + })(log = lib_plankton.log || (lib_plankton.log = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:log«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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_email = /** @class */ (function (_super) { + __extends(class_channel_email, _super); + /** + * [constructor] + */ + function class_channel_email(smtp_credentials, sender, receivers) { + var _this = _super.call(this) || this; + _this.smtp_credentials = smtp_credentials; + _this.sender = sender; + _this.receivers = receivers; + return _this; + } + /** + */ + class_channel_email.prototype.add = function (entry) { + var nm_fs = require("fs"); + lib_plankton.email.send(this.smtp_credentials, this.sender, this.receivers, (("[" + log.level_show(entry.level) + "]") + + + " " + + + ("" + entry.incident + "")), JSON.stringify(entry.details, undefined, " ")); + }; + return class_channel_email; + }(log.class_channel)); + log.class_channel_email = class_channel_email; + })(log = lib_plankton.log || (lib_plankton.log = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:log«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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 desktop notifications via "libnotify" + */ + var class_channel_notify = /** @class */ (function (_super) { + __extends(class_channel_notify, _super); + function class_channel_notify() { + return _super !== null && _super.apply(this, arguments) || this; + } + /** + */ + class_channel_notify.prototype.add = function (entry) { + var nm_child_process = require("child_process"); + var command = ("notify-send" + + + " " + + + ("'" + + + ("[" + log.level_show(entry.level) + "]") + + + " " + + + entry.incident + + + "'") + + + " " + + + ("'" + + + (Object.keys(entry.details) + .map(function (key) { return (key + ": " + JSON.stringify(entry.details[key])); }) + .join("\n")) + + + "'")); + nm_child_process.exec(command, function (error, stdout, stderr) { + // do noting + }); + }; + return class_channel_notify; + }(log.class_channel)); + log.class_channel_notify = class_channel_notify; + })(log = lib_plankton.log || (lib_plankton.log = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:log«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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-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 translate_level(level_string) { + return { + "debug": log.enum_level.debug, + "info": log.enum_level.info, + "notice": log.enum_level.notice, + "warning": log.enum_level.warning, + "error": log.enum_level.error + }[level_string]; + } + /** + */ + function channel_make(description) { + var _a, _b, _c, _d, _e; + switch (description.kind) { + default: { + throw (new Error("unhandled log channel kind: " + description.kind)); + break; + } + case "stdout": { + return (new log.class_channel_minlevel(new log.class_channel_stdout(), translate_level((_a = description.data["threshold"]) !== null && _a !== void 0 ? _a : "debug"))); + break; + } + case "file": { + return (new log.class_channel_minlevel(new log.class_channel_file(((_b = description.data["path"]) !== null && _b !== void 0 ? _b : "/tmp/plankton.log"), false), translate_level((_c = description.data["threshold"]) !== null && _c !== void 0 ? _c : "debug"))); + break; + } + case "email": { + return (new log.class_channel_minlevel(new log.class_channel_email(description.data["smtp_credentials"], description.data["sender"], description.data["receivers"]), translate_level((_d = description.data["threshold"]) !== null && _d !== void 0 ? _d : "debug"))); + break; + } + case "notify": { + return (new log.class_channel_minlevel(new log.class_channel_notify(), translate_level((_e = description.data["threshold"]) !== null && _e !== void 0 ? _e : "debug"))); + break; + } + } + } + log.channel_make = channel_make; + /** + */ + function conf_default() { + return [ + new log.class_channel_minlevel(new log.class_channel_stdout(), log.enum_level.notice), + new log.class_channel_minlevel(new log.class_channel_notify(), log.enum_level.error), + ]; + } + log.conf_default = conf_default; + })(log = lib_plankton.log || (lib_plankton.log = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:log«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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_stack = null; + /** + * pushes a new configuration on the stack and activates it + */ + function conf_push(channels) { + if (_channel_stack === null) { + _channel_stack = []; + } + _channel_stack.push(channels); + } + log.conf_push = conf_push; + /** + * pops the current active configuration from the stack + */ + function conf_pop() { + if (_channel_stack.length > 0) { + _channel_stack.pop(); + } + else { + // do nothing + } + } + log.conf_pop = conf_pop; + /** + * makes the logging system ready + */ + function setup() { + if (_channel_stack === null) { + _channel_stack = []; + conf_push(log.conf_default()); + } + else { + // do nothing + } + } + /** + * consumes a log entry, i.e. sends it to the currently active outputs + */ + function add(entry) { + setup(); + _channel_stack.slice(-1)[0].forEach(function (channel) { return channel.add(entry); }); + } + log.add = add; + /** + */ + function debug(incident, details) { + if (details === void 0) { details = {}; } + add({ "level": log.enum_level.debug, "incident": incident, "details": details }); + } + log.debug = debug; + /** + */ + function info(incident, details) { + if (details === void 0) { details = {}; } + add({ "level": log.enum_level.info, "incident": incident, "details": details }); + } + log.info = info; + /** + */ + function notice(incident, details) { + if (details === void 0) { details = {}; } + add({ "level": log.enum_level.notice, "incident": incident, "details": details }); + } + log.notice = notice; + /** + */ + function warning(incident, details) { + if (details === void 0) { details = {}; } + add({ "level": log.enum_level.warning, "incident": incident, "details": details }); + } + log.warning = warning; + /** + */ + function error(incident, details) { + if (details === void 0) { details = {}; } + add({ "level": log.enum_level.error, "incident": incident, "details": details }); + } + log.error = error; + })(log = lib_plankton.log || (lib_plankton.log = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:log«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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) { + /** + */ + log.conf_push([ + log.channel_make({ + "kind": "stdout", + "data": { + "threshold": "info" + } + }), + ]); + })(log = lib_plankton.log || (lib_plankton.log = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:string«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:string« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:string« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:string«. If not, see . + */ +var plain_text_to_html = function (text) { + let ret = text; + ret = ret.replace(/ /g, "  "); // convert multiple whitespace to forced ones + ret = ret.split("\n").join("
"); + return ret; +}; +/** + * @desc makes a valid + */ +var format_sentence = function (str, rtl = false, caseSense = true) { + if (str === "") { + return str; + } + else { + let marks = { + ".": true, + "?": true, + "!": true + }; + let default_mark = "."; + let ret = str.split(""); + if (!rtl) { + ret[0] = ret[0].toLocaleUpperCase(); + if (!(ret[ret.length - 1] in marks)) { + ret.push(default_mark); + } + } + else { + ret[ret.length - 1] = ret[ret.length - 1].toLocaleUpperCase(); + if (!(ret[0] in marks)) { + ret.unshift(default_mark); + } + } + return ret.join(""); + } +}; +var fill_string_template = function (template_string, object, fabric = function (object, key) { return object[key]; }, delimiter = "%", default_string = null, sloppy) { + function get_tags(str) { + let r = new RegExp(delimiter + "[^\\s^" + delimiter + "]+" + delimiter, "gi"); + return ((str.match(r) || []).map(function (e) { + return e.slice(delimiter.length, e.length - delimiter.length); + })); + } + function replace_tag(str, tag, value) { + let r = new RegExp(delimiter + tag + delimiter, "gi"); + return str.replace(r, value); + } + function replace_tags(str, obj) { + return (get_tags(str).reduce(function (ret, key) { + let value = ""; + try { + value = fabric(obj, key); + if ((!sloppy && (value === void 0)) || (sloppy && (value == void 0))) { + value = default_string; + } + } + catch (e) { + console.warn("invalid placeholder " + key); + value = default_string; + } + return replace_tag(ret, key, value); + }, str)); + } + return replace_tags(template_string, object); +}; +var make_string_template = function (_template, _fabrics = {}) { + function replace_tag(str, tag, value) { + var r = new RegExp("%" + tag + "%", "gi"); + return str.replace(r, value); + } + function replace_tags(str, obj) { + return (Object.keys(obj).reduce(function (ret, key) { + return replace_tag(ret, key, _fabrics[key] || obj[key]); + }, str)); + } + return (function (tags) { + return replace_tags(_template, tags); + }); +}; +var make_eml_header = (function () { + let _template = ""; + _template += "From: %from%\n"; + _template += "To: %recipient%\n"; + _template += "Subject: %subject%\n"; + _template += "X-Mailer: greenscale-plankton.emlgen\n"; + return make_string_template(_template); +})(); +var make_eml_body = (function () { + let exports = {}; + exports["simple_body"] = make_string_template("Content-Type: %contenttype%\n\n%body%\n\n"); + // very basic implementation + // parts = [{contenttype:"text/html; charset=UTF-8", body: "

foo

" }, {...}] + exports["body_boundrary"] = function (parts, boundrary) { + let _template = ""; + _template += "--%boundrary%\n"; + _template += "Content-Type: %contenttype%\n\n%body%\n\n"; + //_template += "--%boundrary%--\n\n"; + let maker = make_string_template(_template); + return (parts.reduce(function (prev, curr) { + curr.boundrary = boundrary; + return [prev, maker(curr)].join(""); + }, "")); + }; + // body must be base64 encoded! + exports["attachment_boundrary"] = function (parts, boundrary) { + let _template = ""; + _template += "--%boundrary%\n"; + _template += "Content-Type: %contenttype%\n"; + _template += "Content-Transfer-Encoding: base64\n"; + _template += "Content-Disposition: %disposition%; filename=\"%name%\"\n\n"; + _template += "%body%\n\n"; + //_template += "--%boundrary%--\n\n"; + let maker = make_string_template(_template); + return (parts.reduce(function (prev, curr) { + curr.boundrary = boundrary; + if (curr.disposition === void 0) + curr.disposition = "inline"; + return [prev, maker(curr)].join(""); + }, "")); + }; + exports["gen_boundrary"] = function () { + return ("xxxxxxxxxxxxxxxxxxxxxx".replace(/[xy]/g, function (c) { + let r = crypto.getRandomValues(new Uint8Array(1))[0] % 16 | 0, v = c == "x" ? r : (r & 0x3 | 0x8); + return v.toString(16); + })); + }; + // simple implementation without alternatives (old rfc) + exports["complete_boundrary"] = function (bodyparts, attachments) { + let ret = ""; + let boundrary = exports["gen_boundrary"](); + ret += exports["body_boundrary"](bodyparts, boundrary); + ret += exports["attachment_boundrary"](attachments, boundrary); + ret += "--" + boundrary + "--\n\nINVISIBLE!!!!"; + return (exports["simple_body"]({ + "contenttype": sprintf("multipart/mixed; boundary=%s", [boundrary]), + "body": ret + })); + }; + return exports; +})(); +/* +This file is part of »bacterio-plankton:string«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:string« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:string« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:string«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var string; + (function (string) { + /** + * @author fenris + */ + const hexdigits = 4; + /** + * @author fenris + */ + const index_max = (1 << (4 * hexdigits)); + /** + * @author fenris + */ + var index_is = 0; + /** + * @author neuc,frac + */ + function empty(str) { + return (str.trim() === ""); + } + string.empty = empty; + /** + * @desc returns a unique string + * @param {string} prefix an optional prefix for the generated string + * @return {string} + * @author fenris + */ + function generate(prefix = "string_") { + if (index_is > index_max) { + throw (new Error("[string_generate] out of valid indices")); + } + else { + return string.sprintf(prefix + "%0" + hexdigits.toString() + "X", [index_is++]); + } + } + string.generate = generate; + /** + * @author fenris + */ + function join(parts, glue = " ") { + if (parts.length == 0) { + return ""; + } + else { + return parts.join(glue); + } + } + string.join = join; + /** + * @desc splits a string, but returns an empty list, if the string is empty + * @param {string} chain + * @param {string} separator + * @return {Array} + * @author fenris + */ + function split(chain, separator = " ") { + if (chain.length == 0) { + return []; + } + else { + return chain.split(separator); + } + } + string.split = split; + /** + * @author neu3no + */ + function explode(str, needle, max) { + let temp = str.split(needle); + const right = temp.splice(max - 1); + temp.push(right.join(needle)); + return temp; + } + string.explode = explode; + /** + * @desc concats a given word with itself n times + * @param {string} word + * @param {int} + * @return {string} + * @author fenris + */ + function repeat(word, count) { + // return ((count == 0) ? "" : (word + repeat(word, count-1))); + let result = ""; + for (let n = 0; n < count; n += 1) { + result += word; + } + return result; + } + string.repeat = repeat; + /** + * @desc lengthens a string by repeatedly appending or prepending another string + * @param {string} word the string to pad + * @param {int} length the length, which the result shall have + * @param {string} symbol the string, which will be added (multiple times) + * @param {boolean} [prepend]; whether to prepend (~true) or append (~false); default: false + * @return {string} the padded string + * @author fenris + */ + function pad(word, length, symbol = " ", mode = "append") { + switch (mode) { + case "prepend": { + // insert symbols only at the beginning + while (word.length < length) + word = symbol + word; + return word.substring(word.length - length); + break; + } + case "append": { + // insert symbols only at the end + while (word.length < length) + word = word + symbol; + return word.substring(0, length); + break; + } + case "widen": { + // insert symbols at both sides + let left = (((length - word.length) & 1) === 0); + while (word.length < length) { + word = (left + ? (symbol + word) + : (word + symbol)); + left = (!left); + } + return word.substring(0, length); + break; + } + default: { + const message = ("unhandled mode '" + mode + "'"); + console.warn(message); + return word; + break; + } + } + } + string.pad = pad; + /** + * @desc checks if a given string conttains a certain substring + * @param {string} string + * @param {string} part + * @return {boolean} + * @author fenris + */ + function contains(chain, part) { + if (typeof (chain) !== "string") { + return false; + } + return (chain.indexOf(part) >= 0); + } + string.contains = contains; + /** + * @desc checks if a given string starts with a certain substring + * @param {string} string + * @param {string} part + * @return {boolean} + * @author fenris + */ + function startsWith(chain, part) { + if (typeof (chain) !== "string") { + return false; + } + // return (string.indexOf(part) === 0); + return ((function (m, n) { + if (n === 0) { + return true; + } + else { + if (m === 0) { + return false; + } + else { + return ((chain[0] == part[0]) + && + startsWith(chain.substring(1), part.substring(1))); + } + } + })(chain.length, part.length)); + } + string.startsWith = startsWith; + /** + * @desc checks if a given string ends with a certain substring + * @param {string} string + * @param {string} part + * @return {boolean} + * @author fenris + */ + function endsWith(chain, part) { + if (typeof (chain) !== "string") { + return false; + } + // return (string.lastIndexOf(part) === string.length-part.length); + return ((function (m, n) { + if (n === 0) { + return true; + } + else { + if (m === 0) { + return false; + } + else { + // console.info(("(" + string[m-1] + " == " + part[n-1] + ")") + " = " + String(string[m-1] == part[n-1])); + return ((chain[m - 1] === part[n - 1]) + && + endsWith(chain.substring(0, m - 1), part.substring(0, n - 1))); + } + } + })(chain.length, part.length)); + } + string.endsWith = endsWith; + /** + * @desc count the occourrences of a string in a string + * @param string haystack_string the string wich should be examined + * @param string needle_string the string which should be counted + * @author neuc + */ + function count_occourrences(haystack_string, needle_string, check_escape) { + let cnt = 0; + let pos = -1; + do { + pos = haystack_string.indexOf(needle_string, pos + 1); + if ((!check_escape) || (haystack_string[pos - 1] != "\\")) { + cnt++; + } + } while (pos >= 0); + return (cnt - 1); + } + string.count_occourrences = count_occourrences; + /** + * @author fenris + */ + function replace(str, replacements, options = {}) { + options = Object.assign({}, options); + let result = str; + replacements.forEach(replacement => { + lib_plankton.log.debug("lib_plankton.string.replace", { + "from": replacement.from, + "to": replacement.to, + }); + result = result.replace(new RegExp(replacement.from, "g"), replacement.to); + }); + return result; + } + string.replace = replace; + /** + * @desc replaces occurences of "{{name}}" in a string by the corresponding values of an argument object + * @author fenris + */ + function coin(str, args, options = {}) { + options = Object.assign({ + "legacy": false, + "open": "{{", + "close": "}}", + }, options); + Object.keys(args).forEach((key) => { + // old syntax + { + if (options.legacy) { + const value = args[key]; + const regexp_argument = new RegExp("\\${" + key + "}", "g"); + lib_plankton.log.debug("lib_plankton.string.coin", { + "key": key, + "regex": regexp_argument.toString(), + "value": value, + }); + str = str.replace(regexp_argument, value); + } + } + // new syntax + { + const value = args[key]; + const regexp_argument = new RegExp(options.open + key + options.close, "g"); + lib_plankton.log.debug("lib_plankton.string.coin", { + "key": key, + "regex": regexp_argument.toString(), + "value": value, + }); + str = str.replace(regexp_argument, value); + } + }); + return str; + } + string.coin = coin; + /** + * @author fenris + * @deprecated use limit + */ + function cut(str, length, delimiter = "…") { + if (str.length <= length) { + return str; + } + else { + return (str.slice(0, length - delimiter.length) + delimiter); + } + } + string.cut = cut; + /** + */ + function limit(str, options = {}) { + options = Object.assign({ + "length": 120, + "indicator": "…", + }, options); + return ((str.length <= options.length) + ? str + : (str.slice(0, options.length - options.indicator.length) + options.indicator)); + } + string.limit = limit; + /** + */ + function slice(str, size) { + let slices = []; + let rest = str; + while (rest.length > 0) { + slices.push(rest.slice(0, size)); + rest = rest.slice(size); + } + return slices; + } + string.slice = slice; + })(string = lib_plankton.string || (lib_plankton.string = {})); +})(lib_plankton || (lib_plankton = {})); +/** + * @deprecated + */ +var lib_string; +(function (lib_string) { + lib_string.empty = lib_plankton.string.empty; + lib_string.generate = lib_plankton.string.generate; + lib_string.split = lib_plankton.string.split; + lib_string.explode = lib_plankton.string.repeat; + lib_string.repeat = lib_plankton.string.repeat; + lib_string.pad = lib_plankton.string.pad; + lib_string.contains = lib_plankton.string.contains; + lib_string.startsWith = lib_plankton.string.startsWith; + lib_string.endsWith = lib_plankton.string.endsWith; + lib_string.count_occourrences = lib_plankton.string.count_occourrences; + lib_string.coin = lib_plankton.string.coin; + lib_string.stance = lib_plankton.string.coin; + lib_string.cut = lib_plankton.string.cut; +})(lib_string || (lib_string = {})); +/* +This file is part of »bacterio-plankton:string«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:string« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:string« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:string«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var string; + (function (string) { + var pattern = /%([-+#0 ]*)([0-9]*)[\.]{0,1}([0-9]*)([\w]{1})/; + var gpattern = /%([-+#0 ]*)([0-9]*)[\.]{0,1}([0-9]*)([\w]{1})/g; + function split_format(format) { + var tmp = format.match(pattern); + if (tmp === null) + return null; + return { + 'flags': tmp[1].split(""), + 'width': Number(tmp[2]), + 'precision': tmp[3] === '' ? null : Number(tmp[3]), + 'specifier': tmp[4], + 'string': format + }; + } + function make_err(format, arg, should) { + return ("[sprintf]" + " " + "argument for '" + format.string + "' has to be '" + should + "' but '" + arg + "' is '" + typeof arg + "'!"); + } + function test_arg(format, arg, should) { + if (typeof arg !== should) { + console.warn(make_err(format, arg, should)); + return false; + } + return true; + } + function string_fill(str, char, len, left) { + while (str.length < len) { + if (left) { + str += char; + } + else { + str = char + str; + } + } + return str; + } + /** + * the known_parameters are used to parse the different identifiers for the welln known syntax: + * flag width precision identifier + * %{[0#+- ]}{[0-9]*}.{[0-9]*}[fFdiueEgGsoxXaAsn] + * flags: + * 0 - fill with '0' instead of ' ' if the string length < width + * # - not implemented + * - - left-justified -> fill on the right side to reach width + * + - force using '+' on positive numbers + * ' ' - add a single space before positive numbers + * + * identifiers + * %f, %F - interpret given number as float, width: the minimal total width (fill with ' ' or '0' if the + * resulting string is too short, precision: cut more then given decimal places + * %d, %i, %u - interpret number as integer, decimal places will be cut. width: like float, precision: + * fill with '0' on right side until length given in precision is reached + * %e - interpret as float and write as scientifical number, width & precision like in float + * %E - same es %e but uppercase 'E' + * %g - use the shortest string of %f or %e + * %G - use the shortest string of %E or %E + * %s - simply print a string + * %o - print the given number in octal notation + * %x - print the given number in hex notation + * %X - same as %x but with uppercase characters + * %a - alias to %x + * %A - alias to %X + * %n - just print nothing + * @type {{}} + */ + var known_params = {}; + known_params["f"] = function (format, arg) { + if (!test_arg(format, arg, "number")) + return "Ø"; + var tmp = Math.abs(arg); + var sign = (arg < 0) ? -1 : 1; + var tmp_result = null; + if (format.precision !== null) { + tmp = Math.floor(Math.pow(10, format.precision) * tmp) / Math.pow(10, format.precision); + var tmp_ = (tmp * sign).toString().split("."); + if (tmp_.length === 1) + tmp_.push(""); + tmp_[1] = string_fill(tmp_[1], "0", format.precision, true); + tmp_result = tmp_.join("."); + } + else { + tmp_result = (sign * tmp).toString(); + } + if ((format.flags.indexOf(" ") >= 0) && (arg >= 0)) { + tmp_result = " " + tmp; + } + else if ((format.flags.indexOf("+") >= 0) && (arg >= 0)) { + tmp_result = "+" + tmp; + } + tmp_result = string_fill(tmp, (format.flags.indexOf("0") >= 0) ? "0" : " ", format.width, (format.flags.indexOf("-") >= 0)); + return tmp_result; + }; + known_params["F"] = known_params["f"]; + known_params["d"] = function (format, arg) { + if (!test_arg(format, arg, 'number')) + return 'Ø'; + var tmp = (((arg < 0 && format.specifier !== 'u') ? -1 : 1) * Math.floor(Math.abs(arg))).toString(); + if ((format.specifier === 'd' || format.specifier === 'i') && format.flags.indexOf(' ') >= 0 && arg >= 0) { + tmp = ' ' + tmp; + } + else if ((format.specifier === 'd' || format.specifier === 'i') && format.flags.indexOf('+') >= 0 && arg >= 0) { + tmp = '+' + tmp; + } + tmp = string_fill(tmp, format.flags.indexOf('0') >= 0 ? '0' : ' ', format.width, format.flags.indexOf('-') >= 0); + tmp = string_fill(tmp, '0', format.precision === null ? 0 : format.precision, false); + return tmp; + }; + known_params["i"] = known_params["d"]; + known_params["u"] = known_params["d"]; + known_params["e"] = function (format, arg) { + if (!test_arg(format, arg, 'number')) + return 'Ø'; + var tmp = arg.toExponential(format.precision === null ? undefined : format.precision).toString(); + if (format.flags.indexOf(' ') >= 0 && arg >= 0) { + tmp = ' ' + tmp; + } + else if (format.flags.indexOf('+') >= 0 && arg >= 0) { + tmp = '+' + tmp; + } + tmp = string_fill(tmp, format.flags.indexOf('0') >= 0 ? '0' : ' ', format.width, format.flags.indexOf('-') >= 0); + return tmp; + }; + known_params["E"] = function (format, arg) { + return known_params["e"](format, arg).toUpperCase(); + }; + known_params["g"] = function (format, arg) { + if (!test_arg(format, arg, 'number')) + return 'Ø'; + var tmpf = known_params["f"](format, arg); + var tmpe = known_params["e"](format, arg); + if (tmpf.length < tmpe.length) { + return tmpf; + } + else { + return tmpe; + } + }; + known_params["G"] = function (format, arg) { + return known_params["g"](format, arg).toUpperCase(); + }; + known_params["s"] = function (format, arg) { + if (!test_arg(format, arg, 'string')) + return 'o.O'; + var tmp = format.precision !== null ? arg.substr(0, format.precision) : arg; + tmp = string_fill(tmp, format.flags.indexOf('0') >= 0 ? '0' : ' ', format.width, format.flags.indexOf('-') >= 0); + return tmp; + }; + known_params["o"] = function (format, arg) { + if (!test_arg(format, arg, 'number')) + return 'Ø'; + var tmp = Math.floor(Math.round(Math.abs(arg))) * ((arg < 0) ? -1 : 1); + return known_params["s"](format, tmp.toString(8)); + }; + known_params["x"] = function (format, arg) { + if (!test_arg(format, arg, 'number')) + return 'Ø'; + var tmp = Math.floor(Math.round(Math.abs(arg))) * ((arg < 0) ? -1 : 1); + return known_params["s"](format, tmp.toString(16)); + }; + known_params["a"] = known_params["x"]; + known_params["X"] = function (format, arg) { + if (!test_arg(format, arg, 'number')) + return 'Ø'; + return known_params["x"](format, arg).toUpperCase(); + }; + known_params["A"] = known_params["X"]; + known_params["c"] = function (format, arg) { + var tmp = ""; + if (typeof arg === "number") { + tmp = String.fromCharCode(arg); + } + else if ((typeof arg === "string") && (arg.length === 1)) { + tmp = arg[0]; + } + else { + console.warn(make_err(format, arg, "number|string") + " and if string it needs to have the length of 1!"); + } + return known_params["s"](format, tmp); + }; + known_params["n"] = function () { + return ""; + }; + var decompose = function (chain, regexp) { + var result = regexp.exec(chain); + if (result == null) { + return null; + } + else { + var front = chain.substring(0, result.index); + var back = chain.substring(result.index + result[0].length); + return { "front": front, "match": result[0], "back": back }; + } + }; + /** + * an implementation of c sprintf + * @param {string} string format string + * @param {array} args arguments which should be filled into + * @returns {string} + */ + string.sprintf = function (input, args = [], original = null) { + if (original == null) + original = input; + var components = decompose(input, pattern); + if (components == null) { + if (args.length > 0) { + console.warn("[sprintf] superfluous arguments while formatting '" + original + "': ", args); + } + return input; + } + else { + var arg; + var rest; + if (args.length > 0) { + arg = args[0]; + rest = args.slice(1); + } + else { + console.warn("[sprintf] out of arguments while formatting '" + original + "'"); + arg = null; + rest = []; + return input; + } + var fmt = split_format(components["match"]); + return (components["front"] + + known_params[fmt.specifier](fmt, arg) + + string.sprintf(components["back"], rest, original)); + } + }; + /** + * an implementation of c printf + * @param {string} string format string + * @param {array} args arguments which should be filled into + * @returns {string} + */ + function printf(format, args) { + console.log(string.sprintf(format, args)); + } + string.printf = printf; + })(string = lib_plankton.string || (lib_plankton.string = {})); +})(lib_plankton || (lib_plankton = {})); +var sprintf = lib_plankton.string.sprintf; +var printf = lib_plankton.string.printf; +/* +This file is part of »bacterio-plankton:string«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:string« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:string« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:string«. If not, see . + */ +var make_logger = (function () { + var _loggers = {}; + var make_logger = function (prefix, current_loglevel) { + var log = []; + var level = [ + "LOG", "INFO", "WARNING", "DEBUG" + ]; + var logger = function (obj, lvl) { + var txt = obj.txt || obj; + if (lvl == void 0) + lvl = 0; + var date = new Date(); + log.push({ + "message": sprintf("%s [%s:%s] %s", [date.toString(), level[lvl], prefix, txt]), + "timeStamp": +(date) + }); + if (lvl <= current_loglevel) { + var msg = ["[" + prefix + "]", txt]; + if (obj.arg) + msg = ["[" + prefix + "]"].concat(Array.prototype.slice.call(obj.arg)); + if (lvl === 0) + console["_log"].apply(console, msg); + else if (lvl === 1) + console["_info"].apply(console, msg); + else if (lvl === 2) + console["_warn"].apply(console, msg); + else if (lvl >= 3) + console["_log"].apply(console, msg); + } + }; + _loggers[prefix] = { + "logger": logger, + "log": log + }; + return logger; + }; + make_logger["loggers"] = _loggers; + make_logger["complete_log"] = function () { + var logs = Object.keys(_loggers) + .reduce(function (p, c) { + return [].concat(p, _loggers[c].log); + }, []); + logs.sort(function (x, y) { + return ((x.timeStamp > y.timeStamp) ? -1 : +1); + }); + return logs.map(function (x, i, a) { + return x.message; + }); + }; + if ( /*!track_exports*/true) { + var _log_all = function (log, lvl, next = function () { }) { + return function () { + var msg = []; + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] === "string") { + msg.push(arguments[i]); + } + else { + msg.push(JSON.stringify(arguments[i])); + } + } + var obj = { + txt: msg.join("\t"), + arg: arguments + }; + log(obj, lvl); + next(); + }; + }; + { + var __warn = make_logger("deprecated console.warn", 99); + var __error = make_logger("deprecated console.error", 99); + var __log = make_logger("deprecated console.log", 99); + var __info = make_logger("deprecated console.info", 99); + // bad ass + console["_log"] = console.log; + console["_error"] = console.error; + console["_warn"] = console.warn; + console["_info"] = console.info; + /* + console["log"] = _log_all(__log, 0); + console["error"] = _log_all(__error, 2); + console["warn"] = _log_all(__warn, 2); + console["info"] = _log_all(__info, 0); + */ + } + /* + { + make_logger["send_log"] = function(){ + eml_log( + function () { + alert("fehlerbericht wurde gesendet!"); + } + ); + }; + var error_log = make_logger("global.error", 99); + window.onerror = _log_all( + error_log, + 1, + function(){ + if (global_config == undefined) { + return false; + } + if (global_config.report_error) { + make_logger["send_log"](); + } + } + ); + } + */ + } + return make_logger; +})(); +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +/* +This file is part of »bacterio-plankton:database«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:database« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:database« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:database«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var database; + (function (database) { + /** + */ + let enum_type; + (function (enum_type) { + enum_type["boolean"] = "boolean"; + enum_type["integer"] = "integer"; + enum_type["string_short"] = "string_short"; + enum_type["string_medium"] = "string_medium"; + enum_type["string_long"] = "string_long"; + enum_type["float"] = "float"; + })(enum_type = database.enum_type || (database.enum_type = {})); + })(database = lib_plankton.database || (lib_plankton.database = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:database«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:database« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:database« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:database«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var database; + (function (database) { + /** + * @todo default case? + */ + function sql_common_value_format(value) { + if (value === undefined) { + throw (new Error("can not format undefined")); + } + else { + if (value === null) { + return "NULL"; + } + else { + switch (typeof (value)) { + case "boolean": { + return (value ? "TRUE" : "FALSE"); + break; + } + case "number": { + return value.toString(); + break; + } + case "string": { + return ("'" + value + "'"); + break; + } + } + } + } + } + database.sql_common_value_format = sql_common_value_format; + /** + */ + function sql_common_formulation_create_table(description_create_table, options = {}) { + var _a, _b, _c, _d, _e, _f; + options = Object.assign({ + "auto_increment_keyword": "AUTO INCREMENT", + "auto_increment_special": null, + "omit_comments": false, + "type_map": { + "boolean": "BOOLEAN", + "integer": "INTEGER", + "string_short": "VARCHAR(63)", + "string_medium": "VARCHAR(255)", + "string_long": "TEXT", + "float": "REAL", + }, + "wrap_name": (x => x), + }, options); + return { + "template": lib_plankton.string.coin("CREATE TABLE IF NOT EXISTS\n\t{{name}}(\n{{entries}}\n\t){{comment}}\n;", { + "name": options.wrap_name(description_create_table.name), + "comment": ((options.omit_comments + || + (((_a = description_create_table.description) !== null && _a !== void 0 ? _a : null) === null)) + ? "" + : lib_plankton.string.coin(" COMMENT '{{comment}}'", { + "comment": description_create_table.description, + })), + "entries": (([] + // key field + .concat((((_b = description_create_table.key_field) !== null && _b !== void 0 ? _b : null) === null) + ? [] + : lib_plankton.string.coin("{{name}} {{parameters}}", { + "name": options.wrap_name(description_create_table.key_field.name), + "parameters": (((options.auto_increment_special === null) + ? + ([] + // type + .concat([ + options.type_map[(_c = description_create_table.key_field.type) !== null && _c !== void 0 ? _c : "integer"], + ]) + // nullability + .concat([ + "NOT NULL", + ]) + // primary key + .concat([ + "PRIMARY KEY", + ]) + // auto increment + .concat((((_d = description_create_table.key_field.auto_increment) !== null && _d !== void 0 ? _d : true) === null) + ? + [] + : + [ + options.auto_increment_keyword, + ])) + : + [ + options.auto_increment_special + ]) + .join(" ")), + })) + // data fields + .concat(((_e = description_create_table.data_fields) !== null && _e !== void 0 ? _e : []) + .map((data_field) => { + var _a, _b; + return lib_plankton.string.coin("{{name}} {{parameters}}", { + "name": options.wrap_name(data_field.name), + "parameters": (([] + // type + .concat([ + options.type_map[data_field.type], + ]) + // nullability + .concat((!((_a = data_field.nullable) !== null && _a !== void 0 ? _a : false)) + ? [] + : ["NULL"]) + // default + .concat((!data_field.hasOwnProperty("default")) + ? [] + : [ + lib_plankton.string.coin(" DEFAULT {{value}}", { + "value": sql_common_value_format(data_field.default) + }), + ]) + // comment + .concat((options.omit_comments + || + (((_b = data_field.description) !== null && _b !== void 0 ? _b : null) === null)) + ? [] + : [ + lib_plankton.string.coin("COMMENT '{{comment}}'", { + "comment": data_field.description, + }), + ])) + .join(" ")) + }); + })) + // constraints + .concat(((_f = description_create_table.constraints) !== null && _f !== void 0 ? _f : []) + .map((constraint) => { + switch (constraint.kind) { + default: { + throw (new Error("unhandled constraint kind: " + constraint.kind)); + break; + } + case "foreign_key": { + return lib_plankton.string.coin("FOREIGN KEY ({{fields}}) REFERENCES {{reference_name}}({{reference_fields}})", { + "fields": (constraint.parameters["fields"] + .map(x => options.wrap_name(x)) + .join(",")), + "reference_name": options.wrap_name(constraint.parameters["reference"]["name"]), + "reference_fields": (constraint.parameters["reference"]["fields"] + .map(x => options.wrap_name(x)) + .join(",")), + }); + break; + } + case "unique": { + return lib_plankton.string.coin("UNIQUE ({{fields}})", { + "fields": (constraint.parameters["fields"] + .map(x => options.wrap_name(x)) + .join(",")), + }); + break; + } + } + }))) + .map(x => ("\t\t" + x)) + .join(",\n")), + }), + "arguments": {} + }; + } + database.sql_common_formulation_create_table = sql_common_formulation_create_table; + /** + */ + function sql_common_formulation_insert(description_insert, options = {}) { + options = Object.assign({ + "wrap_name": (x => x), + "set_returning": false, + }, options); + const field_names = Object.keys(description_insert.values); + return { + "template": lib_plankton.string.coin("INSERT INTO {{table_name}}({{schema}}) VALUES ({{values}}){{returning}};", { + "table_name": options.wrap_name(description_insert.table_name), + "schema": (field_names + .map((field_name) => lib_plankton.string.coin("{{name}}", { + "name": options.wrap_name(field_name), + })) + .join(",")), + "values": (field_names + .map((field_name) => lib_plankton.string.coin("$value_{{name}}", { + "name": field_name, + })) + .join(",")), + "returning": ((options.set_returning + && + ((description_insert.returning !== undefined) + && + (description_insert.returning !== null))) + ? + (" RETURNING " + description_insert.returning) + : + ""), + }), + "arguments": Object.fromEntries(Object.entries(description_insert.values) + .map(([name, value]) => ([ + lib_plankton.string.coin("value_{{name}}", { + "name": name, + }), + value + ]))), + }; + } + database.sql_common_formulation_insert = sql_common_formulation_insert; + /** + */ + function sql_common_formulation_update(description_update, options = {}) { + var _a, _b; + options = Object.assign({ + "wrap_name": (x => x), + }, options); + const field_names = Object.keys(description_update.values); + return { + "template": lib_plankton.string.coin("UPDATE {{table_name}} SET {{assignments}}{{macro_where}};", { + "table_name": options.wrap_name(description_update.table_name), + "assignments": (field_names + .map((field_name) => lib_plankton.string.coin("{{name}} = $value_{{suffix}}", { + "name": options.wrap_name(field_name), + "suffix": field_name, + })) + .join(", ")), + "macro_where": ((((_a = description_update.condition) !== null && _a !== void 0 ? _a : null) === null) + ? "" + : lib_plankton.string.coin(" WHERE {{expression}}", { + "expression": description_update.condition, + })), + }), + "arguments": Object.assign(Object.fromEntries(Object.entries(description_update.values) + .map(([name, value]) => ([ + lib_plankton.string.coin("value_{{name}}", { + "name": name, + }), + value + ]))), ((_b = description_update.arguments) !== null && _b !== void 0 ? _b : {})) + }; + } + database.sql_common_formulation_update = sql_common_formulation_update; + /** + */ + function sql_common_formulation_delete(description_delete, options = {}) { + var _a, _b; + options = Object.assign({ + "wrap_name": (x => x), + }, options); + return { + "template": lib_plankton.string.coin("DELETE FROM {{table_name}}{{macro_where}};", { + "table_name": options.wrap_name(description_delete.table_name), + "macro_where": ((((_a = description_delete.condition) !== null && _a !== void 0 ? _a : null) === null) + ? "" + : lib_plankton.string.coin(" WHERE {{expression}}", { + "expression": description_delete.condition, + })), + }), + "arguments": Object.assign({}, ((_b = description_delete.arguments) !== null && _b !== void 0 ? _b : {})), + }; + } + database.sql_common_formulation_delete = sql_common_formulation_delete; + /** + */ + function sql_common_formulation_select(description_select, options = {}) { + var _a, _b, _c, _d, _e, _f, _g; + options = Object.assign({ + "wrap_name": (x => x), + }, options); + return { + "template": lib_plankton.string.coin("SELECT {{fields}} FROM {{source}}{{macro_where}}{{macro_group_by}}{{macro_having}}{{macro_order_by}}{{macro_limit}};", { + "source": options.wrap_name(description_select.source), + "fields": ((((_a = description_select.fields) !== null && _a !== void 0 ? _a : null) === null) + ? "*" + : (description_select.fields + .map(field_name => lib_plankton.string.coin("{{name}}", { "name": options.wrap_name(field_name) })) + .join(","))), + "macro_where": ((((_b = description_select.condition) !== null && _b !== void 0 ? _b : null) === null) + ? "" + : lib_plankton.string.coin(" WHERE {{expression}}", { + "expression": description_select.condition, + })), + "macro_group_by": ((((_c = description_select.group_by) !== null && _c !== void 0 ? _c : null) === null) + ? "" + : lib_plankton.string.coin(" GROUP BY {{expression}}", { + "expression": description_select.group_by, + })), + "macro_having": ((((_d = description_select.having) !== null && _d !== void 0 ? _d : null) === null) + ? "" + : lib_plankton.string.coin(" HAVING {{expression}}", { + "expression": description_select.having, + })), + "macro_order_by": ((((_e = description_select.order_by) !== null && _e !== void 0 ? _e : null) === null) + ? "" + : lib_plankton.string.coin(" ORDER BY {{expression}}", { + "expression": description_select.order_by, + })), + "macro_limit": ((((_f = description_select.limit) !== null && _f !== void 0 ? _f : null) === null) + ? "" + : lib_plankton.string.coin(" LIMIT {{expression}}", { + "expression": description_select.limit.toFixed(0), + })), + }), + "arguments": Object.assign({}, ((_g = description_select.arguments) !== null && _g !== void 0 ? _g : {})), + }; + } + database.sql_common_formulation_select = sql_common_formulation_select; + })(database = lib_plankton.database || (lib_plankton.database = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:database«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:database« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:database« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:database«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var database; + (function (database) { + /** + */ + function sqlite_make(parameters) { + return { + "path": parameters.path, + "handle": null, + }; + } + database.sqlite_make = sqlite_make; + /** + */ + function sqlite_wrap_name(name) { + return ("`" + name + "`"); + } + database.sqlite_wrap_name = sqlite_wrap_name; + /** + */ + function sqlite_init(subject) { + return __awaiter(this, void 0, void 0, function* () { + if (subject.handle === null) { + yield new Promise((resolve, reject) => { + const _nm_sqlite3 = require("sqlite3"); + subject.handle = new _nm_sqlite3.Database(subject.path, (_nm_sqlite3.OPEN_READWRITE | _nm_sqlite3.OPEN_CREATE | _nm_sqlite3.OPEN_FULLMUTEX), () => { resolve(undefined); }); + }); + } + else { + // do nothing + } + return Promise.resolve(undefined); + }); + } + /** + * @author fenris + */ + function sqlite_adjust_query(subject, query) { + const query_adjusted = { + "template": query.template, + "arguments": Object.fromEntries(Object.entries(query.arguments) + .map(([key, value]) => ([ + ("$" + key), + (((value === null) + || + (value === undefined)) + ? null + : ((typeof (value) === "boolean") + ? (value ? "1" : "0") + : value.toString())) + ]))), + }; + lib_plankton.log.debug("database_sqlite_query", { + "original": query, + "adjusted": query_adjusted, + }); + return query_adjusted; + } + /** + * @author fenris + */ + function sqlite_query_free_get(subject, query) { + return __awaiter(this, void 0, void 0, function* () { + yield sqlite_init(subject); + const query_adjusted = sqlite_adjust_query(subject, query); + return (new Promise((resolve, reject) => { + subject.handle.all(query_adjusted.template, query_adjusted.arguments, (error, rows) => { + if (error !== null) { + reject(error); + } + else { + resolve(rows); + } + }); + })); + }); + } + database.sqlite_query_free_get = sqlite_query_free_get; + /** + * @author fenris + */ + function sqlite_query_free_put(subject, query) { + return __awaiter(this, void 0, void 0, function* () { + yield sqlite_init(subject); + const query_adjusted = sqlite_adjust_query(subject, query); + return (new Promise((resolve, reject) => { + subject.handle.run(query_adjusted.template, query_adjusted.arguments, + // this MUST be an old style function + function (error) { + if (error) { + reject(error); + } + else { + resolve(this["lastID"]); + } + }); + })); + }); + } + database.sqlite_query_free_put = sqlite_query_free_put; + /** + * @author fenris + */ + function sqlite_query_free_set(subject, query) { + return __awaiter(this, void 0, void 0, function* () { + yield sqlite_init(subject); + const query_adjusted = sqlite_adjust_query(subject, query); + return (new Promise((resolve, reject) => { + subject.handle.run(query_adjusted.template, query_adjusted.arguments, + // this MUST be an old style function + function (error) { + if (error) { + reject(error); + } + else { + resolve(this["changes"]); + } + }); + })); + }); + } + database.sqlite_query_free_set = sqlite_query_free_set; + /** + */ + function sqlite_formulation_create_table(description_create_table) { + return database.sql_common_formulation_create_table(description_create_table, { + "auto_increment_keyword": "AUTOINCREMENT", + "auto_increment_special": null, + "omit_comments": true, + "type_map": { + "boolean": "INTEGER", + "integer": "INTEGER", + "string_short": "TEXT", + "string_medium": "TEXT", + "string_long": "TEXT", + "float": "REAL", + }, + "wrap_name": sqlite_wrap_name, + }); + } + database.sqlite_formulation_create_table = sqlite_formulation_create_table; + /** + */ + function sqlite_query_create_table(subject, description) { + return (sqlite_query_free_set(subject, sqlite_formulation_create_table(description)) + .then(x => Promise.resolve(undefined))); + } + database.sqlite_query_create_table = sqlite_query_create_table; + /** + */ + function sqlite_formulation_insert(description_insert) { + return database.sql_common_formulation_insert(description_insert, { + "wrap_name": sqlite_wrap_name, + }); + } + database.sqlite_formulation_insert = sqlite_formulation_insert; + /** + */ + function sqlite_query_insert(subject, description_insert) { + return sqlite_query_free_put(subject, sqlite_formulation_insert(description_insert)); + } + database.sqlite_query_insert = sqlite_query_insert; + /** + */ + function sqlite_formulation_update(description_update) { + return database.sql_common_formulation_update(description_update, { + "wrap_name": sqlite_wrap_name, + }); + } + database.sqlite_formulation_update = sqlite_formulation_update; + /** + */ + function sqlite_query_update(subject, description_update) { + return sqlite_query_free_set(subject, sqlite_formulation_update(description_update)); + } + database.sqlite_query_update = sqlite_query_update; + /** + */ + function sqlite_formulation_delete(description_delete) { + return database.sql_common_formulation_delete(description_delete, { + "wrap_name": sqlite_wrap_name, + }); + } + database.sqlite_formulation_delete = sqlite_formulation_delete; + /** + */ + function sqlite_query_delete(subject, description_delete) { + return sqlite_query_free_set(subject, sqlite_formulation_delete(description_delete)); + } + database.sqlite_query_delete = sqlite_query_delete; + /** + */ + function sqlite_formulation_select(description_select) { + return database.sql_common_formulation_select(description_select, { + "wrap_name": sqlite_wrap_name, + }); + } + database.sqlite_formulation_select = sqlite_formulation_select; + /** + */ + function sqlite_query_select(subject, description_select) { + return sqlite_query_free_get(subject, sqlite_formulation_select(description_select)); + } + database.sqlite_query_select = sqlite_query_select; + /** + */ + function sqlite_database(parameters) { + const subject = sqlite_make(parameters); + return { + "wrap_name": (name) => sqlite_wrap_name(name), + "query_free_get": (query) => sqlite_query_free_get(subject, query), + "query_free_put": (query) => sqlite_query_free_put(subject, query), + "query_free_set": (query) => sqlite_query_free_set(subject, query), + "query_create_table": (description_create_table) => sqlite_query_create_table(subject, description_create_table), + "query_insert": (description_insert) => sqlite_query_insert(subject, description_insert), + "query_update": (description_update) => sqlite_query_update(subject, description_update), + "query_delete": (description_delete) => sqlite_query_delete(subject, description_delete), + "query_select": (description_select) => sqlite_query_select(subject, description_select), + }; + } + database.sqlite_database = sqlite_database; + })(database = lib_plankton.database || (lib_plankton.database = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:database«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:database« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:database« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:database«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var database; + (function (database) { + /** + * @author fenris + */ + class class_sqlite { + constructor(parameters) { this.subject = database.sqlite_make(parameters); } + wrap_name(name) { return database.sqlite_wrap_name(name); } + query_free_get(query) { return database.sqlite_query_free_get(this.subject, query); } + query_free_put(query) { return database.sqlite_query_free_put(this.subject, query); } + query_free_set(query) { return database.sqlite_query_free_set(this.subject, query); } + query_create_table(description_create_table) { return database.sqlite_query_create_table(this.subject, description_create_table); } + query_insert(description_insert) { return database.sqlite_query_insert(this.subject, description_insert); } + query_update(description_update) { return database.sqlite_query_update(this.subject, description_update); } + query_delete(description_delete) { return database.sqlite_query_delete(this.subject, description_delete); } + query_select(description_select) { return database.sqlite_query_select(this.subject, description_select); } + } + database.class_sqlite = class_sqlite; + })(database = lib_plankton.database || (lib_plankton.database = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:database«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:database« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:database« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:database«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var database; + (function (database) { + /** + */ + function postgresql_make(parameters) { + var _a; + return { + "host": parameters.host, + "port": ((_a = parameters.port) !== null && _a !== void 0 ? _a : 5432), + "username": parameters.username, + "password": parameters.password, + "schema": parameters.schema, + "pool": null, + }; + } + database.postgresql_make = postgresql_make; + /** + */ + function postgresql_wrap_name(name) { + return ("" + name + ""); + } + database.postgresql_wrap_name = postgresql_wrap_name; + /** + * https://node-postgres.com/apis/pool + */ + function postgresql_init(subject) { + return __awaiter(this, void 0, void 0, function* () { + if (subject.pool === null) { + const nm_pg = require("pg"); + subject.pool = (new nm_pg.Pool({ + "host": subject.host, + "port": subject.port, + "database": subject.schema, + "user": subject.username, + "password": subject.password, + })); + } + else { + // do nothing + } + return Promise.resolve(undefined); + }); + } + /** + * @author fenris + */ + function postgresql_adjust_query(subject, query) { + let query_adjusted = { + "template": query.template, + "arguments": [] + }; + let index = 1; + while (true) { + const regexp = (new RegExp("\\$([a-zA-Z_][0-9a-zA-Z_]*)", "g")); + const matching = regexp.exec(query_adjusted.template); + if (matching === null) { + break; + } + else { + const part = matching[0]; + const name = matching[1]; + query_adjusted.template = (query_adjusted.template.slice(0, matching.index) + + + ("$" + index.toFixed(0)) + + + query_adjusted.template.slice(matching.index + part.length)); + query_adjusted.arguments.push(query.arguments[name]); + index += 1; + } + } + lib_plankton.log.debug("database_postgresql_query", { + "original": query, + "adjusted": query_adjusted, + }); + return query_adjusted; + } + /** + * @author fenris + * @see https://node-postgres.com/apis/pool#poolquery + */ + function postgresql_query_free_get(subject, query) { + return __awaiter(this, void 0, void 0, function* () { + yield postgresql_init(subject); + const query_adjusted = postgresql_adjust_query(subject, query); + const result = yield subject.pool.query({ + "text": query_adjusted.template, + "values": query_adjusted.arguments, + }); + return result["rows"]; + }); + } + database.postgresql_query_free_get = postgresql_query_free_get; + /** + * @author fenris + * @see https://node-postgres.com/apis/pool#poolquery + */ + function postgresql_query_free_put(subject, query) { + return __awaiter(this, void 0, void 0, function* () { + yield postgresql_init(subject); + const query_adjusted = postgresql_adjust_query(subject, query); + const result = yield subject.pool.query(query_adjusted.template, query_adjusted.arguments); + if (result["rows"].length <= 0) { + return null; + } + else { + const x = result["rows"][0]; + const keys = Object.keys(x); + if (keys.length <= 0) { + return null; + } + else { + return x[Object.keys(x)[0]]; + } + } + }); + } + database.postgresql_query_free_put = postgresql_query_free_put; + /** + * @author fenris + * @see https://node-postgres.com/apis/pool#poolquery + */ + function postgresql_query_free_set(subject, query) { + return __awaiter(this, void 0, void 0, function* () { + yield postgresql_init(subject); + const query_adjusted = postgresql_adjust_query(subject, query); + const result = yield subject.pool.query(query_adjusted.template, query_adjusted.arguments); + return result["rowCount"]; + }); + } + database.postgresql_query_free_set = postgresql_query_free_set; + /** + */ + function postgresql_formulation_create_table(description_create_table) { + return database.sql_common_formulation_create_table(description_create_table, { + "auto_increment_keyword": "", + "auto_increment_special": "SERIAL", + "omit_comments": false, + "type_map": { + "boolean": "BOOLEAN", + "integer": "INTEGER", + "string_short": "VARCHAR(63)", + "string_medium": "VARCHAR(255)", + "string_long": "TEXT", + "float": "REAL", + }, + "wrap_name": postgresql_wrap_name, + }); + } + database.postgresql_formulation_create_table = postgresql_formulation_create_table; + /** + */ + function postgresql_query_create_table(subject, description) { + return (postgresql_query_free_set(subject, postgresql_formulation_create_table(description)) + .then(x => Promise.resolve(undefined))); + } + database.postgresql_query_create_table = postgresql_query_create_table; + /** + */ + function postgresql_formulation_insert(description_insert) { + return database.sql_common_formulation_insert(description_insert, { + "wrap_name": postgresql_wrap_name, + "set_returning": true + }); + } + database.postgresql_formulation_insert = postgresql_formulation_insert; + /** + */ + function postgresql_query_insert(subject, description_insert) { + return postgresql_query_free_put(subject, postgresql_formulation_insert(description_insert)); + } + database.postgresql_query_insert = postgresql_query_insert; + /** + */ + function postgresql_formulation_update(description_update) { + return database.sql_common_formulation_update(description_update, { + "wrap_name": postgresql_wrap_name, + }); + } + database.postgresql_formulation_update = postgresql_formulation_update; + /** + */ + function postgresql_query_update(subject, description_update) { + return postgresql_query_free_set(subject, postgresql_formulation_update(description_update)); + } + database.postgresql_query_update = postgresql_query_update; + /** + */ + function postgresql_formulation_delete(description_delete) { + return database.sql_common_formulation_delete(description_delete, { + "wrap_name": postgresql_wrap_name, + }); + } + database.postgresql_formulation_delete = postgresql_formulation_delete; + /** + */ + function postgresql_query_delete(subject, description_delete) { + return postgresql_query_free_set(subject, postgresql_formulation_delete(description_delete)); + } + database.postgresql_query_delete = postgresql_query_delete; + /** + */ + function postgresql_formulation_select(description_select) { + return database.sql_common_formulation_select(description_select, { + "wrap_name": postgresql_wrap_name, + }); + } + database.postgresql_formulation_select = postgresql_formulation_select; + /** + */ + function postgresql_query_select(subject, description_select) { + return postgresql_query_free_get(subject, postgresql_formulation_select(description_select)); + } + database.postgresql_query_select = postgresql_query_select; + /** + */ + function postgresql_database(parameters) { + const subject = postgresql_make(parameters); + return { + "wrap_name": (name) => postgresql_wrap_name(name), + "query_free_get": (query) => postgresql_query_free_get(subject, query), + "query_free_put": (query) => postgresql_query_free_put(subject, query), + "query_free_set": (query) => postgresql_query_free_set(subject, query), + "query_create_table": (description_create_table) => postgresql_query_create_table(subject, description_create_table), + "query_insert": (description_insert) => postgresql_query_insert(subject, description_insert), + "query_update": (description_update) => postgresql_query_update(subject, description_update), + "query_delete": (description_delete) => postgresql_query_delete(subject, description_delete), + "query_select": (description_select) => postgresql_query_select(subject, description_select), + }; + } + database.postgresql_database = postgresql_database; + })(database = lib_plankton.database || (lib_plankton.database = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:database«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:database« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:database« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:database«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var database; + (function (database) { + /** + * @author fenris + */ + class class_postgresql { + constructor(parameters) { this.subject = database.postgresql_make(parameters); } + wrap_name(name) { return database.postgresql_wrap_name(name); } + query_free_get(query) { return database.postgresql_query_free_get(this.subject, query); } + query_free_put(query) { return database.postgresql_query_free_put(this.subject, query); } + query_free_set(query) { return database.postgresql_query_free_set(this.subject, query); } + query_create_table(description_create_table) { return database.postgresql_query_create_table(this.subject, description_create_table); } + query_insert(description_insert) { return database.postgresql_query_insert(this.subject, description_insert); } + query_update(description_update) { return database.postgresql_query_update(this.subject, description_update); } + query_delete(description_delete) { return database.postgresql_query_delete(this.subject, description_delete); } + query_select(description_select) { return database.postgresql_query_select(this.subject, description_select); } + } + database.class_postgresql = class_postgresql; + })(database = lib_plankton.database || (lib_plankton.database = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:database«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:database« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:database« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:database«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var database; + (function (database) { + /** + */ + function mysql_make(parameters) { + throw (new Error("not implemented")); + } + database.mysql_make = mysql_make; + /** + */ + function mysql_wrap_name(name) { + return ("`" + name + "`"); + } + database.mysql_wrap_name = mysql_wrap_name; + /** + */ + function mysql_init(subject) { + return __awaiter(this, void 0, void 0, function* () { + throw (new Error("not implemented")); + }); + } + /** + * @author fenris + */ + function mysql_adjust_query(subject, query) { + if (subject.verbose) { + console.info(query); + } + throw (new Error("not implemented")); + } + /** + * @author fenris + */ + function mysql_query_free_get(subject, query) { + return __awaiter(this, void 0, void 0, function* () { + throw (new Error("not implemented")); + }); + } + database.mysql_query_free_get = mysql_query_free_get; + /** + * @author fenris + */ + function mysql_query_free_put(subject, query) { + return __awaiter(this, void 0, void 0, function* () { + throw (new Error("not implemented")); + }); + } + database.mysql_query_free_put = mysql_query_free_put; + /** + * @author fenris + */ + function mysql_query_free_set(subject, query) { + return __awaiter(this, void 0, void 0, function* () { + throw (new Error("not implemented")); + }); + } + database.mysql_query_free_set = mysql_query_free_set; + /** + */ + function mysql_formulation_create_table(description_create_table) { + return database.sql_common_formulation_create_table(description_create_table, { + "auto_increment_keyword": "AUTO INCREMENT", + "omit_comments": false, + "type_map": { + "boolean": "BOOLEAN", + "integer": "INTEGER", + "string_short": "VARCHAR(63)", + "string_medium": "VARCHAR(255)", + "string_long": "TEXT", + "float": "REAL", + }, + "wrap_name": mysql_wrap_name, + }); + } + database.mysql_formulation_create_table = mysql_formulation_create_table; + /** + */ + function mysql_query_create_table(subject, description) { + return (mysql_query_free_set(subject, mysql_formulation_create_table(description)) + .then(x => Promise.resolve(undefined))); + } + database.mysql_query_create_table = mysql_query_create_table; + /** + */ + function mysql_formulation_insert(description_insert) { + return database.sql_common_formulation_insert(description_insert, { + "wrap_name": mysql_wrap_name, + }); + } + database.mysql_formulation_insert = mysql_formulation_insert; + /** + */ + function mysql_query_insert(subject, description_insert) { + return mysql_query_free_put(subject, mysql_formulation_insert(description_insert)); + } + database.mysql_query_insert = mysql_query_insert; + /** + */ + function mysql_formulation_update(description_update) { + return database.sql_common_formulation_update(description_update, { + "wrap_name": mysql_wrap_name, + }); + } + database.mysql_formulation_update = mysql_formulation_update; + /** + */ + function mysql_query_update(subject, description_update) { + return mysql_query_free_set(subject, mysql_formulation_update(description_update)); + } + database.mysql_query_update = mysql_query_update; + /** + */ + function mysql_formulation_delete(description_delete) { + return database.sql_common_formulation_delete(description_delete, { + "wrap_name": mysql_wrap_name, + }); + } + database.mysql_formulation_delete = mysql_formulation_delete; + /** + */ + function mysql_query_delete(subject, description_delete) { + return mysql_query_free_set(subject, mysql_formulation_delete(description_delete)); + } + database.mysql_query_delete = mysql_query_delete; + /** + */ + function mysql_formulation_select(description_select) { + return database.sql_common_formulation_select(description_select, { + "wrap_name": mysql_wrap_name, + }); + } + database.mysql_formulation_select = mysql_formulation_select; + /** + */ + function mysql_query_select(subject, description_select) { + return mysql_query_free_get(subject, mysql_formulation_select(description_select)); + } + database.mysql_query_select = mysql_query_select; + /** + */ + function mysql_database(parameters) { + const subject = mysql_make(parameters); + return { + "wrap_name": (name) => mysql_wrap_name(name), + "query_free_get": (query) => mysql_query_free_get(subject, query), + "query_free_put": (query) => mysql_query_free_put(subject, query), + "query_free_set": (query) => mysql_query_free_set(subject, query), + "query_create_table": (description_create_table) => mysql_query_create_table(subject, description_create_table), + "query_insert": (description_insert) => mysql_query_insert(subject, description_insert), + "query_update": (description_update) => mysql_query_update(subject, description_update), + "query_delete": (description_delete) => mysql_query_delete(subject, description_delete), + "query_select": (description_select) => mysql_query_select(subject, description_select), + }; + } + database.mysql_database = mysql_database; + })(database = lib_plankton.database || (lib_plankton.database = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:database«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:database« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:database« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:database«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var database; + (function (database) { + /** + * @author fenris + */ + class class_mysql { + constructor(parameters) { this.subject = database.mysql_make(parameters); } + wrap_name(name) { return database.mysql_wrap_name(name); } + query_free_get(query) { return database.mysql_query_free_get(this.subject, query); } + query_free_put(query) { return database.mysql_query_free_put(this.subject, query); } + query_free_set(query) { return database.mysql_query_free_set(this.subject, query); } + query_create_table(description_create_table) { return database.mysql_query_create_table(this.subject, description_create_table); } + query_insert(description_insert) { return database.mysql_query_insert(this.subject, description_insert); } + query_update(description_update) { return database.mysql_query_update(this.subject, description_update); } + query_delete(description_delete) { return database.mysql_query_delete(this.subject, description_delete); } + query_select(description_select) { return database.mysql_query_select(this.subject, description_select); } + } + database.class_mysql = class_mysql; + })(database = lib_plankton.database || (lib_plankton.database = {})); +})(lib_plankton || (lib_plankton = {})); +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +/* +This file is part of »bacterio-plankton:storage«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:storage« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:storage« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:storage«. If not, see . + */ +/* +This file is part of »bacterio-plankton:storage«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:storage« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:storage« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:storage«. If not, see . + */ +/* +This file is part of »bacterio-plankton:storage«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:storage« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:storage« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:storage«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var storage; + (function (storage) { + var memory; + (function (memory) { + /** + * @author fenris + */ + function make(parameters) { + return { + "data": {} + }; + } + memory.make = make; + /** + * @author fenris + */ + function clear(subject) { + subject.data = {}; + } + memory.clear = clear; + /** + * @author fenris + */ + function write(subject, key, value) { + var exists = (key in subject.data); + subject.data[key] = value; + return exists; + } + memory.write = write; + /** + * @author fenris + */ + function delete_(subject, key) { + if (!(key in subject.data)) { + throw (new Error("no value for key '" + key + "'")); + } + else { + delete subject.data[key]; + } + } + memory.delete_ = delete_; + /** + * @author fenris + */ + function read(subject, key) { + if (!(key in subject.data)) { + throw (new Error("no value for key '" + key + "'")); + } + else { + return subject.data[key]; + } + } + memory.read = read; + /** + * @author fenris + */ + function list(subject) { + return Object.keys(subject.data); + } + memory.list = list; + /** + * @author fenris + */ + function search(subject, term) { + return (list(subject) + .map(function (key) { return ({ "key": key, "preview": key }); })); + } + memory.search = search; + /** + * @author fenris + */ + function implementation_chest(parameters) { + function wrap(core) { + return (new Promise(function (resolve, reject) { resolve(core()); })); + } + var subject = make(parameters); + return { + "setup": function (input) { return Promise.resolve(undefined); }, + "clear": function () { return wrap(function () { return clear(subject); }); }, + "write": function (key, value) { return wrap(function () { return write(subject, key, value); }); }, + "delete": function (key) { return wrap(function () { return delete_(subject, key); }); }, + "read": function (key) { return wrap(function () { return read(subject, key); }); }, + "search": function (term) { return wrap(function () { return search(subject, term); }); } + }; + } + memory.implementation_chest = implementation_chest; + })(memory = storage.memory || (storage.memory = {})); + })(storage = lib_plankton.storage || (lib_plankton.storage = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:storage«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:storage« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:storage« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:storage«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var storage; + (function (storage) { + var memory; + (function (memory) { + /** + * @author fenris + */ + var class_chest = /** @class */ (function () { + function class_chest(parameters) { + this.subject = memory.make(parameters); + } + class_chest.prototype.setup = function (input) { return Promise.resolve(undefined); }; + class_chest.prototype.clear = function () { memory.clear(this.subject); return Promise.resolve(undefined); }; + class_chest.prototype.write = function (key, value) { return Promise.resolve(memory.write(this.subject, key, value)); }; + class_chest.prototype["delete"] = function (key) { memory.delete_(this.subject, key); return Promise.resolve(undefined); }; + class_chest.prototype.read = function (key) { return Promise.resolve(memory.read(this.subject, key)); }; + class_chest.prototype.search = function (term) { return Promise.resolve(memory.search(this.subject, term)); }; + return class_chest; + }()); + memory.class_chest = class_chest; + })(memory = storage.memory || (storage.memory = {})); + })(storage = lib_plankton.storage || (lib_plankton.storage = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:storage«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:storage« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:storage« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:storage«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var storage; + (function (storage) { + var filesystem; + (function (filesystem) { + /** + * @author fenris + */ + function make(parameters) { + return { + "nodemodule": require("fs") + }; + } + filesystem.make = make; + /** + */ + function clear(subject) { + return Promise.reject(new Error("nope")); + } + filesystem.clear = clear; + /** + * @author fenris + */ + function write(subject, path, content) { + return (new Promise(function (resolve, reject) { + var exists = subject.nodemodule.existsSync(path); + subject.nodemodule.writeFile(path, content, {}, function (error) { + if (error === null) { + resolve(exists); + } + else { + reject(error); + } + }); + })); + } + filesystem.write = write; + /** + * @author fenris + */ + function delete_(subject, path) { + return (new Promise(function (resolve, reject) { + subject.nodemodule.unlink(path, function (error) { + if (error === null) { + resolve(undefined); + } + else { + reject(error); + } + }); + })); + } + filesystem.delete_ = delete_; + /** + * @author fenris + */ + function read(subject, path) { + return (new Promise(function (resolve, reject) { + subject.nodemodule.readFile(path, {}, function (error, content) { + if (error === null) { + resolve(content); + } + else { + reject(error); + } + }); + })); + } + filesystem.read = read; + /** + */ + function implementation_chest(parameters) { + var subject = make(parameters); + return { + "setup": function (input) { return Promise.resolve(undefined); }, + "clear": function () { return clear(subject); }, + "write": function (key, value) { return write(subject, key, value); }, + "delete": function (key) { return delete_(subject, key); }, + "read": function (key) { return read(subject, key); }, + "search": function (term) { return Promise.reject("not available"); } + }; + } + filesystem.implementation_chest = implementation_chest; + })(filesystem = storage.filesystem || (storage.filesystem = {})); + })(storage = lib_plankton.storage || (lib_plankton.storage = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:storage«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:storage« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:storage« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:storage«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var storage; + (function (storage) { + var filesystem; + (function (filesystem) { + /** + * @author fenris + */ + var class_chest = /** @class */ (function () { + function class_chest(parameters) { + this.subject = filesystem.make(parameters); + } + class_chest.prototype.setup = function (input) { return Promise.resolve(undefined); }; + class_chest.prototype.clear = function () { return filesystem.clear(this.subject); }; + class_chest.prototype.write = function (key, value) { return filesystem.write(this.subject, key, value); }; + class_chest.prototype["delete"] = function (key) { return filesystem.delete_(this.subject, key); }; + class_chest.prototype.read = function (key) { return filesystem.read(this.subject, key); }; + class_chest.prototype.search = function (searchterm) { return Promise.reject(new Error("not available")); }; + return class_chest; + }()); + filesystem.class_chest = class_chest; + })(filesystem = storage.filesystem || (storage.filesystem = {})); + })(storage = lib_plankton.storage || (lib_plankton.storage = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:storage«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:storage« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:storage« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:storage«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var storage; + (function (storage) { + /** + */ + function sql_table_autokey_make(parameters) { + return { + "database_implementation": parameters.database_implementation, + "table_name": parameters.table_name, + "key_name": parameters.key_name + }; + } + storage.sql_table_autokey_make = sql_table_autokey_make; + /** + */ + function sql_table_autokey_setup(subject, description_create_table) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, subject.database_implementation.query_create_table(description_create_table)]; + }); + }); + } + storage.sql_table_autokey_setup = sql_table_autokey_setup; + /** + */ + function sql_table_autokey_create(subject, value) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, subject.database_implementation.query_insert({ + "table_name": subject.table_name, + "values": value, + "returning": subject.key_name + })]; + }); + }); + } + storage.sql_table_autokey_create = sql_table_autokey_create; + /** + */ + function sql_table_autokey_update(subject, key, value) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, (subject.database_implementation.query_update({ + "table_name": subject.table_name, + "values": value, + "condition": lib_plankton.string.coin("{{key_name}} = $key", { + "key_name": subject.database_implementation.wrap_name(subject.key_name) + }), + "arguments": { + "key": key + } + }) + .then(function (x) { return Promise.resolve(undefined); }))]; + }); + }); + } + storage.sql_table_autokey_update = sql_table_autokey_update; + /** + */ + function sql_table_autokey_delete(subject, key) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, subject.database_implementation.query_delete({ + "table_name": subject.table_name, + "condition": lib_plankton.string.coin("{{key_name}} = $key", { + "key_name": subject.database_implementation.wrap_name(subject.key_name) + }), + "arguments": { + "key": key + } + })]; + case 1: + _a.sent(); + return [2 /*return*/, Promise.resolve(undefined)]; + } + }); + }); + } + storage.sql_table_autokey_delete = sql_table_autokey_delete; + /** + */ + function sql_table_autokey_read(subject, key) { + return __awaiter(this, void 0, void 0, function () { + var rows; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, subject.database_implementation.query_select({ + "source": subject.table_name, + "fields": null, + "condition": lib_plankton.string.coin("{{key_name}} = $key", { + "key_name": subject.database_implementation.wrap_name(subject.key_name) + }), + "arguments": { + "key": key + } + })]; + case 1: + rows = _a.sent(); + if (rows.length < 1) { + return [2 /*return*/, Promise.reject("not found")]; + } + else if (rows.length > 1) { + return [2 /*return*/, Promise.reject("ambiguous")]; + } + else { + delete rows[0][subject.key_name]; + return [2 /*return*/, Promise.resolve(rows[0])]; + } + return [2 /*return*/]; + } + }); + }); + } + storage.sql_table_autokey_read = sql_table_autokey_read; + /** + * @todo correct preview + */ + function sql_table_autokey_search(subject, term) { + return __awaiter(this, void 0, void 0, function () { + var rows; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, subject.database_implementation.query_select({ + "source": subject.table_name, + "fields": null, + "condition": ((term === null) ? null : term.expression), + "arguments": ((term === null) ? null : term.arguments) + })]; + case 1: + rows = _a.sent(); + return [2 /*return*/, Promise.resolve(rows + .map(function (row) { return ({ + "key": row[subject.key_name], + "preview": row + }); }))]; + } + }); + }); + } + storage.sql_table_autokey_search = sql_table_autokey_search; + /** + */ + function sql_table_autokey_store(parameters) { + var subject = sql_table_autokey_make(parameters); + return { + "setup": function (input) { return sql_table_autokey_setup(subject, input); }, + "create": function (value) { return sql_table_autokey_create(subject, value); }, + "update": function (key, value) { return sql_table_autokey_update(subject, key, value); }, + "delete": function (key) { return sql_table_autokey_delete(subject, key); }, + "read": function (key) { return sql_table_autokey_read(subject, key); }, + "search": function (term) { return sql_table_autokey_search(subject, term); } + }; + } + storage.sql_table_autokey_store = sql_table_autokey_store; + })(storage = lib_plankton.storage || (lib_plankton.storage = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:storage«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:storage« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:storage« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:storage«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var storage; + (function (storage) { + /** + * @author fenris + */ + var class_sql_table_autokey = /** @class */ (function () { + function class_sql_table_autokey(parameters) { + this.subject = storage.sql_table_autokey_make(parameters); + } + class_sql_table_autokey.prototype.setup = function (input) { return storage.sql_table_autokey_setup(this.subject, input); }; + class_sql_table_autokey.prototype.create = function (value) { return storage.sql_table_autokey_create(this.subject, value); }; + class_sql_table_autokey.prototype.update = function (key, value) { return storage.sql_table_autokey_update(this.subject, key, value); }; + class_sql_table_autokey.prototype["delete"] = function (key) { return storage.sql_table_autokey_delete(this.subject, key); }; + class_sql_table_autokey.prototype.read = function (key) { return storage.sql_table_autokey_read(this.subject, key); }; + class_sql_table_autokey.prototype.search = function (term) { return storage.sql_table_autokey_search(this.subject, term); }; + return class_sql_table_autokey; + }()); + storage.class_sql_table_autokey = class_sql_table_autokey; + })(storage = lib_plankton.storage || (lib_plankton.storage = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:storage«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:storage« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:storage« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:storage«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var storage; + (function (storage) { + var sql_table_common; + (function (sql_table_common) { + /** + */ + function make(parameters) { + return { + "database_implementation": parameters.database_implementation, + "table_name": parameters.table_name, + "key_names": parameters.key_names + }; + } + sql_table_common.make = make; + /** + */ + function key_condition(subject, key) { + return { + "condition": lib_string.coin("({{clauses}})", { + "clauses": (subject.key_names + .map(function (key_name) { return lib_plankton.string.coin("({{name1}} = $key_{{name2}})", { + "name1": subject.database_implementation.wrap_name(key_name), + "name2": key_name + }); }) + .join(" AND ")) + }), + "arguments": Object.fromEntries(subject.key_names + .map(function (key_name, index) { return ([ + lib_plankton.string.coin("key_{{name}}", { + "name": key_name + }), + key[index] + ]); })) + }; + } + /** + */ + function setup(subject, description_create_table) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, subject.database_implementation.query_create_table(description_create_table)]; + }); + }); + } + sql_table_common.setup = setup; + /** + */ + function clear(subject) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, subject.database_implementation.query_delete({ + "table_name": subject.table_name, + "condition": "TRUE", + "arguments": {} + })]; + case 1: + _a.sent(); + return [2 /*return*/, Promise.resolve(undefined)]; + } + }); + }); + } + sql_table_common.clear = clear; + /** + * @todo optimize: avoid read + */ + function write(subject, key, value) { + return __awaiter(this, void 0, void 0, function () { + var exists, error_1, field_names, condition; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + _a.trys.push([0, 2, , 3]); + return [4 /*yield*/, read(subject, key)]; + case 1: + _a.sent(); + exists = true; + return [3 /*break*/, 3]; + case 2: + error_1 = _a.sent(); + exists = false; + return [3 /*break*/, 3]; + case 3: + field_names = Object.keys(value); + if (!!exists) return [3 /*break*/, 5]; + return [4 /*yield*/, subject.database_implementation.query_insert({ + "table_name": subject.table_name, + "values": Object.assign( + // key + Object.fromEntries(subject.key_names.map(function (key_name, index) { return ([key_name, key[index]]); })), + // value + value) + })]; + case 4: + _a.sent(); + return [3 /*break*/, 7]; + case 5: + condition = key_condition(subject, key); + return [4 /*yield*/, subject.database_implementation.query_update({ + "table_name": subject.table_name, + "values": value, + "condition": condition.condition, + "arguments": condition.arguments + })]; + case 6: + _a.sent(); + _a.label = 7; + case 7: return [2 /*return*/, Promise.resolve(exists)]; + } + }); + }); + } + sql_table_common.write = write; + /** + */ + function delete_(subject, key) { + return __awaiter(this, void 0, void 0, function () { + var condition; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + condition = key_condition(subject, key); + return [4 /*yield*/, subject.database_implementation.query_delete({ + "table_name": subject.table_name, + "condition": condition.condition, + "arguments": condition.arguments + })]; + case 1: + _a.sent(); + return [2 /*return*/, Promise.resolve(undefined)]; + } + }); + }); + } + sql_table_common.delete_ = delete_; + /** + */ + function read(subject, key) { + return __awaiter(this, void 0, void 0, function () { + var condition, rows; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + condition = key_condition(subject, key); + return [4 /*yield*/, subject.database_implementation.query_select({ + "source": subject.table_name, + "fields": null, + "condition": condition.condition, + "arguments": condition.arguments + })]; + case 1: + rows = _a.sent(); + if (rows.length < 1) { + return [2 /*return*/, Promise.reject("not found")]; + } + else if (rows.length > 1) { + return [2 /*return*/, Promise.reject("ambiguous")]; + } + else { + subject.key_names.forEach(function (key_name) { delete rows[0][key_name]; }); + return [2 /*return*/, Promise.resolve(rows[0])]; + } + return [2 /*return*/]; + } + }); + }); + } + sql_table_common.read = read; + /** + * @todo correct preview + */ + function search(subject, term) { + return __awaiter(this, void 0, void 0, function () { + var rows; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, subject.database_implementation.query_select({ + "source": subject.table_name, + "fields": null, + "condition": ((term === null) ? null : term.expression), + "arguments": ((term === null) ? null : term.arguments) + })]; + case 1: + rows = _a.sent(); + return [2 /*return*/, Promise.resolve(rows + .map(function (row) { return ({ + "key": subject.key_names.map(function (name) { return row[name]; }), + "preview": row + }); }))]; + } + }); + }); + } + sql_table_common.search = search; + /** + */ + function chest(parameters) { + var subject = make(parameters); + return { + "setup": function (input) { return setup(subject, input); }, + "clear": function () { return clear(subject); }, + "write": function (key, value) { return write(subject, key, value); }, + "delete": function (key) { return delete_(subject, key); }, + "read": function (key) { return read(subject, key); }, + "search": function (term) { return search(subject, term); } + }; + } + sql_table_common.chest = chest; + })(sql_table_common = storage.sql_table_common || (storage.sql_table_common = {})); + })(storage = lib_plankton.storage || (lib_plankton.storage = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:storage«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:storage« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:storage« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:storage«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var storage; + (function (storage) { + var sql_table_common; + (function (sql_table_common) { + /** + * @author fenris + */ + var class_chest = /** @class */ (function () { + function class_chest(parameters) { + this.subject = sql_table_common.make(parameters); + } + class_chest.prototype.setup = function (input) { return sql_table_common.setup(this.subject, input); }; + class_chest.prototype.clear = function () { return sql_table_common.clear(this.subject); }; + class_chest.prototype.write = function (key, value) { return sql_table_common.write(this.subject, key, value); }; + class_chest.prototype["delete"] = function (key) { return sql_table_common.delete_(this.subject, key); }; + class_chest.prototype.read = function (key) { return sql_table_common.read(this.subject, key); }; + class_chest.prototype.search = function (term) { return sql_table_common.search(this.subject, term); }; + return class_chest; + }()); + sql_table_common.class_chest = class_chest; + })(sql_table_common = storage.sql_table_common || (storage.sql_table_common = {})); + })(storage = lib_plankton.storage || (lib_plankton.storage = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:shape«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:shape« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:shape« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:shape«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var shape; + (function (shape_1) { + /** + * @author fenris + */ + function inspection_create() { + return { + "flaws": [], + "sub": [] + }; + } + shape_1.inspection_create = inspection_create; + /** + * @author fenris + */ + function inspection_add(main, flaw) { + main.flaws.push(flaw); + } + shape_1.inspection_add = inspection_add; + /** + * @author fenris + */ + function inspection_extend(main, prefix, sub) { + if ((sub.flaws.length <= 0) + && + (sub.sub.length <= 0)) { + // do nothing + } + else { + main.sub.push({ "position": prefix, "inspection": sub }); + } + } + shape_1.inspection_extend = inspection_extend; + /** + */ + function inspection_flatten(inspection) { + return (inspection.flaws + .concat(inspection.sub + .map((entry) => (inspection_flatten(entry.inspection) + .map(rest => lib_plankton.string.coin("[{{position}}] {{rest}}", { + "position": entry.position, + "rest": rest + })))) + .reduce((x, y) => x.concat(y), []))); + } + /** + */ + var _pool = {}; + /** + * @todo cache + */ + function construct(shape) { + return _pool[shape.kind].construct(shape.parameters); + } + /** + */ + function get_logic(shape) { + if (!(shape.kind in _pool)) { + throw (new Error("missing shape: " + shape.kind)); + } + else { + return _pool[shape.kind].logic(construct(shape)); + } + } + /** + */ + function inspect(shape, value) { + return get_logic(shape).inspect(inspect, value); + } + shape_1.inspect = inspect; + /** + */ + function inspect_flat(shape, value) { + return inspection_flatten(inspect(shape, value)); + } + shape_1.inspect_flat = inspect_flat; + /** + */ + function show(shape) { + return get_logic(shape).show(show); + } + shape_1.show = show; + /** + */ + function to_typescript_type(shape) { + return get_logic(shape).to_typescript_type(to_typescript_type); + } + shape_1.to_typescript_type = to_typescript_type; + /** + */ + function to_jsonschema(shape) { + return get_logic(shape).to_jsonschema(to_jsonschema); + } + shape_1.to_jsonschema = to_jsonschema; + /** + */ + function to_oas_schema(shape) { + return get_logic(shape).to_oas_schema(to_oas_schema); + } + shape_1.to_oas_schema = to_oas_schema; + /** + */ + function example(shape) { + return get_logic(shape).example(example); + } + shape_1.example = example; + /** + */ + function register(name, construct, logic) { + _pool[name] = { + "construct": construct, + "logic": logic, + }; + } + shape_1.register = register; + })(shape = lib_plankton.shape || (lib_plankton.shape = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:shape«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:shape« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:shape« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:shape«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var shape; + (function (shape_2) { + var any; + (function (any) { + /** + */ + function make(options = {}) { + return {}; + } + any.make = make; + /** + */ + function inspect(sub_inspect, subject, value) { + let inspection = shape_2.inspection_create(); + return inspection; + } + /** + */ + function show(sub_show, subject) { + return "any"; + } + /** + */ + function to_typescript_type(sub_to_typescript_type, subject) { + return "any"; + } + /** + */ + function to_jsonschema(sub_to_jsonschema, subject) { + return {}; + } + /** + */ + function example(sub_example, subject) { + return null; + } + shape_2.register("any", (parameters) => make({}), (subject) => ({ + "inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value), + "show": (sub_show) => show(sub_show, subject), + "to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject), + "to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject), + "to_oas_schema": (sub_to_oas_schema) => to_jsonschema(sub_to_oas_schema, subject), + "example": (sub_example) => example(sub_example, subject), + })); + })(any = shape_2.any || (shape_2.any = {})); + })(shape = lib_plankton.shape || (lib_plankton.shape = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:shape«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:shape« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:shape« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:shape«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var shape; + (function (shape_3) { + var null_; + (function (null_) { + /** + */ + function make(options = {}) { + return {}; + } + null_.make = make; + /** + */ + function inspect(sub_inspect, subject, value) { + let inspection = shape_3.inspection_create(); + if (!(value === null)) { + shape_3.inspection_add(inspection, "null expected"); + } + else { + // all good + } + return inspection; + } + /** + */ + function show(sub_show, subject) { + return "null"; + } + /** + */ + function to_typescript_type(sub_to_typescript_type, subject) { + return "null"; + } + /** + */ + function to_jsonschema(sub_to_jsonschema, subject) { + return { + "type": "null", + }; + } + /** + */ + function example(sub_example, subject) { + return null; + } + shape_3.register("null", (parameters) => make({}), (subject) => ({ + "inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value), + "show": (sub_show) => show(sub_show, subject), + "to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject), + "to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject), + "to_oas_schema": (sub_to_oas_schema) => to_jsonschema(sub_to_oas_schema, subject), + "example": (sub_example) => example(sub_example, subject), + })); + })(null_ = shape_3.null_ || (shape_3.null_ = {})); + })(shape = lib_plankton.shape || (lib_plankton.shape = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:shape«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:shape« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:shape« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:shape«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var shape; + (function (shape_4) { + var boolean; + (function (boolean) { + /** + */ + function make(options = {}) { + options = Object.assign({ + "soft": false, + "defaultvalue": undefined, + "description": undefined, + }, options); + return { + "soft": options.soft, + "defaultvalue": ((options.defaultvalue === undefined) + ? lib_plankton.pod.make_empty() + : lib_plankton.pod.make_filled(options.defaultvalue)), + "description": ((options.description === undefined) + ? lib_plankton.pod.make_empty() + : lib_plankton.pod.make_filled(options.description)), + }; + } + boolean.make = make; + /** + */ + function inspect(sub_inspect, subject, value) { + let inspection = shape_4.inspection_create(); + if (value === null) { + if (subject.soft) { + // all good + } + else { + shape_4.inspection_add(inspection, "null is not allowed"); + } + } + else { + const jstype_actual = typeof (value); + const jstype_expected = "boolean"; + if (jstype_actual === jstype_expected) { + // all good + } + else { + shape_4.inspection_add(inspection, lib_plankton.string.coin("expected JS-type '{{expected}}' but got '{{actual}}'", { + "expected": jstype_expected, + "actual": jstype_actual, + })); + } + } + return inspection; + } + /** + */ + function show(sub_show, subject) { + const core = "boolean"; + return (subject.soft ? ("~" + core) : core); + } + /** + */ + function to_typescript_type(sub_to_typescript_type, subject) { + const core = "boolean"; + return (subject.soft ? ("(null | " + core + ")") : core); + } + /** + */ + function to_jsonschema(sub_to_jsonschema, subject) { + const common = { + "description": lib_plankton.pod.distinguish(subject.description, () => undefined, x => x), + "default": lib_plankton.pod.distinguish(subject.defaultvalue, () => undefined, x => x), + }; + const core = { + "type": "boolean", + }; + return (subject.soft + ? { + "anyOf": [ + Object.assign({ "type": "null" }, common), + Object.assign(core, common), + ], + } + : core); + } + /** + */ + function example(sub_example, subject) { + return (subject.soft ? null : false); + } + shape_4.register("boolean", (parameters) => make({ + "soft": parameters.soft, + "description": parameters.description, + "defaultvalue": parameters.defaultvalue, + }), (subject) => ({ + "inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value), + "show": (sub_show) => show(sub_show, subject), + "to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject), + "to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject), + "to_oas_schema": (sub_to_oas_schema) => to_jsonschema(sub_to_oas_schema, subject), + "example": (sub_example) => example(sub_example, subject), + })); + })(boolean = shape_4.boolean || (shape_4.boolean = {})); + })(shape = lib_plankton.shape || (lib_plankton.shape = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:shape«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:shape« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:shape« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:shape«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var shape; + (function (shape_5) { + var integer; + (function (integer) { + /** + */ + function make(options = {}) { + options = Object.assign({ + "soft": false, + "defaultvalue": undefined, + "description": undefined, + "minimum": undefined, + "maximum": undefined, + }, options); + return { + "soft": options.soft, + "defaultvalue": ((options.defaultvalue === undefined) + ? lib_plankton.pod.make_empty() + : lib_plankton.pod.make_filled(options.defaultvalue)), + "description": ((options.description === undefined) + ? lib_plankton.pod.make_empty() + : lib_plankton.pod.make_filled(options.description)), + "minimum": ((options.minimum === undefined) + ? lib_plankton.pod.make_empty() + : lib_plankton.pod.make_filled(options.minimum)), + "maximum": ((options.minimum === undefined) + ? lib_plankton.pod.make_empty() + : lib_plankton.pod.make_filled(options.maximum)), + }; + } + integer.make = make; + /** + */ + function inspect(sub_inspect, subject, value) { + let inspection = shape_5.inspection_create(); + if (value === null) { + if (subject.soft) { + // all good + } + else { + shape_5.inspection_add(inspection, "null is not allowed"); + } + } + else { + const jstype_actual = typeof (value); + const jstype_expected = "number"; + if (!(jstype_actual === jstype_expected)) { + shape_5.inspection_add(inspection, lib_plankton.string.coin("expected JS-type '{{expected}}' but got '{{actual}}'", { + "expected": jstype_expected, + "actual": jstype_actual, + })); + } + else { + if (isNaN(parseInt(value))) { + shape_5.inspection_add(inspection, "value is not parsable to a valid int"); + } + else { + // minimum + { + if (!lib_plankton.pod.distinguish(subject.minimum, () => true, x => (value >= x))) { + shape_5.inspection_add(inspection, lib_plankton.string.coin("value is below the minimum of '{{minimum}}'", { + "minimum": lib_plankton.pod.cull(subject.minimum).toFixed(0), + })); + } + else { + // do nothing + } + } + // maximum + { + if (!lib_plankton.pod.distinguish(subject.maximum, () => true, x => (value <= x))) { + shape_5.inspection_add(inspection, lib_plankton.string.coin("value is beyond the maximum of '{{maximum}}'", { + "maximum": lib_plankton.pod.cull(subject.maximum).toFixed(0), + })); + } + else { + // do nothing + } + } + } + } + } + return inspection; + } + /** + */ + function show(sub_show, subject) { + const core = "integer"; + return (subject.soft ? ("~" + core) : core); + } + /** + */ + function to_typescript_type(sub_to_typescript_type, subject) { + const core = "number"; + return (subject.soft ? ("(null | " + core + ")") : core); + } + /** + */ + function to_jsonschema(sub_to_jsonschema, subject) { + const common = { + "description": lib_plankton.pod.distinguish(subject.description, () => undefined, x => x), + "default": lib_plankton.pod.distinguish(subject.defaultvalue, () => undefined, x => x), + }; + const core = { + "type": "integer", + "minimum": lib_plankton.pod.distinguish(subject.minimum, () => undefined, x => x), + "maximum": lib_plankton.pod.distinguish(subject.maximum, () => undefined, x => x), + }; + return (subject.soft + ? { + "anyOf": [ + Object.assign({ "type": "null" }, common), + Object.assign(core, common), + ], + } + : core); + } + /** + */ + function example(sub_example, subject) { + return (subject.soft ? null : 0); + } + shape_5.register("integer", (parameters) => make({ + "soft": parameters.soft, + "description": parameters.description, + "defaultvalue": parameters.defaultvalue, + "minimum": parameters.minimum, + "maximum": parameters.maximum, + }), (subject) => ({ + "inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value), + "show": (sub_show) => show(sub_show, subject), + "to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject), + "to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject), + "to_oas_schema": (sub_to_oas_schema) => to_jsonschema(sub_to_oas_schema, subject), + "example": (sub_example) => example(sub_example, subject), + })); + })(integer = shape_5.integer || (shape_5.integer = {})); + })(shape = lib_plankton.shape || (lib_plankton.shape = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:shape«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:shape« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:shape« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:shape«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var shape; + (function (shape_6) { + var float; + (function (float) { + /** + */ + function make(options = {}) { + options = Object.assign({ + "soft": false, + "defaultvalue": undefined, + "description": undefined, + "minimum": undefined, + "maximum": undefined, + }, options); + return { + "soft": options.soft, + "defaultvalue": ((options.defaultvalue === undefined) + ? lib_plankton.pod.make_empty() + : lib_plankton.pod.make_filled(options.defaultvalue)), + "description": ((options.description === undefined) + ? lib_plankton.pod.make_empty() + : lib_plankton.pod.make_filled(options.description)), + "minimum": ((options.minimum === undefined) + ? lib_plankton.pod.make_empty() + : lib_plankton.pod.make_filled(options.minimum)), + "maximum": ((options.minimum === undefined) + ? lib_plankton.pod.make_empty() + : lib_plankton.pod.make_filled(options.maximum)), + }; + } + float.make = make; + /** + */ + function inspect(sub_inspect, subject, value) { + let inspection = shape_6.inspection_create(); + if (value === null) { + if (subject.soft) { + // all good + } + else { + shape_6.inspection_add(inspection, "null is not allowed"); + } + } + else { + const jstype_actual = typeof (value); + const jstype_expected = "number"; + if (!(jstype_actual === jstype_expected)) { + shape_6.inspection_add(inspection, lib_plankton.string.coin("expected JS-type '{{expected}}' but got '{{actual}}'", { + "expected": jstype_expected, + "actual": jstype_actual, + })); + } + else { + if (isNaN(parseInt(value))) { + shape_6.inspection_add(inspection, "value is not parsable to a valid float"); + } + else { + // minimum + { + if (!lib_plankton.pod.distinguish(subject.minimum, () => true, x => (value >= x))) { + shape_6.inspection_add(inspection, lib_plankton.string.coin("value is below the minimum of '{{minimum}}'", { + "minimum": lib_plankton.pod.cull(subject.minimum).toFixed(0), + })); + } + else { + // do nothing + } + } + // maximum + { + if (!lib_plankton.pod.distinguish(subject.maximum, () => true, x => (value <= x))) { + shape_6.inspection_add(inspection, lib_plankton.string.coin("value is beyond the maximum of '{{maximum}}'", { + "maximum": lib_plankton.pod.cull(subject.maximum).toFixed(0), + })); + } + else { + // do nothing + } + } + } + } + } + return inspection; + } + /** + */ + function show(sub_show, subject) { + const core = "float"; + return (subject.soft ? ("~" + core) : core); + } + /** + */ + function to_typescript_type(sub_to_typescript_type, subject) { + const core = "number"; + return (subject.soft ? ("(null | " + core + ")") : core); + } + /** + */ + function to_jsonschema(sub_to_jsonschema, subject) { + const common = { + "description": lib_plankton.pod.distinguish(subject.description, () => undefined, x => x), + "default": lib_plankton.pod.distinguish(subject.defaultvalue, () => undefined, x => x), + }; + const core = { + "type": "float", + "minimum": lib_plankton.pod.distinguish(subject.minimum, () => undefined, x => x), + "maximum": lib_plankton.pod.distinguish(subject.maximum, () => undefined, x => x), + }; + return (subject.soft + ? { + "anyOf": [ + Object.assign({ "type": "null" }, common), + Object.assign(core, common), + ], + } + : core); + } + /** + */ + function example(sub_example, subject) { + return (subject.soft ? null : 0); + } + shape_6.register("float", (parameters) => make({ + "soft": parameters.soft, + "description": parameters.description, + "defaultvalue": parameters.defaultvalue, + "minimum": parameters.minimum, + "maximum": parameters.maximum, + }), (subject) => ({ + "inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value), + "show": (sub_show) => show(sub_show, subject), + "to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject), + "to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject), + "to_oas_schema": (sub_to_oas_schema) => to_jsonschema(sub_to_oas_schema, subject), + "example": (sub_example) => example(sub_example, subject), + })); + })(float = shape_6.float || (shape_6.float = {})); + })(shape = lib_plankton.shape || (lib_plankton.shape = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:shape«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:shape« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:shape« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:shape«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var shape; + (function (shape_7) { + var string; + (function (string) { + /** + */ + function make(options = {}) { + options = Object.assign({ + "soft": false, + "defaultvalue": undefined, + "description": undefined, + "pattern": undefined, + "min_length": undefined, + "max_lenth": undefined, + }, options); + return { + "soft": options.soft, + "defaultvalue": ((options.defaultvalue === undefined) + ? lib_plankton.pod.make_empty() + : lib_plankton.pod.make_filled(options.defaultvalue)), + "description": ((options.description === undefined) + ? lib_plankton.pod.make_empty() + : lib_plankton.pod.make_filled(options.description)), + "pattern": ((options.pattern === undefined) + ? lib_plankton.pod.make_empty() + : lib_plankton.pod.make_filled(options.pattern)), + "min_length": ((options.min_length === undefined) + ? lib_plankton.pod.make_empty() + : lib_plankton.pod.make_filled(options.min_length)), + "max_length": ((options.max_length === undefined) + ? lib_plankton.pod.make_empty() + : lib_plankton.pod.make_filled(options.max_length)), + }; + } + string.make = make; + /** + */ + function inspect(sub_inspect, subject, value) { + let inspection = shape_7.inspection_create(); + if (value === null) { + if (subject.soft) { + // all good + } + else { + shape_7.inspection_add(inspection, "null is not allowed"); + } + } + else { + const jstype_actual = typeof (value); + const jstype_expected = "string"; + if (!(jstype_actual === jstype_expected)) { + shape_7.inspection_add(inspection, lib_plankton.string.coin("expected JS-type '{{expected}}' but got '{{actual}}'", { + "expected": jstype_expected, + "actual": jstype_actual, + })); + } + else { + const value_ = value; + // pattern + { + if (!lib_plankton.pod.distinguish(subject.pattern, () => true, x => (new RegExp(x)).test(value_))) { + shape_7.inspection_add(inspection, lib_plankton.string.coin("string does not match the pattern '{{pattern}}'", { + "pattern": lib_plankton.pod.cull(subject.pattern), + })); + } + else { + // do nothing + } + } + // min_length + { + if (!lib_plankton.pod.distinguish(subject.min_length, () => true, x => (value_.length >= x))) { + shape_7.inspection_add(inspection, lib_plankton.string.coin("string is shorter than '{{min_length}}'", { + "min_length": lib_plankton.pod.cull(subject.min_length).toFixed(0), + })); + } + else { + // do nothing + } + } + // max_length + { + if (!lib_plankton.pod.distinguish(subject.max_length, () => true, x => (value_.length <= x))) { + shape_7.inspection_add(inspection, lib_plankton.string.coin("string is longer than '{{max_length}}'", { + "min_length": lib_plankton.pod.cull(subject.max_length).toFixed(0), + })); + } + else { + // do nothing + } + } + } + } + return inspection; + } + /** + */ + function show(sub_show, subject) { + const core = "string"; + return (subject.soft ? ("~" + core) : core); + } + /** + */ + function to_typescript_type(sub_to_typescript_type, subject) { + const core = "string"; + return (subject.soft ? ("(null | " + core + ")") : core); + } + /** + */ + function to_jsonschema(sub_to_jsonschema, subject) { + const common = { + "description": lib_plankton.pod.distinguish(subject.description, () => undefined, x => x), + "default": lib_plankton.pod.distinguish(subject.defaultvalue, () => undefined, x => x), + }; + const core = { + "type": "string", + // TODO: transform? + "pattern": lib_plankton.pod.distinguish(subject.pattern, () => undefined, x => x), + "minLength": lib_plankton.pod.distinguish(subject.min_length, () => undefined, x => x), + "maxLenth": lib_plankton.pod.distinguish(subject.max_length, () => undefined, x => x), + }; + return (subject.soft + ? { + "anyOf": [ + Object.assign({ "type": "null" }, common), + Object.assign(core, common), + ], + } + : core); + } + /** + */ + function example(sub_example, subject) { + return (subject.soft ? null : ""); + } + shape_7.register("string", (parameters) => make({ + "soft": parameters.soft, + "description": parameters.description, + "defaultvalue": parameters.defaultvalue, + "pattern": parameters.pattern, + "min_length": parameters.min_length, + "max_length": parameters.max_length, + }), (subject) => ({ + "inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value), + "show": (sub_show) => show(sub_show, subject), + "to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject), + "to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject), + "to_oas_schema": (sub_to_oas_chema) => to_jsonschema(sub_to_oas_chema, subject), + "example": (sub_example) => example(sub_example, subject), + })); + })(string = shape_7.string || (shape_7.string = {})); + })(shape = lib_plankton.shape || (lib_plankton.shape = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:shape«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:shape« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:shape« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:shape«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var shape; + (function (shape_8) { + var email; + (function (email) { + /** + */ + function make(options = {}) { + options = Object.assign({ + "soft": false, + "defaultvalue": undefined, + "description": undefined, + }, options); + return { + "core": { + "kind": "string", + "parameters": { + "soft": options.soft, + "defaultvalue": options.defaultvalue, + "description": options.description, + "pattern": "[^@]*@[^@]*", + "min_length": 0, + "max_length": 255, + } + }, + }; + } + email.make = make; + /** + */ + function inspect(sub_inspect, subject, value) { + return sub_inspect(subject.core, value); + } + /** + */ + function show(sub_show, subject) { + return sub_show(subject.core); + } + /** + */ + function to_typescript_type(sub_to_typescript_type, subject) { + return sub_to_typescript_type(subject.core); + } + /** + */ + function to_jsonschema(sub_to_jsonschema, subject) { + return sub_to_jsonschema(subject.core); + } + /** + */ + function example(sub_example, subject) { + return sub_example(subject.core); + } + shape_8.register("email", (parameters) => make({ + "soft": parameters.soft, + "description": parameters.description, + "defaultvalue": parameters.defaultvalue, + }), (subject) => ({ + "inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value), + "show": (sub_show) => show(sub_show, subject), + "to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject), + "to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject), + "to_oas_schema": (sub_to_oas_chema) => to_jsonschema(sub_to_oas_chema, subject), + "example": (sub_example) => example(sub_example, subject), + })); + })(email = shape_8.email || (shape_8.email = {})); + })(shape = lib_plankton.shape || (lib_plankton.shape = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:shape«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:shape« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:shape« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:shape«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var shape; + (function (shape_9) { + var list_; + (function (list_) { + /** + */ + function make(shape_element, options = {}) { + options = Object.assign({ + "soft": false, + "defaultvalue": lib_plankton.pod.make_empty(), + "description": lib_plankton.pod.make_empty(), + }, options); + return { + "shape_element": shape_element, + "soft": options.soft, + "defaultvalue": ((options.defaultvalue === undefined) + ? lib_plankton.pod.make_empty() + : lib_plankton.pod.make_filled(options.defaultvalue)), + "description": ((options.description === undefined) + ? lib_plankton.pod.make_empty() + : lib_plankton.pod.make_filled(options.description)), + }; + } + list_.make = make; + /** + */ + function inspect(sub_inspect, subject, value) { + let inspection = shape_9.inspection_create(); + if (value === null) { + if (subject.soft) { + // all good + } + else { + shape_9.inspection_add(inspection, "null is not allowed"); + } + } + else { + const jstype_actual = typeof (value); + const jstype_expected = "object"; + if (!(jstype_actual === jstype_expected)) { + lib_plankton.string.coin("expected JS-type '{{expected}}' but got '{{actual}}'", { + "expected": jstype_expected, + "actual": jstype_actual, + }); + } + else { + if (!(value instanceof Array)) { + shape_9.inspection_add(inspection, "value does not seem to be an array-instance"); + } + else { + value.forEach((element, index) => { + shape_9.inspection_extend(inspection, lib_plankton.string.coin("element #{{index}}", { + "index": index.toFixed(0), + }), + // subject.shape_element.inspect(element) + sub_inspect(subject.shape_element, element)); + }); + } + } + } + return inspection; + } + /** + */ + function show(sub_show, subject) { + const core = lib_plankton.string.coin("list<{{element}}>", { + "element": sub_show(subject.shape_element), + }); + return (subject.soft ? ("~" + core) : core); + } + /** + */ + function to_typescript_type(sub_to_typescript_type, subject) { + const core = lib_plankton.string.coin("Array<{{element}}>", { + "element": sub_to_typescript_type(subject.shape_element), + }); + return (subject.soft ? ("(null | " + core + ")") : core); + } + /** + */ + function to_jsonschema(sub_to_jsonschema, subject) { + const common = { + "description": lib_plankton.pod.distinguish(subject.description, () => undefined, x => x), + "default": lib_plankton.pod.distinguish(subject.defaultvalue, () => undefined, x => x), + }; + const core = { + "type": "array", + "items": sub_to_jsonschema(subject.shape_element), + }; + return ((subject.soft + ? { + "anyOf": [ + Object.assign({ "type": "null" }, common), + Object.assign(core, common), + ] + } + : core)); + } + /** + */ + function example(sub_example, subject) { + return (subject.soft + ? null + : [ + sub_example(subject.shape_element) + ]); + } + shape_9.register("list", (parameters) => make(parameters.shape_element, { + "soft": parameters.soft, + "description": parameters.description, + "defaultvalue": parameters.defaultvalue, + }), (subject) => ({ + "inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value), + "show": (sub_show) => show(sub_show, subject), + "to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject), + "to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject), + "to_oas_schema": (sub_to_oas_schema) => to_jsonschema(sub_to_oas_schema, subject), + "example": (sub_example) => example(sub_example, subject), + })); + })(list_ = shape_9.list_ || (shape_9.list_ = {})); + })(shape = lib_plankton.shape || (lib_plankton.shape = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:shape«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:shape« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:shape« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:shape«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var shape; + (function (shape_10) { + var map; + (function (map) { + /** + */ + function make(shape_key, shape_value, options = {}) { + options = Object.assign({ + "soft": false, + "defaultvalue": lib_plankton.pod.make_empty(), + "description": lib_plankton.pod.make_empty(), + }, options); + return { + "shape_key": shape_key, + "shape_value": shape_value, + "soft": options.soft, + "defaultvalue": ((options.defaultvalue === undefined) + ? lib_plankton.pod.make_empty() + : lib_plankton.pod.make_filled(options.defaultvalue)), + "description": ((options.description === undefined) + ? lib_plankton.pod.make_empty() + : lib_plankton.pod.make_filled(options.description)), + }; + } + map.make = make; + /** + */ + function inspect(sub_inspect, subject, value) { + let inspection = shape_10.inspection_create(); + if (value === null) { + if (subject.soft) { + // all good + } + else { + shape_10.inspection_add(inspection, "null is not allowed"); + } + } + else { + const jstype_actual = typeof (value); + const jstype_expected = "object"; + if (!(jstype_actual === jstype_expected)) { + lib_plankton.string.coin("expected JS-type '{{expected}}' but got '{{actual}}'", { + "expected": jstype_expected, + "actual": jstype_actual, + }); + } + else { + Object.entries(value) + .forEach(([key, value]) => { + shape_10.inspection_extend(inspection, lib_plankton.string.coin("key '{{key}}'", { + "key": String(key), + }), sub_inspect(subject.shape_key, key)); + shape_10.inspection_extend(inspection, lib_plankton.string.coin("value for '{{key}}'", { + "key": String(key), + }), sub_inspect(subject.shape_value, value)); + }); + } + } + return inspection; + } + /** + */ + function show(sub_show, subject) { + const core = lib_plankton.string.coin("map<{{key}},{{value}}>", { + "key": sub_show(subject.shape_key), + "value": sub_show(subject.shape_value), + }); + return (subject.soft ? ("~" + core) : core); + } + /** + */ + function to_typescript_type(sub_to_typescript_type, subject) { + const core = lib_plankton.string.coin("Record<{{key}},{{value}}>", { + "key": sub_to_typescript_type(subject.shape_key), + "value": sub_to_typescript_type(subject.shape_key), + }); + return (subject.soft ? ("(null | " + core + ")") : core); + } + /** + */ + function to_jsonschema(sub_to_jsonschema, subject) { + const common = { + "description": lib_plankton.pod.distinguish(subject.description, () => undefined, x => x), + "default": lib_plankton.pod.distinguish(subject.defaultvalue, () => undefined, x => x), + }; + const core = { + "type": "object", + "additionalProperties": sub_to_jsonschema(subject.shape_value), + "properties": {}, + "required": [], + }; + return ((subject.soft + ? { + "anyOf": [ + Object.assign({ "type": "null" }, common), + Object.assign(core, common), + ] + } + : core)); + } + /** + */ + function example(sub_example, subject) { + return (subject.soft + ? null + : {}); + } + shape_10.register("map", (parameters) => make(parameters.shape_key, parameters.shape_value, { + "soft": parameters.soft, + "description": parameters.description, + "defaultvalue": parameters.defaultvalue, + }), (subject) => ({ + "inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value), + "show": (sub_show) => show(sub_show, subject), + "to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject), + "to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject), + "to_oas_schema": (sub_to_oas_schema) => to_jsonschema(sub_to_oas_schema, subject), + "example": (sub_example) => example(sub_example, subject), + })); + })(map = shape_10.map || (shape_10.map = {})); + })(shape = lib_plankton.shape || (lib_plankton.shape = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:shape«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:shape« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:shape« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:shape«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var shape; + (function (shape_11) { + var record; + (function (record) { + /** + */ + function make(fields_raw, options = {}) { + options = Object.assign({ + "soft": false, + "defaultvalue": lib_plankton.pod.make_empty(), + "description": lib_plankton.pod.make_empty(), + }, options); + return { + "fields": fields_raw.map(field_raw => ({ + "name": field_raw.name, + "shape": field_raw.shape, + "required": (field_raw.required ?? true) + })), + "soft": options.soft, + "defaultvalue": ((options.defaultvalue === undefined) + ? lib_plankton.pod.make_empty() + : lib_plankton.pod.make_filled(options.defaultvalue)), + "description": ((options.description === undefined) + ? lib_plankton.pod.make_empty() + : lib_plankton.pod.make_filled(options.description)), + }; + } + record.make = make; + /** + */ + function inspect(sub_inspect, subject, value) { + let inspection = shape_11.inspection_create(); + if (value === null) { + if (subject.soft) { + // all good + } + else { + shape_11.inspection_add(inspection, "null is not allowed"); + } + } + else { + const jstype_actual = typeof (value); + const jstype_expected = "object"; + if (!(jstype_actual === jstype_expected)) { + shape_11.inspection_add(inspection, lib_plankton.string.coin("expected JS-type '{{expected}}' but got '{{actual}}'", { + "expected": jstype_expected, + "actual": jstype_actual, + })); + } + else { + subject.fields.forEach(field => { + if (!(field.name in value)) { + if (field.required) { + shape_11.inspection_add(inspection, "missing field '" + field.name + "'"); + } + else { + // do nothing + } + } + else { + const value_ = value[field.name]; + shape_11.inspection_extend(inspection, ("field '" + field.name + "'"), sub_inspect(field.shape, value_)); + } + }); + // extra fields + { + const allowed = subject.fields.map(field => field.name); + (Object.keys(value) + .filter(name => (!allowed.includes(name))) + .forEach(name => { + shape_11.inspection_add(inspection, "extra field '" + name + "'"); + })); + } + } + } + return inspection; + } + /** + */ + function show(sub_show, subject) { + const core = lib_plankton.string.coin("record<{{fields}}>", { + "fields": (subject.fields + .map(field => lib_plankton.string.coin("{{prefix}}{{name}}:{{shape}}", { + "prefix": (field.required ? "" : "?"), + "name": field.name, + "shape": sub_show(field.shape), + })) + .join(",")), + }); + return (subject.soft ? ("~" + core) : core); + } + /** + */ + function to_typescript_type(sub_to_typescript_type, subject) { + const core = lib_plankton.string.coin("{{{fields}}}", { + "fields": (subject.fields + .map(field => lib_plankton.string.coin("{{name}}{{infix}}{{shape}}", { + "name": field.name, + "infix": (field.required ? ":" : "?:"), + "shape": sub_to_typescript_type(field.shape), + })) + .join(";")), + }); + return (subject.soft ? ("(null | " + core + ")") : core); + } + /** + */ + function to_jsonschema(sub_to_jsonschema, subject) { + const common = { + "description": lib_plankton.pod.distinguish(subject.description, () => undefined, x => x), + "default": lib_plankton.pod.distinguish(subject.defaultvalue, () => undefined, x => x), + }; + const core = { + "type": "object", + "additionalProperties": false, + "properties": (Object.fromEntries(subject.fields + .map(field => ([ + field.name, + sub_to_jsonschema(field.shape) + ])))), + "required": (subject.fields + .filter(field => field.required) + .map(field => field.name)), + }; + return ((subject.soft + ? { + "anyOf": [ + Object.assign({ "type": "null" }, common), + Object.assign(core, common), + ] + } + : core)); + } + /** + */ + function example(sub_example, subject) { + return (subject.soft + ? null + : (Object.fromEntries(subject.fields + .filter(field => field.required) + .map(field => ([ + field.name, + sub_example(field.shape) + ]))))); + } + shape_11.register("record", (parameters) => make((parameters.fields + .map(field_raw => ({ + "name": field_raw.name, + "shape": field_raw.shape, + "required": field_raw.required, + }))), { + "soft": parameters.soft, + "description": parameters.description, + "defaultvalue": parameters.defaultvalue, + }), (subject) => ({ + "inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value), + "show": (sub_show) => show(sub_show, subject), + "to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject), + "to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject), + "to_oas_schema": (sub_to_oas_schema) => to_jsonschema(sub_to_oas_schema, subject), + "example": (sub_example) => example(sub_example, subject), + })); + })(record = shape_11.record || (shape_11.record = {})); + })(shape = lib_plankton.shape || (lib_plankton.shape = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:code«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:code« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:code« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:code«. If not, see . + */ +/* +This file is part of »bacterio-plankton:code«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:code« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:code« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:code«. If not, see . + */ +/* +This file is part of »bacterio-plankton:code«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:code« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:code« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:code«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var code; + (function (code) { + /** + * @author fenris + */ + function inverse_encode(decode, to) { + return decode(to); + } + code.inverse_encode = inverse_encode; + /** + * @author fenris + */ + function inverse_decode(encode, from) { + return encode(from); + } + code.inverse_decode = inverse_decode; + })(code = lib_plankton.code || (lib_plankton.code = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:code«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:code« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:code« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:code«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var code; + (function (code) { + /** + * @author fenris + */ + var class_code_inverse = /** @class */ (function () { + /** + * @author fenris + */ + function class_code_inverse(subject) { + this.subject = subject; + } + /** + * @implementation + * @author fenris + */ + class_code_inverse.prototype.encode = function (to) { + var _this = this; + return code.inverse_encode(function (x) { return _this.subject.decode(x); }, to); + }; + /** + * @implementation + * @author fenris + */ + class_code_inverse.prototype.decode = function (from) { + var _this = this; + return code.inverse_decode(function (x) { return _this.subject.encode(x); }, from); + }; + return class_code_inverse; + }()); + code.class_code_inverse = class_code_inverse; + })(code = lib_plankton.code || (lib_plankton.code = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:code«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:code« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:code« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:code«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var code; + (function (code) { + /** + * @author fenris + */ + function pair_encode(encode_first, encode_second, from) { + var between = encode_first(from); + var to = encode_second(between); + return to; + } + code.pair_encode = pair_encode; + /** + * @author fenris + */ + function pair_decode(decode_first, decode_second, to) { + var between = decode_second(to); + var from = decode_first(between); + return from; + } + code.pair_decode = pair_decode; + })(code = lib_plankton.code || (lib_plankton.code = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:code«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:code« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:code« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:code«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var code; + (function (code) { + /** + * @author fenris + */ + var class_code_pair = /** @class */ (function () { + /** + * @author fenris + */ + function class_code_pair(first, second) { + this.first = first; + this.second = second; + } + /** + * @implementation + * @author fenris + */ + class_code_pair.prototype.encode = function (from) { + var _this = this; + return code.pair_encode(function (x) { return _this.first.encode(x); }, function (x) { return _this.second.encode(x); }, from); + }; + /** + * @implementation + * @author fenris + */ + class_code_pair.prototype.decode = function (to) { + var _this = this; + return code.pair_decode(function (x) { return _this.first.decode(x); }, function (x) { return _this.second.decode(x); }, to); + }; + return class_code_pair; + }()); + code.class_code_pair = class_code_pair; + })(code = lib_plankton.code || (lib_plankton.code = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:code«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:code« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:code« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:code«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var code; + (function (code) { + /** + * @author fenris + */ + function chain_encode(encode_links, from) { + var value = from; + encode_links + .forEach(function (link) { + value = link(value); + }); + return value; + } + code.chain_encode = chain_encode; + /** + * @author fenris + */ + function chain_decode(decode_links, to) { + var value = to; + decode_links + .reverse() + .forEach(function (link) { + value = link(value); + }); + return value; + } + code.chain_decode = chain_decode; + })(code = lib_plankton.code || (lib_plankton.code = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:code«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:code« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:code« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:code«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var code; + (function (code) { + /** + * @author fenris + */ + var class_code_chain = /** @class */ (function () { + /** + * @author fenris + */ + function class_code_chain(links) { + this.links = links; + } + /** + * @implementation + * @author fenris + */ + class_code_chain.prototype.encode = function (from) { + return code.chain_encode(this.links.map(function (link) { return (function (x) { return link.encode(x); }); }), from); + }; + /** + * @implementation + * @author fenris + */ + class_code_chain.prototype.decode = function (to) { + return code.chain_decode(this.links.map(function (link) { return (function (x) { return link.decode(x); }); }), to); + }; + return class_code_chain; + }()); + code.class_code_chain = class_code_chain; + })(code = lib_plankton.code || (lib_plankton.code = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:code«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:code« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:code« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:code«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var code; + (function (code) { + /** + * @author Christian Fraß + */ + function flatten_encode(from, keys) { + if (keys === void 0) { keys = null; } + if (keys === null) { + if (from.length > 0) { + keys = Object.keys(from[0]); + } + else { + throw (new Error("encoding impossible")); + } + } + return { + "keys": keys, + "data": from.map(function (line) { return keys.map(function (name) { return line[name]; }); }) + }; + } + code.flatten_encode = flatten_encode; + /** + * @author Christian Fraß + */ + function flatten_decode(to) { + return (to.data + .map(function (dataset) { + var dataset_ = {}; + dataset + .forEach(function (value, index) { + var name = to.keys[index]; + dataset_[name] = value; + }); + return dataset_; + })); + } + code.flatten_decode = flatten_decode; + })(code = lib_plankton.code || (lib_plankton.code = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:code«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:code« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:code« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:code«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var code; + (function (code) { + /** + * @author fenris + */ + var class_code_flatten = /** @class */ (function () { + /** + * @author fenris + */ + function class_code_flatten() { + } + /** + * @implementation + * @author fenris + */ + class_code_flatten.prototype.encode = function (x) { + return code.flatten_encode(x); + }; + /** + * @implementation + * @author fenris + */ + class_code_flatten.prototype.decode = function (x) { + return code.flatten_decode(x); + }; + return class_code_flatten; + }()); + code.class_code_flatten = class_code_flatten; + })(code = lib_plankton.code || (lib_plankton.code = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:www_form«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:www_form« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:www_form« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:www_form«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var www_form; + (function (www_form) { + /** + * @author fenris + */ + function encode(source) { + return (Object.entries(source) + .map(function (_a) { + var key = _a[0], value = _a[1]; + return (key + "=" + encodeURIComponent(value)); + }) + .join("&")); + } + www_form.encode = encode; + /** + * @author fenris + */ + function decode(target) { + return (Object.fromEntries(target.split("&") + .map(function (part) { + var components = part.split("="); + var key = components[0]; + var value = decodeURIComponent(components.slice(1).join("=")); + return [key, value]; + }))); + } + www_form.decode = decode; + })(www_form = lib_plankton.www_form || (lib_plankton.www_form = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:www_form«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:www_form« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:www_form« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:www_form«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var www_form; + (function (www_form) { + /** + * @author fenris + */ + var class_www_form = /** @class */ (function () { + /** + * @author fenris + */ + function class_www_form() { + } + /** + * @implementation + * @author fenris + */ + class_www_form.prototype.encode = function (source) { + return www_form.encode(source); + }; + /** + * @implementation + * @author fenris + */ + class_www_form.prototype.decode = function (target) { + return www_form.decode(target); + }; + return class_www_form; + }()); + www_form.class_www_form = class_www_form; + })(www_form = lib_plankton.www_form || (lib_plankton.www_form = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:url«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:url« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:url« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:url«. If not, see . + */ +/* +This file is part of »bacterio-plankton:url«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:url« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:url« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:url«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var url; + (function (url_1) { + /** + * @author fenris + */ + function encode(url) { + let result = ""; + // scheme + { + if (url.scheme !== null) { + result += (url.scheme + ":"); + } + } + // host + { + if (url.host !== null) { + result += "//"; + // username + { + if (url.username !== null) { + result += url.username; + // password + { + if (url.password !== null) { + result += (":" + url.password); + } + } + result += "@"; + } + } + result += url.host; + } + } + // port + { + if (url.port !== null) { + result += (":" + url.port.toString()); + } + } + // path + { + if (url.path !== null) { + result += url.path; + } + } + // query + { + if (url.query !== null) { + result += ("?" + encodeURI(url.query)); + } + } + // hash + { + if (url.hash !== null) { + result += ("#" + url.hash); + } + } + return result; + } + url_1.encode = encode; + /** + * @author fenris + * @todo arguments + */ + function decode(url_raw) { + const builtin_url = new URL(url_raw); + return { + "scheme": builtin_url.protocol.slice(0, -1), + "host": builtin_url.hostname, + "username": ((builtin_url.username !== "") + ? + builtin_url.username + : + null), + "password": ((builtin_url.password !== "") + ? + builtin_url.password + : + null), + "port": ((builtin_url.port !== "") + ? + parseInt(builtin_url.port) + : + null), + "path": builtin_url.pathname, + "query": builtin_url.search.slice(1), + "hash": ((builtin_url.hash !== "") + ? + builtin_url.hash.slice(1) + : + null), + }; + } + url_1.decode = decode; + /** + * @author fenris + */ + function implementation_code() { + return { + "encode": encode, + "decode": decode, + }; + } + url_1.implementation_code = implementation_code; + })(url = lib_plankton.url || (lib_plankton.url = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:url«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:url« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:url« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:url«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var url; + (function (url) { + /** + * @author fenris + */ + class class_url { + /** + * @author fenris + */ + constructor() { + } + /** + * @implementation + * @author fenris + */ + encode(x) { + return url.encode(x); + } + /** + * @implementation + * @author fenris + */ + decode(x) { + return url.decode(x); + } + } + url.class_url = class_url; + })(url = lib_plankton.url || (lib_plankton.url = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:random«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:random« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:random« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:random«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var random; + (function (random) { + /** + * @author fenris + */ + function sequence(n) { + return ((n <= 0) ? [] : sequence(n - 1).concat([n - 1])); + } + /** + * @author fenris + */ + function interpolate(x, y, t) { + return (((1 - t) * x) + (t * y)); + } + /** + * @author fenris + */ + var _statestack = [ + { + "builtin": true, + "seed": Date.now() + }, + ]; + /** + * @author fenris + */ + function state_get() { + return _statestack[_statestack.length - 1]; + } + /** + * @author fenris + */ + function state_push(state) { + _statestack.push(state); + } + random.state_push = state_push; + /** + * @author fenris + */ + function state_pop() { + if (_statestack.length <= 1) { + throw (new Error("no state to pop")); + } + else { + return _statestack.pop(); + } + } + random.state_pop = state_pop; + /** + * @author fenris + */ + function seed_tick() { + var state = state_get(); + state.seed = ((state.seed << 8) % 99767); + } + /** + * @author fenris + */ + function seed_get(tick) { + if (tick === void 0) { tick = true; } + if (tick) { + seed_tick(); + } + else { + // do nothing + } + return state_get().seed; + } + /** + * returns a random floating point number in the interval [0,1[ + * + * @author fenris + */ + function generate_unit() { + if (state_get().builtin) { + return Math.random(); + } + else { + return ((Math.sin(seed_get() << 8) + 1) / 2); + } + } + random.generate_unit = generate_unit; + /** + * returns a random boolean value + * + * @param {float} [probability] the probability for the return-value "true"; default: 0.5 + * @author fenris + */ + function generate_boolean(options) { + if (options === void 0) { options = {}; } + options = lib_plankton.base.object_merge({ + "probability": 0.5 + }, options); + return (generate_unit() < options.probability); + } + random.generate_boolean = generate_boolean; + /** + * returns a random integer number in the interval [a,b] + * + * @param {int} [minimum] the left side of the halfopen interval (i.e. the smallest included value in the range) + * @param {int} [minimum] the right side of the halfopen interval (i.e. the smallest excluded value in the range) + * @author fenris + */ + function generate_integer(options) { + if (options === void 0) { options = {}; } + options = lib_plankton.base.object_merge({ + "minimum": 0, + "maximum": ((1 << 16) - 1) + }, options); + return Math.floor(interpolate(options.minimum, options.maximum + 1, generate_unit())); + } + random.generate_integer = generate_integer; + random.generate_int = generate_integer; + /** + * returns a random floating point number in the given interval + * + * @author fenris + */ + function generate_float(options) { + if (options === void 0) { options = {}; } + options = lib_plankton.base.object_merge({ + "minimum": 0.0, + "maximum": 1.0 + }, options); + return interpolate(options.minimum, options.maximum, generate_unit()); + } + random.generate_float = generate_float; + /** + * returns a random date + * + * @author fenris + */ + function generate_date(options) { + if (options === void 0) { options = {}; } + options = lib_plankton.base.object_merge({ + "minimum": new Date(0), + "maximum": new Date(Date.now()) + }, options); + return (new Date(generate_integer({ + "minimum": options.minimum.getTime(), + "maximum": options.maximum.getTime() + }))); + } + random.generate_date = generate_date; + /** + * @author fenris + */ + function generate_hexdigit() { + return (this.generate_integer({ "minimum": 0, "maximum": 15 }).toString(16).toUpperCase()); + } + random.generate_hexdigit = generate_hexdigit; + /** + * generates a random string with an optional prefix + * + * @author fenris + */ + function generate_string(options) { + if (options === void 0) { options = {}; } + options = lib_plankton.base.object_merge({ + "length": 8 + }, options); + return (sequence(options.length) + .map(function (x) { return generate_integer({ "minimum": 65, "maximum": 90 }); }) + .map(function (x) { return String.fromCharCode(x); }) + .join("") + .toLowerCase()); + } + random.generate_string = generate_string; + /** + * chooses a value randomly from a list of values with weights (a higher weight means a higher probability to be chosen) + * + * @author fenris + */ + function choose_weighted(sets) { + var sum = sets.reduce(function (sum, set_) { return (sum + set_.weight); }, 0); + if (sum === 0) { + throw (new Error("weights sum up to zero; are all zero or are negative weights included?")); + } + else { + var position_1 = generate_unit(); + return (sets.reduce(function (current, set_) { + var next = { "index": null, "value": null }; + next.index = (current.index + (set_.weight / sum)); + next.value = (((current.index <= position_1) && (position_1 < next.index)) + ? set_.value + : current.value); + return next; + }, { "index": 0, "value": null }).value); + } + } + random.choose_weighted = choose_weighted; + /** + * chooses a value randomly from a list of values with equal probabilities + * + * @author fenris + */ + function choose_uniformly(values) { + return (choose_weighted(values.map(function (value) { return ({ "weight": 1, "value": value }); }))); + } + random.choose_uniformly = choose_uniformly; + /** + * @author fenris + */ + function shuffle(list) { + var list_ = []; + list.forEach(function (element) { + var index = generate_integer({ "minimum": 0, "maximum": list_.length }); + list_.splice(index, 0, element); + }); + return list_; + } + random.shuffle = shuffle; + /** + * @author fenris + */ + function generate_vowel() { + return (choose_weighted([ + { "weight": 1.0, "value": "u" }, + { "weight": 4.0, "value": "o" }, + { "weight": 6.0, "value": "a" }, + { "weight": 4.0, "value": "e" }, + { "weight": 1.0, "value": "i" }, + ])); + } + random.generate_vowel = generate_vowel; + /** + * @author fenris + */ + function generate_halfvowel() { + return (choose_weighted([ + { "weight": 4.0, "value": "y" }, + { "weight": 1.0, "value": "w" }, + ])); + } + random.generate_halfvowel = generate_halfvowel; + /** + * @author fenris + */ + function generate_consonant() { + return (choose_weighted([ + { "weight": 5.0, "value": "l" }, + { "weight": 5.0, "value": "m" }, + { "weight": 5.0, "value": "n" }, + { "weight": 4.0, "value": "b" }, + { "weight": 4.0, "value": "p" }, + { "weight": 4.0, "value": "d" }, + { "weight": 2.0, "value": "dj" }, + { "weight": 4.0, "value": "t" }, + { "weight": 2.0, "value": "tc" }, + { "weight": 4.0, "value": "g" }, + { "weight": 4.0, "value": "k" }, + { "weight": 3.0, "value": "v" }, + { "weight": 3.0, "value": "f" }, + { "weight": 3.0, "value": "z" }, + { "weight": 3.0, "value": "s" }, + { "weight": 3.0, "value": "j" }, + { "weight": 3.0, "value": "c" }, + { "weight": 2.0, "value": "r" }, + { "weight": 1.0, "value": "h" }, + { "weight": 1.0, "value": "x" }, + ])); + } + random.generate_consonant = generate_consonant; + /** + * @author fenris + */ + function generate_letter() { + return choose_uniformly([ + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + ]); + } + random.generate_letter = generate_letter; + /** + * @author fenris + */ + function generate_syllable() { + return (generate_consonant() + + + generate_vowel() + + + (generate_boolean({ "probability": 1 / 8 }) + ? generate_halfvowel() + : "") + + + (generate_boolean({ "probability": 1 / 4 }) + ? generate_consonant() + : "")); + } + random.generate_syllable = generate_syllable; + /** + * @author fenris + */ + function generate_word(options) { + if (options === void 0) { options = {}; } + options = lib_plankton.base.object_merge({ + "syllable_count_minimum": 2, + "syllable_count_maximum": 5 + }, options); + return (sequence(generate_integer({ + "minimum": options.syllable_count_minimum, + "maximum": options.syllable_count_maximum + })) + .map(function (x) { return generate_syllable(); }) + .join("")); + } + random.generate_word = generate_word; + /** + * @author fenris + */ + function generate_text(options) { + if (options === void 0) { options = {}; } + options = lib_plankton.base.object_merge({ + "word_count": generate_integer({ "minimum": 20, "maximum": 80 }) + }, options); + return sequence(options.word_count).map(function (x) { return generate_word(); }).join(" "); + } + random.generate_text = generate_text; + /** + * @author fenris + */ + function generate_city() { + var str = ( + // prefix + (generate_boolean({ "probability": 0.25 }) + ? choose_uniformly([ + "unter", + "ober", + "mittel", + "groß", + "klein", + "neu", + "alt", + ]) + : "") + + + // infix + choose_uniformly([ + "stein", + "frei", + "berns", + "kirch", + "fels", + "weiden", + "buchen", + "eichen", + "eiben", + "linden", + "ulmen", + "birken", + "eschen", + "erlen", + "grün", + "kreuz", + "wald", + "reichen", + "lieben", + "schön", + "heinrichs", + "friedrichs", + "johann", + "walters", + "günthers", + "rupperts", + "wilhems", + "albert", + ]) + + + // suffix + choose_uniformly([ + "feld", + "thal", + "berg", + "burg", + "stadt", + "dorf", + "heim", + "bach", + "au", + "rode", + "ing", + "nitz", + "hausen", + ])); + return (str[0].toUpperCase() + str.substring(1)); + } + random.generate_city = generate_city; + /** + * @author fenris + */ + function generate_street() { + var str = ( + // prefix + choose_uniformly([ + "haupt", + "neben", + "bahnhof", + "markt", + "augustus", + "wilhelm", + "albert", + "friedrich", + "maximilian", + "wagner", + "linden", + "eichen", + "buchen", + "tannen", + "pappel", + "ulmen", + "eschen", + ]) + + + // core + choose_uniformly([ + "straße", + "weg", + "allee", + "pfad", + "hain", + "anger", + "passage", + "platz", + ]) + + + // number + (" " + generate_integer({ "minimum": 1, "maximum": 80 }).toString())); + return (str[0].toUpperCase() + str.substring(1)); + } + random.generate_street = generate_street; + /** + * @author fenris + */ + function generate_guid(options) { + if (options === void 0) { options = {}; } + options = lib_plankton.base.object_merge({ + "with_braces": false + }, options); + /* + return ( + [8,4,4,4,12] + .map(length => sequence(length).map(_ => this.generate_hexdigit()).join("")) + .join("-") + ); + */ + var guid = ("xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(new RegExp("[xy]", "g"), function (symbol) { + var r = generate_integer({ "minimum": 0, "maximum": 15 }); + var v = ((symbol == "y") ? ((r & 0x3) | 0x8) : r); + return (v.toString(16).toUpperCase()); + })); + return (options.with_braces + ? ("{" + guid + "}") + : guid); + } + random.generate_guid = generate_guid; + /** + * @author fenris + */ + function generate_domain(options) { + if (options === void 0) { options = {}; } + options = lib_plankton.base.object_merge({ + "steps": 3 + }, options); + return (sequence(generate_integer({ "minimum": 1, "maximum": options.steps })) + .map(function () { return generate_word(); }) + // tld + .concat(sequence(generate_integer({ "minimum": 2, "maximum": 3 })) + .map(function () { return generate_letter(); }) + .join(""))).join("."); + } + /** + * @author fenris + */ + function generate_url() { + return (lib_plankton.url.encode({ + "scheme": choose_uniformly([ + "http", + "https", + "git", + "smb", + "ftp", + ]), + "host": generate_domain(), + "username": null, + "password": null, + "port": generate_integer({ "minimum": 20, "maximum": 99999 }), + "path": ("/" + + + (sequence(generate_integer({ "minimum": 0, "maximum": 3 })) + .map(function () { return generate_word(); }) + .join("/"))), + "query": choose_uniformly([ + null, + lib_plankton.www_form.encode(Object.fromEntries(sequence(generate_integer({ "minimum": 0, "maximum": 3 })) + .map(function () { return ([ + generate_word(), + generate_integer().toFixed(0), + ]); }))), + ]), + "hash": null + })); + } + random.generate_url = generate_url; + /** + * @author fenris + */ + function generate_email_address() { + return ( + // user + generate_word() + + + "@" + + + generate_domain({ "steps": 1 })); + } + random.generate_email_address = generate_email_address; + /** + * @author fenris + */ + function generate_telephone_number() { + return ( + // country prefix + ("+" + + + generate_integer({ "minimum": 1, "maximum": 999 }).toFixed(0)) + + + " " + + + // provider + +(sequence(3) + .map(function () { return generate_integer({ "minimum": 0, "maximum": 9 }); }) + .join("")) + + + " " + + + // custom + +(sequence(7) + .map(function () { return generate_integer({ "minimum": 0, "maximum": 9 }); }) + .join(""))); + } + random.generate_telephone_number = generate_telephone_number; + /** + * @author fenris + */ + function generate_time() { + return { + "hour": generate_integer({ "minimum": 0, "maximum": 23 }), + "minute": generate_integer({ "minimum": 0, "maximum": 59 }), + "second": generate_integer({ "minimum": 0, "maximum": 59 }) + }; + } + random.generate_time = generate_time; + /** + * @author fenris + * @deprecated + * @todo remove + */ + function generate_for_shape(shape) { + throw (new Error("deprecated! use lib_shape!")); + } + random.generate_for_shape = generate_for_shape; + /** + * @author fenris + */ + /* + export function generate_for_shape_( + shape : lib_plankton.shape.type_shape + ) : any + { + switch (shape.name) { + case "boolean": { + return generate_boolean(); + break; + } + case "int": { + const min = shape.parameters["min"]; + const max = shape.parameters["max"]; + return generate_integer( + { + "minimum": ((min == null) ? undefined : min), + "maximum": ((max == null) ? undefined : max), + } + ); + break; + } + case "float": { + return generate_float( + { + "minimum": shape.parameters["min"], + "maximum": shape.parameters["max"], + } + ); + break; + } + case "string": { + return generate_string(); + break; + } + case "url": { + return generate_url(); + break; + } + case "email": { + return generate_email_address(); + break; + } + case "time": { + return generate_time(); + break; + } + case "array": { + return ( + sequence(generate_integer({"minimum": 2, "maximum": 5})) + .map(() => generate_for_shape_(shape.parameters["shape_element"])) + ); + break; + } + case "object": { + return Object.fromEntries( + shape.parameters["fields"] + .map( + field => ([ + field["name"], + generate_for_shape_(field["shape"]), + ]) + ) + ); + break; + } + case "date": { + return generate_date(); + break; + } + case "enumeration": { + return choose_uniformly(shape.parameters["options"])["value"]; + break; + } + default: { + const message : string = `unhandled shape kind '${shape.name}'`; + // console.warn(message); + // return null; + throw (new Error(message)); + break; + } + } + } + */ + })(random = lib_plankton.random || (lib_plankton.random = {})); +})(lib_plankton || (lib_plankton = {})); +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +/* +This file is part of »bacterio-plankton:storage«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:session« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:session« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:storage«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var session; + (function (session_1) { + /** + */ + var _conf = null; + /** + */ + function check_conf() { + if (_conf === null) { + throw (new Error("session system not set up yet")); + } + else { + // do nothing + } + } + /** + */ + function begin(name, options) { + if (options === void 0) { options = {}; } + return __awaiter(this, void 0, void 0, function () { + var key, attempts, session_old, error_1, session_2, session_raw; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + options = Object.assign({ + "lifetime": _conf.default_lifetime, + "data": null + }, options); + check_conf(); + key = null; + attempts = 0; + _a.label = 1; + case 1: + if (!true) return [3 /*break*/, 6]; + attempts += 1; + key = lib_plankton.call.convey(_conf.key_length, [ + function (x) { return (new Array(x)).fill(null); }, + function (x) { return x.map(function () { return lib_plankton.random.generate_hexdigit(); }); }, + function (x) { return x.join(""); }, + ]); + session_old = null; + _a.label = 2; + case 2: + _a.trys.push([2, 4, , 5]); + return [4 /*yield*/, _conf.data_chest.read(key)]; + case 3: + session_old = _a.sent(); + return [3 /*break*/, 5]; + case 4: + error_1 = _a.sent(); + session_old = null; + return [3 /*break*/, 5]; + case 5: + if (session_old !== null) { + key = null; + if (attempts >= _conf.key_max_attempts) { + // fail + return [3 /*break*/, 6]; + } + else { + // retry + } + } + else { + // suuccess + return [3 /*break*/, 6]; + } + return [3 /*break*/, 1]; + case 6: + if (!(key === null)) return [3 /*break*/, 7]; + throw (new Error("failed to generate unique session key")); + case 7: + session_2 = { + "key": key, + "name": name, + "expiry": (lib_plankton.base.get_current_timestamp() + options.lifetime), + "data": options.data + }; + session_raw = { + "key": session_2.key, + "name": session_2.name, + "expiry": Math.floor(session_2.expiry), + "data": JSON.stringify(session_2.data) + }; + lib_plankton.call.timeout(function () { + lib_plankton.log.info("session_dropping_due_to_being_expired", { + "key": key, + "name": name, + "lifetime": options.lifetime + }); + end(key); + }, options.lifetime); + return [4 /*yield*/, _conf.data_chest.write(key, session_raw)]; + case 8: + _a.sent(); + return [2 /*return*/, Promise.resolve(key)]; + } + }); + }); + } + session_1.begin = begin; + /** + */ + function get(key) { + check_conf(); + return (_conf.data_chest.read(key) + .then(function (session_raw) { + var session = { + "key": session_raw["key"], + "name": session_raw["name"], + "expiry": session_raw["expiry"], + "data": JSON.parse(session_raw["data"]) + }; + var now = lib_plankton.base.get_current_timestamp(); + if (now > session.expiry) { + lib_plankton.log.info("session_dropping_due_to_being_stale", { + "key": session.key, + "name": session.name + }); + end(key); + return Promise.reject(); + } + else { + return Promise.resolve(session); + } + })); + } + session_1.get = get; + /** + */ + function end(key) { + check_conf(); + return _conf.data_chest["delete"](key); + } + session_1.end = end; + /** + */ + function setup(options) { + if (options === void 0) { options = {}; } + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + options = Object.assign({ + "key_length": 16, + "key_max_attempts": 3, + "default_lifetime": 900, + "data_chest": lib_plankton.storage.memory.implementation_chest({}), + "clear": false + }, options); + _conf = { + "key_length": options.key_length, + "key_max_attempts": options.key_max_attempts, + "default_lifetime": options.default_lifetime, + "data_chest": options.data_chest + }; + if (!options.clear) return [3 /*break*/, 2]; + return [4 /*yield*/, _conf.data_chest.clear()]; + case 1: + _a.sent(); + return [3 /*break*/, 2]; + case 2: return [2 /*return*/, Promise.resolve(undefined)]; + } + }); + }); + } + session_1.setup = setup; + })(session = lib_plankton.session || (lib_plankton.session = {})); +})(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:file«. @@ -1584,86 +8455,137 @@ var lib_plankton; (function (lib_plankton) { var file; (function (file) { + /** + * @author fenris + */ + function exists(path) { + var nm_fs = require("fs"); + return (new Promise(function (resolve, reject) { + nm_fs.stat(path, function (error, stats) { + if (error) { + resolve(false); + } + else { + resolve(true); + } + }); + })); + } + file.exists = exists; /** * @author fenris */ function read(path) { - return (fetch("/" + path) - .then(function (result) { return result.text(); })); + var nm_fs = require("fs"); + return (new Promise(function (resolve, reject) { + nm_fs.readFile(path, { + "encoding": "utf8", + "flag": "r" + }, function (error, content) { + if (error == null) { + resolve(content); + } + else { + reject(error); + } + }); + })); } file.read = read; /** * @author fenris */ - function write(path, content) { - return Promise.reject(new Error("not implemented / not possible")); + function read_buffer(path) { + var nm_fs = require("fs"); + return (new Promise(function (resolve, reject) { + nm_fs.readFile(path, { + "flag": "r" + }, function (error, content) { + if (error == null) { + resolve(content); + } + else { + reject(error); + } + }); + })); + } + file.read_buffer = read_buffer; + /** + * @author fenris + */ + function read_stdin() { + return (new Promise(function (resolve, reject) { + var input_raw = ""; + process.stdin.setEncoding("utf8"); + process.stdin.on("readable", function () { + var chunk; + while ((chunk = process.stdin.read()) !== null) { + input_raw += chunk; + } + }); + process.stdin.on("end", function () { + resolve(input_raw); + }); + })); + } + file.read_stdin = read_stdin; + /** + * @author fenris + */ + function write(path, content, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "encoding": "utf-8" + }, options); + var nm_fs = require("fs"); + return (new Promise(function (resolve, reject) { + nm_fs.writeFile(path, content, { + "encoding": options.encoding, + "flag": "w" + }, function (error) { + if (error == null) { + resolve(undefined); + } + else { + reject(error); + } + }); + })); } file.write = write; /** * @author fenris */ - function blob_read_text(blob) { - return (lib_plankton.call.promise_make(function (resolve, reject) { - var reader = (new FileReader()); - reader.addEventListener("load", function (event) { - resolve((reader.result)); + function write_buffer(path, content, options) { + if (options === void 0) { options = {}; } + options = Object.assign({}, options); + var nm_fs = require("fs"); + return (new Promise(function (resolve, reject) { + nm_fs.writeFile(path, content, { + "flag": "w" + }, function (error) { + if (error == null) { + resolve(undefined); + } + else { + reject(error); + } }); - reader.addEventListener("error", function (event) { - reject(new Error("reading file failed")); - }); - reader.addEventListener("abort", function (event) { - reject(new Error("reading file aborted")); - }); - reader.readAsText(blob); })); } - file.blob_read_text = blob_read_text; + file.write_buffer = write_buffer; /** - * @author fenris */ - function blob_read_arraybuffer(blob) { - return (lib_plankton.call.promise_make(function (resolve, reject) { - var reader = (new FileReader()); - reader.addEventListener("load", function (event) { - resolve((reader.result)); + function delete_(path) { + var nm_fs = require("fs"); + return (new Promise(function (resolve, reject) { + nm_fs.unlink(path, function () { + resolve(undefined); }); - reader.addEventListener("error", function (event) { - reject(new Error("reading file failed")); - }); - reader.addEventListener("abort", function (event) { - reject(new Error("reading file aborted")); - }); - reader.readAsArrayBuffer(blob); })); } - file.blob_read_arraybuffer = blob_read_arraybuffer; - /** - * @author fenris - */ - function blob_read_dataurl(blob) { - return (lib_plankton.call.promise_make(function (resolve, reject) { - var reader = new FileReader(); - reader.addEventListener("load", function (event) { - resolve((reader.result)); - }); - reader.addEventListener("error", function (event) { - reject(new Error("reading file failed")); - }); - reader.addEventListener("abort", function (event) { - reject(new Error("reading file aborted")); - }); - reader.readAsDataURL(blob); - })); - } - file.blob_read_dataurl = blob_read_dataurl; - /** - * @author fenris - */ - function blob_write_text(text) { - var blob = (new Blob([text], { "type": "text/plain" })); - return lib_plankton.call.promise_resolve(blob); - } - file.blob_write_text = blob_write_text; + file.delete_ = delete_; })(file = lib_plankton.file || (lib_plankton.file = {})); })(lib_plankton || (lib_plankton = {})); /* @@ -4002,448 +10924,6 @@ var lib_plankton; })(structures = lib_plankton.structures || (lib_plankton.structures = {})); })(lib_plankton || (lib_plankton = {})); /* -This file is part of »bacterio-plankton:code«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:code« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:code« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:code«. If not, see . - */ -/* -This file is part of »bacterio-plankton:code«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:code« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:code« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:code«. If not, see . - */ -/* -This file is part of »bacterio-plankton:code«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:code« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:code« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:code«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var code; - (function (code) { - /** - * @author fenris - */ - function inverse_encode(decode, to) { - return decode(to); - } - code.inverse_encode = inverse_encode; - /** - * @author fenris - */ - function inverse_decode(encode, from) { - return encode(from); - } - code.inverse_decode = inverse_decode; - })(code = lib_plankton.code || (lib_plankton.code = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:code«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:code« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:code« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:code«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var code; - (function (code) { - /** - * @author fenris - */ - var class_code_inverse = /** @class */ (function () { - /** - * @author fenris - */ - function class_code_inverse(subject) { - this.subject = subject; - } - /** - * @implementation - * @author fenris - */ - class_code_inverse.prototype.encode = function (to) { - var _this = this; - return code.inverse_encode(function (x) { return _this.subject.decode(x); }, to); - }; - /** - * @implementation - * @author fenris - */ - class_code_inverse.prototype.decode = function (from) { - var _this = this; - return code.inverse_decode(function (x) { return _this.subject.encode(x); }, from); - }; - return class_code_inverse; - }()); - code.class_code_inverse = class_code_inverse; - })(code = lib_plankton.code || (lib_plankton.code = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:code«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:code« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:code« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:code«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var code; - (function (code) { - /** - * @author fenris - */ - function pair_encode(encode_first, encode_second, from) { - var between = encode_first(from); - var to = encode_second(between); - return to; - } - code.pair_encode = pair_encode; - /** - * @author fenris - */ - function pair_decode(decode_first, decode_second, to) { - var between = decode_second(to); - var from = decode_first(between); - return from; - } - code.pair_decode = pair_decode; - })(code = lib_plankton.code || (lib_plankton.code = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:code«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:code« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:code« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:code«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var code; - (function (code) { - /** - * @author fenris - */ - var class_code_pair = /** @class */ (function () { - /** - * @author fenris - */ - function class_code_pair(first, second) { - this.first = first; - this.second = second; - } - /** - * @implementation - * @author fenris - */ - class_code_pair.prototype.encode = function (from) { - var _this = this; - return code.pair_encode(function (x) { return _this.first.encode(x); }, function (x) { return _this.second.encode(x); }, from); - }; - /** - * @implementation - * @author fenris - */ - class_code_pair.prototype.decode = function (to) { - var _this = this; - return code.pair_decode(function (x) { return _this.first.decode(x); }, function (x) { return _this.second.decode(x); }, to); - }; - return class_code_pair; - }()); - code.class_code_pair = class_code_pair; - })(code = lib_plankton.code || (lib_plankton.code = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:code«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:code« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:code« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:code«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var code; - (function (code) { - /** - * @author fenris - */ - function chain_encode(encode_links, from) { - var value = from; - encode_links - .forEach(function (link) { - value = link(value); - }); - return value; - } - code.chain_encode = chain_encode; - /** - * @author fenris - */ - function chain_decode(decode_links, to) { - var value = to; - decode_links - .reverse() - .forEach(function (link) { - value = link(value); - }); - return value; - } - code.chain_decode = chain_decode; - })(code = lib_plankton.code || (lib_plankton.code = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:code«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:code« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:code« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:code«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var code; - (function (code) { - /** - * @author fenris - */ - var class_code_chain = /** @class */ (function () { - /** - * @author fenris - */ - function class_code_chain(links) { - this.links = links; - } - /** - * @implementation - * @author fenris - */ - class_code_chain.prototype.encode = function (from) { - return code.chain_encode(this.links.map(function (link) { return (function (x) { return link.encode(x); }); }), from); - }; - /** - * @implementation - * @author fenris - */ - class_code_chain.prototype.decode = function (to) { - return code.chain_decode(this.links.map(function (link) { return (function (x) { return link.decode(x); }); }), to); - }; - return class_code_chain; - }()); - code.class_code_chain = class_code_chain; - })(code = lib_plankton.code || (lib_plankton.code = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:code«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:code« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:code« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:code«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var code; - (function (code) { - /** - * @author Christian Fraß - */ - function flatten_encode(from, keys) { - if (keys === void 0) { keys = null; } - if (keys === null) { - if (from.length > 0) { - keys = Object.keys(from[0]); - } - else { - throw (new Error("encoding impossible")); - } - } - return { - "keys": keys, - "data": from.map(function (line) { return keys.map(function (name) { return line[name]; }); }) - }; - } - code.flatten_encode = flatten_encode; - /** - * @author Christian Fraß - */ - function flatten_decode(to) { - return (to.data - .map(function (dataset) { - var dataset_ = {}; - dataset - .forEach(function (value, index) { - var name = to.keys[index]; - dataset_[name] = value; - }); - return dataset_; - })); - } - code.flatten_decode = flatten_decode; - })(code = lib_plankton.code || (lib_plankton.code = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:code«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:code« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:code« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:code«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var code; - (function (code) { - /** - * @author fenris - */ - var class_code_flatten = /** @class */ (function () { - /** - * @author fenris - */ - function class_code_flatten() { - } - /** - * @implementation - * @author fenris - */ - class_code_flatten.prototype.encode = function (x) { - return code.flatten_encode(x); - }; - /** - * @implementation - * @author fenris - */ - class_code_flatten.prototype.decode = function (x) { - return code.flatten_decode(x); - }; - return class_code_flatten; - }()); - code.class_code_flatten = class_code_flatten; - })(code = lib_plankton.code || (lib_plankton.code = {})); -})(lib_plankton || (lib_plankton = {})); -/* This file is part of »bacterio-plankton:json«. Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' @@ -4545,4028 +11025,6 @@ var lib_plankton; json.class_json = class_json; })(json = lib_plankton.json || (lib_plankton.json = {})); })(lib_plankton || (lib_plankton = {})); -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __generator = (this && this.__generator) || function (thisArg, body) { - var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; - function verb(n) { return function (v) { return step([n, v]); }; } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); - while (g && (g = 0, op[0] && (_ = 0)), _) try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [op[0] & 2, t.value]; - switch (op[0]) { - case 0: case 1: t = op; break; - case 4: _.label++; return { value: op[1], done: false }; - case 5: _.label++; y = op[1]; op = [0]; continue; - case 7: op = _.ops.pop(); _.trys.pop(); continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } - if (t[2]) _.ops.pop(); - _.trys.pop(); continue; - } - op = body.call(thisArg, _); - } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; - } -}; -/* -This file is part of »bacterio-plankton:email«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 = {})); -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - if (typeof b !== "function" && b !== null) - throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -/* -This file is part of »bacterio-plankton:log«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 enum_level; - (function (enum_level) { - enum_level[enum_level["debug"] = 0] = "debug"; - enum_level[enum_level["info"] = 1] = "info"; - enum_level[enum_level["notice"] = 2] = "notice"; - enum_level[enum_level["warning"] = 3] = "warning"; - enum_level[enum_level["error"] = 4] = "error"; - })(enum_level = log.enum_level || (log.enum_level = {})); - ; - /** - */ - function level_order(level1, level2) { - return (level1 <= level2); - } - log.level_order = level_order; - /** - */ - function level_show(level) { - switch (level) { - case enum_level.debug: return "debug"; - case enum_level.info: return "info"; - case enum_level.notice: return "notice"; - case enum_level.warning: return "warning"; - case enum_level.error: return "error"; - default: return "(unknown)"; - } - } - log.level_show = level_show; - })(log = lib_plankton.log || (lib_plankton.log = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:log«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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-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 class_channel = /** @class */ (function () { - function class_channel() { - } - return class_channel; - }()); - log.class_channel = class_channel; - })(log = lib_plankton.log || (lib_plankton.log = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:log«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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-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) { - /** - * decorator for filtering out log entries below a certain level threshold - */ - var class_channel_minlevel = /** @class */ (function (_super) { - __extends(class_channel_minlevel, _super); - /** - */ - function class_channel_minlevel(core, threshold) { - var _this = _super.call(this) || this; - _this.core = core; - _this.threshold = threshold; - return _this; - } - /** - */ - class_channel_minlevel.prototype.add = function (entry) { - if (!log.level_order(this.threshold, entry.level)) { - // do nothing - } - else { - this.core.add(entry); - } - }; - return class_channel_minlevel; - }(log.class_channel)); - log.class_channel_minlevel = class_channel_minlevel; - })(log = lib_plankton.log || (lib_plankton.log = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:log«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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) { - return { - "debug": log.enum_level.debug, - "info": log.enum_level.info, - "notice": log.enum_level.notice, - "warning": log.enum_level.warning, - "error": log.enum_level.error - }[level_string]; - } - /** - */ - function channel_make(description) { - var _a; - 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 = 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_stack = null; - /** - * pushes a new configuration on the stack and activates it - */ - function conf_push(channels) { - if (_channel_stack === null) { - _channel_stack = []; - } - _channel_stack.push(channels); - } - log.conf_push = conf_push; - /** - * pops the current active configuration from the stack - */ - function conf_pop() { - if (_channel_stack.length > 0) { - _channel_stack.pop(); - } - else { - // do nothing - } - } - log.conf_pop = conf_pop; - /** - * makes the logging system ready - */ - function setup() { - if (_channel_stack === null) { - _channel_stack = []; - conf_push(log.conf_default()); - } - else { - // do nothing - } - } - /** - * consumes a log entry, i.e. sends it to the currently active outputs - */ - function add(entry) { - setup(); - _channel_stack.slice(-1)[0].forEach(function (channel) { return channel.add(entry); }); - } - log.add = add; - /** - */ - function debug(incident, details) { - if (details === void 0) { details = {}; } - add({ "level": log.enum_level.debug, "incident": incident, "details": details }); - } - log.debug = debug; - /** - */ - function info(incident, details) { - if (details === void 0) { details = {}; } - add({ "level": log.enum_level.info, "incident": incident, "details": details }); - } - log.info = info; - /** - */ - function notice(incident, details) { - if (details === void 0) { details = {}; } - add({ "level": log.enum_level.notice, "incident": incident, "details": details }); - } - log.notice = notice; - /** - */ - function warning(incident, details) { - if (details === void 0) { details = {}; } - add({ "level": log.enum_level.warning, "incident": incident, "details": details }); - } - log.warning = warning; - /** - */ - function error(incident, details) { - if (details === void 0) { details = {}; } - add({ "level": log.enum_level.error, "incident": incident, "details": details }); - } - log.error = error; - })(log = lib_plankton.log || (lib_plankton.log = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:log«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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) { - /** - */ - log.conf_push([ - log.channel_make({ - "kind": "console", - "data": { - "threshold": "info" - } - }), - ]); - })(log = lib_plankton.log || (lib_plankton.log = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:args«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:args« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:args« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:args«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var args; - (function (args) { - /** - */ - var enum_environment; - (function (enum_environment) { - enum_environment["cli"] = "cli"; - enum_environment["url"] = "url"; - })(enum_environment = args.enum_environment || (args.enum_environment = {})); - ; - /** - */ - var enum_kind; - (function (enum_kind) { - enum_kind["positional"] = "positional"; - enum_kind["volatile"] = "volatile"; - })(enum_kind = args.enum_kind || (args.enum_kind = {})); - ; - /** - */ - var enum_type; - (function (enum_type) { - enum_type["boolean"] = "boolean"; - enum_type["integer"] = "int"; - enum_type["float"] = "float"; - enum_type["string"] = "string"; - })(enum_type = args.enum_type || (args.enum_type = {})); - ; - /** - */ - var enum_mode; - (function (enum_mode) { - enum_mode["replace"] = "replace"; - enum_mode["accumulate"] = "accumulate"; - })(enum_mode = args.enum_mode || (args.enum_mode = {})); - ; - })(args = lib_plankton.args || (lib_plankton.args = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:args«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:args« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:args« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:args«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var args; - (function (args) { - /* - export enum_mode { - replace = "replace", - accumulate = "accumulate", - }; - */ - /** - * @author fenris - */ - var class_argument = /** @class */ (function () { - /** - * @author fenris - */ - function class_argument(_a) { - var name = _a["name"], _b = _a["type"], type = _b === void 0 ? args.enum_type.string : _b, _c = _a["kind"], kind = _c === void 0 ? args.enum_kind.positional : _c, _d = _a["mode"], mode = _d === void 0 ? args.enum_mode.replace : _d, _e = _a["default"], default_ = _e === void 0 ? null : _e, _f = _a["info"], info = _f === void 0 ? null : _f, _g = _a["parameters"], parameters = _g === void 0 ? {} : _g, _h = _a["hidden"], hidden = _h === void 0 ? false : _h; - this.name = name; - this.type = type; - this.kind = kind; - this.mode = mode; - this.default_ = default_; - this.info = info; - this.parameters = parameters; - this.hidden = hidden; - if (!this.check()) { - throw (new Error("invalid argument-setup")); - } - } - /** - * @author fenris - */ - class_argument.positional = function (_a) { - var name = _a["name"], _b = _a["type"], type = _b === void 0 ? args.enum_type.string : _b, _c = _a["mode"], mode = _c === void 0 ? args.enum_mode.replace : _c, _d = _a["default"], default_ = _d === void 0 ? null : _d, _e = _a["info"], info = _e === void 0 ? null : _e, _f = _a["hidden"], hidden = _f === void 0 ? false : _f, index = _a["index"]; - return (new class_argument({ - "name": name, - "kind": args.enum_kind.positional, - "type": type, - "mode": mode, - "default": default_, - "info": info, - "hidden": hidden, - "parameters": { - "index": index - } - })); - }; - /** - * @author fenris - */ - class_argument.volatile = function (_a) { - var name = _a["name"], _b = _a["type"], type = _b === void 0 ? args.enum_type.string : _b, _c = _a["mode"], mode = _c === void 0 ? args.enum_mode.replace : _c, _d = _a["default"], default_ = _d === void 0 ? null : _d, _e = _a["info"], info = _e === void 0 ? null : _e, _f = _a["hidden"], hidden = _f === void 0 ? false : _f, indicators_short = _a["indicators_short"], indicators_long = _a["indicators_long"]; - return (new class_argument({ - "name": name, - "kind": args.enum_kind.volatile, - "type": type, - "mode": mode, - "default": default_, - "info": info, - "hidden": hidden, - "parameters": { - "indicators_short": indicators_short, - "indicators_long": indicators_long - } - })); - }; - /** - * @author fenris - */ - class_argument.prototype.check = function () { - var _this = this; - return [ - function () { return ((!(_this.kind == args.enum_kind.volatile)) - || - (("indicators_long" in _this.parameters) - && - (_this.parameters["indicators_long"]["length"] >= 0))); }, - ].every(function (condition) { return condition(); }); - }; - /** - * @author fenris - */ - class_argument.prototype.name_get = function () { - return this.name; - }; - /** - * @author fenris - */ - class_argument.prototype.kind_get = function () { - return this.kind; - }; - /** - * @author fenris - */ - class_argument.prototype.type_get = function () { - return this.type; - }; - /** - * @author fenris - */ - class_argument.prototype.mode_get = function () { - return this.mode; - }; - /** - * @author fenris - */ - class_argument.prototype.default_get = function () { - return this.default_; - }; - /** - * @author fenris - */ - class_argument.prototype.parameters_get = function () { - return this.parameters; - }; - /** - * @author fenris - */ - class_argument.prototype.hidden_get = function () { - return this.hidden; - }; - /** - * @author fenris - */ - class_argument.prototype.toString = function () { - return "<".concat(this.name, ">"); - }; - /** - * @author fenris - */ - class_argument.prototype.indicator_main = function () { - if (this.kind === args.enum_kind.volatile) { - return this.parameters["indicators_long"][0]; - } - else { - return null; - } - }; - /** - * @author fenris - */ - class_argument.prototype.pattern_value = function () { - switch (this.type) { - case args.enum_type.boolean: { - return "false|true"; - break; - } - case args.enum_type.integer: { - return "[0-9]+"; - break; - } - case args.enum_type.float: { - return "\\d*(?:\\.\\d+)?"; - break; - } - case args.enum_type.string: { - return "\\S+"; - break; - } - default: { - throw (new Error("unhandled type ".concat(this.type))); - break; - } - } - }; - /** - * @author fenris - */ - class_argument.prototype.extract = function (raw) { - switch (this.type) { - case args.enum_type.boolean: { - return (raw != "false"); - break; - } - case args.enum_type.integer: { - return parseInt(raw); - break; - } - case args.enum_type.float: { - return parseFloat(raw); - break; - } - case args.enum_type.string: { - return raw; - break; - } - default: { - throw (new Error("unhandled type ".concat(this.type))); - break; - } - } - }; - /** - * @author fenris - */ - class_argument.prototype.assign = function (data, target, raw) { - var value = this.extract(raw); - switch (this.mode) { - case args.enum_mode.replace: { - data[target] = value; - break; - } - case args.enum_mode.accumulate: { - /* - if (! (this.name in data)) { - data[this.name] = []; - } - */ - data[target].push(value); - break; - } - default: { - throw (new Error("unhandled mode ".concat(this.mode))); - } - } - }; - /** - * @author fenris - */ - class_argument.prototype.make = function (data, target) { - var value = data[target]; - return value.toString(); - }; - /** - * @author fenris - */ - class_argument.prototype.generate_help = function () { - var _this = this; - var _a, _b, _c, _d; - var output = ""; - { - switch (this.kind) { - case args.enum_kind.positional: { - var line = ""; - line += "\t"; - line += "<".concat(this.name, ">"); - line += "\n"; - output += line; - } - case args.enum_kind.volatile: { - var line = ""; - line += "\t"; - if (this.type === args.enum_type.boolean) { - line += ([] - .concat(((_a = this.parameters["indicators_short"]) !== null && _a !== void 0 ? _a : []).map(function (indicator) { return ("-" + indicator); })) - .concat(((_b = this.parameters["indicators_long"]) !== null && _b !== void 0 ? _b : []).map(function (indicator) { return ("--" + indicator); })) - .join(" | ")); - } - else { - line += ([] - .concat(((_c = this.parameters["indicators_short"]) !== null && _c !== void 0 ? _c : []).map(function (indicator) { return ("-" + indicator + " " + ("<" + _this.name + ">")); })) - .concat(((_d = this.parameters["indicators_long"]) !== null && _d !== void 0 ? _d : []).map(function (indicator) { return ("--" + indicator + "=" + ("<" + _this.name + ">")); })) - .join(" | ")); - } - line += "\n"; - output += line; - } - } - } - { - var line = ""; - line += "\t\t"; - var infotext = ((this.info == null) ? "(no info available)" : this.info); - line += infotext; - if ((this.type != "boolean") && (this.default_ != null)) { - line += "; default: ".concat(this.default_.toString()); - } - line += "\n"; - output += line; - } - return output; - }; - return class_argument; - }()); - args.class_argument = class_argument; - })(args = lib_plankton.args || (lib_plankton.args = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:args«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:args« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:args« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:args«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var args; - (function (args) { - /** - * @author fenris - */ - var settings = { - "environment": { - "cli": { - "symbols": { - "delimiter": " ", - "prefix": "--", - "assignment": "=" - } - }, - "url": { - "symbols": { - "delimiter": "&", - "prefix": "", - "assignment": "=" - } - } - } - }; - /** - * @author fenris - */ - args.verbosity = 0; - /** - * @author fenris - * @todo check validity - */ - var class_handler = /** @class */ (function () { - /** - * @author fenris - */ - function class_handler(arguments_) { - this.arguments_ = arguments_; - } - /** - * @author fenris - */ - class_handler.prototype.filter = function (kind) { - var arguments_ = {}; - for (var _i = 0, _a = Object.entries(this.arguments_); _i < _a.length; _i++) { - var _b = _a[_i], name = _b[0], argument = _b[1]; - if (argument.kind_get() == kind) { - arguments_[name] = argument; - } - } - return arguments_; - }; - /** - * @author fenris - */ - class_handler.prototype.read = function (environment, input, data) { - var _this = this; - if (data === void 0) { data = {}; } - switch (environment) { - case args.enum_environment.cli: - case args.enum_environment.url: { - // default values - { - for (var _i = 0, _a = Object.entries(this.arguments_); _i < _a.length; _i++) { - var _b = _a[_i], name = _b[0], argument = _b[1]; - data[name] = argument.default_get(); - } - } - // preprocessing - { - // short indicators (lil hacky ...) - { - if (environment == args.enum_environment.cli) { - for (var _c = 0, _d = Object.entries(this.filter(args.enum_kind.volatile)); _c < _d.length; _c++) { - var _e = _d[_c], name = _e[0], argument = _e[1]; - // console.info(argument.parameters_get()["indicators_short"].join("|")); - var pattern_from = ""; - { - pattern_from += "(?:^|".concat(settings["environment"][environment]["symbols"]["delimiter"], ")"); - pattern_from += "-".concat(argument.parameters_get()["indicators_short"].join("|")); - pattern_from += "(?:$|".concat(settings["environment"][environment]["symbols"]["delimiter"], ")"); - } - var pattern_to = ""; - { - pattern_to += settings["environment"][environment]["symbols"]["delimiter"]; - pattern_to += settings["environment"][environment]["symbols"]["prefix"]; - pattern_to += argument.indicator_main(); - if (argument.type_get() == args.enum_type.boolean) { - pattern_to += settings["environment"][environment]["symbols"]["delimiter"]; - } - else { - pattern_to += settings["environment"][environment]["symbols"]["assignment"]; - } - } - var result = input.replace(new RegExp(pattern_from, "g"), pattern_to); - lib_plankton.log.debug("lib_args:read:replacing", { - "pattern_from": pattern_from, - "pattern_to": pattern_to, - "input": input, - "result": result - }); - input = result; - } - } - } - lib_plankton.log.debug("lib_args:read:current_input", { - "input": input - }); - } - // parsing - { - var parts = input - .split(settings["environment"][environment]["symbols"]["delimiter"]) - .filter(function (x) { return (x != ""); }); - var index_expected_1 = 0; - parts.forEach(function (part) { - lib_plankton.log.debug("lib_args:read:analyzing", { - "part": part - }); - var found = [ - function () { - lib_plankton.log.debug("lib_args:read:probing_as_volatile", { - "part": part - }); - for (var _i = 0, _a = Object.entries(_this.filter(args.enum_kind.volatile)); _i < _a.length; _i++) { - var _b = _a[_i], name = _b[0], argument = _b[1]; - lib_plankton.log.debug("lib_args:read:probing_as_volatile:trying", { - "part": part, - "argument": argument.toString() - }); - var pattern = ""; - { - var pattern_front = ""; - pattern_front += "".concat(settings["environment"][environment]["symbols"]["prefix"]); - pattern_front += "(?:".concat(argument.parameters_get()["indicators_long"].join("|"), ")"); - pattern += pattern_front; - } - { - var pattern_back = ""; - pattern_back += "".concat(settings["environment"][environment]["symbols"]["assignment"]); - pattern_back += "(".concat(argument.pattern_value(), ")"); - if (argument.type_get() == args.enum_type.boolean) { - pattern_back = "(?:".concat(pattern_back, ")?"); - } - pattern += pattern_back; - } - lib_plankton.log.debug("lib_args:read:probing_as_volatile:pattern", { - "pattern": pattern - }); - var regexp = new RegExp(pattern); - var matching = regexp.exec(part); - lib_plankton.log.debug("lib_args:read:probing_as_volatile:matching", { - "matching": matching - }); - if (matching == null) { - // do nothing - } - else { - argument.assign(data, name, matching[1]); - return true; - } - } - return false; - }, - function () { - lib_plankton.log.debug("lib_args:read:probing_as_positional", { - "part": part - }); - var positional = _this.filter(args.enum_kind.positional); - for (var _i = 0, _a = Object.entries(positional); _i < _a.length; _i++) { - var _b = _a[_i], name = _b[0], argument = _b[1]; - if (argument.parameters_get()['index'] !== index_expected_1) { - // do nothing - } - else { - lib_plankton.log.debug("lib_args:read:probing_as_positional:trying", { - "part": part, - "argument": argument.toString() - }); - var pattern = ""; - { - var pattern_back = ""; - pattern_back += "(".concat(argument.pattern_value(), ")"); - pattern += pattern_back; - } - lib_plankton.log.debug("lib_args:read:probing_as_positional:pattern", { - "pattern": pattern - }); - var regexp = new RegExp(pattern); - var matching = regexp.exec(part); - lib_plankton.log.debug("lib_args:read:probing_as_positional:matching", { - "matching": matching - }); - if (matching == null) { - return false; - } - else { - argument.assign(data, name, matching[1]); - index_expected_1 += 1; - return true; - } - } - } - return false; - }, - ].some(function (x) { return x(); }); - if (!found) { - lib_plankton.log.warning("lib_args:read:could_not_parse", { - "part": part - }); - } - }); - } - return data; - break; - } - default: { - throw (new Error("unhandled environment ".concat(environment))); - break; - } - } - }; - /** - * @author fenris - * @todo handle if the data object doesn't have the required field or the type is wrong or sth. - */ - class_handler.prototype.write = function (environment, data) { - switch (environment) { - case args.enum_environment.cli: { - return (([] - .concat(Object.entries(this.filter(args.enum_kind.volatile)).map(function (_a) { - var name = _a[0], argument = _a[1]; - var values; - switch (argument.mode_get()) { - case args.enum_mode.replace: { - values = [data[argument.name_get()]]; - break; - } - case args.enum_mode.accumulate: { - values = data[argument.name_get()]; - break; - } - } - return (values - .map(function (value) { return ((settings["environment"][environment]["symbols"]["prefix"] - + - argument.parameters_get()["indicators_long"][0]) - + - (settings["environment"][environment]["symbols"]["assignment"] - + - value.toString())); }) - .join(" ")); - })) - .concat(Object.entries(this.filter(args.enum_kind.positional)).map(function (_a) { - var name = _a[0], argument = _a[1]; - var raw = ""; - { - var raw_back = ""; - raw_back += argument.make(data, name); - raw += raw_back; - } - return raw; - }))) - .join(settings["environment"][environment]["symbols"]["delimiter"])); - break; - } - default: { - throw (new Error("unhandled environment ".concat(environment))); - break; - } - } - }; - /** - * @desc manpage-like info-sheet - * @author fenris - */ - class_handler.prototype.generate_help = function (_a) { - var _b = _a["programname"], programname = _b === void 0 ? null : _b, _c = _a["author"], author = _c === void 0 ? null : _c, _d = _a["description"], description = _d === void 0 ? null : _d, _e = _a["executable"], executable = _e === void 0 ? null : _e; - var environment = args.enum_environment.cli; - var output = ""; - { - var section = ""; - { - var line = ""; - line += ""; - line += "INFO"; - line += "\n"; - section += line; - } - { - var line = ""; - line += "\t"; - line += "".concat(programname, " -- ").concat(description); - line += "\n"; - section += line; - } - section += "\n"; - output += section; - } - { - if (author != null) { - var section = ""; - { - var line = ""; - line += ""; - line += "AUTHOR"; - line += "\n"; - section += line; - } - { - var line = ""; - line += "\t"; - line += "".concat(author); - line += "\n"; - section += line; - } - section += "\n"; - output += section; - } - } - { - var section = ""; - { - var line = ""; - line += ""; - line += "SYNOPSIS"; - line += "\n"; - section += line; - } - { - var line = ""; - line += "\t"; - line += executable; - line += settings["environment"][environment]["symbols"]["delimiter"]; - line += Object.entries(this.filter(args.enum_kind.positional)) - .map(function (_a) { - var name = _a[0], argument = _a[1]; - var part = ""; - part += "<".concat(argument.name_get(), ">"); - return part; - }) - .join(settings["environment"][environment]["symbols"]["delimiter"]); - line += settings["environment"][environment]["symbols"]["delimiter"]; - line += Object.entries(this.filter(args.enum_kind.volatile)) - .filter(function (_a) { - var name = _a[0], argument = _a[1]; - return (!argument.hidden_get()); - }) - .map(function (_a) { - var name = _a[0], argument = _a[1]; - var part = ""; - // part += settings["environment"][environment]["symbols"]["prefix"]; - part += "-"; - part += argument.parameters_get()["indicators_short"][0]; - if (argument.type_get() != "boolean") { - /* - part += settings["environment"][environment]["symbols"]["assignment"]; - part += `<${argument.name_get()}>`; - */ - part += " "; - part += "<".concat(argument.name_get(), ">"); - } - part = "[".concat(part, "]"); - return part; - }) - .join(settings["environment"][environment]["symbols"]["delimiter"]); - line += "\n"; - section += line; - } - section += "\n"; - output += section; - } - { - var section = ""; - { - var line = ""; - line += ""; - line += "OPTIONS"; - line += "\n"; - section += line; - } - { - section += (Object.entries(this.arguments_) - .filter(function (_a) { - var name = _a[0], argument = _a[1]; - return (!argument.hidden_get()); - }) - .map(function (_a) { - var name = _a[0], argument = _a[1]; - return argument.generate_help(); - }) - .join("\n")); - } - section += "\n"; - output += section; - } - return output; - }; - return class_handler; - }()); - args.class_handler = class_handler; - })(args = lib_plankton.args || (lib_plankton.args = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:string«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:string« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:string« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:string«. If not, see . - */ -var plain_text_to_html = function (text) { - let ret = text; - ret = ret.replace(/ /g, "  "); // convert multiple whitespace to forced ones - ret = ret.split("\n").join("
"); - return ret; -}; -/** - * @desc makes a valid - */ -var format_sentence = function (str, rtl = false, caseSense = true) { - if (str === "") { - return str; - } - else { - let marks = { - ".": true, - "?": true, - "!": true - }; - let default_mark = "."; - let ret = str.split(""); - if (!rtl) { - ret[0] = ret[0].toLocaleUpperCase(); - if (!(ret[ret.length - 1] in marks)) { - ret.push(default_mark); - } - } - else { - ret[ret.length - 1] = ret[ret.length - 1].toLocaleUpperCase(); - if (!(ret[0] in marks)) { - ret.unshift(default_mark); - } - } - return ret.join(""); - } -}; -var fill_string_template = function (template_string, object, fabric = function (object, key) { return object[key]; }, delimiter = "%", default_string = null, sloppy) { - function get_tags(str) { - let r = new RegExp(delimiter + "[^\\s^" + delimiter + "]+" + delimiter, "gi"); - return ((str.match(r) || []).map(function (e) { - return e.slice(delimiter.length, e.length - delimiter.length); - })); - } - function replace_tag(str, tag, value) { - let r = new RegExp(delimiter + tag + delimiter, "gi"); - return str.replace(r, value); - } - function replace_tags(str, obj) { - return (get_tags(str).reduce(function (ret, key) { - let value = ""; - try { - value = fabric(obj, key); - if ((!sloppy && (value === void 0)) || (sloppy && (value == void 0))) { - value = default_string; - } - } - catch (e) { - console.warn("invalid placeholder " + key); - value = default_string; - } - return replace_tag(ret, key, value); - }, str)); - } - return replace_tags(template_string, object); -}; -var make_string_template = function (_template, _fabrics = {}) { - function replace_tag(str, tag, value) { - var r = new RegExp("%" + tag + "%", "gi"); - return str.replace(r, value); - } - function replace_tags(str, obj) { - return (Object.keys(obj).reduce(function (ret, key) { - return replace_tag(ret, key, _fabrics[key] || obj[key]); - }, str)); - } - return (function (tags) { - return replace_tags(_template, tags); - }); -}; -var make_eml_header = (function () { - let _template = ""; - _template += "From: %from%\n"; - _template += "To: %recipient%\n"; - _template += "Subject: %subject%\n"; - _template += "X-Mailer: greenscale-plankton.emlgen\n"; - return make_string_template(_template); -})(); -var make_eml_body = (function () { - let exports = {}; - exports["simple_body"] = make_string_template("Content-Type: %contenttype%\n\n%body%\n\n"); - // very basic implementation - // parts = [{contenttype:"text/html; charset=UTF-8", body: "

foo

" }, {...}] - exports["body_boundrary"] = function (parts, boundrary) { - let _template = ""; - _template += "--%boundrary%\n"; - _template += "Content-Type: %contenttype%\n\n%body%\n\n"; - //_template += "--%boundrary%--\n\n"; - let maker = make_string_template(_template); - return (parts.reduce(function (prev, curr) { - curr.boundrary = boundrary; - return [prev, maker(curr)].join(""); - }, "")); - }; - // body must be base64 encoded! - exports["attachment_boundrary"] = function (parts, boundrary) { - let _template = ""; - _template += "--%boundrary%\n"; - _template += "Content-Type: %contenttype%\n"; - _template += "Content-Transfer-Encoding: base64\n"; - _template += "Content-Disposition: %disposition%; filename=\"%name%\"\n\n"; - _template += "%body%\n\n"; - //_template += "--%boundrary%--\n\n"; - let maker = make_string_template(_template); - return (parts.reduce(function (prev, curr) { - curr.boundrary = boundrary; - if (curr.disposition === void 0) - curr.disposition = "inline"; - return [prev, maker(curr)].join(""); - }, "")); - }; - exports["gen_boundrary"] = function () { - return ("xxxxxxxxxxxxxxxxxxxxxx".replace(/[xy]/g, function (c) { - let r = crypto.getRandomValues(new Uint8Array(1))[0] % 16 | 0, v = c == "x" ? r : (r & 0x3 | 0x8); - return v.toString(16); - })); - }; - // simple implementation without alternatives (old rfc) - exports["complete_boundrary"] = function (bodyparts, attachments) { - let ret = ""; - let boundrary = exports["gen_boundrary"](); - ret += exports["body_boundrary"](bodyparts, boundrary); - ret += exports["attachment_boundrary"](attachments, boundrary); - ret += "--" + boundrary + "--\n\nINVISIBLE!!!!"; - return (exports["simple_body"]({ - "contenttype": sprintf("multipart/mixed; boundary=%s", [boundrary]), - "body": ret - })); - }; - return exports; -})(); -/* -This file is part of »bacterio-plankton:string«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:string« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:string« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:string«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var string; - (function (string) { - /** - * @author fenris - */ - const hexdigits = 4; - /** - * @author fenris - */ - const index_max = (1 << (4 * hexdigits)); - /** - * @author fenris - */ - var index_is = 0; - /** - * @author neuc,frac - */ - function empty(str) { - return (str.trim() === ""); - } - string.empty = empty; - /** - * @desc returns a unique string - * @param {string} prefix an optional prefix for the generated string - * @return {string} - * @author fenris - */ - function generate(prefix = "string_") { - if (index_is > index_max) { - throw (new Error("[string_generate] out of valid indices")); - } - else { - return string.sprintf(prefix + "%0" + hexdigits.toString() + "X", [index_is++]); - } - } - string.generate = generate; - /** - * @author fenris - */ - function join(parts, glue = " ") { - if (parts.length == 0) { - return ""; - } - else { - return parts.join(glue); - } - } - string.join = join; - /** - * @desc splits a string, but returns an empty list, if the string is empty - * @param {string} chain - * @param {string} separator - * @return {Array} - * @author fenris - */ - function split(chain, separator = " ") { - if (chain.length == 0) { - return []; - } - else { - return chain.split(separator); - } - } - string.split = split; - /** - * @author neu3no - */ - function explode(str, needle, max) { - let temp = str.split(needle); - const right = temp.splice(max - 1); - temp.push(right.join(needle)); - return temp; - } - string.explode = explode; - /** - * @desc concats a given word with itself n times - * @param {string} word - * @param {int} - * @return {string} - * @author fenris - */ - function repeat(word, count) { - // return ((count == 0) ? "" : (word + repeat(word, count-1))); - let result = ""; - for (let n = 0; n < count; n += 1) { - result += word; - } - return result; - } - string.repeat = repeat; - /** - * @desc lengthens a string by repeatedly appending or prepending another string - * @param {string} word the string to pad - * @param {int} length the length, which the result shall have - * @param {string} symbol the string, which will be added (multiple times) - * @param {boolean} [prepend]; whether to prepend (~true) or append (~false); default: false - * @return {string} the padded string - * @author fenris - */ - function pad(word, length, symbol = " ", mode = "append") { - switch (mode) { - case "prepend": { - // insert symbols only at the beginning - while (word.length < length) - word = symbol + word; - return word.substring(word.length - length); - break; - } - case "append": { - // insert symbols only at the end - while (word.length < length) - word = word + symbol; - return word.substring(0, length); - break; - } - case "widen": { - // insert symbols at both sides - let left = (((length - word.length) & 1) === 0); - while (word.length < length) { - word = (left - ? (symbol + word) - : (word + symbol)); - left = (!left); - } - return word.substring(0, length); - break; - } - default: { - const message = ("unhandled mode '" + mode + "'"); - console.warn(message); - return word; - break; - } - } - } - string.pad = pad; - /** - * @desc checks if a given string conttains a certain substring - * @param {string} string - * @param {string} part - * @return {boolean} - * @author fenris - */ - function contains(chain, part) { - if (typeof (chain) !== "string") { - return false; - } - return (chain.indexOf(part) >= 0); - } - string.contains = contains; - /** - * @desc checks if a given string starts with a certain substring - * @param {string} string - * @param {string} part - * @return {boolean} - * @author fenris - */ - function startsWith(chain, part) { - if (typeof (chain) !== "string") { - return false; - } - // return (string.indexOf(part) === 0); - return ((function (m, n) { - if (n === 0) { - return true; - } - else { - if (m === 0) { - return false; - } - else { - return ((chain[0] == part[0]) - && - startsWith(chain.substring(1), part.substring(1))); - } - } - })(chain.length, part.length)); - } - string.startsWith = startsWith; - /** - * @desc checks if a given string ends with a certain substring - * @param {string} string - * @param {string} part - * @return {boolean} - * @author fenris - */ - function endsWith(chain, part) { - if (typeof (chain) !== "string") { - return false; - } - // return (string.lastIndexOf(part) === string.length-part.length); - return ((function (m, n) { - if (n === 0) { - return true; - } - else { - if (m === 0) { - return false; - } - else { - // console.info(("(" + string[m-1] + " == " + part[n-1] + ")") + " = " + String(string[m-1] == part[n-1])); - return ((chain[m - 1] === part[n - 1]) - && - endsWith(chain.substring(0, m - 1), part.substring(0, n - 1))); - } - } - })(chain.length, part.length)); - } - string.endsWith = endsWith; - /** - * @desc count the occourrences of a string in a string - * @param string haystack_string the string wich should be examined - * @param string needle_string the string which should be counted - * @author neuc - */ - function count_occourrences(haystack_string, needle_string, check_escape) { - let cnt = 0; - let pos = -1; - do { - pos = haystack_string.indexOf(needle_string, pos + 1); - if ((!check_escape) || (haystack_string[pos - 1] != "\\")) { - cnt++; - } - } while (pos >= 0); - return (cnt - 1); - } - string.count_occourrences = count_occourrences; - /** - * @author fenris - */ - function replace(str, replacements, options = {}) { - options = Object.assign({}, options); - let result = str; - replacements.forEach(replacement => { - lib_plankton.log.debug("lib_plankton.string.replace", { - "from": replacement.from, - "to": replacement.to, - }); - result = result.replace(new RegExp(replacement.from, "g"), replacement.to); - }); - return result; - } - string.replace = replace; - /** - * @desc replaces occurences of "{{name}}" in a string by the corresponding values of an argument object - * @author fenris - */ - function coin(str, args, options = {}) { - options = Object.assign({ - "legacy": false, - "open": "{{", - "close": "}}", - }, options); - Object.keys(args).forEach((key) => { - // old syntax - { - if (options.legacy) { - const value = args[key]; - const regexp_argument = new RegExp("\\${" + key + "}", "g"); - lib_plankton.log.debug("lib_plankton.string.coin", { - "key": key, - "regex": regexp_argument.toString(), - "value": value, - }); - str = str.replace(regexp_argument, value); - } - } - // new syntax - { - const value = args[key]; - const regexp_argument = new RegExp(options.open + key + options.close, "g"); - lib_plankton.log.debug("lib_plankton.string.coin", { - "key": key, - "regex": regexp_argument.toString(), - "value": value, - }); - str = str.replace(regexp_argument, value); - } - }); - return str; - } - string.coin = coin; - /** - * @author fenris - * @deprecated use limit - */ - function cut(str, length, delimiter = "…") { - if (str.length <= length) { - return str; - } - else { - return (str.slice(0, length - delimiter.length) + delimiter); - } - } - string.cut = cut; - /** - */ - function limit(str, options = {}) { - options = Object.assign({ - "length": 120, - "indicator": "…", - }, options); - return ((str.length <= options.length) - ? str - : (str.slice(0, options.length - options.indicator.length) + options.indicator)); - } - string.limit = limit; - /** - */ - function slice(str, size) { - let slices = []; - let rest = str; - while (rest.length > 0) { - slices.push(rest.slice(0, size)); - rest = rest.slice(size); - } - return slices; - } - string.slice = slice; - })(string = lib_plankton.string || (lib_plankton.string = {})); -})(lib_plankton || (lib_plankton = {})); -/** - * @deprecated - */ -var lib_string; -(function (lib_string) { - lib_string.empty = lib_plankton.string.empty; - lib_string.generate = lib_plankton.string.generate; - lib_string.split = lib_plankton.string.split; - lib_string.explode = lib_plankton.string.repeat; - lib_string.repeat = lib_plankton.string.repeat; - lib_string.pad = lib_plankton.string.pad; - lib_string.contains = lib_plankton.string.contains; - lib_string.startsWith = lib_plankton.string.startsWith; - lib_string.endsWith = lib_plankton.string.endsWith; - lib_string.count_occourrences = lib_plankton.string.count_occourrences; - lib_string.coin = lib_plankton.string.coin; - lib_string.stance = lib_plankton.string.coin; - lib_string.cut = lib_plankton.string.cut; -})(lib_string || (lib_string = {})); -/* -This file is part of »bacterio-plankton:string«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:string« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:string« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:string«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var string; - (function (string) { - var pattern = /%([-+#0 ]*)([0-9]*)[\.]{0,1}([0-9]*)([\w]{1})/; - var gpattern = /%([-+#0 ]*)([0-9]*)[\.]{0,1}([0-9]*)([\w]{1})/g; - function split_format(format) { - var tmp = format.match(pattern); - if (tmp === null) - return null; - return { - 'flags': tmp[1].split(""), - 'width': Number(tmp[2]), - 'precision': tmp[3] === '' ? null : Number(tmp[3]), - 'specifier': tmp[4], - 'string': format - }; - } - function make_err(format, arg, should) { - return ("[sprintf]" + " " + "argument for '" + format.string + "' has to be '" + should + "' but '" + arg + "' is '" + typeof arg + "'!"); - } - function test_arg(format, arg, should) { - if (typeof arg !== should) { - console.warn(make_err(format, arg, should)); - return false; - } - return true; - } - function string_fill(str, char, len, left) { - while (str.length < len) { - if (left) { - str += char; - } - else { - str = char + str; - } - } - return str; - } - /** - * the known_parameters are used to parse the different identifiers for the welln known syntax: - * flag width precision identifier - * %{[0#+- ]}{[0-9]*}.{[0-9]*}[fFdiueEgGsoxXaAsn] - * flags: - * 0 - fill with '0' instead of ' ' if the string length < width - * # - not implemented - * - - left-justified -> fill on the right side to reach width - * + - force using '+' on positive numbers - * ' ' - add a single space before positive numbers - * - * identifiers - * %f, %F - interpret given number as float, width: the minimal total width (fill with ' ' or '0' if the - * resulting string is too short, precision: cut more then given decimal places - * %d, %i, %u - interpret number as integer, decimal places will be cut. width: like float, precision: - * fill with '0' on right side until length given in precision is reached - * %e - interpret as float and write as scientifical number, width & precision like in float - * %E - same es %e but uppercase 'E' - * %g - use the shortest string of %f or %e - * %G - use the shortest string of %E or %E - * %s - simply print a string - * %o - print the given number in octal notation - * %x - print the given number in hex notation - * %X - same as %x but with uppercase characters - * %a - alias to %x - * %A - alias to %X - * %n - just print nothing - * @type {{}} - */ - var known_params = {}; - known_params["f"] = function (format, arg) { - if (!test_arg(format, arg, "number")) - return "Ø"; - var tmp = Math.abs(arg); - var sign = (arg < 0) ? -1 : 1; - var tmp_result = null; - if (format.precision !== null) { - tmp = Math.floor(Math.pow(10, format.precision) * tmp) / Math.pow(10, format.precision); - var tmp_ = (tmp * sign).toString().split("."); - if (tmp_.length === 1) - tmp_.push(""); - tmp_[1] = string_fill(tmp_[1], "0", format.precision, true); - tmp_result = tmp_.join("."); - } - else { - tmp_result = (sign * tmp).toString(); - } - if ((format.flags.indexOf(" ") >= 0) && (arg >= 0)) { - tmp_result = " " + tmp; - } - else if ((format.flags.indexOf("+") >= 0) && (arg >= 0)) { - tmp_result = "+" + tmp; - } - tmp_result = string_fill(tmp, (format.flags.indexOf("0") >= 0) ? "0" : " ", format.width, (format.flags.indexOf("-") >= 0)); - return tmp_result; - }; - known_params["F"] = known_params["f"]; - known_params["d"] = function (format, arg) { - if (!test_arg(format, arg, 'number')) - return 'Ø'; - var tmp = (((arg < 0 && format.specifier !== 'u') ? -1 : 1) * Math.floor(Math.abs(arg))).toString(); - if ((format.specifier === 'd' || format.specifier === 'i') && format.flags.indexOf(' ') >= 0 && arg >= 0) { - tmp = ' ' + tmp; - } - else if ((format.specifier === 'd' || format.specifier === 'i') && format.flags.indexOf('+') >= 0 && arg >= 0) { - tmp = '+' + tmp; - } - tmp = string_fill(tmp, format.flags.indexOf('0') >= 0 ? '0' : ' ', format.width, format.flags.indexOf('-') >= 0); - tmp = string_fill(tmp, '0', format.precision === null ? 0 : format.precision, false); - return tmp; - }; - known_params["i"] = known_params["d"]; - known_params["u"] = known_params["d"]; - known_params["e"] = function (format, arg) { - if (!test_arg(format, arg, 'number')) - return 'Ø'; - var tmp = arg.toExponential(format.precision === null ? undefined : format.precision).toString(); - if (format.flags.indexOf(' ') >= 0 && arg >= 0) { - tmp = ' ' + tmp; - } - else if (format.flags.indexOf('+') >= 0 && arg >= 0) { - tmp = '+' + tmp; - } - tmp = string_fill(tmp, format.flags.indexOf('0') >= 0 ? '0' : ' ', format.width, format.flags.indexOf('-') >= 0); - return tmp; - }; - known_params["E"] = function (format, arg) { - return known_params["e"](format, arg).toUpperCase(); - }; - known_params["g"] = function (format, arg) { - if (!test_arg(format, arg, 'number')) - return 'Ø'; - var tmpf = known_params["f"](format, arg); - var tmpe = known_params["e"](format, arg); - if (tmpf.length < tmpe.length) { - return tmpf; - } - else { - return tmpe; - } - }; - known_params["G"] = function (format, arg) { - return known_params["g"](format, arg).toUpperCase(); - }; - known_params["s"] = function (format, arg) { - if (!test_arg(format, arg, 'string')) - return 'o.O'; - var tmp = format.precision !== null ? arg.substr(0, format.precision) : arg; - tmp = string_fill(tmp, format.flags.indexOf('0') >= 0 ? '0' : ' ', format.width, format.flags.indexOf('-') >= 0); - return tmp; - }; - known_params["o"] = function (format, arg) { - if (!test_arg(format, arg, 'number')) - return 'Ø'; - var tmp = Math.floor(Math.round(Math.abs(arg))) * ((arg < 0) ? -1 : 1); - return known_params["s"](format, tmp.toString(8)); - }; - known_params["x"] = function (format, arg) { - if (!test_arg(format, arg, 'number')) - return 'Ø'; - var tmp = Math.floor(Math.round(Math.abs(arg))) * ((arg < 0) ? -1 : 1); - return known_params["s"](format, tmp.toString(16)); - }; - known_params["a"] = known_params["x"]; - known_params["X"] = function (format, arg) { - if (!test_arg(format, arg, 'number')) - return 'Ø'; - return known_params["x"](format, arg).toUpperCase(); - }; - known_params["A"] = known_params["X"]; - known_params["c"] = function (format, arg) { - var tmp = ""; - if (typeof arg === "number") { - tmp = String.fromCharCode(arg); - } - else if ((typeof arg === "string") && (arg.length === 1)) { - tmp = arg[0]; - } - else { - console.warn(make_err(format, arg, "number|string") + " and if string it needs to have the length of 1!"); - } - return known_params["s"](format, tmp); - }; - known_params["n"] = function () { - return ""; - }; - var decompose = function (chain, regexp) { - var result = regexp.exec(chain); - if (result == null) { - return null; - } - else { - var front = chain.substring(0, result.index); - var back = chain.substring(result.index + result[0].length); - return { "front": front, "match": result[0], "back": back }; - } - }; - /** - * an implementation of c sprintf - * @param {string} string format string - * @param {array} args arguments which should be filled into - * @returns {string} - */ - string.sprintf = function (input, args = [], original = null) { - if (original == null) - original = input; - var components = decompose(input, pattern); - if (components == null) { - if (args.length > 0) { - console.warn("[sprintf] superfluous arguments while formatting '" + original + "': ", args); - } - return input; - } - else { - var arg; - var rest; - if (args.length > 0) { - arg = args[0]; - rest = args.slice(1); - } - else { - console.warn("[sprintf] out of arguments while formatting '" + original + "'"); - arg = null; - rest = []; - return input; - } - var fmt = split_format(components["match"]); - return (components["front"] - + known_params[fmt.specifier](fmt, arg) - + string.sprintf(components["back"], rest, original)); - } - }; - /** - * an implementation of c printf - * @param {string} string format string - * @param {array} args arguments which should be filled into - * @returns {string} - */ - function printf(format, args) { - console.log(string.sprintf(format, args)); - } - string.printf = printf; - })(string = lib_plankton.string || (lib_plankton.string = {})); -})(lib_plankton || (lib_plankton = {})); -var sprintf = lib_plankton.string.sprintf; -var printf = lib_plankton.string.printf; -/* -This file is part of »bacterio-plankton:string«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:string« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:string« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:string«. If not, see . - */ -var make_logger = (function () { - var _loggers = {}; - var make_logger = function (prefix, current_loglevel) { - var log = []; - var level = [ - "LOG", "INFO", "WARNING", "DEBUG" - ]; - var logger = function (obj, lvl) { - var txt = obj.txt || obj; - if (lvl == void 0) - lvl = 0; - var date = new Date(); - log.push({ - "message": sprintf("%s [%s:%s] %s", [date.toString(), level[lvl], prefix, txt]), - "timeStamp": +(date) - }); - if (lvl <= current_loglevel) { - var msg = ["[" + prefix + "]", txt]; - if (obj.arg) - msg = ["[" + prefix + "]"].concat(Array.prototype.slice.call(obj.arg)); - if (lvl === 0) - console["_log"].apply(console, msg); - else if (lvl === 1) - console["_info"].apply(console, msg); - else if (lvl === 2) - console["_warn"].apply(console, msg); - else if (lvl >= 3) - console["_log"].apply(console, msg); - } - }; - _loggers[prefix] = { - "logger": logger, - "log": log - }; - return logger; - }; - make_logger["loggers"] = _loggers; - make_logger["complete_log"] = function () { - var logs = Object.keys(_loggers) - .reduce(function (p, c) { - return [].concat(p, _loggers[c].log); - }, []); - logs.sort(function (x, y) { - return ((x.timeStamp > y.timeStamp) ? -1 : +1); - }); - return logs.map(function (x, i, a) { - return x.message; - }); - }; - if ( /*!track_exports*/true) { - var _log_all = function (log, lvl, next = function () { }) { - return function () { - var msg = []; - for (var i = 0; i < arguments.length; i++) { - if (typeof arguments[i] === "string") { - msg.push(arguments[i]); - } - else { - msg.push(JSON.stringify(arguments[i])); - } - } - var obj = { - txt: msg.join("\t"), - arg: arguments - }; - log(obj, lvl); - next(); - }; - }; - { - var __warn = make_logger("deprecated console.warn", 99); - var __error = make_logger("deprecated console.error", 99); - var __log = make_logger("deprecated console.log", 99); - var __info = make_logger("deprecated console.info", 99); - // bad ass - console["_log"] = console.log; - console["_error"] = console.error; - console["_warn"] = console.warn; - console["_info"] = console.info; - /* - console["log"] = _log_all(__log, 0); - console["error"] = _log_all(__error, 2); - console["warn"] = _log_all(__warn, 2); - console["info"] = _log_all(__info, 0); - */ - } - /* - { - make_logger["send_log"] = function(){ - eml_log( - function () { - alert("fehlerbericht wurde gesendet!"); - } - ); - }; - var error_log = make_logger("global.error", 99); - window.onerror = _log_all( - error_log, - 1, - function(){ - if (global_config == undefined) { - return false; - } - if (global_config.report_error) { - make_logger["send_log"](); - } - } - ); - } - */ - } - return make_logger; -})(); -/* -This file is part of »bacterio-plankton:complex«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:complex« 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:complex« 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:complex«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var complex; - (function (complex) { - /** - * @author fenris - */ - function _sequence(n) { - return ((n <= 0) ? [] : _sequence(n - 1).concat([n - 1])); - } - /** - * @author fenris - */ - function _coin(template, arguments_) { - if (arguments_ === void 0) { arguments_ = {}; } - var result = template; - Object.keys(arguments_).forEach(function (key) { - var pattern = ("{{" + key + "}}"); - var replacement = String(arguments_[key]); - result = result.replace(new RegExp(pattern, "g"), replacement); - }); - return result; - } - /** - * erstellt eine komplexe Zahl anhand ihrer kartesianischen Koordinaten - * - * @author fenris - */ - function make_cartesian(rea_, ima_) { - return { - "rea": rea_, - "ima": ima_ - }; - } - complex.make_cartesian = make_cartesian; - /** - * erstellt eine komplexe Zahl anhand ihrer Polar-Koordinaten - * - * @author fenris - */ - function make_polar(abs, arg) { - return (make_cartesian((abs * Math.cos(arg)), (abs * Math.sin(arg)))); - } - complex.make_polar = make_polar; - /** - * alias zu "make_cartesian" - * - * @author fenris - */ - function make(rea_, ima_) { - return (make_cartesian(rea_, ima_)); - } - complex.make = make; - /** - * erstellt die komplexe Null - * - * @author fenris - */ - function nul() { - return (make(0, 0)); - } - complex.nul = nul; - /** - * erstellt die komplexe Eins - * - * @author fenris - */ - function one() { - return (make(1, 0)); - } - complex.one = one; - /** - * gibt den Real-Teil einer komplexen Zahl zurück - * - * @author fenris - */ - function rea(x) { - return (x.rea); - } - complex.rea = rea; - /** - * gibt den Imaginär-Teil einer komplexen Zahl zurück - * - * @author fenris - */ - function ima(x) { - return (x.ima); - } - complex.ima = ima; - /** - * gibt die konjugierte komplexe Zahl zurück - * - * @author fenris - */ - function con(x) { - return (make(+x.rea, -x.ima)); - } - complex.con = con; - /** - * gibt den quadrierten Betrag einer komplexen Zahl zurück - * - * @author fenris - */ - function sqrabs(x) { - return (((x.rea * x.rea) + (x.ima * x.ima))); - } - /** - * gibt den Betrag einer komplexen Zahl zurück - * - * @author fenris - */ - function abs(x) { - return (Math.sqrt(sqrabs(x))); - } - complex.abs = abs; - /** - * gibt das Argument einer komplexen Zahl zurück (auf dem Hauptzweig des komplexen Logarithmus) - * - * @author fenris - */ - function arg(x) { - return Math.atan2(x.ima, x.rea); - } - complex.arg = arg; - /** - * gibt eine skalierte komplexe Zahl zurück (das Produkt mit einer reellen Zahl) - * - * @author fenris - */ - function scl(x, s) { - return (make((x.rea * s), (x.ima * s))); - } - complex.scl = scl; - /** - * errechnet die Summe zweier komplexer Zahl - * - * @author fenris - */ - function add(x, y) { - return (make((x.rea + y.rea), (x.ima + y.ima))); - } - complex.add = add; - /** - * gibt die additiv inverse, also negierte komplexe Zahl zurück - * - * @author fenris - */ - function neg(x) { - return (make(-x.rea, -x.ima)); - } - complex.neg = neg; - /** - * ermittelt die Differenz zweier komplexer Zahlen - * - * @author fenris - */ - function sub(x, y) { - return (add(x, neg(y))); - } - complex.sub = sub; - /** - * ermittelt das Produkt zweier komplexer Zahlen - * - * @author fenris - */ - function mul(x, y) { - return (make(((x.rea * y.rea) - (x.ima * y.ima)), ((x.rea * y.ima) + (x.ima * y.rea)))); - } - complex.mul = mul; - /** - * ermittelt die multiplikativ inverse komplexe Zahl, also den Kehrwert - * - * @author fenris - */ - function inv(x) { - var a = sqrabs(x); - if (a <= 0) { - var message = "die komplexe Null ist nicht invertiebar"; - throw (new Error(message)); - } - else { - return (scl(con(x), (1 / a))); - } - } - complex.inv = inv; - /** - * ermittelt den Quotienten zweier komplexer Zahlen - * - * @author fenris - */ - function div(x, y) { - return (mul(x, inv(y))); - } - complex.div = div; - /** - * ermittelt die natürliche Potenz einer komplexen Zahl - * - * @author fenris - */ - function npow(x, n) { - if (n < 0) { - var message = "invalid exponent"; - throw (new Error(message)); - } - else { - var y_1 = one(); - _sequence(n).forEach(function () { y_1 = mul(y_1, x); }); - return y_1; - } - } - complex.npow = npow; - /** - * ermittelt die natürliche Potenz einer komplexen Zahl - * - * @author fenris - * @deprecated use "npow" instead - * @todo remove - */ - function exp(x, n) { - return npow(x, n); - } - complex.exp = exp; - /** - * ermittelt die Potenz zweier komplexer Zahlen - * - * @author fenris - * @todo Probleme der komplexen Exponentiation berücksichtigen - */ - function pow(x, y) { - var a = abs(x); - var b = arg(x); - var c = y.rea; - var d = y.ima; - if (a === 0) { - throw (new Error("not implemented")); - } - else { - var l = Math.log(a); - return (make_polar(Math.exp((l * c) - (b * d)), ((l * d) + (b * c)))); - } - } - complex.pow = pow; - /** - * gibt die n-ten komplexen Einheits-Wurzeln zurück ({x ∈ C | x^n = 1}) - * - * @author fenris - */ - function unitroots(n) { - return (_sequence(n) - .map(function (k) { return make_polar(1, (k / (n + 0.0)) * (2 * Math.PI)); })); - } - complex.unitroots = unitroots; - /** - * {x ∈ C | x^n = y} - * - * @author fenris - */ - function normroots(n, y) { - var z = make_polar(Math.pow(abs(y), (1.0 / n)), (arg(y) / n)); - return (unitroots(n) - .map(function (w) { return mul(w, z); })); - } - complex.normroots = normroots; - /** - * ermittelt ob zwei komplexe Zahlen gleich sind - * - * @author fenris - */ - function equ(x, y, threshold) { - if (threshold === void 0) { threshold = 0.005; } - // return (abs(sub(x, y)) <= threshold); - return ((Math.abs(x.rea - y.rea) <= threshold) - && - (Math.abs(x.ima - y.ima) <= threshold)); - } - complex.equ = equ; - /** - * gibt eine textuelle Repräsentation einer komplexen Zahl zurück - * - * @author fenris - */ - function str(x) { - return _coin( - // "(({{rea}}) + ({{ima}}·i))", - "<{{rea}},{{ima}}>", { - "rea": x.rea.toFixed(4), - "ima": x.ima.toFixed(4) - }); - } - complex.str = str; - })(complex = lib_plankton.complex || (lib_plankton.complex = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:complex«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:complex« 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:complex« 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:complex«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var complex; - (function (complex) { - /** - * @author fenris - */ - var class_complex = /** @class */ (function () { - /** - * @author fenris - */ - function class_complex(subject) { - this.subject = subject; - } - /** - * @author fenris - */ - class_complex._cram = function (subject) { - return (new class_complex(subject)); - }; - /** - * @author fenris - */ - class_complex._tear = function (instance) { - return instance.subject; - }; - /** - * @author fenris - */ - class_complex.make_cartesian = function (rea, ima) { - return (class_complex._cram(complex.make_cartesian(rea, ima))); - }; - /** - * @author fenris - */ - class_complex.make_polar = function (abs, arg) { - return (class_complex._cram(complex.make_polar(abs, arg))); - }; - /** - * @author fenris - */ - class_complex.make = function (rea, ima) { - return (class_complex._cram(complex.make(rea, ima))); - }; - /** - * @author fenris - */ - class_complex.nul = function () { - return (class_complex._cram(complex.nul())); - }; - /** - * @author fenris - */ - class_complex.one = function () { - return (class_complex._cram(complex.one())); - }; - /** - * @author fenris - */ - class_complex.prototype.con = function () { - return (class_complex._cram(complex.con(class_complex._tear(this)))); - }; - /** - * @author fenris - */ - class_complex.prototype.abs = function () { - return (complex.abs(class_complex._tear(this))); - }; - /** - * @author fenris - */ - class_complex.prototype.arg = function () { - return (complex.arg(class_complex._tear(this))); - }; - /** - * @author fenris - */ - class_complex.prototype.scl = function (s) { - return (class_complex._cram(complex.scl(class_complex._tear(this), s))); - }; - /** - * @author fenris - */ - class_complex.prototype.add = function (other) { - return (class_complex._cram(complex.add(class_complex._tear(this), class_complex._tear(other)))); - }; - /** - * @author fenris - */ - class_complex.prototype.neg = function () { - return (class_complex._cram(complex.neg(class_complex._tear(this)))); - }; - /** - * @author fenris - */ - class_complex.prototype.sub = function (other) { - return (class_complex._cram(complex.sub(class_complex._tear(this), class_complex._tear(other)))); - }; - /** - * @author fenris - */ - class_complex.prototype.mul = function (other) { - return (class_complex._cram(complex.mul(class_complex._tear(this), class_complex._tear(other)))); - }; - /** - * @author fenris - */ - class_complex.prototype.inv = function () { - return (class_complex._cram(complex.inv(class_complex._tear(this)))); - }; - /** - * @author fenris - */ - class_complex.prototype.div = function (other) { - return (class_complex._cram(complex.div(class_complex._tear(this), class_complex._tear(other)))); - }; - /** - * @author fenris - */ - class_complex.prototype.exp = function (n) { - return (class_complex._cram(complex.exp(class_complex._tear(this), n))); - }; - /** - * @author fenris - */ - class_complex.prototype.pow = function (other) { - return (class_complex._cram(complex.pow(class_complex._tear(this), class_complex._tear(other)))); - }; - /** - * @author fenris - */ - class_complex.prototype.equ = function (other) { - return (complex.equ(class_complex._tear(this), class_complex._tear(other))); - }; - /** - * @author fenris - */ - class_complex.prototype.str = function () { - return (complex.str(class_complex._tear(this))); - }; - /** - * @author fenris - */ - class_complex.prototype.toString = function () { - return this.str(); - }; - return class_complex; - }()); - complex.class_complex = class_complex; - })(complex = lib_plankton.complex || (lib_plankton.complex = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:math«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:math« 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:math« 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:math«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var math; - (function (math) { - /** - * @desc golden ratio (e.g. for generating colors) - * @author fenris - */ - math.phi = ((Math.sqrt(5) - 1) / 2); - /** - * @author fenris - */ - math.e = Math.E; - /** - * @author fenris - */ - math.pi = Math.PI; - /** - * @author fenris - */ - math.tau = (2 * Math.PI); - })(math = lib_plankton.math || (lib_plankton.math = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:math«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:math« 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:math« 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:math«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var math; - (function (math) { - /** - * @author fenris - */ - function clamp(x, a = 0.0, b = 1.0) { - return Math.min(Math.max(x, a), b); - } - math.clamp = clamp; - /** - * @desc the mathematical sign-function - * @return {int} an element of {-1,0,+1} - * @author fenris - */ - function sgn(x) { - if (x === 0) { - return 0; - } - else { - if (x < 0) { - return -1; - } - else /* (x > 0) */ { - return +1; - } - } - } - math.sgn = sgn; - /** - * @desc integer division - * @author fenris - */ - function div(x, y) { - return Math.floor(x / y); - } - math.div = div; - /** - * @desc real modulo operator - * @author fenris - */ - function mod(x, y) { - // return (x - (div(x, y) * y)); - if (y <= 0) { - throw (new Error("invalid divisor")); - } - else { - return ((x >= 0) - ? (x % y) - : ((y - ((-x) % y)) % y)); - } - } - math.mod = mod; - /** - * @desc computes "x^y mod z" via square-and-multiply - * @param {int} base ("x") - * @param {int} exponent ("y") - * @param {int} modulus ("z") - * @return {int} - * @author fenris - * @todo handle invalid cases (e.g. "z < 1") - * @todo implement iteratively - */ - function modpow(base, exponent, modulus) { - /* - The idea is the following: - - x^y - = x^((y div 2)·2 + (y mod 2)) - = x^((y div 2)·2) · x^(y mod 2) - = (x^(y div 2))^2 · x^(y mod 2) - - For computing (x^(y div 2)) the algorithm is used recursively. Building the square is done without any magic. - The second factor is either 1 or x, since (y mod 2) is either 0 or 1; in other words: multiplying x to the first - factor is only necessary if y is odd. - */ - if (exponent === 0) { - return 1; - } - else { - let a = modpow(base, exponent >> 1, modulus); - a = ((a * a) % modulus); - if ((exponent & 1) != 0) { - a = ((a * base) % modulus); - } - return a; - } - } - math.modpow = modpow; - /** - * @desc determines if two integers are coprime, i.e. that they don't have a common divisor greater than 1 - * @author fenris - * @todo write function "gcdx" and base on it - */ - function coprime(x, y) { - if (y === 0) { - return false; - } - else if (y === 1) { - return true; - } - else { - let z = mod(x, y); - return coprime(y, z); - } - } - math.coprime = coprime; - /** - * @desc extended euclidean algorithm for computing multiplicative inverse elements - * @param {int} modulus - * @param {int} element - * @author fenris - * @todo write function "gcdx" and base on it - * @todo handle more invalid cases - */ - function inv(modulus, element, positive = false) { - if (element === 0) { - throw (new Error("not invertable")); - } - else if (element === 1) { - return 1; - } - else { - let result = div(1 - (modulus * inv(element, mod(modulus, element), false)), element); - return (positive ? mod(result, modulus) : result); - } - } - math.inv = inv; - /** - * @author fenris - */ - function interpolate_linear(x, y, t = 0.5) { - return ((1 - t) * x + t * y); - } - math.interpolate_linear = interpolate_linear; - /** - * @desc kind of the inverse of linear interpolation; i.e. to find the coefficient "t" for given values x, y and - * their presumed interpolation v - * @author fenris - */ - function appoint_linear(x, y, v) { - return ((v - x) / (y - x)); - } - math.appoint_linear = appoint_linear; - /** - * continued fraction decomposition - */ - function cfd(x, n = (1 << 4)) { - let result = []; - let m = 0; - let y = x; - while (true) { - if (m >= n) { - break; - } - else { - const a = Math.floor(y); - result.push(a); - if (y === a) { - break; - } - else { - y = (1 / (y - a)); - m += 1; - } - } - } - return result; - } - math.cfd = cfd; - })(math = lib_plankton.math || (lib_plankton.math = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:math«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:math« 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:math« 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:math«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var math; - (function (math) { - /** - * @author fenris - */ - class class_relation { - /** - * @author fenris - */ - check(value, reference) { - return this.predicate(value, reference); - } - /** - * @author fenris - */ - /*protected*/ constructor(id, { "symbol": symbol = null, "name": name = null, "predicate": predicate, }) { - this.id = id; - this.symbol = symbol; - this.name = name; - this.predicate = predicate; - } - /** - * @author fenris - */ - id_get() { - return this.id; - } - /** - * @author fenris - */ - symbol_get() { - return this.symbol; - } - /** - * @author fenris - */ - name_get() { - return this.name; - } - /** - * @desc [accessor] [implementation] - * @author fenris - */ - _show() { - return `[${this.symbol}]`; - } - /** - * @desc [accessor] [implementation] - * @author fenris - */ - _hash() { - return this.id; - } - /** - * @desc [accessor] [implementation] - * @author fenris - */ - _collate(relation) { - return (this.id == relation.id); - } - /** - * @author fenris - */ - toString() { - return this._show(); - } - /** - * @author fenris - */ - static pool() { - return { - "eq": { - "symbol": "=", - "name": "gleich", - "predicate": (value, reference) => (value == reference), - }, - "ne": { - "symbol": "≠", - "name": "ungleich", - "predicate": (value, reference) => (value != reference), - }, - "gt": { - "symbol": ">", - "name": "größer", - "predicate": (value, reference) => (value > reference), - }, - "ge": { - "symbol": "≥", - "name": "größer oder gleich", - "predicate": (value, reference) => (value >= reference), - }, - "lt": { - "symbol": "<", - "name": "kleiner", - "predicate": (value, reference) => (value < reference), - }, - "le": { - "symbol": "≤", - "name": "kleiner oder gleich", - "predicate": (value, reference) => (value <= reference), - }, - }; - } - /** - * @author fenris - */ - static get(id) { - let pool = this.pool(); - if (id in pool) { - return (new class_relation(id, pool[id])); - } - else { - throw (new Error(`no such relation`)); - } - } - /** - * @author fenris - */ - static available() { - return Object.keys(this.pool()); - } - } - math.class_relation = class_relation; - /** - * @author fenris - */ - class class_filtrationitem { - /** - * @author fenris - */ - constructor({ "extract": extract, "relation": relation, "reference": reference, }) { - this.extract = extract; - this.relation = relation; - this.reference = reference; - } - /** - * @author fenris - */ - check(dataset) { - let value = this.extract(dataset); - let result = this.relation.check(value, this.reference); - return result; - } - /** - * @desc [implementation] - * @author fenris - */ - _show() { - return `(${this.relation.symbol_get()} ${instance_show(this.reference)})`; - } - /** - * @author fenris - */ - toString() { - return this._show(); - } - } - math.class_filtrationitem = class_filtrationitem; - /** - * @desc disjunctive normal form - * @author fenris - */ - class class_filtration { - /** - * @author fenris - */ - constructor(clauses) { - this.clauses = clauses; - } - /** - * @author fenris - */ - check(dataset) { - return (this.clauses.some(clause => clause.every(literal => literal.check(dataset)))); - } - /** - * @author fenris - */ - use(datasets) { - return datasets.filter(dataset => this.check(dataset)); - } - /** - * @desc [implementation] - * @author fenris - */ - _show() { - return ("{" + this.clauses.map(clause => ("[" + clause.map(instance_show).join(",") + "]")).join(",") + "}"); - } - /** - * @author fenris - */ - toString() { - return this._show(); - } - } - math.class_filtration = class_filtration; - /** - * @author fenris - * @deprecated - */ - function comparator_to_relation(comparator) { - console.warn("deprecated!"); - return ((x, y) => (comparator(x, y) <= 0)); - } - math.comparator_to_relation = comparator_to_relation; - /** - * @author fenris - * @deprecated - */ - function relation_to_comparator(relation) { - console.warn("deprecated!"); - return ((x, y) => (relation(x, y) ? (relation(y, x) ? 0 : -1) : 1)); - } - math.relation_to_comparator = relation_to_comparator; - })(math = lib_plankton.math || (lib_plankton.math = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:math«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:math« 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:math« 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:math«. If not, see . - */ -var lib_calculus; -(function (lib_calculus) { - /** - * @class Calculus - * @desc Ensure precision of mathematical operations - */ - class Calculus { - /** - * @constructor - * @þaram {number} norm - */ - constructor(norm = 100000) { - this.NORM = norm; - } - /** - * normalize - * @param {number} value - * @return {number} - */ - normalize(value) { - return (Math.floor(value * this.NORM)); - } - /** - * denormalize - * @param {number} value - * @return {number} - */ - denormalize(value) { - return (Math.floor(value) / this.NORM); - } - } - lib_calculus.Calculus = Calculus; -})(lib_calculus || (lib_calculus = {})); -/* -This file is part of »bacterio-plankton:math«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:math« 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:math« 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:math«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var math; - (function (math) { - /** - * {x ∈ C | 0 = x³ + px + q} - * - * @author fenris - */ - function cardano_reduced(p, q) { - // (p/3)^3 + (q/2)^2 - const determinant = (lib_plankton.complex.add(lib_plankton.complex.exp(lib_plankton.complex.scl(p, 1 / 3.0), 3), lib_plankton.complex.exp(lib_plankton.complex.scl(q, 1 / 2.0), 2))); - const [u, v] = (lib_plankton.complex.normroots(2, determinant) - .map(w => lib_plankton.complex.sub(w, lib_plankton.complex.scl(q, 1 / 2.0))) - .map(z => lib_plankton.complex.normroots(3, z))); - return [ - /* - lib_plankton.complex.add(u[0], v[0]), - lib_plankton.complex.add(u[1], v[2]), - lib_plankton.complex.add(u[2], v[1]), - */ - // (p = -3uv) → (v = p/(-3u)) → (v = (p/(-3))/u) - lib_plankton.complex.add(u[0], lib_plankton.complex.div(lib_plankton.complex.scl(p, -1 / 3.0), u[0])), - lib_plankton.complex.add(u[1], lib_plankton.complex.div(lib_plankton.complex.scl(p, -1 / 3.0), u[1])), - lib_plankton.complex.add(u[2], lib_plankton.complex.div(lib_plankton.complex.scl(p, -1 / 3.0), u[2])), - ]; - } - /** - * {x ∈ C | 0 = x³ + ex² + fx + g} - * - * @author fenris - */ - function cardano_normalized(e, f, g) { - // p := (-1/3)·e² + f - const p = (lib_plankton.complex.add(lib_plankton.complex.scl(lib_plankton.complex.exp(e, 2), -1 / 3.0), f)); - // q := (2/27)·e³ + (-1/3)·e·f + g - const q = (lib_plankton.complex.add(lib_plankton.complex.add(lib_plankton.complex.scl(lib_plankton.complex.exp(e, 3), +2 / 27.0), lib_plankton.complex.scl(lib_plankton.complex.mul(e, f), -1 / 3.0)), g)); - return (cardano_reduced(p, q) - .map(y => lib_plankton.complex.sub(y, lib_plankton.complex.scl(e, 1 / 3.0)))); - } - /** - * {x ∈ C | 0 = ax³ + bx² + cx + d} - * - * @author fenris - */ - function cubic_solve(a, b, c, d) { - if (lib_plankton.complex.equ(a, lib_plankton.complex.nul())) { - const message = "Leitkoeffizient ist Null; dadurch sollte sich das Problem eigentlich vereinfachen"; - throw (new Error(message)); - } - else { - // e = b/a - const e = lib_plankton.complex.div(b, a); - // f = c/a - const f = lib_plankton.complex.div(c, a); - // g = d/a - const g = lib_plankton.complex.div(d, a); - return cardano_normalized(e, f, g); - } - } - math.cubic_solve = cubic_solve; - /** - * {x ∈ C | 0 = ax³ + bx² + cx + d} - * - * @author fenris - */ - function cubic_solve_real(a, b, c, d) { - return cubic_solve(lib_plankton.complex.make(a, 0), lib_plankton.complex.make(b, 0), lib_plankton.complex.make(c, 0), lib_plankton.complex.make(d, 0)); - } - math.cubic_solve_real = cubic_solve_real; - /** - * gets the coefficients of a polynom by the roots - * - * @author fenris - */ - /*export*/ function cubic_construct(solutions) { - const [x, y, z] = solutions.map(lib_plankton.complex.neg); - const mix = function (values) { - return (values - .map(group => (group - .reduce(lib_plankton.complex.mul, lib_plankton.complex.one()))) - .reduce(lib_plankton.complex.add, lib_plankton.complex.nul())); - }; - return { - "a": mix([[]]), - "b": mix([[x], [y], [z]]), - "c": mix([[x, y], [x, z], [y, z]]), - "d": mix([[x, y, z]]), - }; - } - })(math = lib_plankton.math || (lib_plankton.math = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:color«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:color« 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:color« 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:color«. If not, see . - */ -/* -This file is part of »bacterio-plankton:color«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:color« 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:color« 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:color«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var color; - (function (color_1) { - /** - */ - function make_hsv({ "hue": hue = 0.0, "saturation": saturation = 0.5, "value": value = 0.5 }) { - const h = lib_plankton.math.clamp(0, 1, hue); - const s = lib_plankton.math.clamp(0, 1, saturation); - const v = lib_plankton.math.clamp(0, 1, value); - const sector = (Math.floor(h * 6) % 6); - const phase = ((h * 6) - sector); - const p = (v * (1 - s)); - const q = (v * (1 - (s * phase))); - const t = (v * (1 - (s * (1 - phase)))); - return make_rgb([ - { "red": v, "green": t, "blue": p }, - { "red": q, "green": v, "blue": p }, - { "red": p, "green": v, "blue": t }, - { "red": p, "green": q, "blue": v }, - { "red": t, "green": p, "blue": v }, - { "red": v, "green": p, "blue": q }, - ][sector]); - } - color_1.make_hsv = make_hsv; - /** - */ - function make_hsl(model_hsl) { - const { "hue": h, "saturation": s, "lightness": l } = model_hsl; - const h_ = h; - const v = (l + (s * (1 - Math.abs((2 * l) - 1)) / 2)); - const s_ = (2 * (1 - (l / v))); - return make_hsv({ - "hue": h_, - "saturation": s_, - "value": v, - }); - } - color_1.make_hsl = make_hsl; - /** - */ - function make_rgb(model_rgb) { - return { - "model": { - "red": lib_plankton.math.clamp(0, 1, model_rgb.red), - "green": lib_plankton.math.clamp(0, 1, model_rgb.green), - "blue": lib_plankton.math.clamp(0, 1, model_rgb.blue), - } - }; - } - color_1.make_rgb = make_rgb; - /** - */ - function to_hsv(color) { - const { "red": r, "green": g, "blue": b } = color.model; - const p = Math.min(r, g, b); - const q = Math.max(r, g, b); - const c = (q - p); - let h; - { - if (p === q) { - h = 0; - } - else if (q === r) { - h = ((0 / 3) + ((g - b) / (c * 6))); - } - else if (q === g) { - h = ((1 / 3) + ((b - r) / (c * 6))); - } - else if (q === b) { - h = ((2 / 3) + ((r - g) / (c * 6))); - } - else { - throw (new Error("impossible?")); - } - } - const s = ((q === 0) ? 0 : c); - const v = q; - return { - "hue": h, - "saturation": s, - "value": v, - }; - } - color_1.to_hsv = to_hsv; - /** - */ - function to_hsl(color) { - const { "hue": h, "saturation": s, "value": v } = to_hsv(color); - const h_ = h; - const l = (1 / 2 * v * (2 - s)); - const s_ = ((v * s) / (1 - Math.abs((2 * l) - 1))); - return { - "hue": h, - "saturation": s, - "lightness": l, - }; - } - color_1.to_hsl = to_hsl; - /** - */ - function to_rgb(color) { - return color.model; - } - color_1.to_rgb = to_rgb; - /** - */ - function to_cmyk(color) { - throw (new Error("not implemented")); - } - color_1.to_cmyk = to_cmyk; - /** - */ - function add(color1, color2) { - const rgb1 = to_rgb(color1); - const rgb2 = to_rgb(color2); - return make_rgb({ - "red": (rgb1.red + rgb2.red), - "green": (rgb1.green + rgb2.green), - "blue": (rgb1.blue + rgb2.blue), - }); - } - color_1.add = add; - /** - */ - function multiply(color1, color2) { - const rgb1 = to_rgb(color1); - const rgb2 = to_rgb(color2); - return make_rgb({ - "red": (rgb1.red * rgb2.red), - "green": (rgb1.green * rgb2.green), - "blue": (rgb1.blue * rgb2.blue), - }); - } - color_1.multiply = multiply; - /** - * @todo blend through other model? - */ - function blend(color1, color2, strength = 0.5) { - let rgb1 = to_rgb(color1); - let rgb2 = to_rgb(color2); - let t = strength; - return (make_rgb({ - "red": lib_plankton.math.interpolate_linear(rgb1.red, rgb2.red, t), - "green": lib_plankton.math.interpolate_linear(rgb1.green, rgb2.green, t), - "blue": lib_plankton.math.interpolate_linear(rgb1.blue, rgb2.blue, t) - })); - } - color_1.blend = blend; - /** - */ - function mix(color1, color2, { "strength1": option_strength1 = 1, "strength2": option_strength2 = 1, } = {}) { - return (blend(color1, color2, (option_strength1 - / - (option_strength1 - + - option_strength2)))); - } - color_1.mix = mix; - /** - */ - function output_rgb(color) { - const format = (value => Math.round(value * 255).toFixed(0)); - const rgb = to_rgb(color); - return ("rgb" + "(" + ["red", "green", "blue"].map(key => rgb[key]).map(format).join(",") + ")"); - } - color_1.output_rgb = output_rgb; - /** - */ - function output_hex(color) { - const rgb = to_rgb(color); - const format = function (value) { - const value_ = Math.round(value * 255); - // let str : string = lib_plankton.string.pad(value_.toString(16), 2, "0", true); - let str = value_.toString(16); - while (str.length < 2) - str = ("0" + str); - return str; - }; - return ("#" + ["red", "green", "blue"].map(key => rgb[key]).map(format).join("") + ""); - } - color_1.output_hex = output_hex; - /** - */ - function output_dot(color) { - const hsv = to_hsv(color); - let format = function (value) { - return value.toFixed(8); - }; - return ("" + ["hue", "saturation", "value"].map(key => hsv[key]).map(format).join("+") + ""); - } - color_1.output_dot = output_dot; - /** - */ - function give_generic(n, { "offset": option_offset = 0, "saturation": option_saturation = undefined, "value": option_value = undefined, }) { - return make_hsv({ - "hue": (((lib_plankton.math.phi - * - n) - + - option_offset) - % - 1), - "saturation": option_saturation, - "value": option_value, - }); - } - color_1.give_generic = give_generic; - /** - */ - function give_gray({ "value": option_value = 0.5, }) { - return make_hsv({ "hue": 0, "saturation": 0, "value": option_value }); - } - color_1.give_gray = give_gray; - /** - */ - function give_black() { - return give_gray({ "value": 0.0 }); - } - color_1.give_black = give_black; - /** - */ - function give_white() { - return give_gray({ "value": 1.0 }); - } - color_1.give_white = give_white; - /** - */ - function give_red({ "saturation": option_saturation = undefined, "value": option_value = undefined, } = {}) { - return make_hsv({ - "hue": (0 / 6), - "saturation": option_saturation, - "value": option_value - }); - } - color_1.give_red = give_red; - /** - */ - function give_green({ "saturation": option_saturation = undefined, "value": option_value = undefined, } = {}) { - return make_hsv({ - "hue": (2 / 6), - "saturation": option_saturation, - "value": option_value - }); - } - color_1.give_green = give_green; - /** - */ - function give_blue({ "saturation": option_saturation = undefined, "value": option_value = undefined, } = {}) { - return make_hsv({ - "hue": (4 / 6), - "saturation": option_saturation, - "value": option_value - }); - } - color_1.give_blue = give_blue; - /** - */ - function give_yellow({ "saturation": option_saturation = undefined, "value": option_value = undefined, } = {}) { - return make_hsv({ - "hue": (1 / 6), - "saturation": option_saturation, - "value": option_value - }); - } - color_1.give_yellow = give_yellow; - /** - */ - function give_cyan({ "saturation": option_saturation = undefined, "value": option_value = undefined, } = {}) { - return make_hsv({ - "hue": (3 / 6), - "saturation": option_saturation, - "value": option_value - }); - } - color_1.give_cyan = give_cyan; - /** - */ - function give_magenta({ "saturation": option_saturation = undefined, "value": option_value = undefined, } = {}) { - return make_hsv({ - "hue": (5 / 6), - "saturation": option_saturation, - "value": option_value - }); - } - color_1.give_magenta = give_magenta; - })(color = lib_plankton.color || (lib_plankton.color = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:color«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:color« 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:color« 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:color«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var color; - (function (color_2) { - /** - * @author fenris - */ - class class_color { - /** - * @author fenris - */ - constructor(subject) { - this.subject = subject; - } - /** - * @author fenris - */ - static _cram(subject) { - return (new class_color(subject)); - } - /** - * @author fenris - */ - static _tear(instance) { - return (instance.subject); - } - /** - * @author fenris - */ - static make_hsv({ "hue": hue = undefined, "saturation": saturation = undefined, "value": value = undefined }) { - return (class_color._cram(color_2.make_hsv({ - "hue": hue, - "saturation": saturation, - "value": value - }))); - } - /** - * @author fenris - */ - blend(color, strength = 0.5) { - return (class_color._cram(color_2.blend(class_color._tear(this), class_color._tear(color), strength))); - } - /** - * @author fenris - */ - output_rgb() { - return (color_2.output_rgb(class_color._tear(this))); - } - /** - * @author fenris - */ - output_hex() { - return (color_2.output_hex(class_color._tear(this))); - } - /** - * @author fenris - */ - output_dot() { - return (color_2.output_dot(class_color._tear(this))); - } - /** - * @author fenris - */ - static give_generic({ "n": n, "offset": offset = undefined, "saturation": saturation = undefined, "value": value = undefined, }) { - return (class_color._cram(color_2.give_generic(n, { - "offset": offset, - "saturation": saturation, - "value": value, - }))); - } - static generic(x) { return class_color.give_generic(x); } - ; - /** - * @author fenris - */ - static give_gray(value = 0.5) { - return (class_color._cram(color_2.give_gray({ "value": value }))); - } - /** - * @author fenris - */ - static give_black() { - return (class_color._cram(color_2.give_black())); - } - /** - * @author fenris - */ - static give_white() { - return (class_color._cram(color_2.give_white())); - } - /** - * @author fenris - */ - static give_red({ "saturation": saturation = undefined, "value": value = undefined, } = {}) { - return (class_color._cram(color_2.give_red({ - "saturation": saturation, - "value": value, - }))); - } - /** - * @author fenris - */ - static give_green({ "saturation": saturation = undefined, "value": value = undefined, } = {}) { - return (class_color._cram(color_2.give_green({ - "saturation": saturation, - "value": value, - }))); - } - /** - * @author fenris - */ - static give_blue({ "saturation": saturation = undefined, "value": value = undefined, } = {}) { - return (class_color._cram(color_2.give_blue({ - "saturation": saturation, - "value": value, - }))); - } - /** - * @author fenris - */ - static give_yellow({ "saturation": saturation = undefined, "value": value = undefined, } = {}) { - return (class_color._cram(color_2.give_yellow({ - "saturation": saturation, - "value": value, - }))); - } - /** - * @author fenris - */ - static give_cyan({ "saturation": saturation = undefined, "value": value = undefined, } = {}) { - return (class_color._cram(color_2.give_cyan({ - "saturation": saturation, - "value": value, - }))); - } - /** - * @author fenris - */ - static give_magenta({ "saturation": saturation = undefined, "value": value = undefined, } = {}) { - return (class_color._cram(color_2.give_magenta({ - "saturation": saturation, - "value": value, - }))); - } - } - color_2.class_color = class_color; - })(color = lib_plankton.color || (lib_plankton.color = {})); -})(lib_plankton || (lib_plankton = {})); -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - if (typeof b !== "function" && b !== null) - throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -/* -This file is part of »bacterio-plankton:xml«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:xml« 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:xml« 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:xml«. If not, see . - */ -/** - * @author fenris - */ -var lib_plankton; -(function (lib_plankton) { - var xml; - (function (xml) { - /** - * @author fenris - */ - function string_repeat(symbol, count) { - return ((count <= 0) ? "" : (string_repeat(symbol, count - 1) + symbol)); - } - /** - * @author fenris - */ - var class_node = /** @class */ (function () { - function class_node() { - } - return class_node; - }()); - xml.class_node = class_node; - /** - * @author fenris - */ - var class_node_text = /** @class */ (function (_super) { - __extends(class_node_text, _super); - /** - * @author fenris - */ - function class_node_text(content) { - var _this = _super.call(this) || this; - _this.content = content; - return _this; - } - /** - * @author fenris - */ - class_node_text.prototype.compile = function (depth) { - if (depth === void 0) { depth = 0; } - return (string_repeat("\t", depth) + this.content + "\n"); - }; - return class_node_text; - }(class_node)); - xml.class_node_text = class_node_text; - /** - * @author fenris - */ - var class_node_comment = /** @class */ (function (_super) { - __extends(class_node_comment, _super); - /** - * @author fenris - */ - function class_node_comment(content) { - var _this = _super.call(this) || this; - _this.content = content; - return _this; - } - /** - * @author fenris - */ - class_node_comment.prototype.compile = function (depth) { - if (depth === void 0) { depth = 0; } - return (string_repeat("\t", depth) + "" + "\n"); - }; - return class_node_comment; - }(class_node)); - xml.class_node_comment = class_node_comment; - /** - * @author fenris - */ - var class_node_complex = /** @class */ (function (_super) { - __extends(class_node_complex, _super); - /** - * @author fenris - */ - function class_node_complex(name, attributes, children) { - if (attributes === void 0) { attributes = {}; } - if (children === void 0) { children = []; } - var _this = _super.call(this) || this; - _this.name = name; - _this.attributes = attributes; - _this.children = children; - return _this; - } - /** - * @author fenris - */ - class_node_complex.prototype.compile = function (depth) { - var _this = this; - if (depth === void 0) { depth = 0; } - var output = ""; - var attributes = (Object.keys(this.attributes) - .filter(function (key) { return (_this.attributes[key] !== null); }) - .map(function (key) { return (" " + key + "=" + ("\"" + _this.attributes[key] + "\"")); }) - .join("")); - output += (string_repeat("\t", depth) + "<" + this.name + attributes + ">" + "\n"); - this.children.forEach(function (child) { return (output += child.compile(depth + 1)); }); - output += (string_repeat("\t", depth) + "" + "\n"); - return output; - }; - return class_node_complex; - }(class_node)); - xml.class_node_complex = class_node_complex; - })(xml = lib_plankton.xml || (lib_plankton.xml = {})); -})(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:date«. @@ -10741,198 +13199,2548 @@ var lib_plankton; })(http = lib_plankton.http || (lib_plankton.http = {})); })(lib_plankton || (lib_plankton = {})); /* -This file is part of »bacterio-plankton:url«. +This file is part of »bacterio-plankton:object«. Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' -»bacterio-plankton:url« is free software: you can redistribute it and/or modify +»bacterio-plankton:object« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. -»bacterio-plankton:url« is distributed in the hope that it will be useful, +»bacterio-plankton:object« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:url«. If not, see . - */ -/* -This file is part of »bacterio-plankton:url«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:url« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:url« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:url«. If not, see . +along with »bacterio-plankton:object«. If not, see . */ var lib_plankton; (function (lib_plankton) { - var url; - (function (url_1) { + var object; + (function (object_1) { /** * @author fenris */ - function encode(url) { - let result = ""; - // scheme - { - if (url.scheme !== null) { - result += (url.scheme + ":"); + function fetch(object, fieldname, fallback, escalation) { + if (fallback === void 0) { fallback = null; } + if (escalation === void 0) { escalation = 1; } + if ((fieldname in object) && (object[fieldname] !== undefined)) { + return object[fieldname]; + } + else { + switch (escalation) { + case 0: { + return fallback; + break; + } + case 1: { + var message = ("field '".concat(fieldname, "' not in structure")); + message += ("; using fallback value '".concat(String(fallback), "'")); + // console.warn(message); + return fallback; + break; + } + case 2: { + var message = ("field '".concat(fieldname, "' not in structure")); + throw (new Error(message)); + break; + } + default: { + throw (new Error("invalid escalation level ".concat(escalation))); + break; + } } } - // host - { - if (url.host !== null) { - result += "//"; - // username - { - if (url.username !== null) { - result += url.username; - // password - { - if (url.password !== null) { - result += (":" + url.password); - } - } - result += "@"; + } + object_1.fetch = fetch; + /** + * @author fenris + */ + function map(object_from, transformator) { + var object_to = {}; + Object.keys(object_from).forEach(function (key) { return (object_to[key] = transformator(object_from[key], key)); }); + return object_to; + } + object_1.map = map; + /** + * @desc gibt ein Objekt mit bestimmten Einträgen des Eingabe-Objekts zurück + * @author fenris + */ + function filter(object_from, predicate) { + var object_to = {}; + Object.keys(object_from).forEach(function (key) { + var value = object_from[key]; + if (predicate(value, key)) { + object_to[key] = value; + } + }); + return object_to; + } + object_1.filter = filter; + /** + * @desc wandelt ein Array mit Einträgen der Form {key,value} in ein entsprechendes Objekt um + * @author fenris + */ + function from_array(array) { + var object = {}; + array.forEach(function (entry) { return (object[entry.key] = entry.value); }); + return object; + } + object_1.from_array = from_array; + /** + * @desc wandelt ein Objekt in ein entsprechendes Array mit Einträgen der Form {key,value} um + * @author fenris + */ + function to_array(object) { + var array = []; + Object.keys(object).forEach(function (key) { return array.push({ "key": key, "value": object[key] }); }); + return array; + } + object_1.to_array = to_array; + /** + * @desc gibt eine Liste von Schlüsseln eines Objekts zurück + * @author fenris + */ + function keys(object) { + return Object.keys(object); + } + object_1.keys = keys; + /** + * @desc gibt eine Liste von Werten eines Objekts zurück + * @author fenris + */ + function values(object) { + return to_array(object).map(function (entry) { return entry.value; }); + } + object_1.values = values; + /** + * @desc liest ein Baum-artiges Objekt an einer bestimmten Stelle aus + * @author fenris + */ + function path_read(object, path, fallback, escalation) { + if (fallback === void 0) { fallback = null; } + if (escalation === void 0) { escalation = 1; } + var steps = ((path.length == 0) ? [] : path.split(".")); + if (steps.length == 0) { + throw (new Error("empty path")); + } + else { + var position_1 = object; + var reachable = (position_1 != null) && steps.slice(0, steps.length - 1).every(function (step) { + position_1 = lib_plankton.object.fetch(position_1, step, null, 0); + return (position_1 != null); + }); + if (reachable) { + return lib_plankton.object.fetch(position_1, steps[steps.length - 1], fallback, escalation); + } + else { + return lib_plankton.object.fetch({}, "_dummy_", fallback, escalation); + } + } + } + object_1.path_read = path_read; + /** + * @desc schreibt einen Wert an eine bestimmte Stelle in einem Baum-artigen Objekt + * @author fenris + */ + function path_write(object, path, value, construct) { + if (construct === void 0) { construct = true; } + var steps = ((path.length == 0) ? [] : path.split(".")); + if (steps.length == 0) { + throw (new Error("empty path")); + } + else { + var position_2 = object; + var reachable = steps.slice(0, steps.length - 1).every(function (step) { + var position_ = lib_plankton.object.fetch(position_2, step, null, 0); + if (position_ == null) { + if (construct) { + position_2[step] = {}; + position_2 = position_2[step]; + return true; + } + else { + return false; } } - result += url.host; + else { + position_2 = position_; + return true; + } + }); + if (reachable) { + position_2[steps[steps.length - 1]] = value; + } + else { + var message = ("path '".concat(path, "' does not exist and may not be constructed")); + throw (new Error(message)); } } - // port - { - if (url.port !== null) { - result += (":" + url.port.toString()); + } + object_1.path_write = path_write; + /** + * @desc prüft ob ein Objekt einem bestimmten Muster entspricht + * @param {Object} object das zu prüfende Objekt + * @param {Object} pattern das einzuhaltende Muster + * @param {Function} connlate eine Funktion zum Feststellen der Gleichheit von Einzelwerten + * @author fenris + */ + function matches(object, pattern, collate) { + if (collate === void 0) { collate = instance_collate; } + return Object.keys(pattern).every(function (key) { return collate(pattern[key], object[key]); }); + } + object_1.matches = matches; + /** + * @desc erzeugt eine Projektion eines Baum-artigen Objekts in ein Listen-artiges Objekt + * @param {string} [separator] welches Zeichen als Trenner zwischen zwei Pfad-Schritten verwendet werden soll + * @author fenris + */ + function flatten(value, separator, key_for_element) { + if (separator === void 0) { separator = "."; } + if (key_for_element === void 0) { key_for_element = (function (index) { return ("element_" + index.toFixed(0)); }); } + var integrate = function (result, key_, value_) { + if (value_ == null) { + result[key_] = value_; + } + else { + // primitive Werte direkt übernehmen + if (typeof (value_) != "object") { + result[key_] = value_; + } + // sonst durch rekursiven Aufruf die flache Variante des Wertes ermitteln und einarbeiten + else { + var result_1 = flatten(value_); + Object.keys(result_1) + .forEach(function (key__) { + var value__ = result_1[key__]; + var key_new = (key_ + separator + key__); + result[key_new] = value__; + }); + } + } + }; + if ((value === null) || (value === undefined)) { + return null; + } + else { + var result_2 = {}; + if (typeof (value) != "object") { + result_2["value"] = value; + } + else { + if (value instanceof Array) { + var array = (value); + array + .forEach(function (element, index) { + integrate(result_2, key_for_element(index), element); + }); + } + else { + var object_2 = (value); + Object.keys(object_2) + .forEach(function (key) { + integrate(result_2, key, object_2[key]); + }); + } + } + return result_2; + } + } + object_1.flatten = flatten; + /** + * @author fenris + */ + function clash(x, y, _a) { + var _b = _a === void 0 ? {} : _a, _c = _b["overwrite"], overwrite = _c === void 0 ? true : _c, _d = _b["hooks"], _e = _d === void 0 ? {} : _d, _f = _e["existing"], hook_existing = _f === void 0 ? null : _f; + if (hook_existing == null) { + (function (key, value_old, value_new) { return console.warn("field ".concat(key, " already defined")); }); + } + var z = {}; + Object.keys(x).forEach(function (key) { + z[key] = x[key]; + }); + Object.keys(y).forEach(function (key) { + if (key in z) { + if (hook_existing != null) { + hook_existing(key, z[key], y[key]); + } + if (overwrite) { + z[key] = y[key]; + } + } + else { + z[key] = y[key]; + } + }); + return z; + } + object_1.clash = clash; + /** + * @author fenris + */ + function patch(core, mantle, deep, path) { + if (deep === void 0) { deep = true; } + if (path === void 0) { path = null; } + if (mantle == null) { + console.warn("mantle is null; core was", core); + } + else { + Object.keys(mantle).forEach(function (key) { + var path_ = ((path == null) ? key : "".concat(path, ".").concat(key)); + var value_mantle = mantle[key]; + if (!(key in core)) { + if ((typeof (value_mantle) == "object") && (value_mantle != null) && deep) { + if (value_mantle instanceof Array) { + core[key] = []; + value_mantle.forEach(function (element) { + if ((typeof (element) == "object") && (element != null)) { + var element_ = {}; + patch(element_, element); + core[key].push(element_); + } + else { + core[key].push(element); + } + }); + } + else { + core[key] = {}; + patch(core[key], value_mantle, deep, path_); + } + } + else { + core[key] = value_mantle; + } + } + else { + var value_core = core[key]; + if (typeof (value_core) == typeof (value_mantle)) { + if ((typeof (value_mantle) == "object") && (value_mantle != null) && deep) { + patch(core[key], value_mantle, deep, path_); + } + else { + core[key] = value_mantle; + } + } + else { + if ((value_core != null) && (value_mantle != null)) { + var message = "objects have different shapes at path '".concat(path_, "'; core has type '").concat(typeof (value_core), "' and mantle has type '").concat(typeof (value_mantle), "'"); + console.warn(message); + } + core[key] = value_mantle; + // throw (new Error(message)); + } + } + }); + } + } + object_1.patch = patch; + /** + * @author fenris + */ + function patched(core, mantle, deep) { + if (deep === void 0) { deep = undefined; } + var result = {}; + patch(result, core, deep); + patch(result, mantle, deep); + return result; + } + object_1.patched = patched; + /** + * @author fenris + */ + function attached(object, key, value) { + var mantle = {}; + mantle[key] = value; + return patched(object, mantle, false); + } + object_1.attached = attached; + /** + * @author fenris + */ + function copy(object) { + return patched({}, object); + } + object_1.copy = copy; + })(object = lib_plankton.object || (lib_plankton.object = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:markdown«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:markdown« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:markdown« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:markdown«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var markdown; + (function (markdown) { + /** + * @author fenris + */ + function code(content) { + return lib_plankton.string.coin("`{{content}}`", { + "content": content + }); + } + markdown.code = code; + /** + * @author fenris + */ + function paragraph(content) { + return lib_plankton.string.coin("{{content}}\n\n", { + "content": content + }); + } + markdown.paragraph = paragraph; + /** + * @author fenris + */ + function sectionhead(level, content) { + return lib_plankton.string.coin("{{grids}} {{content}}\n\n", { + "grids": lib_plankton.string.repeat("#", level), + "content": content + }); + } + markdown.sectionhead = sectionhead; + })(markdown = lib_plankton.markdown || (lib_plankton.markdown = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:api«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:api« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:api« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:api«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var api; + (function (api) { + /** + */ + let enum_checklevel; + (function (enum_checklevel) { + enum_checklevel["none"] = "none"; + enum_checklevel["soft"] = "soft"; + enum_checklevel["hard"] = "hard"; + })(enum_checklevel = api.enum_checklevel || (api.enum_checklevel = {})); + /** + */ + class class_error_permission_denied extends Error { + } + api.class_error_permission_denied = class_error_permission_denied; + })(api = lib_plankton.api || (lib_plankton.api = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:api«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:api« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:api« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:api«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var api; + (function (api_1) { + /** + * @throws Error if the inspection had foundings and the level is high enough + * @author fenris + */ + function validate(level, shape, value, options = {}) { + options = lib_plankton.object.patched({ + "kind": "value", + "message_factory": ((kind, findings) => ("malformed " + kind + ": " + findings.join("; "))), + }, options); + if (level === api_1.enum_checklevel.none) { + return value; + } + else { + const inspection = lib_plankton.shape.inspect_flat(shape, value); + if (inspection.length === 0) { + return value; + } + else { + const message = options.message_factory(options.kind, inspection); + switch (level) { + case api_1.enum_checklevel.soft: { + console.warn(message); + return value; + break; + } + case api_1.enum_checklevel.hard: + default: + { + throw (new Error(message)); + break; + } + } } } - // path - { - if (url.path !== null) { - result += url.path; - } + } + /** + * @author fenris + */ + function make(title) { + const api = { + "title": title, + "actions": {}, + }; + return api; + } + api_1.make = make; + /** + * @throws Error if a action with the given name has already been registered + * @author fenris + */ + function register(api, name, options = {}) { + options = /*lib_plankton.object.patched*/ Object.assign({ + "active": (version) => true, + "execution": (version, environment, input) => lib_plankton.call.promise_reject("not implemented"), + "restriction": (version, environment) => true, + "input_shape": (version) => ({ "kind": "any" }), + "output_shape": (version) => ({ "kind": "any" }), + "title": null, + "description": null, + }, options); + if (api.actions.hasOwnProperty(name)) { + throw (new Error("an action with the name '" + name + "' has already been registered")); } - // query - { - if (url.query !== null) { - result += ("?" + encodeURI(url.query)); - } + else { + const action = { + "name": name, + "active": options.active, + "execution": options.execution, + "restriction": options.restriction, + "input_shape": options.input_shape, + "output_shape": options.output_shape, + "title": options.title, + "description": options.description, + }; + api.actions[name] = action; } - // hash - { - if (url.hash !== null) { - result += ("#" + url.hash); + } + api_1.register = register; + /** + * @throws Error if not found + * @author fenris + */ + function get_action(api, name) { + if (api.actions.hasOwnProperty(name)) { + const action = api.actions[name]; + return action; + } + else { + throw (new Error("no action with name '" + name + "'")); + } + } + api_1.get_action = get_action; + /** + * @author fenris + */ + function call(api, name, options = {}) { + options = /*lib_plankton.object.patched*/ Object.assign({ + "version": null, + "input": null, + "environment": {}, + "checklevel_restriction": api_1.enum_checklevel.hard, + "checklevel_input": api_1.enum_checklevel.soft, + "checklevel_output": api_1.enum_checklevel.soft, + }, options); + return (lib_plankton.call.promise_resolve(undefined) + // get action + .then(() => lib_plankton.call.promise_resolve(get_action(api, name))) + .then((action) => (lib_plankton.call.promise_resolve(undefined) + // check permission + .then(() => { + let conf; + switch (options.checklevel_restriction) { + case api_1.enum_checklevel.none: { + conf = { + "actual_check": false, + "escalate": false, + }; + break; + } + case api_1.enum_checklevel.soft: { + conf = { + "actual_check": true, + "escalate": false, + }; + break; + } + default: + case api_1.enum_checklevel.hard: { + conf = { + "actual_check": true, + "escalate": true, + }; + break; + } + } + return ((conf.actual_check + ? action.restriction(options.version, options.environment) + : Promise.resolve(true)) + .then((valid) => { + if (!valid) { + if (conf.escalate) { + return Promise.reject(new api_1.class_error_permission_denied()); + } + else { + lib_plankton.log.warning("api_permission_missing", { + "version": options.version, + "environment": options.environment, + "action_name": action.name, + }); + return Promise.resolve(null); + } + } + else { + return Promise.resolve(null); + } + })); + }) + // validate and adjust input + .then(() => lib_plankton.call.promise_resolve(validate(options.checklevel_input, action.input_shape(options.version), options.input, { + "kind": "input", + }))) + // execute + .then((input) => action.execution(options.version, options.environment, options.input)) + // validate output + .then((output) => lib_plankton.call.promise_resolve(validate(options.checklevel_output, action.output_shape(options.version), output, { + "kind": "output", + })))))); + } + api_1.call = call; + /** + * @author fenris + */ + function generate_documentation_for_action(api, name, options = {}) { + options = Object.assign({ + "version": null, + }, options); + const action = get_action(api, name); + let result = ""; + if (!action.active(options.version)) { + // do nothing + } + else { + // name + { + result += lib_plankton.markdown.sectionhead(2, lib_plankton.markdown.code(action.name)); + } + // description + { + result += lib_plankton.markdown.sectionhead(3, "Description"); + result += lib_plankton.markdown.paragraph(action.description ?? "-"); + } + // input shape + { + result += lib_plankton.markdown.sectionhead(3, "Input"); + result += lib_plankton.markdown.paragraph(lib_plankton.markdown.code(lib_plankton.shape.show(action.input_shape(options.version)))); + } + // output shape + { + result += lib_plankton.markdown.sectionhead(3, "Output"); + result += lib_plankton.markdown.paragraph(lib_plankton.markdown.code(lib_plankton.shape.show(action.output_shape(options.version)))); } } return result; } - url_1.encode = encode; - /** - * @author fenris - * @todo arguments - */ - function decode(url_raw) { - const builtin_url = new URL(url_raw); - return { - "scheme": builtin_url.protocol.slice(0, -1), - "host": builtin_url.hostname, - "username": ((builtin_url.username !== "") - ? - builtin_url.username - : - null), - "password": ((builtin_url.password !== "") - ? - builtin_url.password - : - null), - "port": ((builtin_url.port !== "") - ? - parseInt(builtin_url.port) - : - null), - "path": builtin_url.pathname, - "query": builtin_url.search.slice(1), - "hash": ((builtin_url.hash !== "") - ? - builtin_url.hash.slice(1) - : - null), - }; - } - url_1.decode = decode; + api_1.generate_documentation_for_action = generate_documentation_for_action; /** * @author fenris */ - function implementation_code() { - return { - "encode": encode, - "decode": decode, - }; + function generate_documentation(api, options = {}) { + options = Object.assign({ + "version": null, + }, options); + let result = ""; + result += lib_plankton.markdown.paragraph(api.title); + result += lib_plankton.markdown.sectionhead(1, "Actions"); + // iterate through actions and use "generate_documentation_for_action" + Object.entries(api.actions) + .forEach(([action_name, action]) => { + result += generate_documentation_for_action(api, action_name, { + "version": options.version, + }); + }); + return result; } - url_1.implementation_code = implementation_code; - })(url = lib_plankton.url || (lib_plankton.url = {})); + api_1.generate_documentation = generate_documentation; + })(api = lib_plankton.api || (lib_plankton.api = {})); })(lib_plankton || (lib_plankton = {})); /* -This file is part of »bacterio-plankton:url«. +This file is part of »bacterio-plankton:api«. Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' -»bacterio-plankton:url« is free software: you can redistribute it and/or modify +»bacterio-plankton:api« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. -»bacterio-plankton:url« is distributed in the hope that it will be useful, +»bacterio-plankton:api« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:url«. If not, see . +along with »bacterio-plankton:api«. If not, see . */ var lib_plankton; (function (lib_plankton) { - var url; - (function (url) { + var api; + (function (api) { /** * @author fenris */ - class class_url { + class class_api { /** * @author fenris */ - constructor() { + constructor(subject) { + this.subject = subject; } /** - * @implementation * @author fenris */ - encode(x) { - return url.encode(x); + static create(name) { + const subject = api.make(name); + return (new class_api(subject)); } /** - * @implementation * @author fenris */ - decode(x) { - return url.decode(x); + register(name, options = {}) { + return api.register(this.subject, name, options); + } + /** + * @author fenris + */ + call(name, options = {}) { + return api.call(this.subject, name, options); + } + /** + * @author fenris + */ + generate_documentation_for_action(name) { + return api.generate_documentation_for_action(this.subject, name); + } + /** + * @author fenris + */ + generate_documentation() { + return api.generate_documentation(this.subject); } } - url.class_url = class_url; - })(url = lib_plankton.url || (lib_plankton.url = {})); + api.class_api = class_api; + })(api = lib_plankton.api || (lib_plankton.api = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:rest«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:rest« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:rest« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:rest«. If not, see . + */ +/* +This file is part of »bacterio-plankton:rest«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:rest« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:rest« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:rest«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var rest; + (function (rest_1) { + /** + */ + function http_request_method_to_oas(http_request_method) { + switch (http_request_method) { + case lib_plankton.http.enum_method.get: return "get"; + case lib_plankton.http.enum_method.post: return "post"; + case lib_plankton.http.enum_method.patch: return "patch"; + case lib_plankton.http.enum_method.head: return "head"; + case lib_plankton.http.enum_method.delete: return "delete"; + case lib_plankton.http.enum_method.options: return "options"; + case lib_plankton.http.enum_method.put: return "put"; + default: throw (new Error("impossible")); + } + } + /** + */ + function wildcard_step_decode(step) { + const matches = (new RegExp("^:(.*)$")).exec(step); + if ((matches === null) || (matches.length < 2)) { + return null; + } + else { + return matches[1]; + } + } + /** + */ + function wildcard_step_encode(name) { + return (":" + name); + } + /** + */ + function routenode_iterate(routenode, procedure, steps) { + procedure(routenode, steps); + Object.entries(routenode.sub_branch).forEach(([key, value]) => { + routenode_iterate(value, procedure, steps.concat([key])); + }); + if (!(routenode.sub_wildcard === null)) { + routenode_iterate(routenode.sub_wildcard.node, procedure, steps.concat([wildcard_step_encode(routenode.sub_wildcard.name)])); + } + } + /** + */ + function routenode_flatten(routenode) { + let list = []; + routenode_iterate(routenode, (routenode_, steps) => { + list.push({ "steps": steps, "node": routenode_ }); + }, []); + return list; + } + /** + */ + function routenode_spawn(steps, http_method, operation) { + let routenode; + if (steps.length <= 0) { + routenode = { + "operations": Object.fromEntries([[http_method, operation]]), + "sub_branch": {}, + "sub_wildcard": null, + }; + } + else { + const steps_head = steps[0]; + const steps_tail = steps.slice(1); + const sub = routenode_spawn(steps_tail, http_method, operation); + const wildcard_name = wildcard_step_decode(steps_head); + if (wildcard_name === null) { + // branch + routenode = { + "operations": {}, + "sub_branch": Object.fromEntries([[steps_head, sub]]), + "sub_wildcard": null, + }; + } + else { + // wildcard + routenode = { + "operations": {}, + "sub_branch": {}, + "sub_wildcard": { "name": wildcard_name, "node": sub }, + }; + } + } + return routenode; + } + /** + */ + function routenode_path_read(routenode, steps) { + if (steps.length <= 0) { + return { + "steps": [], + "rest": [], + "routenode": routenode, + "parameters": {}, + }; + } + else { + const path_head = steps[0]; + const path_tail = steps.slice(1); + if (path_head in routenode.sub_branch) { + const result = routenode_path_read(routenode.sub_branch[path_head], path_tail); + return { + "steps": [path_head].concat(result.steps), + "rest": result.rest, + "routenode": result.routenode, + "parameters": result.parameters, + }; + } + else { + if (!(routenode.sub_wildcard === null)) { + const result = routenode_path_read(routenode.sub_wildcard.node, path_tail); + if (!(routenode.sub_wildcard.name in result.parameters)) { + // do nothing + } + else { + lib_plankton.log.warning("rest_overwriting_path_parameter", { + "key": routenode.sub_wildcard.name, + "value_old": result.parameters[routenode.sub_wildcard.name], + "value_new": path_head, + }); + } + return { + "steps": [path_head].concat(result.steps), + "rest": result.rest, + "routenode": result.routenode, + "parameters": lib_plankton.object.patched(Object.fromEntries([[routenode.sub_wildcard.name, path_head]]), result.parameters), + }; + } + else { + return { + "steps": [path_head], + "rest": path_tail, + "routenode": routenode, + "parameters": {}, + }; + } + } + } + } + /** + */ + function routenode_path_write(routenode, steps, http_method, operation, options = {}) { + options = lib_plankton.object.patched({ + "create": false, + }, options); + if (steps.length <= 0) { + if (!(http_method in routenode.operations)) { + // do nothing + } + else { + lib_plankton.log.warning("rest_overwriting_action", { + "http_method": http_method, + "steps": steps, + }); + } + routenode.operations[http_method] = operation; + } + else { + const steps_head = steps[0]; + const steps_tail = steps.slice(1); + const wildcard_name = wildcard_step_decode(steps_head); + if (!(wildcard_name === null)) { + // wildcard + if (routenode.sub_wildcard === null) { + if (!options.create) { + throw (new Error("may not create missing route")); + } + else { + routenode.sub_wildcard = { + "name": wildcard_name, + "node": routenode_spawn(steps_tail, http_method, operation), + }; + } + } + else { + if (!(routenode.sub_wildcard.name === wildcard_name)) { + /* + lib_plankton.log.warning( + "rest_overwriting_wildcard_node", + { + "wildcard_name": wildcard_name, + } + ); + */ + throw (new Error("inconsistent wildcard name: '" + routenode.sub_wildcard.name + "' vs. '" + wildcard_name + "'")); + } + else { + // walk + routenode_path_write(routenode.sub_wildcard.node, steps_tail, http_method, operation, options); + } + } + } + else { + if (steps_head in routenode.sub_branch) { + // walk branch + routenode_path_write(routenode.sub_branch[steps_head], steps_tail, http_method, operation, options); + } + else { + // add branch + if (!options.create) { + throw (new Error("may not create missing route")); + } + else { + routenode.sub_branch[steps_head] = routenode_spawn(steps_tail, http_method, operation); + } + } + } + } + } + /** + */ + function make(options = {}) { + options = lib_plankton.object.patched({ + "title": "REST-API", + "versioning_method": "none", + "versioning_header_name": "X-Api-Version", + "versioning_query_key": "version", + "header_parameters": [], + "set_access_control_headers": false, + "authentication": { + "kind": "none", + "parameters": {}, + }, + "actions": [], + }, options); + const subject = { + "api": lib_plankton.api.make(options.title), + "versioning_method": options.versioning_method, + "versioning_header_name": options.versioning_header_name, + "versioning_query_key": options.versioning_query_key, + "routetree": { + "operations": {}, + "sub_branch": {}, + "sub_wildcard": null, + }, + "header_parameters": options.header_parameters, + "set_access_control_headers": options.set_access_control_headers, + "authentication": options.authentication, + }; + options.actions.forEach(action_definition => { + rest.register(subject, action_definition.http_method, action_definition.path, action_definition.options); + }); + return subject; + } + rest_1.make = make; + /** + */ + function register(rest, http_method, path, options) { + options = lib_plankton.object.patched({ + "active": ((version) => true), + "execution": ((stuff) => Promise.resolve({ "status_code": 501, "data": null })), + "restriction": ((stuff) => Promise.resolve(true)), + "input_schema": ((version) => ({})), + "output_schema": ((version) => ({})), + "title": null, + "description": null, + "query_parameters": [], + "request_body_mimetype": "application/json", + "request_body_decode": ((http_request_body, http_request_header_content_type) => (((http_request_header_content_type !== null) + && + (http_request_header_content_type.startsWith("application/json")) + && + (http_request_body !== null) + && + (http_request_body.toString() !== "")) + ? JSON.parse(http_request_body.toString()) + : ((http_request_body !== null) + ? http_request_body.toString() + : null))), + "response_body_mimetype": "application/json", + // TODO: no "from"? + "response_body_encode": ((output) => Buffer["from"](JSON.stringify(output))), + }, options); + const steps = lib_plankton.string.split(path, "/").slice(1); + const steps_enriched = ((rest.versioning_method === "path") + ? ["{version}"].concat(steps) + : steps); + const action_name = (steps.concat([lib_plankton.http.encode_method(http_method).toLowerCase()]) + .join("_")); + const operation = { + "action_name": action_name, + "query_parameters": options.query_parameters, + "request_body_mimetype": options.request_body_mimetype, + "request_body_decode": options.request_body_decode, + "response_body_mimetype": options.response_body_mimetype, + "response_body_encode": options.response_body_encode, + "input_schema": options.input_schema, + "output_schema": options.output_schema, + }; + routenode_path_write(rest.routetree, steps_enriched, http_method, operation, { + "create": true, + }); + lib_plankton.api.register(rest.api, action_name, { + "active": options.active, + "execution": (version, environment, input) => options.execution({ + "version": version, + "path_parameters": environment.path_parameters, + "query_parameters": environment.query_parameters, + "headers": environment.headers, + "input": input + }), + "restriction": (version, environment) => options.restriction({ + "version": version, + "path_parameters": environment.path_parameters, + "query_parameters": environment.query_parameters, + "headers": environment.headers, + }), + "title": options.title, + "description": options.description, + // TODO + // "input_shape": options.input_type, + // "output_shape": options.output_type, + }); + lib_plankton.log.debug("rest_route_added", { + "http_method": http_method, + "path": path, + // "routetree": rest.routetree, + }); + } + rest_1.register = register; + /** + * @todo check request body mimetype? + * @todo check query paramater validity + */ + async function call(rest, http_request, options = {}) { + options = /*lib_plankton.object.patched*/ Object.assign({ + "checklevel_restriction": lib_plankton.api.enum_checklevel.hard, + "checklevel_input": lib_plankton.api.enum_checklevel.soft, + "checklevel_output": lib_plankton.api.enum_checklevel.soft, + }, options); + lib_plankton.log.info("rest_call", { + "http_request": { + "scheme": http_request.scheme, + "host": http_request.host, + "path": http_request.path, + "version": http_request.version, + "method": http_request.method, + "query": http_request.query, + "headers": http_request.headers, + "body": String(http_request.body), + } + }); + // parse target and query parameters + // const url_stuff : URL = new URL("http://dummy" + http_request.target); + const path = http_request.path; + const query_parameters_raw = new URLSearchParams(http_request.query); + let query_parameters = {}; + for (const [key, value] of query_parameters_raw) { + query_parameters[key] = value; + } + const steps = lib_plankton.string.split(path, "/").slice(1); + if (steps.length <= 0) { + throw (new Error("empty path")); + } + else { + // resolve + const stuff = routenode_path_read(rest.routetree, steps); + const allowed_methods = (Object.keys(stuff.routenode.operations) + .map(x => lib_plankton.http.encode_method(x)) + .join(", ")); + // get version + let version; + switch (rest.versioning_method) { + case "none": { + version = null; + break; + } + case "path": { + version = stuff.parameters["version"]; + // delete stuff.parameters["version"]; + break; + } + case "header": { + version = http_request.headers[rest.versioning_header_name]; + // delete http_request.headers[rest.versioning_header_name]; + break; + } + case "query": { + version = query_parameters[rest.versioning_query_key]; + // delete query_parameters[rest.versioning_query_key]; + break; + } + default: { + throw (new Error("unhandled versioning method: " + rest.versioning_method)); + break; + } + } + const additional_response_headers = (rest.set_access_control_headers + ? { + "Access-Control-Allow-Headers": (([ + "Content-Type", + "X-Api-Key", + ] + .concat((rest.versioning_header_name !== null) + ? [rest.versioning_header_name] + : []) + .concat((rest.authentication.kind === "key_header") + ? [rest.authentication.parameters["name"]] + : [])) + .join(", ")), + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Methods": allowed_methods, + } + : {}); + if (stuff.rest.length > 0) { + return { + "version": "HTTP/1.1", + "status_code": 404, + "headers": {}, + "body": null, + }; + } + else { + if (http_request.method === lib_plankton.http.enum_method.options) { + return { + "version": "HTTP/1.1", + "status_code": 200, + "headers": Object.assign({}, additional_response_headers), + "body": null, + }; + } + else { + if (!(http_request.method in stuff.routenode.operations)) { + if (Object.keys(stuff.routenode.operations).length <= 0) { + return { + "version": "HTTP/1.1", + "status_code": 404, + "headers": Object.assign({}, additional_response_headers), + "body": null, + }; + } + else { + return { + "version": "HTTP/1.1", + "status_code": 405, + "headers": Object.assign({ + "Allow": allowed_methods, + }, additional_response_headers), + "body": null, + }; + } + } + else { + // call + let result; + let error; + const operation = stuff.routenode.operations[http_request.method]; + const stuff_ = { + "version": version, + "headers": http_request.headers, + "path_parameters": stuff.parameters, + "query_parameters": query_parameters, + "input": ((http_request.body === null) + ? null + : operation.request_body_decode(http_request.body, (http_request.headers["Content-Type"] + ?? + http_request.headers["content-type"] + ?? + null))), + }; + /* + const allowed : boolean = ( + (operation.restriction === null) + ? true + : operation.restriction(stuff_) + ); + */ + let response; + /* + if (! allowed) { + lib_plankton.log.error( + "rest_access_denied", + { + "http_request": { + "target": http_request.target, + "method": http_request.method, + "headers": http_request.headers, + "body": ( + (http_request.body === null) + ? null + : lib_plankton.string.limit(http_request.body.toString(), {"length": 200}) + ), + }, + } + ); + response = { + "version": "HTTP/1.1", + "status_code": 403, + "headers": Object.assign( + { + }, + additional_response_headers + ), + "body": Buffer["from"]("forbidden"), + }; + } + else*/ { + try { + result = await lib_plankton.api.call(rest.api, operation.action_name, { + "version": stuff_.version, + "environment": { + "headers": stuff_.headers, + "path_parameters": stuff_.path_parameters, + "query_parameters": stuff_.query_parameters, + }, + "input": stuff_.input, + "checklevel_restriction": options.checklevel_restriction, + "checklevel_input": options.checklevel_input, + "checklevel_output": options.checklevel_output, + }); + error = null; + } + catch (error_) { + result = null; + error = error_; + } + if ((result === null) || (error !== null)) { + if (error instanceof lib_plankton.api.class_error_permission_denied) { + response = { + "version": "HTTP/1.1", + "status_code": 403, + "headers": Object.assign({}, additional_response_headers), + "body": null, + }; + } + else { + lib_plankton.log.error("rest_execution_failed", { + "http_request": { + "version": http_request.version, + "scheme": http_request.scheme, + "method": http_request.method, + "path": http_request.path, + "query": http_request.query, + "headers": http_request.headers, + "body": ((http_request.body === null) + ? null + : lib_plankton.string.limit(http_request.body.toString(), { "length": 200 })), + }, + "error": { + "message": error.toString(), + "file_name": error.fileName, + "line_number": error.lineNumber, + "stack": error.stack, + }, + }); + response = { + "version": "HTTP/1.1", + "status_code": 500, + "headers": Object.assign({}, additional_response_headers), + "body": Buffer["from"]("internal error"), + }; + } + } + else { + // encode + response = { + "version": "HTTP/1.1", + "status_code": result.status_code, + "headers": Object.assign({ + "Content-Type": operation.response_body_mimetype, + }, additional_response_headers), + "body": operation.response_body_encode(result.data), + }; + } + } + return response; + } + } + } + } + } + rest_1.call = call; + /** + * @see https://swagger.io/specification/#openrest-object + */ + function to_oas(rest, options = {}) { + options = lib_plankton.object.patched({ + "version": null, + "servers": [], + }, options); + const subject = rest; + const version = (options.version ?? "-"); + return { + "openapi": "3.0.3", + "info": { + "version": version, + "title": (rest.api.title ?? "API"), + // "description": (rest.api.description ?? undefined), + }, + "servers": options.servers.map(url => ({ "url": url })), + "components": { + "securitySchemes": (((description) => ({ + "none": {}, + "key_header": { + "default_security_schema": { + "type": "restKey", + "in": "header", + "name": description.parameters["name"], + }, + }, + }[description.kind]))(rest.authentication)), + }, + "security": [ + { + "default_security_schema": [], + } + ], + "paths": lib_plankton.call.convey(rest.routetree, [ + routenode_flatten, + (x) => x.map((entry) => { + const steps_ = entry.steps; + const path = lib_plankton.string.join(steps_, "_"); + const key = ((steps_.length <= 0) + ? "/" + : lib_plankton.string.join([""].concat(steps_ + .map(step => ((wildcard_step_decode(step) !== null) + ? ("{" + wildcard_step_decode(step) + "}") + : step))), "/")); + return [ + key, + lib_plankton.call.convey(entry.node.operations, [ + x => Object.entries(x), + (pairs) => pairs.map(([http_method, operation]) => ([ + http_request_method_to_oas(http_method), + { + "operationId": (http_request_method_to_oas(http_method) + + + "_" + + + path), + "summary": (operation.title + ?? + [""].concat(steps_).join(" ")), + "description": (lib_plankton.api.get_action(rest.api, operation.action_name).description + ?? + "(missing)"), + "parameters": [].concat( + // header parameters + rest.header_parameters.map(header_parameter => ({ + "name": header_parameter.name, + "in": "header", + "required": header_parameter.required, + "schema": { + "type": "string", + }, + "description": (header_parameter.description ?? undefined), + })), + // path parameters + lib_plankton.call.convey(steps_, [ + x => x.map(y => wildcard_step_decode(y)), + x => x.filter(y => (!(y === null))), + x => x.map(y => ({ + "name": y, + "in": "path", + "required": true, + "schema": { + "type": "string", + }, + })), + ]), + // query parameters + operation.query_parameters.map((query_parameter) => ({ + "name": query_parameter.name, + "in": "query", + "required": query_parameter.required, + "schema": { + "type": "string", + }, + "description": (query_parameter.description ?? undefined), + }))), + "requestBody": (([ + lib_plankton.http.enum_method.get, + lib_plankton.http.enum_method.head, + lib_plankton.http.enum_method.delete, + ].includes(http_method)) + ? undefined + : { + "content": Object.fromEntries([ + [ + operation.request_body_mimetype, + { + "schema": operation.input_schema(options.version), + } + ] + ]) + }), + "responses": { + "default": { + "description": "", + "content": Object.fromEntries([ + [ + operation.response_body_mimetype, + { + "schema": operation.output_schema(options.version), + } + ] + ]), + } + }, + } + ])), + (pairs) => Object.fromEntries(pairs), + ]), + ]; + }), + x => x.filter(y => (Object.keys(y[1]).length > 0)), + x => Object.fromEntries(x), + ]) + }; + } + rest_1.to_oas = to_oas; + })(rest = lib_plankton.rest || (lib_plankton.rest = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:server«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:server« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:server« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:server«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var server; + (function (server) { + /** + * @author fenris + */ + function make(handle, options = {}) { + options = Object.assign({ + "host": "::", + "port": 9999, + "threshold": 0.25, + }, options); + return { + "host": options.host, + "port": options.port, + "threshold": options.threshold, + "handle": handle, + "serverobj": undefined, + }; + } + server.make = make; + /** + * @author fenris + * @deprecated + */ + function make_old(port, handle) { + return make(handle, { + "host": "::", + "port": port, + "threshold": 0.25, + }); + } + server.make_old = make_old; + /** + * @author fenris + * @see https://nodejs.org/api/net.html#serverlistenport-host-backlog-callback + */ + function start(subject) { + const net = require("net"); + return (new Promise((resolve, reject) => { + // @ts-ignore + let input_chunks = []; + subject.serverobj = net.createServer({ + "allowHalfOpen": false, + }, (socket) => { + let timeout_handler = null; + let ended = false; + const process_input = function () { + // @ts-ignore + const input = Buffer.concat(input_chunks); + /* + const metadata : type_metadata = { + "ip_address": socket.remoteAddress, + }; + */ + lib_plankton.log.debug("server_process_input", { + "input": input, + }); + (subject.handle(input /*, metadata*/) + .then((output) => { + lib_plankton.log.debug("server_writing", { + "output": output, + }); + socket.write(output); + socket.end(); + }) + .catch((error) => { + lib_plankton.log.warning("server_handle_failed", { + "error": error.toString(), + }); + // socket.write(""); + socket.end(); + }) + .then(() => { + input_chunks = []; + })); + }; + const timeout_stop = function () { + if (timeout_handler === null) { + // do nothing + } + else { + lib_plankton.log.debug("server_timeout_cancelling"); + clearTimeout(timeout_handler); + timeout_handler = null; + } + }; + const timeout_start = function () { + if (subject.threshold === null) { + process_input(); + } + else { + if (timeout_handler === null) { + timeout_handler = setTimeout(() => { + lib_plankton.log.debug("server_timeout_reached"); + timeout_handler = null; + process_input(); + }, (subject.threshold * 1000)); + } + else { + lib_plankton.log.warning("server_timeout_already_started"); + // do nothing + } + } + }; + lib_plankton.log.info("server_client connected", {}); + socket.on("data", (input_chunk_raw) => { + lib_plankton.log.debug("server_reading_chunk", { + "chunk_raw": input_chunk_raw, + }); + timeout_stop(); + const input_chunk = ((input_chunk_raw instanceof Buffer) + ? + input_chunk_raw + : + // @ts-ignore + Buffer.from(input_chunk_raw)); + input_chunks.push(input_chunk); + timeout_start(); + }); + socket.on("end", () => { + if (!ended) { + lib_plankton.log.info("server_client_disconnected", {}); + ended = true; + timeout_stop(); + } + else { + lib_plankton.log.info("server_socket_already_ended"); + // do nothing + } + }); + }); + subject.serverobj.on("error", (error) => { + // throw error; + process.stderr.write("net_error: " + String(error) + "\n\n"); + }); + subject.serverobj.listen(subject.port, subject.host, 511, () => { + lib_plankton.log.info("server_listenting", { + "host": subject.host, + "port": subject.port, + }); + resolve(undefined); + }); + })); + } + server.start = start; + /** + * @author fenris + */ + function kill(subject) { + subject.serverobj.close(); + lib_plankton.log.info("server_stopped", {}); + } + server.kill = kill; + })(server = lib_plankton.server || (lib_plankton.server = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:server«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:server« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:server« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:server«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var server; + (function (server) { + /** + * @author fenris + */ + class class_server { + /** + * @author fenris + */ + constructor(handle, options = {}) { + options = Object.assign({ + "host": "::", + "port": 9999, + }, options); + this.subject = server.make(handle, { + "host": options.host, + "port": options.port, + }); + } + /** + * @author fenris + */ + start() { + return server.start(this.subject); + } + /** + * @author fenris + */ + kill() { + return server.kill(this.subject); + } + } + server.class_server = class_server; + })(server = lib_plankton.server || (lib_plankton.server = {})); +})(lib_plankton || (lib_plankton = {})); +var lib_server = lib_plankton.server; +/* +This file is part of »bacterio-plankton:args«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:args« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:args« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:args«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var args; + (function (args) { + /** + */ + var enum_environment; + (function (enum_environment) { + enum_environment["cli"] = "cli"; + enum_environment["url"] = "url"; + })(enum_environment = args.enum_environment || (args.enum_environment = {})); + ; + /** + */ + var enum_kind; + (function (enum_kind) { + enum_kind["positional"] = "positional"; + enum_kind["volatile"] = "volatile"; + })(enum_kind = args.enum_kind || (args.enum_kind = {})); + ; + /** + */ + var enum_type; + (function (enum_type) { + enum_type["boolean"] = "boolean"; + enum_type["integer"] = "int"; + enum_type["float"] = "float"; + enum_type["string"] = "string"; + })(enum_type = args.enum_type || (args.enum_type = {})); + ; + /** + */ + var enum_mode; + (function (enum_mode) { + enum_mode["replace"] = "replace"; + enum_mode["accumulate"] = "accumulate"; + })(enum_mode = args.enum_mode || (args.enum_mode = {})); + ; + })(args = lib_plankton.args || (lib_plankton.args = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:args«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:args« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:args« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:args«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var args; + (function (args) { + /* + export enum_mode { + replace = "replace", + accumulate = "accumulate", + }; + */ + /** + * @author fenris + */ + var class_argument = /** @class */ (function () { + /** + * @author fenris + */ + function class_argument(_a) { + var name = _a["name"], _b = _a["type"], type = _b === void 0 ? args.enum_type.string : _b, _c = _a["kind"], kind = _c === void 0 ? args.enum_kind.positional : _c, _d = _a["mode"], mode = _d === void 0 ? args.enum_mode.replace : _d, _e = _a["default"], default_ = _e === void 0 ? null : _e, _f = _a["info"], info = _f === void 0 ? null : _f, _g = _a["parameters"], parameters = _g === void 0 ? {} : _g, _h = _a["hidden"], hidden = _h === void 0 ? false : _h; + this.name = name; + this.type = type; + this.kind = kind; + this.mode = mode; + this.default_ = default_; + this.info = info; + this.parameters = parameters; + this.hidden = hidden; + if (!this.check()) { + throw (new Error("invalid argument-setup")); + } + } + /** + * @author fenris + */ + class_argument.positional = function (_a) { + var name = _a["name"], _b = _a["type"], type = _b === void 0 ? args.enum_type.string : _b, _c = _a["mode"], mode = _c === void 0 ? args.enum_mode.replace : _c, _d = _a["default"], default_ = _d === void 0 ? null : _d, _e = _a["info"], info = _e === void 0 ? null : _e, _f = _a["hidden"], hidden = _f === void 0 ? false : _f, index = _a["index"]; + return (new class_argument({ + "name": name, + "kind": args.enum_kind.positional, + "type": type, + "mode": mode, + "default": default_, + "info": info, + "hidden": hidden, + "parameters": { + "index": index + } + })); + }; + /** + * @author fenris + */ + class_argument.volatile = function (_a) { + var name = _a["name"], _b = _a["type"], type = _b === void 0 ? args.enum_type.string : _b, _c = _a["mode"], mode = _c === void 0 ? args.enum_mode.replace : _c, _d = _a["default"], default_ = _d === void 0 ? null : _d, _e = _a["info"], info = _e === void 0 ? null : _e, _f = _a["hidden"], hidden = _f === void 0 ? false : _f, indicators_short = _a["indicators_short"], indicators_long = _a["indicators_long"]; + return (new class_argument({ + "name": name, + "kind": args.enum_kind.volatile, + "type": type, + "mode": mode, + "default": default_, + "info": info, + "hidden": hidden, + "parameters": { + "indicators_short": indicators_short, + "indicators_long": indicators_long + } + })); + }; + /** + * @author fenris + */ + class_argument.prototype.check = function () { + var _this = this; + return [ + function () { return ((!(_this.kind == args.enum_kind.volatile)) + || + (("indicators_long" in _this.parameters) + && + (_this.parameters["indicators_long"]["length"] >= 0))); }, + ].every(function (condition) { return condition(); }); + }; + /** + * @author fenris + */ + class_argument.prototype.name_get = function () { + return this.name; + }; + /** + * @author fenris + */ + class_argument.prototype.kind_get = function () { + return this.kind; + }; + /** + * @author fenris + */ + class_argument.prototype.type_get = function () { + return this.type; + }; + /** + * @author fenris + */ + class_argument.prototype.mode_get = function () { + return this.mode; + }; + /** + * @author fenris + */ + class_argument.prototype.default_get = function () { + return this.default_; + }; + /** + * @author fenris + */ + class_argument.prototype.parameters_get = function () { + return this.parameters; + }; + /** + * @author fenris + */ + class_argument.prototype.hidden_get = function () { + return this.hidden; + }; + /** + * @author fenris + */ + class_argument.prototype.toString = function () { + return "<".concat(this.name, ">"); + }; + /** + * @author fenris + */ + class_argument.prototype.indicator_main = function () { + if (this.kind === args.enum_kind.volatile) { + return this.parameters["indicators_long"][0]; + } + else { + return null; + } + }; + /** + * @author fenris + */ + class_argument.prototype.pattern_value = function () { + switch (this.type) { + case args.enum_type.boolean: { + return "false|true"; + break; + } + case args.enum_type.integer: { + return "[0-9]+"; + break; + } + case args.enum_type.float: { + return "\\d*(?:\\.\\d+)?"; + break; + } + case args.enum_type.string: { + return "\\S+"; + break; + } + default: { + throw (new Error("unhandled type ".concat(this.type))); + break; + } + } + }; + /** + * @author fenris + */ + class_argument.prototype.extract = function (raw) { + switch (this.type) { + case args.enum_type.boolean: { + return (raw != "false"); + break; + } + case args.enum_type.integer: { + return parseInt(raw); + break; + } + case args.enum_type.float: { + return parseFloat(raw); + break; + } + case args.enum_type.string: { + return raw; + break; + } + default: { + throw (new Error("unhandled type ".concat(this.type))); + break; + } + } + }; + /** + * @author fenris + */ + class_argument.prototype.assign = function (data, target, raw) { + var value = this.extract(raw); + switch (this.mode) { + case args.enum_mode.replace: { + data[target] = value; + break; + } + case args.enum_mode.accumulate: { + /* + if (! (this.name in data)) { + data[this.name] = []; + } + */ + data[target].push(value); + break; + } + default: { + throw (new Error("unhandled mode ".concat(this.mode))); + } + } + }; + /** + * @author fenris + */ + class_argument.prototype.make = function (data, target) { + var value = data[target]; + return value.toString(); + }; + /** + * @author fenris + */ + class_argument.prototype.generate_help = function () { + var _this = this; + var _a, _b, _c, _d; + var output = ""; + { + switch (this.kind) { + case args.enum_kind.positional: { + var line = ""; + line += "\t"; + line += "<".concat(this.name, ">"); + line += "\n"; + output += line; + } + case args.enum_kind.volatile: { + var line = ""; + line += "\t"; + if (this.type === args.enum_type.boolean) { + line += ([] + .concat(((_a = this.parameters["indicators_short"]) !== null && _a !== void 0 ? _a : []).map(function (indicator) { return ("-" + indicator); })) + .concat(((_b = this.parameters["indicators_long"]) !== null && _b !== void 0 ? _b : []).map(function (indicator) { return ("--" + indicator); })) + .join(" | ")); + } + else { + line += ([] + .concat(((_c = this.parameters["indicators_short"]) !== null && _c !== void 0 ? _c : []).map(function (indicator) { return ("-" + indicator + " " + ("<" + _this.name + ">")); })) + .concat(((_d = this.parameters["indicators_long"]) !== null && _d !== void 0 ? _d : []).map(function (indicator) { return ("--" + indicator + "=" + ("<" + _this.name + ">")); })) + .join(" | ")); + } + line += "\n"; + output += line; + } + } + } + { + var line = ""; + line += "\t\t"; + var infotext = ((this.info == null) ? "(no info available)" : this.info); + line += infotext; + if ((this.type != "boolean") && (this.default_ != null)) { + line += "; default: ".concat(this.default_.toString()); + } + line += "\n"; + output += line; + } + return output; + }; + return class_argument; + }()); + args.class_argument = class_argument; + })(args = lib_plankton.args || (lib_plankton.args = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:args«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:args« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:args« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:args«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var args; + (function (args) { + /** + * @author fenris + */ + var settings = { + "environment": { + "cli": { + "symbols": { + "delimiter": " ", + "prefix": "--", + "assignment": "=" + } + }, + "url": { + "symbols": { + "delimiter": "&", + "prefix": "", + "assignment": "=" + } + } + } + }; + /** + * @author fenris + */ + args.verbosity = 0; + /** + * @author fenris + * @todo check validity + */ + var class_handler = /** @class */ (function () { + /** + * @author fenris + */ + function class_handler(arguments_) { + this.arguments_ = arguments_; + } + /** + * @author fenris + */ + class_handler.prototype.filter = function (kind) { + var arguments_ = {}; + for (var _i = 0, _a = Object.entries(this.arguments_); _i < _a.length; _i++) { + var _b = _a[_i], name = _b[0], argument = _b[1]; + if (argument.kind_get() == kind) { + arguments_[name] = argument; + } + } + return arguments_; + }; + /** + * @author fenris + */ + class_handler.prototype.read = function (environment, input, data) { + var _this = this; + if (data === void 0) { data = {}; } + switch (environment) { + case args.enum_environment.cli: + case args.enum_environment.url: { + // default values + { + for (var _i = 0, _a = Object.entries(this.arguments_); _i < _a.length; _i++) { + var _b = _a[_i], name = _b[0], argument = _b[1]; + data[name] = argument.default_get(); + } + } + // preprocessing + { + // short indicators (lil hacky ...) + { + if (environment == args.enum_environment.cli) { + for (var _c = 0, _d = Object.entries(this.filter(args.enum_kind.volatile)); _c < _d.length; _c++) { + var _e = _d[_c], name = _e[0], argument = _e[1]; + // console.info(argument.parameters_get()["indicators_short"].join("|")); + var pattern_from = ""; + { + pattern_from += "(?:^|".concat(settings["environment"][environment]["symbols"]["delimiter"], ")"); + pattern_from += "-".concat(argument.parameters_get()["indicators_short"].join("|")); + pattern_from += "(?:$|".concat(settings["environment"][environment]["symbols"]["delimiter"], ")"); + } + var pattern_to = ""; + { + pattern_to += settings["environment"][environment]["symbols"]["delimiter"]; + pattern_to += settings["environment"][environment]["symbols"]["prefix"]; + pattern_to += argument.indicator_main(); + if (argument.type_get() == args.enum_type.boolean) { + pattern_to += settings["environment"][environment]["symbols"]["delimiter"]; + } + else { + pattern_to += settings["environment"][environment]["symbols"]["assignment"]; + } + } + var result = input.replace(new RegExp(pattern_from, "g"), pattern_to); + lib_plankton.log.debug("lib_args:read:replacing", { + "pattern_from": pattern_from, + "pattern_to": pattern_to, + "input": input, + "result": result + }); + input = result; + } + } + } + lib_plankton.log.debug("lib_args:read:current_input", { + "input": input + }); + } + // parsing + { + var parts = input + .split(settings["environment"][environment]["symbols"]["delimiter"]) + .filter(function (x) { return (x != ""); }); + var index_expected_1 = 0; + parts.forEach(function (part) { + lib_plankton.log.debug("lib_args:read:analyzing", { + "part": part + }); + var found = [ + function () { + lib_plankton.log.debug("lib_args:read:probing_as_volatile", { + "part": part + }); + for (var _i = 0, _a = Object.entries(_this.filter(args.enum_kind.volatile)); _i < _a.length; _i++) { + var _b = _a[_i], name = _b[0], argument = _b[1]; + lib_plankton.log.debug("lib_args:read:probing_as_volatile:trying", { + "part": part, + "argument": argument.toString() + }); + var pattern = ""; + { + var pattern_front = ""; + pattern_front += "".concat(settings["environment"][environment]["symbols"]["prefix"]); + pattern_front += "(?:".concat(argument.parameters_get()["indicators_long"].join("|"), ")"); + pattern += pattern_front; + } + { + var pattern_back = ""; + pattern_back += "".concat(settings["environment"][environment]["symbols"]["assignment"]); + pattern_back += "(".concat(argument.pattern_value(), ")"); + if (argument.type_get() == args.enum_type.boolean) { + pattern_back = "(?:".concat(pattern_back, ")?"); + } + pattern += pattern_back; + } + lib_plankton.log.debug("lib_args:read:probing_as_volatile:pattern", { + "pattern": pattern + }); + var regexp = new RegExp(pattern); + var matching = regexp.exec(part); + lib_plankton.log.debug("lib_args:read:probing_as_volatile:matching", { + "matching": matching + }); + if (matching == null) { + // do nothing + } + else { + argument.assign(data, name, matching[1]); + return true; + } + } + return false; + }, + function () { + lib_plankton.log.debug("lib_args:read:probing_as_positional", { + "part": part + }); + var positional = _this.filter(args.enum_kind.positional); + for (var _i = 0, _a = Object.entries(positional); _i < _a.length; _i++) { + var _b = _a[_i], name = _b[0], argument = _b[1]; + if (argument.parameters_get()['index'] !== index_expected_1) { + // do nothing + } + else { + lib_plankton.log.debug("lib_args:read:probing_as_positional:trying", { + "part": part, + "argument": argument.toString() + }); + var pattern = ""; + { + var pattern_back = ""; + pattern_back += "(".concat(argument.pattern_value(), ")"); + pattern += pattern_back; + } + lib_plankton.log.debug("lib_args:read:probing_as_positional:pattern", { + "pattern": pattern + }); + var regexp = new RegExp(pattern); + var matching = regexp.exec(part); + lib_plankton.log.debug("lib_args:read:probing_as_positional:matching", { + "matching": matching + }); + if (matching == null) { + return false; + } + else { + argument.assign(data, name, matching[1]); + index_expected_1 += 1; + return true; + } + } + } + return false; + }, + ].some(function (x) { return x(); }); + if (!found) { + lib_plankton.log.warning("lib_args:read:could_not_parse", { + "part": part + }); + } + }); + } + return data; + break; + } + default: { + throw (new Error("unhandled environment ".concat(environment))); + break; + } + } + }; + /** + * @author fenris + * @todo handle if the data object doesn't have the required field or the type is wrong or sth. + */ + class_handler.prototype.write = function (environment, data) { + switch (environment) { + case args.enum_environment.cli: { + return (([] + .concat(Object.entries(this.filter(args.enum_kind.volatile)).map(function (_a) { + var name = _a[0], argument = _a[1]; + var values; + switch (argument.mode_get()) { + case args.enum_mode.replace: { + values = [data[argument.name_get()]]; + break; + } + case args.enum_mode.accumulate: { + values = data[argument.name_get()]; + break; + } + } + return (values + .map(function (value) { return ((settings["environment"][environment]["symbols"]["prefix"] + + + argument.parameters_get()["indicators_long"][0]) + + + (settings["environment"][environment]["symbols"]["assignment"] + + + value.toString())); }) + .join(" ")); + })) + .concat(Object.entries(this.filter(args.enum_kind.positional)).map(function (_a) { + var name = _a[0], argument = _a[1]; + var raw = ""; + { + var raw_back = ""; + raw_back += argument.make(data, name); + raw += raw_back; + } + return raw; + }))) + .join(settings["environment"][environment]["symbols"]["delimiter"])); + break; + } + default: { + throw (new Error("unhandled environment ".concat(environment))); + break; + } + } + }; + /** + * @desc manpage-like info-sheet + * @author fenris + */ + class_handler.prototype.generate_help = function (_a) { + var _b = _a["programname"], programname = _b === void 0 ? null : _b, _c = _a["author"], author = _c === void 0 ? null : _c, _d = _a["description"], description = _d === void 0 ? null : _d, _e = _a["executable"], executable = _e === void 0 ? null : _e; + var environment = args.enum_environment.cli; + var output = ""; + { + var section = ""; + { + var line = ""; + line += ""; + line += "INFO"; + line += "\n"; + section += line; + } + { + var line = ""; + line += "\t"; + line += "".concat(programname, " -- ").concat(description); + line += "\n"; + section += line; + } + section += "\n"; + output += section; + } + { + if (author != null) { + var section = ""; + { + var line = ""; + line += ""; + line += "AUTHOR"; + line += "\n"; + section += line; + } + { + var line = ""; + line += "\t"; + line += "".concat(author); + line += "\n"; + section += line; + } + section += "\n"; + output += section; + } + } + { + var section = ""; + { + var line = ""; + line += ""; + line += "SYNOPSIS"; + line += "\n"; + section += line; + } + { + var line = ""; + line += "\t"; + line += executable; + line += settings["environment"][environment]["symbols"]["delimiter"]; + line += Object.entries(this.filter(args.enum_kind.positional)) + .map(function (_a) { + var name = _a[0], argument = _a[1]; + var part = ""; + part += "<".concat(argument.name_get(), ">"); + return part; + }) + .join(settings["environment"][environment]["symbols"]["delimiter"]); + line += settings["environment"][environment]["symbols"]["delimiter"]; + line += Object.entries(this.filter(args.enum_kind.volatile)) + .filter(function (_a) { + var name = _a[0], argument = _a[1]; + return (!argument.hidden_get()); + }) + .map(function (_a) { + var name = _a[0], argument = _a[1]; + var part = ""; + // part += settings["environment"][environment]["symbols"]["prefix"]; + part += "-"; + part += argument.parameters_get()["indicators_short"][0]; + if (argument.type_get() != "boolean") { + /* + part += settings["environment"][environment]["symbols"]["assignment"]; + part += `<${argument.name_get()}>`; + */ + part += " "; + part += "<".concat(argument.name_get(), ">"); + } + part = "[".concat(part, "]"); + return part; + }) + .join(settings["environment"][environment]["symbols"]["delimiter"]); + line += "\n"; + section += line; + } + section += "\n"; + output += section; + } + { + var section = ""; + { + var line = ""; + line += ""; + line += "OPTIONS"; + line += "\n"; + section += line; + } + { + section += (Object.entries(this.arguments_) + .filter(function (_a) { + var name = _a[0], argument = _a[1]; + return (!argument.hidden_get()); + }) + .map(function (_a) { + var name = _a[0], argument = _a[1]; + return argument.generate_help(); + }) + .join("\n")); + } + section += "\n"; + output += section; + } + return output; + }; + return class_handler; + }()); + args.class_handler = class_handler; + })(args = lib_plankton.args || (lib_plankton.args = {})); })(lib_plankton || (lib_plankton = {})); diff --git a/source/api/actions/calendar_list.ts b/source/api/actions/calendar_list.ts new file mode 100644 index 0000000..14bdd83 --- /dev/null +++ b/source/api/actions/calendar_list.ts @@ -0,0 +1,74 @@ + +namespace _zeitbild.api +{ + + /** + */ + export function register_calendar_list( + rest_subject : lib_plankton.rest.type_rest + ) : void + { + register< + null, + Array< + { + id : _zeitbild.type.calendar_id; + preview : { + name : string; + }; + } + > + >( + rest_subject, + lib_plankton.http.enum_method.get, + "/calendar/list", + { + "description": "listet alle Kalender auf", + "query_parameters": [ + ], + "output_schema": () => ({ + "type": "array", + "items": { + "type": "object", + "nullable": false, + "additionalProperties": false, + "properties": { + "id": { + "type": "number", + "nullable": false, + }, + "preview": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "nullable": false, + }, + }, + "required": [ + "name", + ] + } + }, + "required": [ + "id", + "preview", + ], + } + }), + "restriction": restriction_none, // TODO + "execution": () => ( + _zeitbild.service.calendar.list(null) + .then( + data => Promise.resolve({ + "status_code": 200, + "data": data, + }) + ) + ) + } + ); + } + +} diff --git a/source/api/actions/meta_ping.ts b/source/api/actions/meta_ping.ts new file mode 100644 index 0000000..bfe01f1 --- /dev/null +++ b/source/api/actions/meta_ping.ts @@ -0,0 +1,40 @@ + +namespace _zeitbild.api +{ + + /** + */ + export function register_meta_ping( + rest_subject : lib_plankton.rest.type_rest + ) : void + { + lib_plankton.rest.register< + null, + string + > + ( + rest_subject, + lib_plankton.http.enum_method.get, + _zeitbild.conf.get().server.path_base + "/meta/ping", + { + "description": "sendet ein 'pong' zurück; gedacht um die Erreichbarkeit des Backends zu prüfen", + "input_schema": () => ({ + "nullable": true, + }), + "output_schema": () => ({ + "nullable": false, + "type": "string", + }), + "restriction": restriction_none, + "execution": () => { + return Promise.resolve({ + "status_code": 200, + "data": "pong", + }); + }, + } + ); + } + +} + diff --git a/source/api/actions/meta_spec.ts b/source/api/actions/meta_spec.ts new file mode 100644 index 0000000..cecb3ad --- /dev/null +++ b/source/api/actions/meta_spec.ts @@ -0,0 +1,37 @@ + +namespace _zeitbild.api +{ + + /** + */ + export function register_meta_spec( + rest_subject : lib_plankton.rest.type_rest + ) : void + { + lib_plankton.rest.register< + null, + any + > + ( + rest_subject, + lib_plankton.http.enum_method.get, + _zeitbild.conf.get().server.path_base + "/meta/spec", + { + "description": "gibt die API-Spezifikation im OpenAPI-Format aus", + "input_schema": () => ({ + "nullable": true, + }), + "output_schema": () => ({ + }), + "restriction": restriction_none, + "execution": () => { + return Promise.resolve({ + "status_code": 200, + "data": lib_plankton.rest.to_oas(rest_subject), + }); + }, + } + ); + } + +} diff --git a/source/api/base.ts b/source/api/base.ts new file mode 100644 index 0000000..6eb2444 --- /dev/null +++ b/source/api/base.ts @@ -0,0 +1,76 @@ + +namespace _zeitbild.api +{ + + /** + * @todo zu plankton auslagern? + */ + type type_stuff = { + version: (null | string); + headers: Record; + path_parameters: Record; + query_parameters: Record; + }; + + + /** + */ + export async function session_from_stuff( + stuff : {headers : Record;} + ) : Promise<{key : string; value : lib_plankton.session.type_session}> + { + const key : string = (stuff.headers["X-Session-Key"] || stuff.headers["X-Session-Key".toLowerCase()]); + const value : lib_plankton.session.type_session = await lib_plankton.session.get(key); + return {"key": key, "value": value}; + } + + + /** + */ + export const restriction_none : lib_plankton.rest.type_restriction = ( + (stuff) => Promise.resolve(true) + ); + + + /** + */ + export function register( + rest_subject : lib_plankton.rest.type_rest, + http_method : lib_plankton.http.enum_method, + path : string, + options : { + active ?: ((version : string) => boolean); + restriction ?: (null | lib_plankton.rest.type_restriction); + execution ?: lib_plankton.rest.type_execution; + title ?: (null | string); + description ?: (null | string); + query_parameters ?: Array< + { + name : string; + description : (null | string); + required : boolean; + } + >; + input_schema ?: ((version: (null | string)) => lib_plankton.rest.type_oas_schema); + output_schema ?: ((version: (null | string)) => lib_plankton.rest.type_oas_schema); + request_body_mimetype ?: string; + request_body_decode ?: ((http_request_body : Buffer, http_request_header_content_type : (null | string)) => any); + response_body_mimetype ?: string; + response_body_encode ?: ((output : any) => Buffer); + } = {} + ) : void + { + options = Object.assign( + { + }, + options + ); + lib_plankton.rest.register( + rest_subject, + http_method, + (_zeitbild.conf.get().server.path_base + path), + options + ); + } + +} diff --git a/source/api/functions.ts b/source/api/functions.ts new file mode 100644 index 0000000..a11b616 --- /dev/null +++ b/source/api/functions.ts @@ -0,0 +1,37 @@ + +namespace _zeitbild.api +{ + + /** + */ + export function make( + ) : lib_plankton.rest.type_rest + { + const rest_subject : lib_plankton.rest.type_rest = lib_plankton.rest.make( + { + "title": "zeitbild", + "versioning_method": "header", + "versioning_header_name": "X-Api-Version", + "set_access_control_headers": true, + "authentication": { + "kind": "key_header", + "parameters": {"name": "X-Session-Key"} + }, + } + ); + // meta + { + _zeitbild.api.register_meta_ping(rest_subject); + _zeitbild.api.register_meta_spec(rest_subject); + } + // calendar + { + _zeitbild.api.register_calendar_list(rest_subject); + } + + + return rest_subject; + } + +} + diff --git a/source/backend.ts b/source/backend.ts new file mode 100644 index 0000000..332a099 --- /dev/null +++ b/source/backend.ts @@ -0,0 +1,6 @@ + +/** + */ +namespace _zeitbild.frontend.resources.backend +{ +} diff --git a/source/conf.ts b/source/conf.ts new file mode 100644 index 0000000..8e7c31b --- /dev/null +++ b/source/conf.ts @@ -0,0 +1,237 @@ + +namespace _zeitbild.conf +{ + + /** + */ + type type_log_threshold = ( + "debug" + | + "info" + | + "notice" + | + "warning" + | + "error" + ); + + + /** + */ + type type_log_format = ( + "jsonl" + | + "human_readable" + ); + + + /** + */ + export type type_conf = { + general : { + language : (null | string); + }; + log : Array< + { + kind : "stdout"; + data : { + threshold : type_log_threshold; + }; + } + | + { + kind : "file"; + data : { + threshold : type_log_threshold; + path : string; + }; + } + | + { + kind : "email"; + data : { + threshold : type_log_threshold; + smtp_credentials : { + host : string; + port : int; + username : string; + password : string; + }; + sender : string; + receivers : Array; + }; + } + >; + server : { + host : string; + port : int; + path_base : string; + }; + database : ( + { + kind : "sqlite"; + data : { + path : string; + }; + } + | + { + kind : "postgresql"; + data : { + host : string; + port ?: int; + username : string; + password : string; + schema : string; + }; + } + ); + session_management : { + in_memory : boolean; + drop_all_at_start : boolean; + lifetime : int; + }; + }; + + + /** + */ + var _data : (null | type_conf) = null; + + + /** + */ + export function inject( + conf_raw : any + ) : void + { + const version : int = (conf_raw["version"] ?? 1); + _data = { + "general": ( + ((node_general) => ({ + "language": (node_general["language"] ?? null), + })) (conf_raw["general"] ?? {}) + ), + "log": ( + (() => { + const node_log = ( + conf_raw["log"] + ?? + [ + { + "kind": "stdout", + "data": { + } + }, + ] + ); + return ( + node_log.map( + (node_log_entry : any) => ({ + "kind": node_log_entry["kind"], + "data": Object.assign( + { + "format": "human_readable", + "threshold": "notice", + }, + (node_log_entry["data"] ?? {}) + ) + }) + ) + ); + }) () + ), + "server": ( + ((node_server) => ({ + "host": (() => { + return (node_server["host"] ?? "::"); + }) (), + "port": (node_server["port"] ?? 7845), + "path_base": (node_server["path_base"] ?? ""), + })) (conf_raw["server"] ?? {}) + ), + "database": ( + ((node_database) => { + const kind : string = (node_database["kind"] ?? "sqlite"); + const node_database_data_raw = (node_database["data"] ?? {}); + switch (kind) { + case "sqlite": { + return { + "kind": kind, + "data": { + "path": (node_database_data_raw["path"] ?? "data.sqlite"), + } + }; + break; + } + case "postgresql": { + return { + "kind": kind, + "data": node_database_data_raw, + }; + break; + } + default: { + throw (new Error("unhandled")); + break; + } + } + }) (conf_raw["database"] ?? {}) + ), + "session_management": ( + ((node_session_management) => ({ + "in_memory": (node_session_management["in_memory"] ?? true), + "drop_all_at_start": (node_session_management["drop_all_at_start"] ?? true), + "lifetime": (node_session_management["lifetime"] ?? 900), + })) (conf_raw["session_management"] ?? {}) + ), + }; + } + + + /** + * @todo mandatory fields + */ + export async function load( + path : string + ) : Promise + { + let conf_raw : any; + if (! (await lib_plankton.file.exists(path))) { + // return Promise.reject(new Error("configuration file not found: " + path + "; using fallback")); + conf_raw = {}; + } + else { + try { + conf_raw = lib_plankton.json.decode(await lib_plankton.file.read(path)); + } + catch (error) { + conf_raw = null; + } + } + if (conf_raw === null) { + return Promise.reject("configuration file could not be read"); + } + else { + inject(conf_raw); + // process.stderr.write(JSON.stringify(_data, undefined, "\t")); + return Promise.resolve(undefined); + } + } + + + /** + */ + export function get( + ) : type_conf + { + if (_data === null) { + throw (new Error("conf not loaded yet")); + } + else { + return _data; + } + } + +} diff --git a/source/database.ts b/source/database.ts new file mode 100644 index 0000000..c88a3ab --- /dev/null +++ b/source/database.ts @@ -0,0 +1,112 @@ + +namespace _zeitbild.database +{ + + /** + */ + const _compatible_revisions : Array = [ + "r1", + ]; + + + /** + */ + export function get_implementation( + ) : lib_plankton.database.type_database + { + switch (_zeitbild.conf.get().database.kind) { + case "sqlite": { + type type_parameters = { + path : string; + }; + const parameters : type_parameters = (_zeitbild.conf.get().database.data as type_parameters); + return lib_plankton.database.sqlite_database( + { + "path": parameters.path, + } + ); + break; + } + case "postgresql": { + type type_parameters = { + host : string; + port ?: int; + username : string; + password : string; + schema : string; + }; + const parameters : type_parameters = (_zeitbild.conf.get().database.data as type_parameters); + return lib_plankton.database.postgresql_database( + { + "host": parameters.host, + "port": parameters.port, + "username": parameters.username, + "password": parameters.password, + "schema": parameters.schema, + } + ); + } + default: { + throw (new Error("database implementation not available: " + _zeitbild.conf.get().database.kind)); + } + } + } + + + /** + */ + function get_revision( + ) : Promise<(null | string)> + { + return ( + get_implementation().query_select( + { + "source": "_meta", + "fields": ["revision"], + } + ) + .then<(null | string)>( + (rows) => Promise.resolve<(null | string)>(rows[0]["revision"]) + ) + .catch<(null | string)>( + (reason) => { + lib_plankton.log.warning( + "database_get_revision_error", + { + "reason": String(reason), + } + ); + return Promise.resolve<(null | string)>(null); + } + ) + ); + } + + + /** + */ + export async function check( + ) : Promise + { + const revision : (null | string) = await get_revision(); + lib_plankton.log.info( + "database_check", + { + "revision_found": revision, + "revisions_compatible": _compatible_revisions, + } + ); + if (revision === null) { + return Promise.reject(new Error("database appearently missing")); + } + else { + if (! _compatible_revisions.includes(revision)) { + return Promise.reject(new Error("database revision incompatible; found: " + revision + "; required: " + String(_compatible_revisions))); + } + else { + return Promise.resolve(undefined); + } + } + } + +} diff --git a/source/logic/helpers.ts b/source/helpers.ts similarity index 99% rename from source/logic/helpers.ts rename to source/helpers.ts index e3ebf88..9a13b93 100644 --- a/source/logic/helpers.ts +++ b/source/helpers.ts @@ -1,7 +1,7 @@ /** */ -namespace _zeitbild.frontend.helpers +namespace _zeitbild.helpers { /** diff --git a/source/index.html b/source/index.html deleted file mode 100644 index 185ef1a..0000000 --- a/source/index.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - diff --git a/source/logic/backend.ts b/source/logic/backend.ts deleted file mode 100644 index ccb2f05..0000000 --- a/source/logic/backend.ts +++ /dev/null @@ -1,333 +0,0 @@ -/** - */ -namespace _zeitbild.frontend.resources.backend -{ - - /** - */ - var _data : _zeitbild.frontend.type_datamodel; - - - /** - */ - export async function init( - ) : Promise - { - const path : string = "data.json"; - if (_data === undefined) { - _data = lib_plankton.call.convey( - await lib_plankton.file.read(path), - [ - lib_plankton.json.decode, - (data_raw : any) => ( - ({ - "users": data_raw["users"], - "calendars": ( - data_raw["calendars"] - .map( - (calendar_entry_raw : any) => ({ - "id": calendar_entry_raw["id"], - "object": ( - ((calendar_object_raw) => { - switch (calendar_object_raw["kind"]) { - default: { - return calendar_object_raw; - break; - } - case "concrete": { - return { - "kind": "concrete", - "data": { - "name": calendar_object_raw["data"]["name"], - "private": ( - calendar_object_raw["data"]["private"] - ?? - false - ), - "users": calendar_object_raw["data"]["users"], - "events": ( - calendar_object_raw["data"]["events"] - .map( - (event_raw : any) => ({ - "name": event_raw["name"], - "begin": event_raw["begin"], - "end": ( - ( - ( - event_raw["end"] - ?? - null - ) - === - null - ) - ? - null - : - event_raw["end"] - ), - "location": ( - event_raw["location"] - ?? - null - ), - "description": ( - event_raw["description"] - ?? - null - ), - }) - ) - ), - }, - }; - break; - } - } - }) (calendar_entry_raw["object"]) - ), - }) - ) - ), - }) as type_datamodel - ), - ] - ); - } - else { - // do nothing - } - return Promise.resolve(undefined); - } - - - /** - */ - export async function calendar_list( - ) : Promise< - Array< - { - key : type_calendar_id; - preview : { - name : string; - } - } - > - > - { - await init(); - return Promise.resolve( - _data.calendars - .map( - (calendar_entry) => { - switch (calendar_entry.object.kind) { - case "concrete": { - return { - "key": calendar_entry.id, - "preview": { - "name": calendar_entry.object.data.name, - } - }; - break; - } - case "caldav": { - return { - "key": calendar_entry.id, - "preview": { - "name": "(imported)", - } - }; - } - } - } - ) - ); - } - - - /** - */ - export async function calendar_read( - calendar_id : type_calendar_id - ) : Promise - { - await init(); - const hits = ( - _data.calendars - .filter( - (calendar_entry) => (calendar_entry.id === calendar_id) - ) - ); - if (hits.length <= 0) { - return Promise.reject(new Error("not found")); - } - else { - return Promise.resolve(hits[0].object); - } - } - - - /** - * @todo prevent loops - */ - export async function calendar_gather_events( - calendar_ids : Array, - from_pit : _zeitbild.frontend.helpers.type_pit, - to_pit : _zeitbild.frontend.helpers.type_pit - ) : Promise< - Array< - { - calendar_id : type_calendar_id; - calendar_name : string; - event : type_event; - } - > - > - { - lib_plankton.log.info( - "calendar_gather_events", - { - "calendar_ids": calendar_ids, - } - ); - await init(); - let result : Array< - { - calendar_id : type_calendar_id; - calendar_name : string; - event : type_event; - } - > = []; - for await (const calendar_id of calendar_ids) { - const calendar_object : type_calendar_object = await calendar_read( - calendar_id - ); - if (calendar_object.data.private) { - lib_plankton.log.info( - "calendar_gather_events_private_calendar_blocked", - { - "calendar_id": calendar_id, - } - ); - } - else { - switch (calendar_object.kind) { - case "concrete": { - result = ( - result - .concat( - calendar_object.data.events - .filter( - (event) => _zeitbild.frontend.helpers.pit_is_between( - _zeitbild.frontend.helpers.pit_from_datetime(event.begin), - from_pit, - to_pit - ) - ) - .map( - (event) => ({ - "calendar_id": calendar_id, - "calendar_name": calendar_object.data.name, - "event": event - }) - ) - ) - ); - break; - } - case "caldav": { - const url : lib_plankton.url.type_url = lib_plankton.url.decode( - calendar_object.data.source_url - ); - const http_request : lib_plankton.http.type_request = { - "version": "HTTP/2", - "scheme": ((url.scheme === "https") ? "https" : "http"), - "host": url.host, - "path": (url.path ?? "/"), - "query": url.query, - "method": lib_plankton.http.enum_method.get, - "headers": {}, - "body": null, - }; - // TODO: cache? - const http_response : lib_plankton.http.type_response = await lib_plankton.http.call( - http_request, - { - } - ); - const vcalendar : lib_plankton.ical.type_vcalendar = lib_plankton.ical.ics_decode( - http_response.body.toString(), - { - } - ); - result = ( - result - .concat( - vcalendar.vevents - .map( - (vevent : lib_plankton.ical.type_vevent) => ( - (vevent.dtstart !== undefined) - ? - { - "name": ( - (vevent.summary !== undefined) - ? - vevent.summary - : - "???" - ), - "begin": _zeitbild.frontend.helpers.ical_dt_to_own_datetime(vevent.dtstart), - "end": ( - (vevent.dtend !== undefined) - ? - _zeitbild.frontend.helpers.ical_dt_to_own_datetime(vevent.dtend) - : - null - ), - "location": ( - (vevent.location !== undefined) - ? - vevent.location - : - null - ), - "description": ( - (vevent.description !== undefined) - ? - vevent.description - : - null - ), - } - : - null - ) - ) - .filter( - (event) => (event !== null) - ) - .filter( - (event) => _zeitbild.frontend.helpers.pit_is_between( - _zeitbild.frontend.helpers.pit_from_datetime(event.begin), - from_pit, - to_pit - ) - ) - .map( - (event) => ({ - "calendar_id": calendar_id, - "calendar_name": calendar_object.data.name, - "event": event, - }) - ) - ) - ); - break; - } - } - } - } - return Promise.resolve(result); - } - -} diff --git a/source/logic/cli.ts b/source/logic/cli.ts deleted file mode 100644 index cd3af7e..0000000 --- a/source/logic/cli.ts +++ /dev/null @@ -1,218 +0,0 @@ - - -/** - */ -async function main( - args_raw : Array -) : Promise -{ - const arg_handler : lib_plankton.args.class_handler = new lib_plankton.args.class_handler({ - "data_path": lib_plankton.args.class_argument.volatile({ - "indicators_long": ["data-path"], - "indicators_short": ["d"], - "type": lib_plankton.args.enum_type.string, - "mode": lib_plankton.args.enum_mode.replace, - "default": "data.json", - // "info": null, - "name": "data-path", - }), - "timezone_shift": lib_plankton.args.class_argument.volatile({ - "indicators_long": ["timezone-shift"], - "indicators_short": ["t"], - "type": lib_plankton.args.enum_type.integer, - "mode": lib_plankton.args.enum_mode.replace, - "default": 0, - // "info": null, - "name": "timezone-shift", - }), - "calendar_id": lib_plankton.args.class_argument.volatile({ - "indicators_long": ["calendar"], - "indicators_short": ["c"], - "type": lib_plankton.args.enum_type.integer, - "mode": lib_plankton.args.enum_mode.replace, - "default": 1, - // "info": null, - "name": "calendar_id", - }), - "view_mode": lib_plankton.args.class_argument.volatile({ - "indicators_long": ["view-moode"], - "indicators_short": ["m"], - "type": lib_plankton.args.enum_type.string, - "mode": lib_plankton.args.enum_mode.replace, - "default": "table", - // "info": null, - "name": "view_mode", - }), - "help": lib_plankton.args.class_argument.volatile({ - "indicators_long": ["help"], - "indicators_short": ["h"], - "type": lib_plankton.args.enum_type.boolean, - "mode": lib_plankton.args.enum_mode.replace, - "default": false, - // "info": null, - "name": "help", - }), - }); - const args : Record = arg_handler.read(lib_plankton.args.enum_environment.cli, args_raw.join(" ")); - - // init - lib_plankton.log.conf_push( - [ - // lib_plankton.log.channel_make({"kind": "file", "data": {"threshold": "debug", "path": "/tmp/kalender.log"}}), - lib_plankton.log.channel_make({"kind": "file", "data": {"threshold": "info", "path": "/dev/stderr"}}), - // lib_plankton.log.channel_make({"kind": "stdout", "data": {"threshold": "info"}}), - ] - ); - - // exec - if (args["help"]) { - process.stdout.write( - arg_handler.generate_help( - { - "programname": "kalender", - "description": "Kalender", - "executable": "kalender", - } - ) - + - "\n" - ); - } - else { - const data : type_datamodel = lib_plankton.call.convey( - await lib_plankton.file.read(args["data_path"]), - [ - lib_plankton.json.decode, - (data_raw : any) => ( - ({ - "users": data_raw["users"], - "calendars": ( - data_raw["calendars"] - .map( - (calendar_entry_raw : any) => ({ - "id": calendar_entry_raw["id"], - "object": ( - ((calendar_object_raw) => { - switch (calendar_object_raw["kind"]) { - default: { - return calendar_object_raw; - break; - } - case "concrete": { - return { - "kind": "concrete", - "data": { - "name": calendar_object_raw["data"]["name"], - "users": calendar_object_raw["data"]["users"], - "events": ( - calendar_object_raw["data"]["events"] - .map( - (event_raw : any) => ({ - "name": event_raw["name"], - "begin": event_raw["begin"], - "end": ( - (event_raw["end"] === null) - ? - null - : - event_raw["end"] - ), - "description": event_raw["description"], - }) - ) - ), - }, - }; - break; - } - } - }) (calendar_entry_raw["object"]) - ), - }) - ) - ), - }) as type_datamodel - ), - ] - ); - let content : string; - switch (args["view_mode"]) { - default: { - content = ""; - throw (new Error("invalid view mode")); - break; - } - case "table": { - content = await calendar_view_table_html( - data, - args.calendar_id, - { - "timezone_shift": args["timezone_shift"], - } - ); - break; - } - case "list": { - content = await calendar_view_list_html( - data, - args.calendar_id, - { - "timezone_shift": args["timezone_shift"], - } - ); - break; - } - } - const output : string = template_coin( - "main", - { - "content": content, - } - ); - process.stdout.write(output); - } - return Promise.resolve(undefined); -} - -/* -process.stderr.write( - JSON.stringify( - { - "x1": datetime_from_date_object( - new Date(Date.now()), - { - "timezone_shift": 2, - } - ), - "x2": datetime_from_date_object( - new Date(Date.now()), - { - "timezone_shift": 0, - } - ), - "x3": pit_from_year_and_week( - 2024, - 37, - { - "timezone_shift": 0, - } - ), - }, - undefined, - "\t" - ) - + - "\n" -); - */ -( - main(process.argv.slice(2)) - .then( - () => {} - ) - /* - .catch( - (error) => {process.stderr.write(String(error) + "\n");} - ) - */ -); diff --git a/source/logic/main.ts b/source/logic/main.ts deleted file mode 100644 index 4a123f4..0000000 --- a/source/logic/main.ts +++ /dev/null @@ -1,133 +0,0 @@ -/** - */ -namespace _zeitbild.frontend -{ - - /** - */ - type type_conf = { - view_mode : string; - calendar_ids : Array; - timezone_shift : int; - }; - - - /** - */ - async function render( - conf : type_conf, - calendar_ids : Array - ) : Promise - { - calendar_ids.sort(); - const target : HTMLElement = (document.querySelector("body") as HTMLBodyElement); - switch (conf.view_mode) { - default: { - throw (new Error("invalid view mode")); - break; - } - case "table": { - const content : string = await _zeitbild.frontend.view.calendar_view_table_html( - calendar_ids, - { - "from": { - "year": 2024, - "week": 35 - }, - "to": { - "year": 2024, - "week": 43 - }, - "timezone_shift": conf.timezone_shift, - } - ); - target.innerHTML = content; - /* - document.querySelectorAll(".tableview-sources-entry").forEach( - (element) => { - element.addEventListener( - "click", - (event) => { - const element_ : HTMLElement = (event.target as HTMLElement); - const calendar_id : type_calendar_id = parseInt(element_.getAttribute("rel") as string); - const active : boolean = element_.classList.toggle("tableview-sources-entry-active"); - render( - conf, - lib_plankton.call.convey( - calendar_ids, - [ - (x : Array) => ( - active - ? - calendar_ids.concat([calendar_id]) - : - calendar_ids.filter(y => (y !== calendar_id)) - ), - ] - ) - ); - } - ); - } - ); - */ - break; - } - case "list": { - const content : string = await _zeitbild.frontend.view.calendar_view_list_html( - calendar_ids, - { - "timezone_shift": conf.timezone_shift, - } - ); - target.innerHTML = content; - break; - } - } - return Promise.resolve(undefined); - } - - - /** - */ - export async function main( - ) : Promise - { - // init - lib_plankton.log.conf_push( - [ - lib_plankton.log.channel_make({"kind": "console", "data": {"threshold": "info"}}), - ] - ); - - // conf - const conf : type_conf = lib_plankton.json.decode(await lib_plankton.file.read("conf.json")); - - // args - - const url : URL = new URL(window.location.toString()); - const calendar_ids : Array = ( - (url.searchParams.get("ids") !== null) - ? - lib_plankton.call.convey( - url.searchParams.get("ids"), - [ - (x : string) => lib_plankton.string.split(x, ","), - (x : Array) => x.map(y => parseInt(y)), - ] - ) - : - (await _zeitbild.frontend.resources.backend.calendar_list()).map(x => x.key) - ); - - // exec - await render( - conf, - calendar_ids - ); - - return Promise.resolve(undefined); - } - -} - diff --git a/source/logic/types.ts b/source/logic/types.ts deleted file mode 100644 index 4baa03b..0000000 --- a/source/logic/types.ts +++ /dev/null @@ -1,103 +0,0 @@ - -/** - */ -namespace _zeitbild.frontend -{ - - /** - */ - type type_role = ( - "editor" - | - "viewer" - ); - - - /** - */ - type type_user_id = int; - - - /** - */ - type type_user_object = { - name : string; - }; - - - /** - */ - export type type_event = { - name : string; - begin : _zeitbild.frontend.helpers.type_datetime; - end : ( - null - | - _zeitbild.frontend.helpers.type_datetime - ); - location : ( - null - | - string - ); - description : ( - null - | - string - ); - }; - - - /** - */ - export type type_calendar_id = int; - - - /** - */ - export type type_calendar_object = ( - { - kind : "concrete"; - data : { - name : string; - private : boolean; - users : Array< - { - id : type_user_id; - role : type_role; - } - >; - events : Array; - }; - } - | - { - kind : "caldav"; - data : { - name : string; - private : boolean; - read_only : boolean; - source_url : string; - } - } - ); - - - /** - */ - export type type_datamodel = { - users : Array< - { - id : type_user_id; - object : type_user_object; - } - >; - calendars : Array< - { - id : type_calendar_id; - object : type_calendar_object; - } - >; - }; - -} diff --git a/source/main.ts b/source/main.ts new file mode 100644 index 0000000..f61b221 --- /dev/null +++ b/source/main.ts @@ -0,0 +1,227 @@ + +/** + */ +async function main( + args_raw : Array +) : Promise +{ + // init1 + lib_plankton.log.conf_push( + [ + lib_plankton.log.channel_make({"kind": "stdout", "data": {"threshold": "debug"}}), + ] + ); + + // args + const arg_handler : lib_plankton.args.class_handler = new lib_plankton.args.class_handler({ + "action": lib_plankton.args.class_argument.positional({ + "index": 0, + "type": lib_plankton.args.enum_type.string, + "mode": lib_plankton.args.enum_mode.replace, + "default": "serve", + "name": "action", + "info": lib_plankton.string.coin( + "{{description}}:\n{{options}}\n\t\t", + { + "description": "action", + "options": ( + [ + { + "name": "serve", + "description": "serve" + }, + { + "name": "api-doc", + "description": "api-doc" + }, + { + "name": "expose-conf", + "description": "expose-conf" + }, + { + "name": "help", + "description": "help" + }, + ] + .map( + entry => lib_plankton.string.coin( + "\t\t- {{name}}\n\t\t\t{{description}}\n", + { + "name": entry.name, + "description": entry.description, + } + ) + ) + .join("") + ), + } + ), + }), + "conf_path": lib_plankton.args.class_argument.volatile({ + "indicators_long": ["conf_path"], + "indicators_short": ["c"], + "type": lib_plankton.args.enum_type.string, + "mode": lib_plankton.args.enum_mode.replace, + "default": "conf.json", + // "info": null, + "name": "conf-path", + }), + "data_path": lib_plankton.args.class_argument.volatile({ + "indicators_long": ["data-path"], + "indicators_short": ["d"], + "type": lib_plankton.args.enum_type.string, + "mode": lib_plankton.args.enum_mode.replace, + "default": "data.json", + // "info": null, + "name": "data-path", + }), + "help": lib_plankton.args.class_argument.volatile({ + "indicators_long": ["help"], + "indicators_short": ["h"], + "type": lib_plankton.args.enum_type.boolean, + "mode": lib_plankton.args.enum_mode.replace, + "default": false, + // "info": null, + "name": "help", + }), + }); + const args : Record = arg_handler.read(lib_plankton.args.enum_environment.cli, args_raw.join(" ")); + + // init2 + await _zeitbild.conf.load(args["conf_path"]); + lib_plankton.log.conf_push( + _zeitbild.conf.get().log.map( + log_output => lib_plankton.log.channel_make( + { + "kind": log_output.kind, + "data": log_output.data + } + ) + ) + ); + + // exec + if (args["help"]) { + process.stdout.write( + arg_handler.generate_help( + { + "programname": "zeitbild", + "description": "zeitbild-backend", + "executable": "zeitbild", + } + ) + + + "\n" + ); + } + else { + switch (args["action"]) { + default: { + lib_plankton.log.error( + "main_invalid_action", + { + "action": args["action"], + } + ); + break; + } + case "expose-conf": { + process.stdout.write( + JSON.stringify( + _zeitbild.conf.get(), + undefined, + "\t" + ) + + + "\n" + ); + break; + } + case "api-doc": { + lib_plankton.log.conf_push([]); + const rest_subject : lib_plankton.rest.type_rest = _zeitbild.api.make(); + lib_plankton.log.conf_pop(); + process.stdout.write( + JSON.stringify( + lib_plankton.rest.to_oas(rest_subject), + undefined, + "\t" + ) + ); + break; + } + case "serve": { + // prepare database + await _zeitbild.database.check(); + + await lib_plankton.session.setup( + { + "data_chest": ( + _zeitbild.conf.get().session_management.in_memory + ? lib_plankton.storage.memory.implementation_chest({}) + : lib_plankton.call.convey( + lib_plankton.storage.sql_table_common.chest( + { + "database_implementation": _zeitbild.database.get_implementation(), + "table_name": "sessions", + "key_names": ["key"], + } + ), + [ + (core : any) => ({ + "setup": (input : any) => core.setup(undefined), + "clear": () => core.clear(), + "write": (key : any, value : any) => core.write([key], {"data": JSON.stringify(value)}), + "delete": (key : any) => core.delete([key]), + "read": (key : any) => core.read([key]).then((row : any) => JSON.parse(row["data"])), + // "search": (term : any) => core.search(term).then(() => []), + "search": (term : any) => Promise.reject(new Error("not implemented")), + }), + ] + ) + ), + "default_lifetime": _zeitbild.conf.get().session_management.lifetime, + } + ); + + const rest_subject : lib_plankton.rest.type_rest = _zeitbild.api.make(); + const server : lib_plankton.server.type_subject = lib_plankton.server.make( + async (input, metadata) => { + const http_request : lib_plankton.http.type_request = lib_plankton.http.decode_request(input.toString()); + const http_response : lib_plankton.http.type_response = await lib_plankton.rest.call( + rest_subject, + http_request, + { + "checklevel_restriction": lib_plankton.api.enum_checklevel.hard, + // "checklevel_input": lib_plankton.api.enum_checklevel.soft, + // "checklevel_output": lib_plankton.api.enum_checklevel.soft, + } + ); + const output : string = lib_plankton.http.encode_response(http_response); + return output; + }, + { + "host": _zeitbild.conf.get().server.host, + "port": _zeitbild.conf.get().server.port, + // DANGER! DANGER! + "threshold": 0.125, + } + ); + + lib_plankton.server.start(server); + break; + } + } + } + return Promise.resolve(undefined); +} + +( + main(process.argv.slice(2)) + .then( + () => {} + ) + .catch( + (error) => {process.stderr.write(String(error) + "\n");} + ) +); diff --git a/source/repositories/calendar.ts b/source/repositories/calendar.ts new file mode 100644 index 0000000..ae2dd2d --- /dev/null +++ b/source/repositories/calendar.ts @@ -0,0 +1,254 @@ + +namespace _zeitbild.repository.calendar +{ + + /** + */ + var _core_store : ( + null + | + lib_plankton.storage.type_core_store< + _zeitbild.type.calendar_id, + Record, + {}, + lib_plankton.storage.type_sql_table_autokey_search_term, + Record + > + ) = null; + + + /** + */ + var _event_store : ( + null + | + lib_plankton.storage.type_core_store< + _zeitbild.type.event_id, + Record, + {}, + lib_plankton.storage.type_sql_table_autokey_search_term, + Record + > + ) = null; + + + /** + */ + function get_core_store( + ) : lib_plankton.storage.type_core_store< + _zeitbild.type.calendar_id, + Record, + {}, + lib_plankton.storage.type_sql_table_autokey_search_term, + Record + > + { + if (_core_store === null) { + _core_store = lib_plankton.storage.sql_table_autokey_core_store( + { + "database_implementation": _zeitbild.database.get_implementation(), + "table_name": "calendars", + "key_name": "id", + } + ); + } + else { + // do nothing + } + return _core_store; + } + + + /** + */ + function get_event_store( + ) : lib_plankton.storage.type_core_store< + _zeitbild.type.event_id, + Record, + {}, + lib_plankton.storage.type_sql_table_autokey_search_term, + Record + > + { + if (_event_store === null) { + _event_store = lib_plankton.storage.sql_table_autokey_core_store( + { + "database_implementation": _zeitbild.database.get_implementation(), + "table_name": "events", + "key_name": "id", + } + ); + } + else { + // do nothing + } + return _event_store; + } + + + /** + * @todo use events table + */ + function encode( + object : _zeitbild.type.calendar_object + ) : Record + { + switch (object.kind) { + /* + case "concrete": { + const data_raw : any = lib_plankton.json.encode(object.data); + data_raw["users"] + return { + "name": object.name, + "private": object.private, + "kind": object.kind, + "data": { + "users": data_raw["users"], + "events": [] // TODO + }, + }; + } + */ + default: { + return { + "name": object.name, + "private": object.private, + "kind": object.kind, + "data": lib_plankton.json.encode(object.data), + }; + } + } + } + + + /** + */ + function decode( + row : Record + ) : _zeitbild.type.calendar_object + { + return { + "name": row["name"], + "private": row["private"], + "kind": row["kind"], + "data": lib_plankton.json.decode(row["data"]), + }; + } + + + /** + */ + export async function dump( + ) : Promise< + Array< + { + id : _zeitbild.type.calendar_id; + object : _zeitbild.type.calendar_object; + } + > + > + { + return ( + (await get_core_store().search(null)) + .map( + ({"key": key, "preview": preview}) => ({ + "id": key, + "object": (preview as _zeitbild.type.calendar_object), + }) + ) + ); + } + + + /** + * @todo optimize + */ + export async function list( + search_term : (null | string) + ) : Promise< + Array< + { + id : _zeitbild.type.calendar_id; + preview : { + name : string; + }; + } + > + > + { + return ( + (await get_core_store().search(null)) + .filter( + ({"key": key, "preview": preview}) => ( + ( + (search_term === null) + || + (search_term.length <= 1) + ) + ? true + : ( + preview["name"].toLowerCase().includes(search_term.toLowerCase()) + ) + ) + ) + .map( + ({"key": key, "preview": preview}) => ({ + "id": key, + "preview": { + "name": preview["name"], + } + }) + ) + ); + } + + + /** + */ + export async function read( + id : _zeitbild.type.calendar_id + ) : Promise<_zeitbild.type.calendar_object> + { + const row : Record = await get_core_store().read(id); + + return decode(row); + } + + + /** + */ + export async function create( + value : _zeitbild.type.calendar_object + ) : Promise<_zeitbild.type.calendar_id> + { + const row : Record = encode(value); + const id : _zeitbild.type.calendar_id = await get_core_store().create(row); + + return id; + } + + + /** + */ + export async function update( + id : _zeitbild.type.calendar_id, + value : _zeitbild.type.calendar_object + ) : Promise + { + const row : Record = encode(value); + + await get_core_store().update(id, row); + } + + + /** + */ + export async function delete_( + id : _zeitbild.type.calendar_id + ) : Promise + { + await get_core_store().delete(id); + } + +} + diff --git a/source/services/calendar.ts b/source/services/calendar.ts new file mode 100644 index 0000000..c843304 --- /dev/null +++ b/source/services/calendar.ts @@ -0,0 +1,206 @@ + +namespace _zeitbild.service.calendar +{ + + /** + */ + export async function list( + search_term : (null | string) + ) : Promise< + Array< + { + id : _zeitbild.type.calendar_id; + preview : { + name : string; + } + } + > + > + { + return ( + _zeitbild.repository.calendar.list(search_term) + .then( + x => x.map( + (y : any) => ({ + "id": y.key, + "preview": y.preview, + }) + ) + ) + ); + } + + + /** + */ + export async function get( + calendar_id : _zeitbild.type.calendar_id + ) : Promise<_zeitbild.type.calendar_object> + { + return _zeitbild.repository.calendar.read(calendar_id); + } + + + /** + * @todo prevent loops + */ + export async function gather_events( + calendar_ids : Array<_zeitbild.type.calendar_id>, + from_pit : _zeitbild.helpers.type_pit, + to_pit : _zeitbild.helpers.type_pit + ) : Promise< + Array< + { + calendar_id : _zeitbild.type.calendar_id; + calendar_name : string; + event : _zeitbild.type.event_object; + } + > + > + { + lib_plankton.log.info( + "calendar_gather_events", + { + "calendar_ids": calendar_ids, + } + ); + let result : Array< + { + calendar_id : _zeitbild.type.calendar_id; + calendar_name : string; + event : _zeitbild.type.event_object; + } + > = []; + for await (const calendar_id of calendar_ids) { + const calendar_object : _zeitbild.type.calendar_object = await _zeitbild.repository.calendar.read( + calendar_id + ); + if (calendar_object.private) { + lib_plankton.log.info( + "calendar_gather_events_private_calendar_blocked", + { + "calendar_id": calendar_id, + } + ); + } + else { + switch (calendar_object.kind) { + case "concrete": { + result = ( + result + .concat( + calendar_object.data.events + .filter( + (event : _zeitbild.type.event_object) => _zeitbild.helpers.pit_is_between( + _zeitbild.helpers.pit_from_datetime(event.begin), + from_pit, + to_pit + ) + ) + .map( + (event : _zeitbild.type.event_object) => ({ + "calendar_id": calendar_id, + "calendar_name": calendar_object.name, + "event": event + }) + ) + ) + ); + break; + } + case "caldav": { + const url : lib_plankton.url.type_url = lib_plankton.url.decode( + calendar_object.data.source_url + ); + const http_request : lib_plankton.http.type_request = { + "version": "HTTP/2", + "scheme": ((url.scheme === "https") ? "https" : "http"), + "host": url.host, + "path": (url.path ?? "/"), + "query": url.query, + "method": lib_plankton.http.enum_method.get, + "headers": {}, + "body": null, + }; + // TODO: cache? + const http_response : lib_plankton.http.type_response = await lib_plankton.http.call( + http_request, + { + } + ); + const vcalendar : lib_plankton.ical.type_vcalendar = lib_plankton.ical.ics_decode( + http_response.body.toString(), + { + } + ); + result = ( + result + .concat( + vcalendar.vevents + .map( + (vevent : lib_plankton.ical.type_vevent) => ( + (vevent.dtstart !== undefined) + ? + { + "name": ( + (vevent.summary !== undefined) + ? + vevent.summary + : + "???" + ), + "begin": _zeitbild.helpers.ical_dt_to_own_datetime(vevent.dtstart), + "end": ( + (vevent.dtend !== undefined) + ? + _zeitbild.helpers.ical_dt_to_own_datetime(vevent.dtend) + : + null + ), + "location": ( + (vevent.location !== undefined) + ? + vevent.location + : + null + ), + "description": ( + (vevent.description !== undefined) + ? + vevent.description + : + null + ), + } + : + null + ) + ) + .filter( + (event) => (event !== null) + ) + .filter( + (event) => _zeitbild.helpers.pit_is_between( + _zeitbild.helpers.pit_from_datetime(event.begin), + from_pit, + to_pit + ) + ) + .map( + (event) => ({ + "calendar_id": calendar_id, + "calendar_name": calendar_object.name, + "event": event, + }) + ) + ) + ); + break; + } + } + } + } + return Promise.resolve(result); + } + +} diff --git a/source/style/main.css b/source/style/main.css deleted file mode 100644 index 61cd645..0000000 --- a/source/style/main.css +++ /dev/null @@ -1,84 +0,0 @@ -html { - background-color: #111; - color: #FFF; - font-family: sans-serif; -} - -.calendar { - display: flex; - flex-direction: row; - flex-wrap: wrap; -} - -.calendar-pane-left { - flex-basis: 12.5%; -} - -.calendar-pane-right { - flex-basis: 87.5%; -} - -.tableview-sources { - margin: 0; - padding: 0; - list-style-type: none; - font-size: 0.75em; -} - -.tableview-sources-entry { - margin: 8px; - padding: 4px; - cursor: pointer; -} - -.tableview-sources-entry:not(.tableview-sources-entry-active) { - filter: saturate(0); -} - -.calendar table { - width: 100%; - border-collapse: collapse; -} - -.calendar-cell { - border: 1px solid #888; - padding: 8px; - vertical-align: top; -} - -.calendar-cell-day { - width: 13.5%; -} - -.calendar-cell-week { - width: 5.5%; -} - -.calendar-cell-regular { - width: 13.5%; - height: 120px; -} - -.calendar-cell-today { - outline: 4px solid #FFF; -} - -.calendar-day { - font-size: 0.75em; - cursor: help; -} - -.calendar-events { - margin: 0; padding: 0; - list-style-type: none; -} - -.calendar-event_entry { - margin: 4px; - padding: 4px; - border-radius: 2px; - font-size: 0.75em; - color: #FFF; - font-weight: bold; - cursor: pointer; -} diff --git a/source/templates/main.html.tpl b/source/templates/main.html.tpl deleted file mode 100644 index db89e2e..0000000 --- a/source/templates/main.html.tpl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/source/templates/tableview-cell-entry.html.tpl b/source/templates/tableview-cell-entry.html.tpl deleted file mode 100644 index d0346b1..0000000 --- a/source/templates/tableview-cell-entry.html.tpl +++ /dev/null @@ -1,3 +0,0 @@ -
  • - {{name}} -
  • diff --git a/source/templates/tableview-cell.html.tpl b/source/templates/tableview-cell.html.tpl deleted file mode 100644 index fa4a53f..0000000 --- a/source/templates/tableview-cell.html.tpl +++ /dev/null @@ -1,8 +0,0 @@ - - - {{day}} - -
      -{{entries}} -
    - diff --git a/source/templates/tableview-row.html.tpl b/source/templates/tableview-row.html.tpl deleted file mode 100644 index 29e19af..0000000 --- a/source/templates/tableview-row.html.tpl +++ /dev/null @@ -1,6 +0,0 @@ - - - {{week}} - -{{cells}} - diff --git a/source/templates/tableview-sources-entry.html.tpl b/source/templates/tableview-sources-entry.html.tpl deleted file mode 100644 index 861ea42..0000000 --- a/source/templates/tableview-sources-entry.html.tpl +++ /dev/null @@ -1 +0,0 @@ -
  • {{name}}
  • diff --git a/source/templates/tableview.html.tpl b/source/templates/tableview.html.tpl deleted file mode 100644 index b476b5a..0000000 --- a/source/templates/tableview.html.tpl +++ /dev/null @@ -1,27 +0,0 @@ -
    -
    -
      -{{sources}} -
    -
    -
    - - - - - - - - - - - - - - -{{rows}} - -
    MoDiMiDoFrSaSo
    -
    -
    - diff --git a/source/types.ts b/source/types.ts new file mode 100644 index 0000000..83fec00 --- /dev/null +++ b/source/types.ts @@ -0,0 +1,93 @@ + +/** + */ +namespace _zeitbild.type +{ + + /** + */ + type role = ( + "editor" + | + "viewer" + ); + + + /** + */ + type user_id = int; + + + /** + */ + type user_object = { + name : string; + }; + + + /** + */ + export type event_id = int; + + + /** + */ + export type event_object = { + name : string; + begin : _zeitbild.helpers.type_datetime; + end : ( + null + | + _zeitbild.helpers.type_datetime + ); + location : ( + null + | + string + ); + description : ( + null + | + string + ); + }; + + + /** + */ + export type calendar_id = int; + + + /** + */ + export type calendar_object = ( + { + name : string; + private : boolean; + } + & + ( + { + kind : "concrete"; + data : { + users : Array< + { + id : user_id; + role : role; + } + >; + events : Array; + }; + } + | + { + kind : "caldav"; + data : { + read_only : boolean; + source_url : string; + } + } + ) + ); + +} diff --git a/source/logic/view.ts b/source/view.ts similarity index 100% rename from source/logic/view.ts rename to source/view.ts diff --git a/tools/build b/tools/build index 82e348f..70ed3d6 100755 --- a/tools/build +++ b/tools/build @@ -12,7 +12,7 @@ def main(): "-o", "--output-directory", type = str, - default = "/tmp/kalender", + default = "/tmp/zeitbild", metavar = "", help = "output directory", ) diff --git a/tools/makefile b/tools/makefile index a479915..8990357 100644 --- a/tools/makefile +++ b/tools/makefile @@ -2,7 +2,7 @@ dir_lib := lib dir_source := source -dir_temp := /tmp/kalender-temp +dir_temp := /tmp/zeitbild-temp dir_build := build dir_tools := tools @@ -11,53 +11,42 @@ cmd_chmod := chmod cmd_cp := cp cmd_log := echo "--" cmd_mkdir := mkdir -p +cmd_echo := echo cmd_tsc := ${dir_tools}/typescript/node_modules/.bin/tsc ## rules .PHONY: default -default: index templates style logic +default: ${dir_build}/zeitbild -.PHONY: index -index: ${dir_build}/index.html - -${dir_build}/index.html: \ - ${dir_source}/index.html - @ ${cmd_log} "index …" - @ ${cmd_cp} -u -v $^ $@ - -.PHONY: templates -templates: \ - $(wildcard ${dir_source}/templates/*) - @ ${cmd_log} "templates …" - @ ${cmd_mkdir} ${dir_build}/templates - @ ${cmd_cp} -r -u -v ${dir_source}/templates/* ${dir_build}/templates/ - -.PHONY: style -style: \ - $(wildcard ${dir_source}/style/*) - @ ${cmd_log} "style …" - @ ${cmd_mkdir} ${dir_build} - @ ${cmd_cat} ${dir_source}/style/* > ${dir_build}/style.css - -.PHONY: logic -logic: ${dir_build}/logic.js - -${dir_temp}/logic-unlinked.js: \ +${dir_temp}/zeitbild-unlinked.js: \ ${dir_lib}/plankton/plankton.d.ts \ - ${dir_source}/logic/helpers.ts \ - ${dir_source}/logic/types.ts \ - ${dir_source}/logic/backend.ts \ - ${dir_source}/logic/view.ts \ - ${dir_source}/logic/main.ts - @ ${cmd_log} "logic | compile …" + ${dir_source}/helpers.ts \ + ${dir_source}/conf.ts \ + ${dir_source}/database.ts \ + ${dir_source}/types.ts \ + ${dir_source}/repositories/calendar.ts \ + ${dir_source}/services/calendar.ts \ + ${dir_source}/api/base.ts \ + ${dir_source}/api/actions/meta_ping.ts \ + ${dir_source}/api/actions/meta_spec.ts \ + ${dir_source}/api/actions/calendar_list.ts \ + ${dir_source}/api/functions.ts \ + ${dir_source}/main.ts + @ ${cmd_log} "compile …" @ ${cmd_mkdir} $(dir $@) - @ ${cmd_tsc} --lib dom,es2020 --strict $^ --outFile $@ + @ ${cmd_tsc} --lib es2020 --strict $^ --outFile $@ -${dir_build}/logic.js: \ +${dir_temp}/head.js: + @ ${cmd_mkdir} $(dir $@) + @ ${cmd_echo} "#!/usr/bin/env node" > $@ + +${dir_build}/zeitbild: \ + ${dir_temp}/head.js \ ${dir_lib}/plankton/plankton.js \ - ${dir_temp}/logic-unlinked.js - @ ${cmd_log} "logic | link …" + ${dir_temp}/zeitbild-unlinked.js + @ ${cmd_log} "link …" @ ${cmd_mkdir} $(dir $@) @ ${cmd_cat} $^ > $@ + @ ${cmd_chmod} +x $@ diff --git a/tools/update-plankton b/tools/update-plankton index ccf3d0d..a156eaf 100755 --- a/tools/update-plankton +++ b/tools/update-plankton @@ -7,22 +7,26 @@ dir=lib/plankton modules="" modules="${modules} base" modules="${modules} call" +modules="${modules} log" +modules="${modules} storage" +modules="${modules} database" +modules="${modules} session" modules="${modules} file" +modules="${modules} string" modules="${modules} structures" modules="${modules} json" -modules="${modules} args" -modules="${modules} string" -modules="${modules} color" -modules="${modules} xml" modules="${modules} ical" -modules="${modules} http" -modules="${modules} log" modules="${modules} url" +modules="${modules} http" +modules="${modules} api" +modules="${modules} rest" +modules="${modules} server" +modules="${modules} args" ## exec mkdir -p ${dir} cd ${dir} -ptk bundle web ${modules} +ptk bundle node ${modules} cd - > /dev/null