From b5b5dde9e397a4036e396bf4e4cad4e88d953b8e Mon Sep 17 00:00:00 2001 From: Fenris Wolf Date: Sun, 10 Nov 2024 17:20:41 +0100 Subject: [PATCH] [res] --- lib/plankton/plankton.d.ts | 1033 +++++++------ lib/plankton/plankton.js | 2935 +++++++++++++++++++----------------- source/main.ts | 52 +- tools/update-plankton | 5 +- 4 files changed, 2122 insertions(+), 1903 deletions(-) diff --git a/lib/plankton/plankton.d.ts b/lib/plankton/plankton.d.ts index 03dd668..ff94071 100644 --- a/lib/plankton/plankton.d.ts +++ b/lib/plankton/plankton.d.ts @@ -1,11 +1,11 @@ /** * @author fenris */ -declare type int = number; +type int = number; /** * @author fenris */ -declare type float = number; +type float = number; declare var process: any; declare var require: any; declare class Buffer { @@ -22,7 +22,7 @@ declare namespace lib_plankton.base { /** * @author fenris */ -declare type type_pseudopointer = { +type type_pseudopointer = { value: type_value; }; /** @@ -355,36 +355,6 @@ declare namespace lib_plankton.call { */ function promise_delay(promise: type_promise, delay: int): type_promise; } -declare namespace lib_plankton.call { - /** - */ - class CancellablePromise extends Promise { - /** - */ - private cancelled; - /** - */ - private interval; - /** - */ - private subject; - /** - */ - constructor(executor: ((resolve: any, reject: any) => void)); - /** - */ - private clear; - /** - */ - then(onfulfilled?: ((value: type_result) => (type_next_resolved | PromiseLike)), onrejected?: ((reason: any) => (type_next_rejected | PromiseLike))): Promise; - /** - */ - catch(x: any): Promise; - /** - */ - cancel(): void; - } -} /** * initializer might be obsolete, since promises are reusable after having been resolved or rejected */ @@ -670,183 +640,311 @@ declare namespace lib_plankton.log { warning = 3, error = 4 } - /** - */ - function level_order(level1: enum_level, level2: enum_level): boolean; - /** - */ - function level_show(level: enum_level): string; /** */ type type_entry = { level: enum_level; incident: string; - details: Record; + tags: Array; + details: any; }; -} -/** - * @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; + type type_channel_description = lib_plankton.call.type_coproduct; + /** + */ + type type_channel_logic = { + send: ((entry: type_entry) => void); + }; + /** + */ + type type_logger_data = Array; + /** + */ + type type_logger_logic = Array; + /** + */ + type type_format_definition = ({ + kind: "jsonl"; + data: { + structured: boolean; + }; + } | { + kind: "human_readable"; + data: {}; + }); } declare namespace lib_plankton.log { /** */ - abstract class class_channel { - /** - */ - abstract add(entry: type_entry): void; - } + function level_order(level1: enum_level, level2: enum_level): boolean; + /** + */ + function level_show(level: enum_level, { "abbreviated": option_abbreviated, }?: { + abbreviated?: boolean; + }): string; + /** + */ + function level_decode(level_string: string): enum_level; } declare namespace lib_plankton.log { /** - * output for writing log entries to stdout + * @todo use label */ - class class_channel_stdout extends class_channel { - /** - */ - add(entry: type_entry): void; - } -} -declare namespace lib_plankton.log { + function get_logger_logic(logger_data: type_logger_data): type_logger_logic; /** */ - 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 { + function format_entry(format_definition: type_format_definition, entry: type_entry): string; /** */ - class class_channel_email extends class_channel { + function parse_format_definition(format_definition_raw: any): type_format_definition; +} +declare namespace lib_plankton.log.channel.filtered { + /** + */ + type type_predicate = ((entry: type_entry) => boolean); + /** + */ + type type_subject = { /** + * @todo check if it has to be logic */ - private smtp_credentials; + core: type_channel_logic; + predicate: type_predicate; + }; + /** + */ + function predicate_incident(substring: string): type_predicate; + /** + */ + function predicate_level(threshold: enum_level): type_predicate; + /** + */ + function predicate_tag(tag: string): type_predicate; + /** + * combines other predicates in disjunctive normal form + */ + function predicate_complex(definition: Array>): type_predicate; + /** + */ + function send(subject: type_subject, entry: type_entry): void; + /** + */ + function logic(subject: type_subject): type_channel_logic; +} +declare namespace lib_plankton.log.channel.minlevel { + /** + */ + type type_subject = { /** + * @todo check if it has to be logic */ - private sender; - /** - */ - private receivers; - /** - * [constructor] - */ - constructor(smtp_credentials: { + core: type_channel_logic; + threshold: enum_level; + }; + /** + */ + function send(subject: type_subject, entry: type_entry): void; + /** + */ + function logic(subject: type_subject): type_channel_logic; +} +declare namespace lib_plankton.log.channel.std { + /** + */ + type type_subject = { + target: ("stdout" | "stderr"); + format: type_format_definition; + }; + /** + */ + function send(subject: type_subject, entry: type_entry): void; + /** + */ + function logic(subject: type_subject): type_channel_logic; +} +declare namespace lib_plankton.log.channel.file { + /** + */ + type type_subject = { + path: string; + format: type_format_definition; + }; + /** + */ + function send(subject: type_subject, entry: type_entry): void; + /** + */ + function logic(subject: type_subject): type_channel_logic; +} +declare namespace lib_plankton.log.channel.notify { + /** + */ + type type_subject = {}; + /** + * @todo tags + */ + function send(subject: type_subject, entry: type_entry): void; + /** + */ + function logic(subject: type_subject): type_channel_logic; +} +declare namespace lib_plankton.log.channel.email { + /** + */ + type type_subject = { + 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; + sender: string; + receivers: Array; + }; + /** + * @todo tags + */ + function send(subject: type_subject, entry: type_entry): void; /** */ - type type_configuration = Array; - /** - */ - function conf_default(): type_configuration; + function logic(subject: type_subject): type_channel_logic; } 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; + function get_channel_logic(channel_description: type_channel_description): type_channel_logic; } declare namespace lib_plankton.log { + /** + */ + function default_logger(): type_logger_data; +} +declare namespace lib_plankton.log { + /** + */ + function set_main_logger(logger_data: type_logger_data): void; + /** + * consumes a log entry, i.e. sends it to all channels + */ + function send_(logger: type_logger_logic, entry: type_entry): void; + /** + * [convenience] + * + * @todo rename to "send" + */ + function debug_(logger: type_logger_logic, incident: string, { "tags": option_tags, "details": option_details, }?: { + tags?: Array; + details?: any; + }): void; + /** + * [convenience] + * + * @todo rename to "info" + */ + function info_(logger: type_logger_logic, incident: string, { "tags": option_tags, "details": option_details, }?: { + tags?: Array; + details?: any; + }): void; + /** + * [convenience] + * + * @todo rename to "notice" + */ + function notice_(logger: type_logger_logic, incident: string, { "tags": option_tags, "details": option_details, }?: { + tags?: Array; + details?: any; + }): void; + /** + * [convenience] + * + * @todo rename to "warning" + */ + function warning_(logger: type_logger_logic, incident: string, { "tags": option_tags, "details": option_details, }?: { + tags?: Array; + details?: any; + }): void; + /** + * [convenience] + * + * @todo rename to "error" + */ + function error_(logger: type_logger_logic, incident: string, { "tags": option_tags, "details": option_details, }?: { + tags?: Array; + details?: any; + }): void; + /** + * [convenience] + */ + function _send(entry: type_entry): void; + /** + * [convenience] + */ + function _debug(incident: string, { "tags": option_tags, "details": option_details, }?: { + tags?: Array; + details?: any; + }): void; + /** + * [convenience] + */ + function _info(incident: string, { "tags": option_tags, "details": option_details, }?: { + tags?: Array; + details?: any; + }): void; + /** + * [convenience] + */ + function _notice(incident: string, { "tags": option_tags, "details": option_details, }?: { + tags?: Array; + details?: any; + }): void; + /** + * [convenience] + */ + function _warning(incident: string, { "tags": option_tags, "details": option_details, }?: { + tags?: Array; + details?: any; + }): void; + /** + * [convenience] + */ + function _error(incident: string, { "tags": option_tags, "details": option_details, }?: { + tags?: Array; + details?: any; + }): void; + /** + * [convenience] + * + * @deprecated use ._debug instead! + */ + function debug(incident: string, details?: any, tags?: Array): void; + /** + * [convenience] + * + * @deprecated use ._info instead! + */ + function info(incident: string, details?: any, tags?: Array): void; + /** + * [convenience] + * + * @deprecated use ._notice instead! + */ + function notice(incident: string, details?: any, tags?: Array): void; + /** + * [convenience] + * + * @deprecated use ._warning instead! + */ + function warning(incident: string, details?: any, tags?: Array): void; + /** + * [convenience] + * + * @deprecated use ._error instead! + */ + function error(incident: string, details?: any, tags?: Array): void; } declare namespace lib_plankton.code { /** @@ -1564,6 +1662,9 @@ declare namespace lib_plankton.string { /** */ function slice(str: string, size: int): Array; + /** + */ + function capitalize(str: string): string; } /** * @deprecated @@ -2164,7 +2265,7 @@ declare namespace lib_plankton.storage.memory { clear(): Promise; write(key: any, value: any): Promise; delete(key: any): Promise; - read(key: any): Promise; + read(key: any): Promise>; search(term: any): Promise<{ key: string; preview: string; @@ -3095,7 +3196,7 @@ declare namespace lib_plankton.pit { /** * @todo test */ - function to_datetime(pit: type_pit, { timezone_shift, }?: { + function to_datetime(pit: type_pit, { "timezone_shift": option_timezone_shift, }?: { timezone_shift?: int; }): type_datetime; /** @@ -3124,13 +3225,13 @@ declare namespace lib_plankton.pit { * @param week week according to specified timezone shift * @return the begin of the week (monday, 00:00) */ - function from_ywd(ywd: type_ywd, options?: { + function from_ywd(ywd: type_ywd, { "timezone_shift": option_timezone_shift, }?: { timezone_shift?: int; }): type_pit; /** * @todo timezone */ - function to_ywd(pit: type_pit, options?: { + function to_ywd(pit: type_pit, { "timezone_shift": option_timezone_shift, }?: { timezone_shift?: int; }): type_ywd; /** @@ -3167,13 +3268,13 @@ declare namespace lib_plankton.pit { function date_format(date: type_date): string; /** */ - function time_format(time: type_time, { show_seconds, }?: { + function time_format(time: type_time, { "show_seconds": option_show_seconds, }?: { show_seconds?: boolean; }): string; /** * @todo show timezone */ - function datetime_format(datetime: (null | type_datetime), { timezone_indicator, show_timezone, adjust_to_ce, omit_date, }?: { + function datetime_format(datetime: (null | type_datetime), { "timezone_indicator": option_timezone_indicator, "show_timezone": option_show_timezone, "adjust_to_ce": option_adjust_to_ce, "omit_date": option_omit_date, }?: { timezone_indicator?: string; show_timezone?: boolean; adjust_to_ce?: boolean; @@ -3181,7 +3282,7 @@ declare namespace lib_plankton.pit { }): string; /** */ - function timespan_format(from: type_datetime, to: (null | type_datetime), { timezone_indicator, show_timezone, adjust_to_ce, omit_date, }?: { + function timespan_format(from: type_datetime, to: (null | type_datetime), { "timezone_indicator": option_timezone_indicator, "show_timezone": option_show_timezone, "adjust_to_ce": option_adjust_to_ce, "omit_date": option_omit_date, }?: { timezone_indicator?: string; show_timezone?: boolean; adjust_to_ce?: boolean; @@ -3369,6 +3470,58 @@ declare namespace lib_plankton.ical { */ function ics_encode(vcalendar: type_vcalendar): string; } +declare namespace lib_plankton.http_base { + /** + * @author roydfalk + */ + type type_request = { + scheme: ("http" | "https"); + host: (null | string); + path: string; + version: string; + method: type_method; + query: (null | string); + headers: Record; + body: (null | Buffer); + }; + /** + * @author fenris + */ + type type_response = { + version: (null | string); + status_code: type_status_code; + headers: Record; + body: Buffer; + }; +} +declare namespace lib_plankton.http_base { + /** + * @author fenris + */ + function encode_request(encode_method: ((method: type_method) => string), request: type_request): string; + /** + * @author fenris + */ + function decode_request(decode_method: ((method_raw: string) => type_method), has_body: ((method: type_method) => boolean), request_raw: string): type_request; + /** + * @author fenris + */ + function encode_response(encode_status_code: ((status_code: type_status_code) => string), get_status_text: ((status_code: type_status_code) => string), response: type_response): string; + /** + * @author fenris + */ + function decode_response(decode_status_code: ((status_code_raw: string) => type_status_code), response_raw: string): type_response; + /** + * executes an HTTP request + * + * @todo define type_signal + */ + function call(has_body: ((method: type_method) => boolean), encode_method: ((method: type_method) => string), decode_status_code: ((status_code_raw: string) => type_status_code), request: type_request, { "timeout": option_timeout, "follow_redirects": option_follow_redirects, "implementation": option_implementation, }?: { + timeout?: (null | float); + follow_redirects?: boolean; + implementation?: ("fetch" | "http_module"); + }): Promise>; +} declare namespace lib_plankton.http { /** * @author fenris @@ -3383,31 +3536,71 @@ declare namespace lib_plankton.http { patch = "patch" } /** - * @author roydfalk */ - type type_request_generic = { - scheme: ("http" | "https"); - host: (null | string); - path: string; - version: string; - method: type_method; - query: (null | string); - headers: Record; - body: (null | Buffer); - }; + enum enum_status_code { + continue_ = 100, + switching_protocols = 101, + early_hints = 103, + ok = 200, + created = 201, + accepted = 202, + non_authoritative_information = 203, + no_content = 204, + reset_content = 205, + partial_coentent = 206, + multiple_choices = 300, + moved_permanently = 301, + found = 302, + see_other = 303, + not_modified = 304, + temporary_redirect = 307, + permanent_redirect = 308, + bad_request = 400, + unauthorized = 401, + payment_required = 402, + forbidden = 403, + not_found = 404, + method_not_allowed = 405, + not_acceptable = 406, + proxy_authentication_required = 407, + request_timeout = 408, + conflict = 409, + gone = 410, + length_required = 411, + precondition_failed = 412, + payload_too_large = 413, + uri_too_long = 414, + unsupported_media_type = 415, + range_not_satisfiable = 416, + expectation_failed = 417, + i_m_a_teapot = 418, + unprocessable_entity = 422, + too_early = 425, + upgrade_required = 426, + precondition_required = 428, + too_many_requests = 429, + request_header_fields_too_large = 431, + unavailable_for_legal_reasons = 451, + internal_server_error = 500, + not_implemented = 501, + bad_gateway = 502, + service_unavailable = 503, + gateway_timeout = 504, + http_version_not_supported = 505, + variant_also_negotiates = 506, + insufficient_storage = 507, + loop_detected = 508, + not_extended = 510, + network_authentication = 511 + } /** * @author fenris */ - type type_request = type_request_generic; + type type_request = lib_plankton.http_base.type_request; /** * @author fenris */ - type type_response = { - version: (null | string); - status_code: int; - headers: Record; - body: Buffer; - }; + type type_response = lib_plankton.http_base.type_response; } declare namespace lib_plankton.http { /** @@ -3418,10 +3611,6 @@ declare namespace lib_plankton.http { * @author fenris */ function decode_method(method_raw: string): enum_method; - /** - * @author fenris - */ - function encode_request(request: type_request): string; /** * @author fenris */ @@ -3429,7 +3618,7 @@ declare namespace lib_plankton.http { /** * @author fenris */ - function decode_request_generic(decode_method_: ((method_raw: string) => type_method), has_body: ((method: type_method) => boolean), request_raw: string): type_request_generic; + function encode_request(request: type_request): string; /** * @author fenris */ @@ -3447,52 +3636,12 @@ declare namespace lib_plankton.http { * * @todo define type_signal */ - function call(request: type_request, options?: { + function call(request: type_request, { "timeout": option_timeout, "follow_redirects": option_follow_redirects, "implementation": option_implementation, }?: { timeout?: (null | float); follow_redirects?: boolean; implementation?: ("fetch" | "http_module"); }): Promise; } -declare namespace lib_plankton.http { - /** - * @author fenris - */ - class class_http_request implements lib_plankton.code.interface_code { - /** - * @author fenris - */ - constructor(); - /** - * @implementation - * @author fenris - */ - encode(x: type_request): string; - /** - * @implementation - * @author fenris - */ - decode(x: string): type_request; - } - /** - * @author fenris - */ - class class_http_response implements lib_plankton.code.interface_code { - /** - * @author fenris - */ - constructor(); - /** - * @implementation - * @author fenris - */ - encode(x: type_response): string; - /** - * @implementation - * @author fenris - */ - decode(x: string): type_response; - } -} /** * @author fenris */ @@ -3572,7 +3721,7 @@ declare namespace lib_plankton.xml { } declare namespace lib_plankton.webdav { /** - * @author roydfalk + * @todo try to base on lib_plankton.http.enum_method */ enum enum_method { options = "options", @@ -3591,17 +3740,74 @@ declare namespace lib_plankton.webdav { unlock = "unlock" } /** - * @author roydfalk + * @todo try to base on lib_plankton.http.enum_status_code + */ + enum enum_status_code { + continue_ = 100, + switching_protocols = 101, + early_hints = 103, + ok = 200, + created = 201, + accepted = 202, + non_authoritative_information = 203, + no_content = 204, + reset_content = 205, + partial_coentent = 206, + multistatus = 207, + multiple_choices = 300, + moved_permanently = 301, + found = 302, + see_other = 303, + not_modified = 304, + temporary_redirect = 307, + permanent_redirect = 308, + bad_request = 400, + unauthorized = 401, + payment_required = 402, + forbidden = 403, + not_found = 404, + method_not_allowed = 405, + not_acceptable = 406, + proxy_authentication_required = 407, + request_timeout = 408, + conflict = 409, + gone = 410, + length_required = 411, + precondition_failed = 412, + payload_too_large = 413, + uri_too_long = 414, + unsupported_media_type = 415, + range_not_satisfiable = 416, + expectation_failed = 417, + i_m_a_teapot = 418, + unprocessable_entity = 422, + too_early = 425, + upgrade_required = 426, + precondition_required = 428, + too_many_requests = 429, + request_header_fields_too_large = 431, + unavailable_for_legal_reasons = 451, + internal_server_error = 500, + not_implemented = 501, + bad_gateway = 502, + service_unavailable = 503, + gateway_timeout = 504, + http_version_not_supported = 505, + variant_also_negotiates = 506, + insufficient_storage = 507, + loop_detected = 508, + not_extended = 510, + network_authentication = 511 + } + /** * @see http://www.webdav.org/specs/rfc2518.html#ELEMENT_href */ type type_data_href = string; /** - * @author roydfalk * @see http://www.webdav.org/specs/rfc2518.html#ELEMENT_status */ type type_data_status = string; /** - * @author roydfalk * @see http://www.webdav.org/specs/rfc2518.html#ELEMENT_prop */ type type_data_prop = { @@ -3609,7 +3815,6 @@ declare namespace lib_plankton.webdav { value: (null | string); }; /** - * @author roydfalk * @see http://www.webdav.org/specs/rfc2518.html#ELEMENT_propstat */ type type_data_propstat = { @@ -3618,7 +3823,6 @@ declare namespace lib_plankton.webdav { description: (null | string); }; /** - * @author roydfalk * @see http://www.webdav.org/specs/rfc2518.html#ELEMENT_response */ type type_data_response = { @@ -3632,7 +3836,6 @@ declare namespace lib_plankton.webdav { description: (null | string); }; /** - * @author roydfalk * @see http://www.webdav.org/specs/rfc2518.html#ELEMENT_multistatus */ type type_data_multistatus = { @@ -3640,18 +3843,11 @@ declare namespace lib_plankton.webdav { description: (null | string); }; /** - * @author roydfalk */ - type type_request = lib_plankton.http.type_request_generic; + type type_request = lib_plankton.http_base.type_request; /** - * @author roydfalk */ - type type_response = { - version: (null | string); - status_code: int; - headers: Record; - body: Buffer; - }; + type type_response = lib_plankton.http_base.type_response; } declare namespace lib_plankton.webdav { /** @@ -3667,25 +3863,28 @@ declare namespace lib_plankton.webdav { */ function decode_method(method_raw: string): enum_method; /** - */ - function data_multistatus_encode(data_multistatus: type_data_multistatus): string; - /** - * @author roydfalk + * @todo check */ function has_body(method: enum_method): boolean; /** - * @author fenris */ function decode_request(request_raw: string): type_request; /** - * @author fenris - * @todo try to base on lib_plankton.http.encode_response */ function encode_response(response: type_response): string; + /** + */ + function decode_response(response_raw: string): type_response; + /** + */ + function encode_request(request: type_request): string; + /** + */ + function data_multistatus_encode(data_multistatus: type_data_multistatus): string; } declare namespace lib_plankton.caldav { /** - * @author roydfalk + * @todo try to base on lib_plankton.webdav.enum_method */ enum enum_method { options = "options", @@ -3707,45 +3906,98 @@ declare namespace lib_plankton.caldav { acl = "acl" } /** - * @author roydfalk + * @todo try to base on lib_plankton.webdav.enum_status_code */ - type type_request = lib_plankton.http.type_request_generic; + enum enum_status_code { + continue_ = 100, + switching_protocols = 101, + early_hints = 103, + ok = 200, + created = 201, + accepted = 202, + non_authoritative_information = 203, + no_content = 204, + reset_content = 205, + partial_coentent = 206, + multistatus = 207, + multiple_choices = 300, + moved_permanently = 301, + found = 302, + see_other = 303, + not_modified = 304, + temporary_redirect = 307, + permanent_redirect = 308, + bad_request = 400, + unauthorized = 401, + payment_required = 402, + forbidden = 403, + not_found = 404, + method_not_allowed = 405, + not_acceptable = 406, + proxy_authentication_required = 407, + request_timeout = 408, + conflict = 409, + gone = 410, + length_required = 411, + precondition_failed = 412, + payload_too_large = 413, + uri_too_long = 414, + unsupported_media_type = 415, + range_not_satisfiable = 416, + expectation_failed = 417, + i_m_a_teapot = 418, + unprocessable_entity = 422, + too_early = 425, + upgrade_required = 426, + precondition_required = 428, + too_many_requests = 429, + request_header_fields_too_large = 431, + unavailable_for_legal_reasons = 451, + internal_server_error = 500, + not_implemented = 501, + bad_gateway = 502, + service_unavailable = 503, + gateway_timeout = 504, + http_version_not_supported = 505, + variant_also_negotiates = 506, + insufficient_storage = 507, + loop_detected = 508, + not_extended = 510, + network_authentication = 511 + } /** - * @author roydfalk */ - type type_response = { - version: (null | string); - status_code: int; - headers: Record; - body: Buffer; - }; + type type_request = lib_plankton.http_base.type_request; + /** + */ + type type_response = lib_plankton.http_base.type_response; } declare namespace lib_plankton.caldav { /** - * @author roydfalk */ function is_special_method(method: enum_method): boolean; /** - * @author roydfalk */ function encode_method(method: enum_method): string; /** - * @author roydfalk */ function decode_method(method_raw: string): enum_method; /** - * @author roydfalk + * @todo check */ function has_body(method: enum_method): boolean; /** - * @author fenris + */ + function encode_request(request: type_request): string; + /** */ function decode_request(request_raw: string): type_request; /** - * @author fenris - * @todo try to base on lib_plankton.http.encode_response */ function encode_response(response: type_response): string; + /** + */ + function decode_response(response_raw: string): type_response; } declare namespace lib_plankton.markdown { /** @@ -4064,221 +4316,15 @@ declare namespace lib_plankton.rest_base { * @todo check request body mimetype? * @todo check query paramater validity */ - function call>(encode_http_method: ((http_method: type_http_method) => string), rest: type_rest, http_request: type_http_request, options?: { + function call(encode_http_method: ((http_method: type_http_method) => string), decode_status_code: ((status_code_raw: int) => type_http_status_code), rest: type_rest, http_request: lib_plankton.http_base.type_request, { "checklevel_restriction": option_checklevel_restriction, "checklevel_input": option_checklevel_input, "checklevel_output": option_checklevel_output, }?: { checklevel_restriction?: lib_plankton.api.enum_checklevel; checklevel_input?: lib_plankton.api.enum_checklevel; checklevel_output?: lib_plankton.api.enum_checklevel; - }): Promise; + }): Promise>; /** * @see https://swagger.io/specification/#openrest-object */ - function to_oas(http_request_method_to_oas: ((http_request_method: type_method) => string), rest: type_rest, options?: { - version?: (null | string); - servers?: Array; - }): any; -} -declare namespace lib_plankton.rest_http { - /** - */ - type type_oas_schema = lib_plankton.rest_base.type_oas_schema; - /** - */ - type type_execution = lib_plankton.rest_base.type_execution; - /** - */ - type type_restriction = lib_plankton.rest_base.type_restriction; - /** - */ - type type_operation = lib_plankton.rest_base.type_operation; - /** - */ - type type_routenode = lib_plankton.rest_base.type_routenode; - /** - */ - type type_rest = lib_plankton.rest_base.type_rest; -} -declare namespace lib_plankton.rest_http { - /** - */ - 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?: ((version: string) => 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?: ((version: string) => 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.rest_webdav { - /** - */ - type type_oas_schema = lib_plankton.rest_base.type_oas_schema; - /** - */ - type type_execution = lib_plankton.rest_base.type_execution; - /** - */ - type type_restriction = lib_plankton.rest_base.type_restriction; - /** - */ - type type_operation = lib_plankton.rest_base.type_operation; - /** - */ - type type_routenode = lib_plankton.rest_base.type_routenode; - /** - */ - type type_rest = lib_plankton.rest_base.type_rest; -} -declare namespace lib_plankton.rest_webdav { - /** - */ - 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.webdav.enum_method; - path: string; - options: { - active?: ((version: string) => boolean); - restriction?: (null | type_restriction); - execution?: type_execution; - title?: (null | string); - description?: (null | string); - query_parameters?: ((version: string) => 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.webdav.enum_method, path: string, options: { - active?: ((version: string) => boolean); - restriction?: (null | type_restriction); - execution?: type_execution; - title?: (null | string); - description?: (null | string); - query_parameters?: ((version: string) => 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.webdav.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?: { + function to_oas(http_request_method_to_oas: ((http_request_method: type_method) => string), has_body: ((method: type_method) => boolean), rest: type_rest, options?: { version?: (null | string); servers?: Array; }): any; @@ -4372,6 +4418,7 @@ declare namespace lib_plankton.rest_caldav { /** * @todo check request body mimetype? * @todo check query paramater validity + * @todo improve status code mapping */ function call(rest: type_rest, http_request: lib_plankton.caldav.type_request, options?: { checklevel_restriction?: lib_plankton.api.enum_checklevel; diff --git a/lib/plankton/plankton.js b/lib/plankton/plankton.js index dec742c..bda12c3 100644 --- a/lib/plankton/plankton.js +++ b/lib/plankton/plankton.js @@ -776,89 +776,6 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:call«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var call; - (function (call) { - /** - */ - class CancellablePromise extends Promise { - /** - */ - constructor(executor) { - super((resolve, reject) => { }); - this.subject = (new Promise((resolve, reject) => { - Promise.race([ - new Promise(executor), - new Promise((resolve_, reject_) => { - this.interval = setInterval(() => { - if (!this.cancelled) { - // do nothing - } - else { - reject_(new Error("cancelled")); - this.clear(); - } - }, 0); - }), - ]) - .then(resolve, reject); - })); - this.cancelled = false; - this.interval = null; - } - /** - */ - clear() { - if (this.interval === null) { - // do nothing - } - else { - clearInterval(this.interval); - this.interval = null; - } - } - /** - */ - then(onfulfilled, onrejected) { - this.clear(); - return this.subject.then(onfulfilled, onrejected); - } - /** - */ - catch(x) { - this.clear(); - return this.subject.catch(x); - } - /** - */ - cancel() { - this.cancelled = true; - this.clear(); - } - } - call.CancellablePromise = CancellablePromise; - })(call = lib_plankton.call || (lib_plankton.call = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:call«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:call« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:call« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:call«. If not, see . */ @@ -1527,7 +1444,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); - while (_) try { + 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]) { @@ -1606,21 +1523,6 @@ var lib_plankton; 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«. @@ -1655,6 +1557,31 @@ var lib_plankton; enum_level[enum_level["error"] = 4] = "error"; })(enum_level = log.enum_level || (log.enum_level = {})); ; + })(log = lib_plankton.log || (lib_plankton.log = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:log«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:log« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:lang« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:log«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var log; + (function (log) { /** */ function level_order(level1, level2) { @@ -1663,469 +1590,33 @@ var lib_plankton; log.level_order = level_order; /** */ - function level_show(level) { - switch (level) { - case enum_level.debug: return "debug"; - case enum_level.info: return "info"; - case enum_level.notice: return "notice"; - case enum_level.warning: return "warning"; - case enum_level.error: return "error"; - default: return "(unknown)"; + function level_show(level, _a) { + var _b = _a === void 0 ? {} : _a, _c = _b["abbreviated"], option_abbreviated = _c === void 0 ? false : _c; + if (option_abbreviated) { + switch (level) { + case log.enum_level.debug: return "DBG"; + case log.enum_level.info: return "INF"; + case log.enum_level.notice: return "NTC"; + case log.enum_level.warning: return "WRN"; + case log.enum_level.error: return "ERR"; + default: return "(unknown)"; + } + } + else { + switch (level) { + case log.enum_level.debug: return "debug"; + case log.enum_level.info: return "info"; + case log.enum_level.notice: return "notice"; + case log.enum_level.warning: return "warning"; + case log.enum_level.error: return "error"; + default: return "(unknown)"; + } } } log.level_show = level_show; - })(log = lib_plankton.log || (lib_plankton.log = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:log«. - -Copyright 2016-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) { + function level_decode(level_string) { return { "debug": log.enum_level.debug, "info": log.enum_level.info, @@ -2134,43 +1625,587 @@ var lib_plankton; "error": log.enum_level.error }[level_string]; } + log.level_decode = level_decode; + })(log = lib_plankton.log || (lib_plankton.log = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:log«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:log« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:lang« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:log«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var log; + (function (log) { + /** + * @todo use label + */ + function get_logger_logic(logger_data) { + return logger_data.map(function (channel_description) { return lib_plankton.log.get_channel_logic(channel_description); }); + } + log.get_logger_logic = get_logger_logic; /** */ - function channel_make(description) { - var _a, _b, _c, _d, _e; - switch (description.kind) { - default: { - throw (new Error("unhandled log channel kind: " + description.kind)); + function format_entry(format_definition, entry) { + switch (format_definition.kind) { + case "jsonl": { + var now = Date.now(); + var timestamp = (now / 1000); + var datetime = (new Date(now)).toISOString(); + return (JSON.stringify({ + "datetime_timestamp": timestamp.toFixed(0), + "datetime_string": datetime /*.slice(0, 19)*/, + "level_numeric": entry.level, + "level_name": log.level_show(entry.level, { "abbreviated": false }), + "tags": entry.tags, + "incident": entry.incident, + "details": entry.details + }, undefined, (format_definition.data.structured + ? + "\t" + : + undefined))); break; } - case "stdout": { - return (new log.class_channel_minlevel(new log.class_channel_stdout(), translate_level((_a = description.data["threshold"]) !== null && _a !== void 0 ? _a : "debug"))); + case "human_readable": { + var parts = []; + parts.push(("<" + (new Date(Date.now())).toISOString() /*.slice(0, 19)*/ + ">")); + parts.push(("[" + log.level_show(entry.level, { "abbreviated": true }) + "]")); + for (var _i = 0, _a = entry.tags; _i < _a.length; _i++) { + var tag = _a[_i]; + parts.push(("{" + tag + "}")); + } + parts.push(entry.incident); + (entry.details !== null) && parts.push((": " + JSON.stringify(entry.details, undefined, undefined))); + return (parts.join(" ")); + break; + } + default: { + throw (new Error("unhandled format kind: " + format_definition["kind"])); + break; + } + } + } + log.format_entry = format_entry; + /** + */ + function parse_format_definition(format_definition_raw) { + return lib_plankton.call.distinguish((format_definition_raw !== null && format_definition_raw !== void 0 ? format_definition_raw : { + "kind": "human_readable", + "data": {} + }), { + "jsonl": function (_a) { + var structured = _a["structured"]; + return ({ + "kind": "jsonl", + "data": { + "structured": (structured !== null && structured !== void 0 ? structured : false) + } + }); + }, + "human_readable": function (data_) { return ({ + "kind": "human_readable", + "data": {} + }); } + }); + } + log.parse_format_definition = parse_format_definition; + })(log = lib_plankton.log || (lib_plankton.log = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:log«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:log« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:lang« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:log«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var log; + (function (log) { + var channel; + (function (channel) { + var filtered; + (function (filtered) { + /** + */ + function predicate_incident(substring) { + return (function (entry) { return entry.incident.includes(substring); }); + } + filtered.predicate_incident = predicate_incident; + /** + */ + function predicate_level(threshold) { + return (function (entry) { return log.level_order(threshold, entry.level); }); + } + filtered.predicate_level = predicate_level; + /** + */ + function predicate_tag(tag) { + return (function (entry) { return entry.tags.includes(tag); }); + } + filtered.predicate_tag = predicate_tag; + /** + * combines other predicates in disjunctive normal form + */ + function predicate_complex(definition) { + return (function (entry) { return definition.some(function (clause) { return clause.every(function (literal) { return (literal.item(entry) + === + literal.mode); }); }); }); + } + filtered.predicate_complex = predicate_complex; + /** + */ + function send(subject, entry) { + if (!subject.predicate(entry)) { + // do nothing + } + else { + subject.core.send(entry); + } + } + filtered.send = send; + /** + */ + function logic(subject) { + return { + "send": function (entry) { return send(subject, entry); } + }; + } + filtered.logic = logic; + })(filtered = channel.filtered || (channel.filtered = {})); + })(channel = log.channel || (log.channel = {})); + })(log = lib_plankton.log || (lib_plankton.log = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:log«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:log« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:lang« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:log«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var log; + (function (log) { + var channel; + (function (channel) { + var minlevel; + (function (minlevel) { + /** + */ + function to_filter_subject(subject) { + return { + "core": subject.core, + "predicate": lib_plankton.log.channel.filtered.predicate_level(subject.threshold) + }; + } + /** + */ + function send(subject, entry) { + lib_plankton.log.channel.filtered.send(to_filter_subject(subject), entry); + } + minlevel.send = send; + /** + */ + function logic(subject) { + return { + "send": function (entry) { return send(subject, entry); } + }; + } + minlevel.logic = logic; + })(minlevel = channel.minlevel || (channel.minlevel = {})); + })(channel = log.channel || (log.channel = {})); + })(log = lib_plankton.log || (lib_plankton.log = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:log«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:log« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:lang« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:log«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var log; + (function (log) { + var channel; + (function (channel) { + var std; + (function (std) { + /** + */ + function send(subject, entry) { + var write = lib_plankton.call.distinguish({ + "kind": subject.target, + "data": null + }, { + "stdout": function () { return function (x) { return process.stdout.write(x); }; }, + "stderr": function () { return function (x) { return process.stderr.write(x); }; } + }); + write(lib_plankton.log.format_entry(subject.format, entry) + + + "\n"); + } + std.send = send; + /** + */ + function logic(subject) { + return { + "send": function (entry) { return send(subject, entry); } + }; + } + std.logic = logic; + })(std = channel.std || (channel.std = {})); + })(channel = log.channel || (log.channel = {})); + })(log = lib_plankton.log || (lib_plankton.log = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:log«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:log« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:lang« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:log«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var log; + (function (log) { + var channel; + (function (channel) { + var file; + (function (file) { + /** + */ + function send(subject, entry) { + var _this = this; + var nm_fs = require("fs"); + nm_fs.writeFile(subject.path, (lib_plankton.log.format_entry(subject.format, entry) + + + "\n"), { + "flag": "a+" + }, function (error) { + if (error !== null) { + process.stderr.write('-- [plankton] could not add log entry to file ' + _this.path + "\n"); + } + else { + // do nothing + } + }); + } + file.send = send; + /** + */ + function logic(subject) { + return { + "send": function (entry) { return send(subject, entry); } + }; + } + file.logic = logic; + })(file = channel.file || (channel.file = {})); + })(channel = log.channel || (log.channel = {})); + })(log = lib_plankton.log || (lib_plankton.log = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:log«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:log« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:lang« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:log«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var log; + (function (log) { + var channel; + (function (channel) { + var notify; + (function (notify) { + /** + * @todo tags + */ + function send(subject, entry) { + var nm_child_process = require("child_process"); + var command = ("notify-send" + + + " " + + + ("'" + + + ("[" + log.level_show(entry.level) + "]") + + + " " + + + entry.incident + + + "'") + + + " " + + + ("'" + + + JSON.stringify(entry.details) + + + "'")); + nm_child_process.exec(command, function (error, stdout, stderr) { + // do noting + }); + } + notify.send = send; + /** + */ + function logic(subject) { + return { + "send": function (entry) { return send(subject, entry); } + }; + } + notify.logic = logic; + })(notify = channel.notify || (channel.notify = {})); + })(channel = log.channel || (log.channel = {})); + })(log = lib_plankton.log || (lib_plankton.log = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:log«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:log« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:lang« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:log«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var log; + (function (log) { + var channel; + (function (channel) { + var email; + (function (email) { + /** + * @todo tags + */ + function send(subject, entry) { + var nm_fs = require("fs"); + lib_plankton.email.send(subject.smtp_credentials, subject.sender, subject.receivers, (("[" + log.level_show(entry.level) + "]") + + + " " + + + ("" + entry.incident + "")), JSON.stringify(entry.details, undefined, " ")); + } + email.send = send; + /** + */ + function logic(subject) { + return { + "send": function (entry) { return send(subject, entry); } + }; + } + email.logic = logic; + })(email = channel.email || (channel.email = {})); + })(channel = log.channel || (log.channel = {})); + })(log = lib_plankton.log || (lib_plankton.log = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:log«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:log« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:lang« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:log«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var log; + (function (log) { + /** + */ + function get_channel_logic(channel_description) { + var _a, _b, _c, _d, _e, _f, _g, _h, _j; + switch (channel_description.kind) { + default: { + throw (new Error("unhandled log channel kind: " + channel_description.kind)); + break; + } + case "filtered": { + return lib_plankton.log.channel.filtered.logic({ + "core": get_channel_logic(channel_description.data.core), + "predicate": lib_plankton.log.channel.filtered.predicate_complex(channel_description.data.predicate.map(function (clause_raw) { return clause_raw.map(function (literal_raw) { + var _a; + return ({ + "mode": ((_a = literal_raw["mode"]) !== null && _a !== void 0 ? _a : true), + "item": lib_plankton.call.distinguish(literal_raw["item"], { + "incident": function (_a) { + var substring = _a["substring"]; + if (substring === undefined) { + throw (new Error("required parameter missing: substring")); + } + else { + return lib_plankton.log.channel.filtered.predicate_incident(substring); + } + }, + "level": function (_a) { + var threshold = _a["threshold"]; + if (threshold === undefined) { + throw (new Error("required parameter missing: threshold")); + } + else { + return lib_plankton.log.channel.filtered.predicate_level(log.level_decode(threshold)); + } + }, + "tag": function (_a) { + var value = _a["value"]; + if (value === undefined) { + throw (new Error("required parameter missing: value")); + } + else { + return lib_plankton.log.channel.filtered.predicate_tag(value); + } + } + }, { + "fallback": function () { return function (entry) { return true; }; } + }) + }); + }); })) + }); + break; + } + case "minlevel": { + return lib_plankton.log.channel.minlevel.logic({ + "core": get_channel_logic(channel_description.data.core), + "threshold": log.level_decode(channel_description.data.threshold) + }); + break; + } + case "std": { + return lib_plankton.log.channel.std.logic({ + "target": ((_b = (_a = channel_description === null || channel_description === void 0 ? void 0 : channel_description.data) === null || _a === void 0 ? void 0 : _a.target) !== null && _b !== void 0 ? _b : "stdout"), + "format": log.parse_format_definition((_c = channel_description === null || channel_description === void 0 ? void 0 : channel_description.data) === null || _c === void 0 ? void 0 : _c.format) + }); 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"))); + /** + * @todo exceptions on missing parameters + */ + return lib_plankton.log.channel.file.logic({ + "path": ((_e = (_d = channel_description === null || channel_description === void 0 ? void 0 : channel_description.data) === null || _d === void 0 ? void 0 : _d.path) !== null && _e !== void 0 ? _e : "log"), + "format": log.parse_format_definition((_f = channel_description === null || channel_description === void 0 ? void 0 : channel_description.data) === null || _f === void 0 ? void 0 : _f.format) + }); 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"))); + return lib_plankton.log.channel.notify.logic({}); + break; + } + case "email": { + /** + * @todo exceptions on missing parameters + */ + return lib_plankton.log.channel.email.logic({ + "smtp_credentials": channel_description.data.smtp_credentials, + "sender": ((_h = (_g = channel_description.data) === null || _g === void 0 ? void 0 : _g.sender) !== null && _h !== void 0 ? _h : "plankton"), + "receivers": (_j = channel_description.data) === null || _j === void 0 ? void 0 : _j.receivers + }); 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.get_channel_logic = get_channel_logic; })(log = lib_plankton.log || (lib_plankton.log = {})); })(lib_plankton || (lib_plankton = {})); /* @@ -2198,122 +2233,288 @@ var lib_plankton; (function (log) { /** */ - var _channel_stack = null; - /** - * pushes a new configuration on the stack and activates it - */ - function conf_push(channels) { - if (_channel_stack === null) { - _channel_stack = []; - } - _channel_stack.push(channels); + function default_logger() { + return [ + { + "kind": "minlevel", + "data": { + "core": { + "kind": "std", + "data": { + "target": "stdout", + "format": { + "kind": "human_readable", + "data": {} + } + } + }, + "threshold": "info" + } + }, + ]; } - log.conf_push = conf_push; + log.default_logger = default_logger; + })(log = lib_plankton.log || (lib_plankton.log = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:log«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:log« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:lang« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:log«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var log; + (function (log) { /** - * pops the current active configuration from the stack */ - function conf_pop() { - if (_channel_stack.length > 0) { - _channel_stack.pop(); - } - else { - // do nothing - } + var _main_logger_data = null; + /** + */ + function set_main_logger(logger_data) { + _main_logger_data = logger_data; } - log.conf_pop = conf_pop; + log.set_main_logger = set_main_logger; /** - * makes the logging system ready */ - function setup() { - if (_channel_stack === null) { - _channel_stack = []; - conf_push(log.conf_default()); - } - else { - // do nothing - } + function get_main_logger() { + return (_main_logger_data !== null && _main_logger_data !== void 0 ? _main_logger_data : log.default_logger()); } /** - * consumes a log entry, i.e. sends it to the currently active outputs */ - function add(entry) { - setup(); - _channel_stack.slice(-1)[0].forEach(function (channel) { return channel.add(entry); }); + function get_main_logger_logic() { + return lib_plankton.log.get_logger_logic(get_main_logger()); } - log.add = add; /** + * consumes a log entry, i.e. sends it to all channels */ - function debug(incident, details) { - if (details === void 0) { details = {}; } - add({ "level": log.enum_level.debug, "incident": incident, "details": details }); + function send_(logger, entry) { + logger.forEach(function (channel) { return channel.send(entry); }); + } + log.send_ = send_; + /** + * [convenience] + * + * @todo rename to "send" + */ + function debug_(logger, incident, _a) { + var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d; + send_(logger, { + "level": log.enum_level.debug, + "incident": incident, + "tags": option_tags, + "details": option_details + }); + } + log.debug_ = debug_; + /** + * [convenience] + * + * @todo rename to "info" + */ + function info_(logger, incident, _a) { + var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d; + send_(logger, { + "level": log.enum_level.info, + "incident": incident, + "tags": option_tags, + "details": option_details + }); + } + log.info_ = info_; + /** + * [convenience] + * + * @todo rename to "notice" + */ + function notice_(logger, incident, _a) { + var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d; + send_(logger, { + "level": log.enum_level.notice, + "incident": incident, + "tags": option_tags, + "details": option_details + }); + } + log.notice_ = notice_; + /** + * [convenience] + * + * @todo rename to "warning" + */ + function warning_(logger, incident, _a) { + var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d; + send_(logger, { + "level": log.enum_level.warning, + "incident": incident, + "tags": option_tags, + "details": option_details + }); + } + log.warning_ = warning_; + /** + * [convenience] + * + * @todo rename to "error" + */ + function error_(logger, incident, _a) { + var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d; + send_(logger, { + "level": log.enum_level.error, + "incident": incident, + "tags": option_tags, + "details": option_details + }); + } + log.error_ = error_; + /** + * [convenience] + */ + function _send(entry) { + send_(get_main_logger_logic(), entry); + } + log._send = _send; + /** + * [convenience] + */ + function _debug(incident, _a) { + var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d; + debug_(get_main_logger_logic(), incident, { + "tags": option_tags, + "details": option_details + }); + } + log._debug = _debug; + /** + * [convenience] + */ + function _info(incident, _a) { + var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d; + info_(get_main_logger_logic(), incident, { + "tags": option_tags, + "details": option_details + }); + } + log._info = _info; + /** + * [convenience] + */ + function _notice(incident, _a) { + var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d; + notice_(get_main_logger_logic(), incident, { + "tags": option_tags, + "details": option_details + }); + } + log._notice = _notice; + /** + * [convenience] + */ + function _warning(incident, _a) { + var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d; + warning_(get_main_logger_logic(), incident, { + "tags": option_tags, + "details": option_details + }); + } + log._warning = _warning; + /** + * [convenience] + */ + function _error(incident, _a) { + var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d; + error_(get_main_logger_logic(), incident, { + "tags": option_tags, + "details": option_details + }); + } + log._error = _error; + /** + * [convenience] + * + * @deprecated use ._debug instead! + */ + function debug(incident, details, tags) { + if (details === void 0) { details = null; } + if (tags === void 0) { tags = []; } + _debug(incident, { + "details": details, + "tags": tags + }); } log.debug = debug; /** + * [convenience] + * + * @deprecated use ._info instead! */ - function info(incident, details) { - if (details === void 0) { details = {}; } - add({ "level": log.enum_level.info, "incident": incident, "details": details }); + function info(incident, details, tags) { + if (details === void 0) { details = null; } + if (tags === void 0) { tags = []; } + _info(incident, { + "details": details, + "tags": tags + }); } log.info = info; /** + * [convenience] + * + * @deprecated use ._notice instead! */ - function notice(incident, details) { - if (details === void 0) { details = {}; } - add({ "level": log.enum_level.notice, "incident": incident, "details": details }); + function notice(incident, details, tags) { + if (details === void 0) { details = null; } + if (tags === void 0) { tags = []; } + _notice(incident, { + "details": details, + "tags": tags + }); } log.notice = notice; /** + * [convenience] + * + * @deprecated use ._warning instead! */ - function warning(incident, details) { - if (details === void 0) { details = {}; } - add({ "level": log.enum_level.warning, "incident": incident, "details": details }); + function warning(incident, details, tags) { + if (details === void 0) { details = null; } + if (tags === void 0) { tags = []; } + _warning(incident, { + "details": details, + "tags": tags + }); } log.warning = warning; /** + * [convenience] + * + * @deprecated use ._error instead! */ - function error(incident, details) { - if (details === void 0) { details = {}; } - add({ "level": log.enum_level.error, "incident": incident, "details": details }); + function error(incident, details, tags) { + if (details === void 0) { details = null; } + if (tags === void 0) { tags = []; } + _error(incident, { + "details": details, + "tags": tags + }); } log.error = error; })(log = lib_plankton.log || (lib_plankton.log = {})); })(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:code«. Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' @@ -4629,6 +4830,7 @@ var lib_plankton; */ function generate(prefix = "string_") { if (index_is > index_max) { + lib_plankton.log.error("plankton.string.generate.out_of_valid_indices", null); throw (new Error("[string_generate] out of valid indices")); } else { @@ -4929,6 +5131,12 @@ var lib_plankton; return slices; } string.slice = slice; + /** + */ + function capitalize(str) { + return (str[0].toUpperCase() + str.slice(1)); + } + string.capitalize = capitalize; })(string = lib_plankton.string || (lib_plankton.string = {})); })(lib_plankton || (lib_plankton = {})); /** @@ -6533,7 +6741,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); - while (_) try { + 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]) { @@ -10138,7 +10346,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); - while (_) try { + 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]) { @@ -10647,15 +10855,15 @@ var lib_plankton; /** * @todo test */ - function to_datetime(pit, { timezone_shift = 0, } = {}) { + function to_datetime(pit, { "timezone_shift": option_timezone_shift = 0, } = {}) { return lib_plankton.call.convey(pit, [ to_date_object, (x) => x.getTime(), - (x) => (x + ((timezone_shift * (60 * 60)) * 1000)), + (x) => (x + ((option_timezone_shift * (60 * 60)) * 1000)), (x) => new Date(x), x => x.toISOString(), x => ({ - "timezone_shift": timezone_shift, + "timezone_shift": option_timezone_shift, "date": { "year": parseInt(x.slice(0, 4)), "month": parseInt(x.slice(5, 7)), @@ -10859,12 +11067,9 @@ var lib_plankton; * @param week week according to specified timezone shift * @return the begin of the week (monday, 00:00) */ - function from_ywd(ywd, options = {}) { - options = Object.assign({ - "timezone_shift": 0, - }, options); + function from_ywd(ywd, { "timezone_shift": option_timezone_shift = 0, } = {}) { return lib_plankton.call.convey({ - "timezone_shift": options.timezone_shift, + "timezone_shift": option_timezone_shift, "date": { "year": ywd.year, "month": 1, @@ -10886,10 +11091,7 @@ var lib_plankton; /** * @todo timezone */ - function to_ywd(pit, options = {}) { - options = Object.assign({ - "timezone_shift": 0, - }, options); + function to_ywd(pit, { "timezone_shift": option_timezone_shift = 0, } = {}) { return lib_plankton.call.convey(pit, [ to_date_object, x => ({ @@ -11027,8 +11229,8 @@ var lib_plankton; pit_1.date_format = date_format; /** */ - function time_format(time, { show_seconds = false, } = {}) { - return lib_plankton.string.coin((show_seconds + function time_format(time, { "show_seconds": option_show_seconds = false, } = {}) { + return lib_plankton.string.coin((option_show_seconds ? "{{hour}}:{{minute}}:{{seconds}}" : @@ -11042,12 +11244,12 @@ var lib_plankton; /** * @todo show timezone */ - function datetime_format(datetime, { timezone_indicator = "", show_timezone = false, adjust_to_ce = false, omit_date = false, } = {}) { + function datetime_format(datetime, { "timezone_indicator": option_timezone_indicator = "", "show_timezone": option_show_timezone = false, "adjust_to_ce": option_adjust_to_ce = false, "omit_date": option_omit_date = false, } = {}) { if (datetime === null) { return "-"; } else { - const datetime_adjusted = (adjust_to_ce + const datetime_adjusted = (option_adjust_to_ce ? to_datetime_ce(from_datetime(datetime)) : @@ -11055,7 +11257,7 @@ var lib_plankton; return lib_plankton.string.coin("{{macro_date_and_time}}{{macro_timezone}}", { "macro_date_and_time": ([ // date - (omit_date + (option_omit_date ? null : @@ -11069,10 +11271,10 @@ var lib_plankton; ] .filter(x => (x !== null)) .join(", ")), - "macro_timezone": (show_timezone + "macro_timezone": (option_show_timezone ? lib_plankton.string.coin(" [{{timezone_indicator}}{{timezone_value}}]", { - "timezone_indicator": timezone_indicator, + "timezone_indicator": option_timezone_indicator, "timezone_value": timezone_shift_format(datetime_adjusted.timezone_shift), }) : @@ -11083,8 +11285,8 @@ var lib_plankton; pit_1.datetime_format = datetime_format; /** */ - function timespan_format(from, to, { timezone_indicator = "", show_timezone = false, adjust_to_ce = false, omit_date = false, } = {}) { - const from_adjusted = (adjust_to_ce + function timespan_format(from, to, { "timezone_indicator": option_timezone_indicator = "", "show_timezone": option_show_timezone = false, "adjust_to_ce": option_adjust_to_ce = false, "omit_date": option_omit_date = false, } = {}) { + const from_adjusted = (option_adjust_to_ce ? datetime_translate_ce(from) : @@ -11093,7 +11295,7 @@ var lib_plankton; ? null : - (adjust_to_ce + (option_adjust_to_ce ? datetime_translate_ce(to) : @@ -11102,7 +11304,7 @@ var lib_plankton; "from": datetime_format(from_adjusted, { "show_timezone": false, "adjust_to_ce": false, - "omit_date": omit_date, + "omit_date": option_omit_date, }), "to_macro": ((to_adjusted === null) ? @@ -11117,10 +11319,10 @@ var lib_plankton; (from_adjusted.date.day === to_adjusted.date.day)) }), })), - "macro_timezone": (show_timezone + "macro_timezone": (option_show_timezone ? lib_plankton.string.coin(" [{{timezone_indicator}}{{timezone_value}}]", { - "timezone_indicator": timezone_indicator, + "timezone_indicator": option_timezone_indicator, "timezone_value": timezone_shift_format(from_adjusted.timezone_shift), }) : @@ -12063,6 +12265,327 @@ var lib_plankton; })(ical = lib_plankton.ical || (lib_plankton.ical = {})); })(lib_plankton || (lib_plankton = {})); /* +This file is part of »bacterio-plankton:http_base«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:http_base« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:http_base« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:http_base«. If not, see . + */ +/* +This file is part of »bacterio-plankton:http_base«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:http_base« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:http_base« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:http_base«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var http_base; + (function (http_base) { + /** + * @author fenris + */ + const linebreak = "\r\n"; + /** + */ + function capitalize_all(str) { + return str.split("-").map(x => lib_plankton.string.capitalize(x)).join("-"); + } + /** + * @author fenris + */ + function encode_request(encode_method, request) { + let request_raw = ""; + request_raw += lib_plankton.string.coin("{{method}} {{path}}{{query}} {{version}}{{linebreak}}", { + "method": encode_method(request.method), + "path": request.path, + "query": ((request.query === null) ? "" : request.query), + "version": request.version, + "linebreak": linebreak, + }); + if (request.host === null) { + // do nothing + } + else { + request_raw += lib_plankton.string.coin("Host: {{host}}{{linebreak}}", { + "host": request.host, + "linebreak": linebreak, + }); + } + for (const [key, value] of Object.entries(request.headers)) { + request_raw += lib_plankton.string.coin("{{key}}: {{value}}{{linebreak}}", { + "key": capitalize_all(key), + "value": value, + "linebreak": linebreak, + }); + } + request_raw += linebreak; + if (request.body === null) { + // do nothing + } + else { + request_raw += request.body.toString(); + } + return request_raw; + } + http_base.encode_request = encode_request; + /** + * @author fenris + */ + function decode_request(decode_method, has_body, request_raw) { + const lines = request_raw.split(linebreak); + const first = lines.shift(); + const parts = first.split(" "); + const method = decode_method(parts[0]); + const path_and_query = parts[1]; + const parts_ = path_and_query.split("?"); + const path = parts_[0]; + const query = ((parts_.length <= 1) ? null : ("?" + parts_.slice(1).join("?"))); + const version = parts[2]; + let headers = {}; + while (true) { + const line = lines.shift(); + if (line === "") { + break; + } + else { + const [key, value] = line.split(": ", 2); + headers[key.toLowerCase()] = value; + } + } + const body = (has_body(method) + // @ts-ignore + ? Buffer.from(lines.join(linebreak)) + : null); + const request = { + // TODO + "scheme": "http", + "host": (headers["host"] ?? null), + "path": path, + "version": version, + "method": method, + "query": query, + "headers": headers, + "body": body, + }; + return request; + } + http_base.decode_request = decode_request; + /** + * @author fenris + */ + function encode_response(encode_status_code, get_status_text, response) { + let response_raw = ""; + response_raw += lib_plankton.string.coin("{{version}} {{status_code}} {{status_text}}{{linebreak}}", { + "version": response.version, + "status_code": encode_status_code(response.status_code), + "status_text": get_status_text(response.status_code), + "linebreak": linebreak, + }); + for (const [key, value] of Object.entries(response.headers)) { + response_raw += lib_plankton.string.coin("{{key}}: {{value}}{{linebreak}}", { + "key": capitalize_all(key), + "value": value, + "linebreak": linebreak, + }); + } + response_raw += linebreak; + response_raw += response.body.toString(); + return response_raw; + } + http_base.encode_response = encode_response; + /** + * @author fenris + */ + function decode_response(decode_status_code, response_raw) { + const lines = response_raw.split(linebreak); + const first = lines.shift(); + const first_parts = first.split(" "); + const version = first_parts[0]; + const status_code = decode_status_code(first_parts[1]); + // first_parts.slice(2) ? probably irrelevant + let headers = {}; + while (true) { + const line = lines.shift(); + if (line === "") { + break; + } + else { + const [key, value] = line.split(": ", 2); + headers[key.toLowerCase()] = value; + } + } + // @ts-ignore + const body = Buffer.from(lines.join(linebreak)); + const response = { + // TODO + "version": version, + "status_code": status_code, + "headers": headers, + "body": body, + }; + return response; + } + http_base.decode_response = decode_response; + /** + * executes an HTTP request + * + * @todo define type_signal + */ + async function call(has_body, encode_method, decode_status_code, request, { "timeout": option_timeout = 5.0, "follow_redirects": option_follow_redirects = false, "implementation": option_implementation = "fetch", } = {}) { + const target = lib_plankton.string.coin("{{scheme}}://{{host}}{{path}}{{query}}", { + "scheme": request.scheme, + "host": request.host, + "path": request.path, + "query": (request.query ?? ""), + }); + switch (option_implementation) { + default: { + return Promise.reject(new Error("invalid implementation: " + option_implementation)); + break; + } + case "fetch": { + function core(signal) { + return (fetch(target, Object.assign({ + "method": encode_method(request.method), + "headers": request.headers, + /* + "redirect": ( + option_follow_redirects + ? + "follow" + : + "manual" + ), + */ + "signal": (signal + ?? + undefined), + // "keepalive": false, + }, ((has_body(request.method) + && + (request.body !== null)) + ? { + "body": request.body.toString(), + } + : {}))) + .catch((reason) => { + // console.info(reason); + return Promise.reject(reason); + }) + .then((response_raw) => (response_raw.text() + .then((body) => Promise.resolve({ + // TODO + "version": null, + "status_code": decode_status_code(response_raw.status.toFixed(0)), + "headers": ((headers_raw => { + let headers = {}; + headers_raw.forEach((value, key) => { + headers[key] = value; + }); + return headers; + })(response_raw.headers)), + "body": body, + }))))); + } + function timeout(controller) { + return (new Promise((resolve, reject) => { + if (option_timeout === null) { + // do nothing (neither resolve nor reject ever) + } + else { + setTimeout(() => { + controller.abort(); + resolve(null); + }, (option_timeout * 1000)); + } + })); + } + const controller = new AbortController(); + const signal = controller.signal; + const response = await Promise.race([ + timeout(controller), + core(signal), + ]); + if (response === null) { + throw (new Error("http_request_timeout")); + } + else { + return response; + } + break; + } + case "http_module": { + // @ts-ignore + const nm_http = require("http"); + // @ts-ignore + const nm_https = require("https"); + return (new Promise((resolve, reject) => { + const req = ((request.scheme === "https") + ? nm_https + : nm_http) + .request(target, { + "method": request.method, + "headers": request.headers, + }, (res) => { + try { + let response_body = ""; + res.setEncoding("utf8"); + res.on("data", (chunk) => { + response_body += chunk; + }); + res.on("end", () => { + resolve({ + // TODO + "version": null, + "status_code": res.statusCode, + "headers": res.headers, + "body": response_body, + }); + }); + } + catch (error) { + reject(error); + } + }); + req.on("error", (error) => { + reject(error); + }); + req.write(request.body); + req.end(); + })); + break; + } + } + } + http_base.call = call; + })(http_base = lib_plankton.http_base || (lib_plankton.http_base = {})); +})(lib_plankton || (lib_plankton = {})); +/* This file is part of »bacterio-plankton:http«. Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' @@ -12098,6 +12621,65 @@ var lib_plankton; enum_method["put"] = "put"; enum_method["patch"] = "patch"; })(enum_method = http.enum_method || (http.enum_method = {})); + /** + */ + let enum_status_code; + (function (enum_status_code) { + enum_status_code[enum_status_code["continue_"] = 100] = "continue_"; + enum_status_code[enum_status_code["switching_protocols"] = 101] = "switching_protocols"; + enum_status_code[enum_status_code["early_hints"] = 103] = "early_hints"; + enum_status_code[enum_status_code["ok"] = 200] = "ok"; + enum_status_code[enum_status_code["created"] = 201] = "created"; + enum_status_code[enum_status_code["accepted"] = 202] = "accepted"; + enum_status_code[enum_status_code["non_authoritative_information"] = 203] = "non_authoritative_information"; + enum_status_code[enum_status_code["no_content"] = 204] = "no_content"; + enum_status_code[enum_status_code["reset_content"] = 205] = "reset_content"; + enum_status_code[enum_status_code["partial_coentent"] = 206] = "partial_coentent"; + enum_status_code[enum_status_code["multiple_choices"] = 300] = "multiple_choices"; + enum_status_code[enum_status_code["moved_permanently"] = 301] = "moved_permanently"; + enum_status_code[enum_status_code["found"] = 302] = "found"; + enum_status_code[enum_status_code["see_other"] = 303] = "see_other"; + enum_status_code[enum_status_code["not_modified"] = 304] = "not_modified"; + enum_status_code[enum_status_code["temporary_redirect"] = 307] = "temporary_redirect"; + enum_status_code[enum_status_code["permanent_redirect"] = 308] = "permanent_redirect"; + enum_status_code[enum_status_code["bad_request"] = 400] = "bad_request"; + enum_status_code[enum_status_code["unauthorized"] = 401] = "unauthorized"; + enum_status_code[enum_status_code["payment_required"] = 402] = "payment_required"; + enum_status_code[enum_status_code["forbidden"] = 403] = "forbidden"; + enum_status_code[enum_status_code["not_found"] = 404] = "not_found"; + enum_status_code[enum_status_code["method_not_allowed"] = 405] = "method_not_allowed"; + enum_status_code[enum_status_code["not_acceptable"] = 406] = "not_acceptable"; + enum_status_code[enum_status_code["proxy_authentication_required"] = 407] = "proxy_authentication_required"; + enum_status_code[enum_status_code["request_timeout"] = 408] = "request_timeout"; + enum_status_code[enum_status_code["conflict"] = 409] = "conflict"; + enum_status_code[enum_status_code["gone"] = 410] = "gone"; + enum_status_code[enum_status_code["length_required"] = 411] = "length_required"; + enum_status_code[enum_status_code["precondition_failed"] = 412] = "precondition_failed"; + enum_status_code[enum_status_code["payload_too_large"] = 413] = "payload_too_large"; + enum_status_code[enum_status_code["uri_too_long"] = 414] = "uri_too_long"; + enum_status_code[enum_status_code["unsupported_media_type"] = 415] = "unsupported_media_type"; + enum_status_code[enum_status_code["range_not_satisfiable"] = 416] = "range_not_satisfiable"; + enum_status_code[enum_status_code["expectation_failed"] = 417] = "expectation_failed"; + enum_status_code[enum_status_code["i_m_a_teapot"] = 418] = "i_m_a_teapot"; + enum_status_code[enum_status_code["unprocessable_entity"] = 422] = "unprocessable_entity"; + enum_status_code[enum_status_code["too_early"] = 425] = "too_early"; + enum_status_code[enum_status_code["upgrade_required"] = 426] = "upgrade_required"; + enum_status_code[enum_status_code["precondition_required"] = 428] = "precondition_required"; + enum_status_code[enum_status_code["too_many_requests"] = 429] = "too_many_requests"; + enum_status_code[enum_status_code["request_header_fields_too_large"] = 431] = "request_header_fields_too_large"; + enum_status_code[enum_status_code["unavailable_for_legal_reasons"] = 451] = "unavailable_for_legal_reasons"; + enum_status_code[enum_status_code["internal_server_error"] = 500] = "internal_server_error"; + enum_status_code[enum_status_code["not_implemented"] = 501] = "not_implemented"; + enum_status_code[enum_status_code["bad_gateway"] = 502] = "bad_gateway"; + enum_status_code[enum_status_code["service_unavailable"] = 503] = "service_unavailable"; + enum_status_code[enum_status_code["gateway_timeout"] = 504] = "gateway_timeout"; + enum_status_code[enum_status_code["http_version_not_supported"] = 505] = "http_version_not_supported"; + enum_status_code[enum_status_code["variant_also_negotiates"] = 506] = "variant_also_negotiates"; + enum_status_code[enum_status_code["insufficient_storage"] = 507] = "insufficient_storage"; + enum_status_code[enum_status_code["loop_detected"] = 508] = "loop_detected"; + enum_status_code[enum_status_code["not_extended"] = 510] = "not_extended"; + enum_status_code[enum_status_code["network_authentication"] = 511] = "network_authentication"; + })(enum_status_code = http.enum_status_code || (http.enum_status_code = {})); })(http = lib_plankton.http || (lib_plankton.http = {})); })(lib_plankton || (lib_plankton = {})); /* @@ -12123,22 +12705,6 @@ var lib_plankton; (function (lib_plankton) { var http; (function (http) { - /** - * @author fenris - */ - const linebreak = "\r\n"; - /** - * @todo outsource to string module - */ - function capitalize(str) { - return (str[0].toUpperCase() + str.slice(1)); - } - /** - * @todo outsource to string module - */ - function capitalize_all(str) { - return str.split("-").map(x => capitalize(x)).join("-"); - } /** * @author fenris */ @@ -12171,10 +12737,21 @@ var lib_plankton; } } http.decode_method = decode_method; + /** + */ + function encode_status_code(status_code) { + return status_code.toFixed(0); + } + /** + * @todo check for existance + */ + function decode_status_code(status_code_raw) { + return parseInt(status_code_raw); + } /** * @author fenris */ - function get_statustext(statuscode) { + function get_status_text(statuscode) { switch (statuscode) { case 100: return "Continue"; case 101: return "Switching Protocols"; @@ -12233,43 +12810,6 @@ var lib_plankton; default: throw (new Error("unhandled statuscode: " + statuscode.toFixed(0))); } } - /** - * @author fenris - */ - function encode_request(request) { - let request_raw = ""; - request_raw += (encode_method(request.method) - + - " " - + - request.path - + - ((request.query === null) ? "" : request.query) - + - " " - + - request.version - + - linebreak); - if (request.host === null) { - // do nothing - } - else { - request_raw += ("Host: " + request.host + linebreak); - } - for (const [key, value] of Object.entries(request.headers)) { - request_raw += (capitalize_all(key) + ": " + value + linebreak); - } - request_raw += linebreak; - if (request.body === null) { - // do nothing - } - else { - request_raw += request.body.toString(); - } - return request_raw; - } - http.encode_request = encode_request; /** * @author fenris */ @@ -12284,107 +12824,29 @@ var lib_plankton; /** * @author fenris */ - function decode_request_generic(decode_method_, has_body, request_raw) { - const lines = request_raw.split(linebreak); - const first = lines.shift(); - const parts = first.split(" "); - const method = decode_method_(parts[0]); - const path_and_query = parts[1]; - const parts_ = path_and_query.split("?"); - const path = parts_[0]; - const query = ((parts_.length <= 1) ? null : ("?" + parts_.slice(1).join("?"))); - const version = parts[2]; - let headers = {}; - while (true) { - const line = lines.shift(); - if (line === "") { - break; - } - else { - const [key, value] = line.split(": ", 2); - headers[key.toLowerCase()] = value; - } - } - const body = (has_body(method) - // @ts-ignore - ? Buffer.from(lines.join(linebreak)) - : null); - const request_generic = { - // TODO - "scheme": "http", - "host": (headers["host"] ?? null), - "path": path, - "version": version, - "method": method, - "query": query, - "headers": headers, - "body": body, - }; - return request_generic; + function encode_request(request) { + return lib_plankton.http_base.encode_request(encode_method, request); } - http.decode_request_generic = decode_request_generic; + http.encode_request = encode_request; /** * @author fenris */ function decode_request(request_raw) { - return decode_request_generic(decode_method, has_body, request_raw); + return lib_plankton.http_base.decode_request(decode_method, has_body, request_raw); } http.decode_request = decode_request; /** * @author fenris */ function encode_response(response) { - let response_raw = ""; - response_raw += (response.version - + - " " - + - response.status_code.toFixed(0) - + - " " - + - get_statustext(response.status_code) - + - linebreak); - for (const [key, value] of Object.entries(response.headers)) { - response_raw += (capitalize_all(key) + ": " + value + linebreak); - } - response_raw += linebreak; - response_raw += response.body; - return response_raw; + return lib_plankton.http_base.encode_response(encode_status_code, get_status_text, response); } http.encode_response = encode_response; /** * @author fenris */ function decode_response(response_raw) { - const lines = response_raw.split(linebreak); - const first = lines.shift(); - const first_parts = first.split(" "); - const version = first_parts[0]; - const status_code = parseInt(first_parts[1]); - // first_parts.slice(2) ? probably irrelevant - let headers = {}; - while (true) { - const line = lines.shift(); - if (line === "") { - break; - } - else { - const [key, value] = line.split(": ", 2); - headers[key.toLowerCase()] = value; - } - } - // @ts-ignore - const body = Buffer.from(lines.join(linebreak)); - const response = { - // TODO - "version": version, - "status_code": status_code, - "headers": headers, - "body": body, - }; - return response; + return lib_plankton.http_base.decode_response(decode_status_code, response_raw); } http.decode_response = decode_response; /** @@ -12392,240 +12854,16 @@ var lib_plankton; * * @todo define type_signal */ - async function call(request, options = {}) { - options = Object.assign({ - "timeout": 5.0, - "follow_redirects": false, - "implementation": "fetch", - }, options); - const target = (request.scheme - + - "://" - + - request.host - + - request.path - + - ((request.query === null) - ? "" - : request.query)); - switch (options.implementation) { - default: { - return Promise.reject("invalid implementation: " + options.implementation); - break; - } - case "fetch": { - function core(signal) { - return (fetch(target, Object.assign({ - "method": ((method => { - switch (method) { - case http.enum_method.head: return "HEAD"; - case http.enum_method.options: return "OPTIONS"; - case http.enum_method.get: return "GET"; - case http.enum_method.delete: return "DELETE"; - case http.enum_method.post: return "POST"; - case http.enum_method.put: return "PUT"; - case http.enum_method.patch: return "PATCH"; - } - })(request.method)), - "headers": request.headers, - /* - "redirect": ( - options.follow_redirects - ? - "follow" - : - "manual" - ), - */ - "signal": (signal - ?? - undefined), - // "keepalive": false, - }, ((((method => { - switch (method) { - case http.enum_method.head: return false; - case http.enum_method.options: return false; - case http.enum_method.get: return false; - case http.enum_method.delete: return false; - case http.enum_method.post: return true; - case http.enum_method.put: return true; - case http.enum_method.patch: return true; - } - })(request.method)) - && - (request.body !== null)) - ? { - "body": request.body.toString(), - } - : {}))) - .catch((reason) => { - // console.info(reason); - return Promise.reject(reason); - }) - .then((response_raw) => (response_raw.text() - .then((body) => Promise.resolve({ - // TODO - "version": null, - "status_code": response_raw.status, - "headers": ((headers_raw => { - let headers = {}; - headers_raw.forEach((value, key) => { - headers[key] = value; - }); - return headers; - })(response_raw.headers)), - "body": body, - }))))); - } - function timeout(controller) { - return (new Promise((resolve, reject) => { - if (options.timeout === null) { - // do nothing (neither resolve nor reject ever) - } - else { - setTimeout(() => { - controller.abort(); - resolve(null); - }, (options.timeout * 1000)); - } - })); - } - const controller = new AbortController(); - const signal = controller.signal; - const response = await Promise.race([ - timeout(controller), - core(signal), - ]); - if (response === null) { - throw (new Error("http_request_timeout")); - } - else { - return response; - } - break; - } - case "http_module": { - // @ts-ignore - const nm_http = require("http"); - // @ts-ignore - const nm_https = require("https"); - return (new Promise((resolve, reject) => { - const req = ((request.scheme === "https") - ? nm_https - : nm_http) - .request(target, { - "method": request.method, - "headers": request.headers, - }, (res) => { - try { - let response_body = ""; - res.setEncoding("utf8"); - res.on("data", (chunk) => { - response_body += chunk; - }); - res.on("end", () => { - resolve({ - // TODO - "version": null, - "status_code": res.statusCode, - "headers": res.headers, - "body": response_body, - }); - }); - } - catch (error) { - reject(error); - } - }); - req.on("error", (error) => { - reject(error); - }); - req.write(request.body); - req.end(); - })); - break; - } - } + async function call(request, { "timeout": option_timeout = 5.0, "follow_redirects": option_follow_redirects = false, "implementation": option_implementation = "fetch", } = {}) { + return lib_plankton.http_base.call(has_body, encode_method, decode_status_code, request, { + "timeout": option_timeout, + "follow_redirects": option_follow_redirects, + "implementation": option_implementation, + }); } http.call = call; })(http = lib_plankton.http || (lib_plankton.http = {})); })(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:http«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:http« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:http« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:http«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var http; - (function (http) { - /** - * @author fenris - */ - class class_http_request { - /** - * @author fenris - */ - constructor() { - } - /** - * @implementation - * @author fenris - */ - encode(x) { - return http.encode_request(x); - } - /** - * @implementation - * @author fenris - */ - decode(x) { - return http.decode_request(x); - } - } - http.class_http_request = class_http_request; - /** - * @author fenris - */ - class class_http_response { - /** - * @author fenris - */ - constructor() { - } - /** - * @implementation - * @author fenris - */ - encode(x) { - return http.encode_response(x); - } - /** - * @implementation - * @author fenris - */ - decode(x) { - return http.decode_response(x); - } - } - http.class_http_response = class_http_response; - })(http = lib_plankton.http || (lib_plankton.http = {})); -})(lib_plankton || (lib_plankton = {})); var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || @@ -12790,7 +13028,7 @@ var lib_plankton; var webdav; (function (webdav) { /** - * @author roydfalk + * @todo try to base on lib_plankton.http.enum_method */ let enum_method; (function (enum_method) { @@ -12810,6 +13048,67 @@ var lib_plankton; enum_method["unlock"] = "unlock"; })(enum_method = webdav.enum_method || (webdav.enum_method = {})); ; + /** + * @todo try to base on lib_plankton.http.enum_status_code + */ + let enum_status_code; + (function (enum_status_code) { + enum_status_code[enum_status_code["continue_"] = 100] = "continue_"; + enum_status_code[enum_status_code["switching_protocols"] = 101] = "switching_protocols"; + enum_status_code[enum_status_code["early_hints"] = 103] = "early_hints"; + enum_status_code[enum_status_code["ok"] = 200] = "ok"; + enum_status_code[enum_status_code["created"] = 201] = "created"; + enum_status_code[enum_status_code["accepted"] = 202] = "accepted"; + enum_status_code[enum_status_code["non_authoritative_information"] = 203] = "non_authoritative_information"; + enum_status_code[enum_status_code["no_content"] = 204] = "no_content"; + enum_status_code[enum_status_code["reset_content"] = 205] = "reset_content"; + enum_status_code[enum_status_code["partial_coentent"] = 206] = "partial_coentent"; + enum_status_code[enum_status_code["multistatus"] = 207] = "multistatus"; + enum_status_code[enum_status_code["multiple_choices"] = 300] = "multiple_choices"; + enum_status_code[enum_status_code["moved_permanently"] = 301] = "moved_permanently"; + enum_status_code[enum_status_code["found"] = 302] = "found"; + enum_status_code[enum_status_code["see_other"] = 303] = "see_other"; + enum_status_code[enum_status_code["not_modified"] = 304] = "not_modified"; + enum_status_code[enum_status_code["temporary_redirect"] = 307] = "temporary_redirect"; + enum_status_code[enum_status_code["permanent_redirect"] = 308] = "permanent_redirect"; + enum_status_code[enum_status_code["bad_request"] = 400] = "bad_request"; + enum_status_code[enum_status_code["unauthorized"] = 401] = "unauthorized"; + enum_status_code[enum_status_code["payment_required"] = 402] = "payment_required"; + enum_status_code[enum_status_code["forbidden"] = 403] = "forbidden"; + enum_status_code[enum_status_code["not_found"] = 404] = "not_found"; + enum_status_code[enum_status_code["method_not_allowed"] = 405] = "method_not_allowed"; + enum_status_code[enum_status_code["not_acceptable"] = 406] = "not_acceptable"; + enum_status_code[enum_status_code["proxy_authentication_required"] = 407] = "proxy_authentication_required"; + enum_status_code[enum_status_code["request_timeout"] = 408] = "request_timeout"; + enum_status_code[enum_status_code["conflict"] = 409] = "conflict"; + enum_status_code[enum_status_code["gone"] = 410] = "gone"; + enum_status_code[enum_status_code["length_required"] = 411] = "length_required"; + enum_status_code[enum_status_code["precondition_failed"] = 412] = "precondition_failed"; + enum_status_code[enum_status_code["payload_too_large"] = 413] = "payload_too_large"; + enum_status_code[enum_status_code["uri_too_long"] = 414] = "uri_too_long"; + enum_status_code[enum_status_code["unsupported_media_type"] = 415] = "unsupported_media_type"; + enum_status_code[enum_status_code["range_not_satisfiable"] = 416] = "range_not_satisfiable"; + enum_status_code[enum_status_code["expectation_failed"] = 417] = "expectation_failed"; + enum_status_code[enum_status_code["i_m_a_teapot"] = 418] = "i_m_a_teapot"; + enum_status_code[enum_status_code["unprocessable_entity"] = 422] = "unprocessable_entity"; + enum_status_code[enum_status_code["too_early"] = 425] = "too_early"; + enum_status_code[enum_status_code["upgrade_required"] = 426] = "upgrade_required"; + enum_status_code[enum_status_code["precondition_required"] = 428] = "precondition_required"; + enum_status_code[enum_status_code["too_many_requests"] = 429] = "too_many_requests"; + enum_status_code[enum_status_code["request_header_fields_too_large"] = 431] = "request_header_fields_too_large"; + enum_status_code[enum_status_code["unavailable_for_legal_reasons"] = 451] = "unavailable_for_legal_reasons"; + enum_status_code[enum_status_code["internal_server_error"] = 500] = "internal_server_error"; + enum_status_code[enum_status_code["not_implemented"] = 501] = "not_implemented"; + enum_status_code[enum_status_code["bad_gateway"] = 502] = "bad_gateway"; + enum_status_code[enum_status_code["service_unavailable"] = 503] = "service_unavailable"; + enum_status_code[enum_status_code["gateway_timeout"] = 504] = "gateway_timeout"; + enum_status_code[enum_status_code["http_version_not_supported"] = 505] = "http_version_not_supported"; + enum_status_code[enum_status_code["variant_also_negotiates"] = 506] = "variant_also_negotiates"; + enum_status_code[enum_status_code["insufficient_storage"] = 507] = "insufficient_storage"; + enum_status_code[enum_status_code["loop_detected"] = 508] = "loop_detected"; + enum_status_code[enum_status_code["not_extended"] = 510] = "not_extended"; + enum_status_code[enum_status_code["network_authentication"] = 511] = "network_authentication"; + })(enum_status_code = webdav.enum_status_code || (webdav.enum_status_code = {})); })(webdav = lib_plankton.webdav || (lib_plankton.webdav = {})); })(lib_plankton || (lib_plankton = {})); /* @@ -12835,22 +13134,6 @@ var lib_plankton; (function (lib_plankton) { var webdav; (function (webdav) { - /** - * @author fenris - */ - const linebreak = "\r\n"; - /** - * @todo outsource to string module - */ - function capitalize(str) { - return (str[0].toUpperCase() + str.slice(1)); - } - /** - * @todo outsource to string module - */ - function capitalize_all(str) { - return str.split("-").map(x => capitalize(x)).join("-"); - } /** * @author roydfalk */ @@ -12917,9 +13200,19 @@ var lib_plankton; } webdav.decode_method = decode_method; /** - * @author fenris */ - function get_statustext(statuscode) { + function encode_status_code(status_code) { + return status_code.toFixed(0); + } + /** + * @todo check for existance + */ + function decode_status_code(status_code_raw) { + return parseInt(status_code_raw); + } + /** + */ + function get_status_text(statuscode) { switch (statuscode) { case 100: return "Continue"; case 101: return "Switching Protocols"; @@ -12979,6 +13272,47 @@ var lib_plankton; default: throw (new Error("unhandled statuscode: " + statuscode.toFixed(0))); } } + /** + * @todo check + */ + function has_body(method) { + return [ + webdav.enum_method.post, + webdav.enum_method.put, + webdav.enum_method.patch, + webdav.enum_method.propfind, + webdav.enum_method.proppatch, + webdav.enum_method.mkcol, + webdav.enum_method.copy, + webdav.enum_method.move, + webdav.enum_method.lock, + ].includes(method); + } + webdav.has_body = has_body; + /** + */ + function decode_request(request_raw) { + return lib_plankton.http_base.decode_request(decode_method, has_body, request_raw); + } + webdav.decode_request = decode_request; + /** + */ + function encode_response(response) { + return lib_plankton.http_base.encode_response(encode_status_code, get_status_text, response); + } + webdav.encode_response = encode_response; + /** + */ + function decode_response(response_raw) { + return lib_plankton.http_base.decode_response(decode_status_code, response_raw); + } + webdav.decode_response = decode_response; + /** + */ + function encode_request(request) { + return lib_plankton.http_base.encode_request(encode_method, request); + } + webdav.encode_request = encode_request; /** */ function data_href_encode_xml(data_href) { @@ -13041,56 +13375,6 @@ var lib_plankton; return data_multistatus_encode_xml(data_multistatus).compile(); } webdav.data_multistatus_encode = data_multistatus_encode; - /** - * @author roydfalk - */ - function has_body(method) { - return [ - webdav.enum_method.post, - webdav.enum_method.put, - webdav.enum_method.patch, - webdav.enum_method.propfind, - webdav.enum_method.proppatch, - webdav.enum_method.mkcol, - webdav.enum_method.copy, - webdav.enum_method.move, - webdav.enum_method.lock, - webdav.enum_method.unlock, // TODO verify - ].includes(method); - } - webdav.has_body = has_body; - /** - * @author fenris - */ - function decode_request(request_raw) { - return lib_plankton.http.decode_request_generic(decode_method, has_body, request_raw); - } - webdav.decode_request = decode_request; - /** - * @author fenris - * @todo try to base on lib_plankton.http.encode_response - */ - function encode_response(response) { - let response_raw = ""; - response_raw += (response.version - + - " " - + - response.status_code.toFixed(0) - + - " " - + - get_statustext(response.status_code) - + - linebreak); - for (const [key, value] of Object.entries(response.headers)) { - response_raw += (capitalize_all(key) + ": " + value + linebreak); - } - response_raw += linebreak; - response_raw += response.body; - return response_raw; - } - webdav.encode_response = encode_response; })(webdav = lib_plankton.webdav || (lib_plankton.webdav = {})); })(lib_plankton || (lib_plankton = {})); /* @@ -13117,7 +13401,7 @@ var lib_plankton; var caldav; (function (caldav) { /** - * @author roydfalk + * @todo try to base on lib_plankton.webdav.enum_method */ let enum_method; (function (enum_method) { @@ -13140,6 +13424,67 @@ var lib_plankton; enum_method["acl"] = "acl"; })(enum_method = caldav.enum_method || (caldav.enum_method = {})); ; + /** + * @todo try to base on lib_plankton.webdav.enum_status_code + */ + let enum_status_code; + (function (enum_status_code) { + enum_status_code[enum_status_code["continue_"] = 100] = "continue_"; + enum_status_code[enum_status_code["switching_protocols"] = 101] = "switching_protocols"; + enum_status_code[enum_status_code["early_hints"] = 103] = "early_hints"; + enum_status_code[enum_status_code["ok"] = 200] = "ok"; + enum_status_code[enum_status_code["created"] = 201] = "created"; + enum_status_code[enum_status_code["accepted"] = 202] = "accepted"; + enum_status_code[enum_status_code["non_authoritative_information"] = 203] = "non_authoritative_information"; + enum_status_code[enum_status_code["no_content"] = 204] = "no_content"; + enum_status_code[enum_status_code["reset_content"] = 205] = "reset_content"; + enum_status_code[enum_status_code["partial_coentent"] = 206] = "partial_coentent"; + enum_status_code[enum_status_code["multistatus"] = 207] = "multistatus"; + enum_status_code[enum_status_code["multiple_choices"] = 300] = "multiple_choices"; + enum_status_code[enum_status_code["moved_permanently"] = 301] = "moved_permanently"; + enum_status_code[enum_status_code["found"] = 302] = "found"; + enum_status_code[enum_status_code["see_other"] = 303] = "see_other"; + enum_status_code[enum_status_code["not_modified"] = 304] = "not_modified"; + enum_status_code[enum_status_code["temporary_redirect"] = 307] = "temporary_redirect"; + enum_status_code[enum_status_code["permanent_redirect"] = 308] = "permanent_redirect"; + enum_status_code[enum_status_code["bad_request"] = 400] = "bad_request"; + enum_status_code[enum_status_code["unauthorized"] = 401] = "unauthorized"; + enum_status_code[enum_status_code["payment_required"] = 402] = "payment_required"; + enum_status_code[enum_status_code["forbidden"] = 403] = "forbidden"; + enum_status_code[enum_status_code["not_found"] = 404] = "not_found"; + enum_status_code[enum_status_code["method_not_allowed"] = 405] = "method_not_allowed"; + enum_status_code[enum_status_code["not_acceptable"] = 406] = "not_acceptable"; + enum_status_code[enum_status_code["proxy_authentication_required"] = 407] = "proxy_authentication_required"; + enum_status_code[enum_status_code["request_timeout"] = 408] = "request_timeout"; + enum_status_code[enum_status_code["conflict"] = 409] = "conflict"; + enum_status_code[enum_status_code["gone"] = 410] = "gone"; + enum_status_code[enum_status_code["length_required"] = 411] = "length_required"; + enum_status_code[enum_status_code["precondition_failed"] = 412] = "precondition_failed"; + enum_status_code[enum_status_code["payload_too_large"] = 413] = "payload_too_large"; + enum_status_code[enum_status_code["uri_too_long"] = 414] = "uri_too_long"; + enum_status_code[enum_status_code["unsupported_media_type"] = 415] = "unsupported_media_type"; + enum_status_code[enum_status_code["range_not_satisfiable"] = 416] = "range_not_satisfiable"; + enum_status_code[enum_status_code["expectation_failed"] = 417] = "expectation_failed"; + enum_status_code[enum_status_code["i_m_a_teapot"] = 418] = "i_m_a_teapot"; + enum_status_code[enum_status_code["unprocessable_entity"] = 422] = "unprocessable_entity"; + enum_status_code[enum_status_code["too_early"] = 425] = "too_early"; + enum_status_code[enum_status_code["upgrade_required"] = 426] = "upgrade_required"; + enum_status_code[enum_status_code["precondition_required"] = 428] = "precondition_required"; + enum_status_code[enum_status_code["too_many_requests"] = 429] = "too_many_requests"; + enum_status_code[enum_status_code["request_header_fields_too_large"] = 431] = "request_header_fields_too_large"; + enum_status_code[enum_status_code["unavailable_for_legal_reasons"] = 451] = "unavailable_for_legal_reasons"; + enum_status_code[enum_status_code["internal_server_error"] = 500] = "internal_server_error"; + enum_status_code[enum_status_code["not_implemented"] = 501] = "not_implemented"; + enum_status_code[enum_status_code["bad_gateway"] = 502] = "bad_gateway"; + enum_status_code[enum_status_code["service_unavailable"] = 503] = "service_unavailable"; + enum_status_code[enum_status_code["gateway_timeout"] = 504] = "gateway_timeout"; + enum_status_code[enum_status_code["http_version_not_supported"] = 505] = "http_version_not_supported"; + enum_status_code[enum_status_code["variant_also_negotiates"] = 506] = "variant_also_negotiates"; + enum_status_code[enum_status_code["insufficient_storage"] = 507] = "insufficient_storage"; + enum_status_code[enum_status_code["loop_detected"] = 508] = "loop_detected"; + enum_status_code[enum_status_code["not_extended"] = 510] = "not_extended"; + enum_status_code[enum_status_code["network_authentication"] = 511] = "network_authentication"; + })(enum_status_code = caldav.enum_status_code || (caldav.enum_status_code = {})); })(caldav = lib_plankton.caldav || (lib_plankton.caldav = {})); })(lib_plankton || (lib_plankton = {})); /* @@ -13166,34 +13511,24 @@ var lib_plankton; var caldav; (function (caldav) { /** - * @author fenris - */ - const linebreak = "\r\n"; - /** - * @todo outsource to string module - */ - function capitalize(str) { - return (str[0].toUpperCase() + str.slice(1)); - } - /** - * @todo outsource to string module - */ - function capitalize_all(str) { - return str.split("-").map(x => capitalize(x)).join("-"); - } - /** - * @author roydfalk */ function is_special_method(method) { - return ((method === caldav.enum_method.report) + return ((method === caldav.enum_method.propfind) || - (method === caldav.enum_method.mkcalendar) + (method === caldav.enum_method.proppatch) || - (method === caldav.enum_method.acl)); + (method === caldav.enum_method.mkcol) + || + (method === caldav.enum_method.copy) + || + (method === caldav.enum_method.move) + || + (method === caldav.enum_method.lock) + || + (method === caldav.enum_method.unlock)); } caldav.is_special_method = is_special_method; /** - * @author roydfalk */ function encode_method(method) { switch (method) { @@ -13211,15 +13546,11 @@ var lib_plankton; case caldav.enum_method.move: return "MOVE"; case caldav.enum_method.lock: return "LOCK"; case caldav.enum_method.unlock: return "UNLOCK"; - case caldav.enum_method.report: return "REPORT"; - case caldav.enum_method.mkcalendar: return "MKCALENDAR"; - case caldav.enum_method.acl: return "ACL"; default: throw (new Error("impossible")); } } caldav.encode_method = encode_method; /** - * @author roydfalk */ function decode_method(method_raw) { switch (method_raw) { @@ -13237,17 +13568,24 @@ var lib_plankton; case "MOVE": return caldav.enum_method.move; case "LOCK": return caldav.enum_method.lock; case "UNLOCK": return caldav.enum_method.unlock; - case "REPORT": return caldav.enum_method.report; - case "MKCALENDAR": return caldav.enum_method.mkcalendar; - case "ACL": return caldav.enum_method.acl; default: throw (new Error("unhandled method: " + method_raw)); } } caldav.decode_method = decode_method; /** - * @author fenris */ - function get_statustext(statuscode) { + function encode_status_code(status_code) { + return status_code.toFixed(0); + } + /** + * @todo check for existance + */ + function decode_status_code(status_code_raw) { + return parseInt(status_code_raw); + } + /** + */ + function get_status_text(statuscode) { switch (statuscode) { case 100: return "Continue"; case 101: return "Switching Protocols"; @@ -13308,7 +13646,7 @@ var lib_plankton; } } /** - * @author roydfalk + * @todo check */ function has_body(method) { return [ @@ -13321,43 +13659,33 @@ var lib_plankton; caldav.enum_method.copy, caldav.enum_method.move, caldav.enum_method.lock, - caldav.enum_method.unlock, - caldav.enum_method.mkcalendar, // TODO verify ].includes(method); } caldav.has_body = has_body; /** - * @author fenris + */ + function encode_request(request) { + return lib_plankton.http_base.encode_request(encode_method, request); + } + caldav.encode_request = encode_request; + /** */ function decode_request(request_raw) { - return lib_plankton.http.decode_request_generic(decode_method, has_body, request_raw); + return lib_plankton.http_base.decode_request(decode_method, has_body, request_raw); } caldav.decode_request = decode_request; /** - * @author fenris - * @todo try to base on lib_plankton.http.encode_response */ function encode_response(response) { - let response_raw = ""; - response_raw += (response.version - + - " " - + - response.status_code.toFixed(0) - + - " " - + - get_statustext(response.status_code) - + - linebreak); - for (const [key, value] of Object.entries(response.headers)) { - response_raw += (capitalize_all(key) + ": " + value + linebreak); - } - response_raw += linebreak; - response_raw += response.body; - return response_raw; + return lib_plankton.http_base.encode_response(encode_status_code, get_status_text, response); } caldav.encode_response = encode_response; + /** + */ + function decode_response(response_raw) { + return lib_plankton.http_base.decode_response(decode_status_code, response_raw); + } + caldav.decode_response = decode_response; })(caldav = lib_plankton.caldav || (lib_plankton.caldav = {})); })(lib_plankton || (lib_plankton = {})); /* @@ -14123,12 +14451,7 @@ var lib_plankton; * @todo check request body mimetype? * @todo check query paramater validity */ - async function call(encode_http_method, 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); + async function call(encode_http_method, decode_status_code, rest, http_request, { "checklevel_restriction": option_checklevel_restriction = lib_plankton.api.enum_checklevel.hard, "checklevel_input": option_checklevel_input = lib_plankton.api.enum_checklevel.soft, "checklevel_output": option_checklevel_output = lib_plankton.api.enum_checklevel.soft, } = {}) { lib_plankton.log.info("rest_call", { "http_request": { "scheme": http_request.scheme, @@ -14205,16 +14528,16 @@ var lib_plankton; if (stuff.rest.length > 0) { return { "version": "HTTP/1.1", - "status_code": 404, + "status_code": decode_status_code(404), "headers": {}, "body": null, }; } else { - if (http_request.method === lib_plankton.http.enum_method.options) { + if (http_request.method === "OPTIONS") { return { "version": "HTTP/1.1", - "status_code": 200, + "status_code": decode_status_code(200), "headers": Object.assign({}, additional_response_headers), "body": null, }; @@ -14225,7 +14548,7 @@ var lib_plankton; if (Object.keys(stuff.routenode.operations).length <= 0) { return { "version": "HTTP/1.1", - "status_code": 404, + "status_code": decode_status_code(404), "headers": Object.assign({}, additional_response_headers), "body": null, }; @@ -14233,7 +14556,7 @@ var lib_plankton; else { return { "version": "HTTP/1.1", - "status_code": 405, + "status_code": decode_status_code(405), "headers": Object.assign({ "Allow": allowed_methods, }, additional_response_headers), @@ -14305,9 +14628,9 @@ var lib_plankton; "query_parameters": stuff_.query_parameters, }, "input": stuff_.input, - "checklevel_restriction": options.checklevel_restriction, - "checklevel_input": options.checklevel_input, - "checklevel_output": options.checklevel_output, + "checklevel_restriction": option_checklevel_restriction, + "checklevel_input": option_checklevel_input, + "checklevel_output": option_checklevel_output, }); error = null; } @@ -14319,7 +14642,7 @@ var lib_plankton; if (error instanceof lib_plankton.api.class_error_permission_denied) { response = { "version": "HTTP/1.1", - "status_code": 403, + "status_code": decode_status_code(403), "headers": Object.assign({}, additional_response_headers), "body": null, }; @@ -14346,7 +14669,7 @@ var lib_plankton; }); response = { "version": "HTTP/1.1", - "status_code": 500, + "status_code": decode_status_code(500), "headers": Object.assign({}, additional_response_headers), "body": Buffer["from"]("internal error"), }; @@ -14356,7 +14679,7 @@ var lib_plankton; // encode response = { "version": "HTTP/1.1", - "status_code": result.status_code, + "status_code": decode_status_code(result.status_code), "headers": Object.assign({ "Content-Type": operation.response_body_mimetype, }, additional_response_headers), @@ -14374,7 +14697,7 @@ var lib_plankton; /** * @see https://swagger.io/specification/#openrest-object */ - function to_oas(http_request_method_to_oas, rest, options = {}) { + function to_oas(http_request_method_to_oas, has_body, rest, options = {}) { options = lib_plankton.object.patched({ "version": null, "servers": [], @@ -14469,11 +14792,7 @@ var lib_plankton; }, "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)) + "requestBody": ((!has_body(http_method)) ? undefined : { "content": Object.fromEntries([ @@ -14513,183 +14832,6 @@ var lib_plankton; })(rest_base = lib_plankton.rest_base || (lib_plankton.rest_base = {})); })(lib_plankton || (lib_plankton = {})); /* -This file is part of »bacterio-plankton:rest_http«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:rest_http« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:rest_http« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:rest_http«. If not, see . - */ -/* -This file is part of »bacterio-plankton:rest_http«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:rest_http« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:rest_http« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:rest_http«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var rest_http; - (function (rest_http) { - /** - */ - 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 make(options = {}) { - return lib_plankton.rest_base.make(lib_plankton.http.encode_method, options); - } - rest_http.make = make; - /** - */ - function register(rest, http_method, path, options) { - lib_plankton.rest_base.register(lib_plankton.http.encode_method, rest, http_method, path, options); - } - rest_http.register = register; - /** - * @todo check request body mimetype? - * @todo check query paramater validity - */ - async function call(rest, http_request, options = {}) { - return lib_plankton.rest_base.call(lib_plankton.http.encode_method, rest, http_request, options); - } - rest_http.call = call; - /** - * @see https://swagger.io/specification/#openrest-object - */ - function to_oas(rest, options = {}) { - return lib_plankton.rest_base.to_oas(http_request_method_to_oas, rest, options); - } - rest_http.to_oas = to_oas; - })(rest_http = lib_plankton.rest_http || (lib_plankton.rest_http = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:rest_webdav«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:rest_webdav« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General 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_webdav« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU 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_webdav«. If not, see . - */ -/* -This file is part of »bacterio-plankton:rest_webdav«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:rest_webdav« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General 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_webdav« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU 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_webdav«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var rest_webdav; - (function (rest_webdav) { - /** - */ - function http_request_method_to_oas(http_request_method) { - switch (http_request_method) { - case lib_plankton.webdav.enum_method.get: return "get"; - case lib_plankton.webdav.enum_method.post: return "post"; - case lib_plankton.webdav.enum_method.patch: return "patch"; - case lib_plankton.webdav.enum_method.head: return "head"; - case lib_plankton.webdav.enum_method.delete: return "delete"; - case lib_plankton.webdav.enum_method.options: return "options"; - case lib_plankton.webdav.enum_method.put: return "put"; - case lib_plankton.webdav.enum_method.propfind: return "PROPFIND"; - case lib_plankton.webdav.enum_method.proppatch: return "PROPPATCH"; - case lib_plankton.webdav.enum_method.mkcol: return "MKCOL"; - case lib_plankton.webdav.enum_method.copy: return "COPY"; - case lib_plankton.webdav.enum_method.move: return "MOVE"; - case lib_plankton.webdav.enum_method.lock: return "LOCK"; - case lib_plankton.webdav.enum_method.unlock: return "UNLOCK"; - default: throw (new Error("impossible")); - } - } - /** - */ - function make(options = {}) { - return lib_plankton.rest_base.make(lib_plankton.webdav.encode_method, options); - } - rest_webdav.make = make; - /** - */ - function register(rest, http_method, path, options) { - lib_plankton.rest_base.register(lib_plankton.webdav.encode_method, rest, http_method, path, options); - } - rest_webdav.register = register; - /** - * @todo check request body mimetype? - * @todo check query paramater validity - */ - async function call(rest, http_request, options = {}) { - return lib_plankton.rest_base.call(lib_plankton.webdav.encode_method, rest, http_request, options); - } - rest_webdav.call = call; - /** - * @see https://swagger.io/specification/#openrest-object - */ - function to_oas(rest, options = {}) { - return lib_plankton.rest_base.to_oas(http_request_method_to_oas, rest, options); - } - rest_webdav.to_oas = to_oas; - })(rest_webdav = lib_plankton.rest_webdav || (lib_plankton.rest_webdav = {})); -})(lib_plankton || (lib_plankton = {})); -/* This file is part of »bacterio-plankton:rest_caldav«. Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' @@ -14742,16 +14884,16 @@ var lib_plankton; case lib_plankton.caldav.enum_method.delete: return "delete"; case lib_plankton.caldav.enum_method.options: return "options"; case lib_plankton.caldav.enum_method.put: return "put"; - case lib_plankton.caldav.enum_method.propfind: return "PROPFIND"; - case lib_plankton.caldav.enum_method.proppatch: return "PROPPATCH"; - case lib_plankton.caldav.enum_method.mkcol: return "MKCOL"; - case lib_plankton.caldav.enum_method.copy: return "COPY"; - case lib_plankton.caldav.enum_method.move: return "MOVE"; - case lib_plankton.caldav.enum_method.lock: return "LOCK"; - case lib_plankton.caldav.enum_method.unlock: return "UNLOCK"; - case lib_plankton.caldav.enum_method.report: return "REPORT"; - case lib_plankton.caldav.enum_method.mkcalendar: return "MKCALENDAR"; - case lib_plankton.caldav.enum_method.acl: return "ACL"; + case lib_plankton.caldav.enum_method.propfind: return "propfind"; + case lib_plankton.caldav.enum_method.proppatch: return "proppatch"; + case lib_plankton.caldav.enum_method.mkcol: return "mkcol"; + case lib_plankton.caldav.enum_method.copy: return "copy"; + case lib_plankton.caldav.enum_method.move: return "move"; + case lib_plankton.caldav.enum_method.lock: return "lock"; + case lib_plankton.caldav.enum_method.unlock: return "unlock"; + case lib_plankton.caldav.enum_method.report: return "report"; + case lib_plankton.caldav.enum_method.mkcalendar: return "mkcalendar"; + case lib_plankton.caldav.enum_method.acl: return "acl"; default: throw (new Error("impossible")); } } @@ -14770,16 +14912,17 @@ var lib_plankton; /** * @todo check request body mimetype? * @todo check query paramater validity + * @todo improve status code mapping */ async function call(rest, http_request, options = {}) { - return lib_plankton.rest_base.call(lib_plankton.caldav.encode_method, rest, http_request, options); + return lib_plankton.rest_base.call(lib_plankton.caldav.encode_method, (x => x), rest, http_request, options); } rest_caldav.call = call; /** * @see https://swagger.io/specification/#openrest-object */ function to_oas(rest, options = {}) { - return lib_plankton.rest_base.to_oas(http_request_method_to_oas, rest, options); + return lib_plankton.rest_base.to_oas(http_request_method_to_oas, lib_plankton.caldav.has_body, rest, options); } rest_caldav.to_oas = to_oas; })(rest_caldav = lib_plankton.rest_caldav || (lib_plankton.rest_caldav = {})); @@ -15812,7 +15955,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); - while (_) try { + 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]) { diff --git a/source/main.ts b/source/main.ts index b53b44d..9acebe2 100644 --- a/source/main.ts +++ b/source/main.ts @@ -159,11 +159,17 @@ async function main( ) : Promise { // init1 - lib_plankton.log.conf_push( + /* + lib_plankton.log.set_main_logger( [ - lib_plankton.log.channel_make({"kind": "stdout", "data": {"threshold": "info"}}), + { + "kind": "std", + "data": { + } + } ] ); + */ // args const arg_handler : lib_plankton.args.class_handler = new lib_plankton.args.class_handler({ @@ -246,20 +252,45 @@ async function main( "name": "help", }), }); - const args : Record = arg_handler.read(lib_plankton.args.enum_environment.cli, args_raw.join(" ")); + const args : Record = arg_handler.read( + lib_plankton.args.enum_environment.cli, + args_raw.join(" ") + ); // init2 await _zeitbild.conf.init( args["conf_path"] ); - lib_plankton.log.conf_push( + lib_plankton.log.set_main_logger( _zeitbild.conf.get().log.map( - (log_output : any) => lib_plankton.log.channel_make( - { - "kind": log_output.kind, - "data": log_output.data + (log_output : any) => { + switch (log_output.kind) { + case "stdout": { + return { + "kind": "minlevel", + "data": { + "core": { + "kind": "std", + "data": { + "target": "stdout", + "format": { + "kind": "human_readable", + "data": { + } + } + } + }, + "threshold": log_output.data.threshold, + } + }; + break; + } + default: { + throw (new Error("unhandled")); + break; + } } - ) + } ) ); _zeitbild.cache = lib_plankton.cache.chest.implementation( @@ -321,9 +352,8 @@ async function main( break; } case "api-doc": { - lib_plankton.log.conf_push([]); + lib_plankton.log.set_main_logger([]); const rest_subject : lib_plankton.rest_caldav.type_rest = _zeitbild.api.make(); - lib_plankton.log.conf_pop(); process.stdout.write( JSON.stringify( lib_plankton.rest_caldav.to_oas(rest_subject), diff --git a/tools/update-plankton b/tools/update-plankton index b62b0e6..b74d7d8 100755 --- a/tools/update-plankton +++ b/tools/update-plankton @@ -24,9 +24,8 @@ modules="${modules} http" modules="${modules} webdav" modules="${modules} caldav" modules="${modules} api" -modules="${modules} rest" -modules="${modules} rest_http" -modules="${modules} rest_webdav" +# modules="${modules} rest_http" +# modules="${modules} rest_webdav" modules="${modules} rest_caldav" modules="${modules} server" modules="${modules} args"