From 3fa5d0820b1d2ca865bd162f5e05ce03dbebb82e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Fra=C3=9F?= Date: Tue, 1 Jul 2025 17:19:47 +0000 Subject: [PATCH] [task-153] --- data/localization/deu.json | 2 +- data/localization/eng.json | 2 +- source/conf.ts | 920 ++++--------------------------------- source/main.ts | 15 +- 4 files changed, 95 insertions(+), 844 deletions(-) diff --git a/data/localization/deu.json b/data/localization/deu.json index ded9340..feb163c 100644 --- a/data/localization/deu.json +++ b/data/localization/deu.json @@ -15,7 +15,7 @@ "core.reminder.reminder": "Erinnerung", "args.action.description": "auszuführende Aktion", "args.conf_path.description": "Pfad zur Konfigurations-Datei", - "args.conf_schema.description": "nur das Konfigurations-Schema in einer spezifischen Version ausgeben (jüngste Version mittels '{{arg}}')", + "args.conf_schema.description": "nur das Konfigurations-Schema ausgeben", "args.conf_expose.description": "die vervollständigte Konfiguration ausgeben", "args.single_run.description": "nur einen Durchlauf ausführen", "args.dry_run.description": "das Senden von Benachrichtigungen überspringen", diff --git a/data/localization/eng.json b/data/localization/eng.json index 9bd8702..3491010 100644 --- a/data/localization/eng.json +++ b/data/localization/eng.json @@ -15,7 +15,7 @@ "core.reminder.reminder": "reminder", "args.action.description": "what to do", "args.conf_path.description": "path to configuration file", - "args.conf_schema.description": "only print the configuration schema in a specific version (latest version via argument '{{arg}}')", + "args.conf_schema.description": "only print the configuration schema", "args.conf_expose.description": "whether to expose the full configuration", "args.single_run.description": "whether to only execute one iteration at run", "args.dry_run.description": "whether to skip the sending of reminders (logs will be written)", diff --git a/source/conf.ts b/source/conf.ts index 8e0dff9..ecffd80 100644 --- a/source/conf.ts +++ b/source/conf.ts @@ -18,9 +18,6 @@ along with »munin«. If not, see . */ -/** - * @todo versioning - */ namespace _munin.conf { @@ -43,281 +40,7 @@ namespace _munin.conf /** - */ - type type_conf_v1 = { - sources : Array< - ( - { - kind : "kalender_digital"; - data : { - path : string; - filtration : { - category_blacklist : Array; - title_blacklist : Array; - }; - }; - } - ) - >; - targets : Array< - ( - { - kind : "telegram_bot"; - data : { - bot_token : string; - chat_id : int; - /** - * in hours - */ - interval : Array; - } - } - ) - >; - frequency : float; - labels : { - head : string; - title : string; - time : string; - location : string; - }; - }; - - - /** - */ - type type_conf_v2 = { - sources : Array< - ( - { - kind : "ical_feed"; - data : { - url : string; - filtration : { - category_blacklist : Array; - title_blacklist : Array; - } - } - } - ) - >; - targets : Array< - ( - { - kind : "telegram_bot"; - data : { - bot_token : string; - chat_id : int; - /** - * in hours - */ - reminders : Array; - } - } - ) - >; - settings : { - interval : float; - }; - labels : { - head : string; - title : string; - time : string; - location : string; - }; - }; - - - /** - */ - type type_conf_v3 = { - sources : Array< - ( - { - kind : "ical_feed"; - data : { - url : string; - filtration : { - category_blacklist : Array; - title_blacklist : Array; - } - } - } - ) - >; - targets : Array< - ( - { - kind : "email"; - data : { - smtp_host : string; - smtp_port : int; - smtp_username : string; - smtp_password : string; - sender : string; - receivers : Array; - /** - * in hours - */ - reminders : Array; - } - } - | - { - kind : "telegram_bot"; - data : { - bot_token : string; - chat_id : int; - /** - * in hours - */ - reminders : Array; - } - } - ) - >; - settings : { - interval : float; - }; - labels : { - head : string; - title : string; - time : string; - location : string; - }; - }; - - - /** - */ - type type_conf_v4 = { - sources : Array< - ( - { - kind : "ical_feed"; - data : { - url : string; - filtration : { - category_whitelist : (null | Array); - category_blacklist : (null | Array); - title_whitelist : (null | Array); - title_blacklist : (null | Array); - } - } - } - ) - >; - targets : Array< - ( - { - kind : "email"; - data : { - smtp_host : string; - smtp_port : int; - smtp_username : string; - smtp_password : string; - sender : string; - receivers : Array; - hide_tags : boolean; - /** - * in hours - */ - reminders : Array; - } - } - | - { - kind : "telegram_bot"; - data : { - bot_token : string; - chat_id : int; - hide_tags : boolean; - /** - * in hours - */ - reminders : Array; - } - } - ) - >; - settings : { - interval : float; - }; - labels : { - head : string; - title : string; - time : string; - location : string; - }; - }; - - - /** - */ - type type_conf_v5 = { - sources : Array< - ( - { - kind : "ical_feed"; - data : { - url : string; - filtration : { - category_whitelist : (null | Array); - category_blacklist : (null | Array); - title_whitelist : (null | Array); - title_blacklist : (null | Array); - } - } - } - ) - >; - targets : Array< - ( - { - kind : "email"; - data : { - smtp_host : string; - smtp_port : int; - smtp_username : string; - smtp_password : string; - sender : string; - receivers : Array; - hide_tags : boolean; - /** - * in hours - */ - reminders : Array; - } - } - | - { - kind : "telegram_bot"; - data : { - bot_token : string; - chat_id : int; - hide_tags : boolean; - /** - * in hours - */ - reminders : Array; - } - } - ) - >; - settings : { - interval : float; - }; - labels : { - head : string; - title : string; - time : string; - location : string; - events : string; - }; - }; - - - /** + * @todo rename to "type_conf" */ type type_conf_v6 = { sources : Array< @@ -348,9 +71,6 @@ namespace _munin.conf sender : string; receivers : Array; hide_tags : boolean; - /** - * in hours - */ reminders : Array; } } @@ -361,9 +81,6 @@ namespace _munin.conf bot_token : string; chat_id : int; hide_tags : boolean; - /** - * in hours - */ reminders : Array; } } @@ -373,318 +90,22 @@ namespace _munin.conf interval : float; }; }; - + /** + */ + const current_version : string = "6"; + + + /** + * @todo remove */ export type type_conf = type_conf_v6; - /** - */ - function convert_from_v1( - conf_v1 : type_conf_v1 - ) : type_conf_v2 - { - return { - "sources": conf_v1.sources.map( - source => { - switch (source.kind) { - case "kalender_digital": { - return { - "kind": "ical_feed", - "data": { - "url": lib_plankton.url.encode( - { - "scheme": "https", - "host": "export.kalender.digital", - "username": null, - "password": null, - "port": null, - "path": ("/ics/" + source.data.path + ".ics"), - "query": "past_months=0&future_months=1", - "hash": null, - } - ), - "filtration": source.data.filtration, - } - }; - break; - } - default: { - // return source; - throw (new Error("unhandled source kind: " + source.kind)); - break; - } - } - } - ), - "targets": conf_v1.targets.map( - target => { - switch (target.kind) { - case "telegram_bot": { - return { - "kind": "telegram_bot", - "data": { - "bot_token": target.data.bot_token, - "chat_id": target.data.chat_id, - "reminders": target.data.interval, - }, - }; - break; - } - default: { - // return target; - throw (new Error("unhandled target kind: " + target.kind)); - break; - } - } - } - ), - "settings": { - "interval": conf_v1.frequency, - }, - "labels": conf_v1.labels, - }; - } - - - /** - */ - function convert_from_v2( - conf_v2 : type_conf_v2 - ) : type_conf_v3 - { - return conf_v2; - } - - - /** - */ - function convert_from_v3( - conf_v3 : type_conf_v3 - ) : type_conf_v4 - { - return { - "sources": conf_v3.sources.map( - source => { - switch (source.kind) { - case "ical_feed": { - return { - "kind": "ical_feed", - "data": { - "url": source.data.url, - "filtration": { - "category_whitelist": null, - "category_blacklist": source.data.filtration.category_blacklist, - "title_whitelist": null, - "title_blacklist": source.data.filtration.category_blacklist, - }, - } - }; - break; - } - default: { - // return source; - throw (new Error("unhandled source kind: " + source.kind)); - break; - } - } - } - ), - "targets": conf_v3.targets.map( - target => { - switch (target.kind) { - case "email": { - return { - "kind": "email", - "data": { - "smtp_host": target.data.smtp_host, - "smtp_port": target.data.smtp_port, - "smtp_username": target.data.smtp_username, - "smtp_password": target.data.smtp_password, - "sender": target.data.sender, - "receivers": target.data.receivers, - "hide_tags": false, - "reminders": target.data.reminders, - }, - }; - break; - } - case "telegram_bot": { - return { - "kind": "telegram_bot", - "data": { - "bot_token": target.data.bot_token, - "chat_id": target.data.chat_id, - "hide_tags": false, - "reminders": target.data.reminders, - }, - }; - break; - } - default: { - // return target; - throw (new Error("unhandled target kind: " + String(target))); - break; - } - } - } - ), - "settings": conf_v3.settings, - "labels": conf_v3.labels, - }; - } - - - /** - */ - function convert_from_v4( - conf_v4 : type_conf_v4 - ) : type_conf_v5 - { - const map_reminder = hours => ({ - "frequency": "hourly", - "offset": 0, - "from": hours, - "to": (hours + 1), - } as type_reminder_raw); - return { - "sources": conf_v4.sources, - "targets": conf_v4.targets.map( - target => { - switch (target.kind) { - case "email": { - return { - "kind": "email", - "data": { - "smtp_host": target.data.smtp_host, - "smtp_port": target.data.smtp_port, - "smtp_username": target.data.smtp_username, - "smtp_password": target.data.smtp_password, - "sender": target.data.sender, - "receivers": target.data.receivers, - "hide_tags": target.data.hide_tags, - "reminders": target.data.reminders.map(map_reminder), - }, - }; - break; - } - case "telegram_bot": { - return { - "kind": "telegram_bot", - "data": { - "bot_token": target.data.bot_token, - "chat_id": target.data.chat_id, - "hide_tags": target.data.hide_tags, - "reminders": target.data.reminders.map(map_reminder), - }, - }; - break; - } - default: { - // return target; - throw (new Error("unhandled target kind: " + String(target))); - break; - } - } - } - ), - "settings": conf_v4.settings, - "labels": Object.assign({"events": "Termine"}, conf_v4.labels), - }; - } - - - /** - */ - function convert_from_v5( - conf_v5 : type_conf_v5 - ) : type_conf_v6 - { - lib_plankton.log._notice( - "munin.conf.dropping_labels", - { - } - ); - return { - "sources": conf_v5.sources, - "targets": conf_v5.targets, - "settings": conf_v5.settings, - }; - } - - - /** - */ - function schema_source_kalender_digital( - version : string - ) : lib_plankton.conf.type_schema - { - return { - "type": "object", - "properties": { - "kind": { - "nullable": false, - "type": "string", - "enum": ["kalender_digital"] - }, - "data": { - "nullable": false, - "type": "object", - "properties": { - "path": { - "nullable": false, - "type": "string" - }, - "filtration": { - "nullable": false, - "type": "object", - "properties": { - "category_blacklist": { - "nullable": true, - "type": "array", - "items": { - "nullable": false, - "type": "string", - }, - "default": [], - }, - "title_blacklist": { - "nullable": true, - "type": "array", - "items": { - "nullable": false, - "type": "string", - }, - "default": [], - }, - }, - "additionalProperties": false, - "required": [ - ], - "default": {} - }, - }, - "additionalProperties": false, - "required": [ - "path", - ] - } - }, - "additionalProperties": false, - "required": [ - "kind", - "data", - ] - }; - } - - /** */ function schema_source_ical_feed( - version : string ) : lib_plankton.conf.type_schema { return { @@ -768,137 +189,82 @@ namespace _munin.conf /** */ function schema_sources( - version : string ) : lib_plankton.conf.type_schema { - switch (version) { - case "1": - { - return { - "nullable": false, - "type": "array", - "items": { - "nullable": false, - "anyOf": [ - schema_source_kalender_digital(version), - ], - } - }; - break; + return { + "nullable": false, + "type": "array", + "items": { + "nullable": false, + "anyOf": [ + schema_source_ical_feed(), + ], } - default: - case "2": - { - return { - "nullable": false, - "type": "array", - "items": { - "nullable": false, - "anyOf": [ - schema_source_ical_feed(version), - ], - } - }; - break; - } - } + }; } /** */ function schema_reminder( - version : string ) : lib_plankton.conf.type_schema { - switch (version) - { - case "1": - case "2": - case "3": - case "4": - { - return { - "type": "integer", - }; - } - default: - { - return { + return { + "nullable": false, + "type": "object", + "properties": { + "frequency": { "nullable": false, - "type": "object", - "properties": { - "frequency": { - "nullable": false, - "type": "string", - "enum": [ - "hourly", - "daily", - "weekly", - "monthly", - ] - }, - "offset": { - "nullable": false, - "type": "integer", - "default": 0 - }, - "from": { - "nullable": false, - "type": "integer" - }, - "to": { - "nullable": false, - "type": "integer" - }, - }, - "additionalProperties": false, - "required": [ - "frequency", - "from", - "to", + "type": "string", + "enum": [ + "hourly", + "daily", + "weekly", + "monthly", ] - }; - break; - } - } + }, + "offset": { + "nullable": false, + "type": "integer", + "default": 0 + }, + "from": { + "nullable": false, + "type": "integer" + }, + "to": { + "nullable": false, + "type": "integer" + }, + }, + "additionalProperties": false, + "required": [ + "frequency", + "from", + "to", + ] + }; } /** */ function default_reminder( - version : string ) : any { - switch (version) - { - case "1": - case "2": - case "3": - case "4": + return [ { - return [24]; + "frequency": "hourly", + "from": 24, + "to": 25 } - default: - { - return [ - { - "frequency": "hourly", - "from": 24, - "to": 25 - } - ]; - break; - } - } + ]; } /** */ function schema_target_email( - version : string ) : lib_plankton.conf.type_schema { return { @@ -951,8 +317,8 @@ namespace _munin.conf "reminders": { "nullable": false, "type": "array", - "items": schema_reminder(version), - "default": default_reminder(version), + "items": schema_reminder(), + "default": default_reminder(), }, "language": { "nullable": false, @@ -982,7 +348,6 @@ namespace _munin.conf /** */ function schema_target_telegram_bot( - version : string ) : lib_plankton.conf.type_schema { return { @@ -1014,8 +379,8 @@ namespace _munin.conf "reminders": { "nullable": false, "type": "array", - "items": schema_reminder(version), - "default": default_reminder(version), + "items": schema_reminder(), + "default": default_reminder(), }, "language": { "nullable": false, @@ -1042,7 +407,6 @@ namespace _munin.conf /** */ function schema_targets( - version : string ) : lib_plankton.conf.type_schema { return { @@ -1050,26 +414,10 @@ namespace _munin.conf "type": "array", "items": { "nullable": false, - "anyOf": (() => { - switch (version) { - case "1": - case "2": - { - return [ - schema_target_telegram_bot(version), - ]; - break; - } - default: - { - return [ - schema_target_email(version), - schema_target_telegram_bot(version), - ]; - break; - } - } - }) (), + "anyOf": [ + schema_target_email(), + schema_target_telegram_bot(), + ] } }; } @@ -1078,7 +426,6 @@ namespace _munin.conf /** */ function schema_settings( - version : string ) : lib_plankton.conf.type_schema { return { @@ -1102,95 +449,40 @@ namespace _munin.conf /** */ - function schema_labels( - version : string + export function schema( ) : lib_plankton.conf.type_schema { return { "nullable": false, "type": "object", "properties": { - "head": { - "nullable": false, - "type": "string", - "default": "Termin-Erinnerung" - }, - "title": { - "nullable": false, - "type": "string", - "default": "was" - }, - "time": { - "nullable": false, - "type": "string", - "default": "wann" - }, - "location": { - "nullable": false, - "type": "string", - "default": "wo" - }, - "events": { - "nullable": false, - "type": "string", - "default": "Termine" - }, + "sources": schema_sources(), + "targets": schema_targets(), + "settings": schema_settings(), }, "additionalProperties": false, "required": [ + "sources", + "targets", ], - "default": {} }; } /** */ - export function schema( - version : string = "6" + export function schema_extended( ) : lib_plankton.conf.type_schema { - switch (version) { - case "1": { - return { + return { + "type": "object", + "properties": { + "version": { "nullable": false, - "type": "object", - "properties": { - "sources": schema_sources(version), - "targets": schema_targets(version), - "frequency": { - "nullable": false, - "type": "number", - "default": 1.0, - }, - "labels": schema_labels(version), - }, - "additionalProperties": false, - "required": [ - "sources", - "targets", - ], - }; - break; - } - default: - { - return { - "nullable": false, - "type": "object", - "properties": { - "sources": schema_sources(version), - "targets": schema_targets(version), - "settings": schema_settings(version), - "labels": schema_labels(version), - }, - "additionalProperties": false, - "required": [ - "sources", - "targets", - ], - }; - break; + "type": "string", + "enum": [current_version], + }, + "content": _munin.conf.schema(), } } } @@ -1202,54 +494,18 @@ namespace _munin.conf path : string ) : Promise { - const conf_raw : {version : string; content : any} = await lib_plankton.conf.load_versioned( - path, - schema, - { - "1": {"target": "2", "function": convert_from_v1}, - "2": {"target": "3", "function": convert_from_v2}, - "3": {"target": "4", "function": convert_from_v3}, - "4": {"target": "5", "function": convert_from_v4}, - "5": {"target": "6", "function": convert_from_v5}, - "6": null, - } + const conf_raw : {version : string; content : any} = await lib_plankton.conf.load( + schema(), + path ); - - /* - switch (conf_raw.version) { - case "1": { - const conf_v1 : type_conf_v1 = (conf_raw.content as type_conf_v1); - const conf_v2 : type_conf_v2 = convert_from_v1(conf_v1); - const conf_v3 : type_conf_v3 = convert_from_v2(conf_v2); - const conf_v4 : type_conf_v4 = convert_from_v3(conf_v3); - return conf_v4; - break; - } - case "2": { - const conf_v2 : type_conf_v2 = (conf_raw.content as type_conf_v2); - const conf_v3 : type_conf_v3 = convert_from_v2(conf_v2); - const conf_v4 : type_conf_v4 = convert_from_v3(conf_v3); - return conf_v4; - break; - } - case "3": { - const conf_v3 : type_conf_v3 = (conf_raw.content as type_conf_v3); - const conf_v4 : type_conf_v4 = convert_from_v3(conf_v3); - return conf_v4; - break; - } - case "4": { - const conf_v4 : type_conf_v4 = (conf_raw.content as type_conf_v4); - return conf_v4; - break; - } - default: { - throw (new Error("invalid version: " + conf_raw.version)); - break; - } + if (conf_raw.version !== current_version) + { + throw (new Error("conf expected in version '" + current_version + "'")); + } + else + { + return (conf_raw.content as type_conf_v6); } - */ - return (conf_raw.content as type_conf_v6); } } diff --git a/source/main.ts b/source/main.ts index 3bbb69e..21145e3 100644 --- a/source/main.ts +++ b/source/main.ts @@ -80,15 +80,10 @@ namespace _munin "conf_schema": lib_plankton.args.class_argument.volatile({ "indicators_long": ["conf-schema"], "indicators_short": ["s"], - "type": lib_plankton.args.enum_type.string, + "type": lib_plankton.args.enum_type.boolean, "mode": lib_plankton.args.enum_mode.replace, - "default": "", - "info": lib_plankton.string.coin( - lib_plankton.translate.get("args.conf_schema.description"), - { - "arg": "_", - } - ), + "default": false, + "info": lib_plankton.translate.get("args.conf_schema.description"), "name": "conf-schema", }), "conf_expose": lib_plankton.args.class_argument.volatile({ @@ -155,10 +150,10 @@ namespace _munin ); } else { - if (args.conf_schema !== "") { + if (args.conf_schema) { process.stdout.write( lib_plankton.json.encode( - _munin.conf.schema((args.conf_schema === "_") ? undefined : args.conf_schema), + _munin.conf.schema_extended(), { "formatted": true, }