This commit is contained in:
fenris 2025-10-17 00:42:11 +02:00
parent 944043d873
commit e552560887
13 changed files with 879 additions and 654 deletions

View file

@ -229,9 +229,10 @@ declare namespace lib_plankton.base {
function object_merge(core: Record<string, any>, mantle: Record<string, any>): Record<string, any>; function object_merge(core: Record<string, any>, mantle: Record<string, any>): Record<string, any>;
/** /**
*/ */
function buffer_show(buffer: Buffer, { "block_size": option_block_size, "break_char": option_break_char, }?: { function buffer_show(buffer: Buffer, { "block_size": option_block_size, "break_char": option_break_char, "render_readable_characters": render_readable_characters, }?: {
block_size?: int; block_size?: int;
break_char?: string; break_char?: string;
render_readable_characters?: boolean;
}): string; }): string;
} }
declare module lib_plankton.pod { declare module lib_plankton.pod {
@ -4128,7 +4129,7 @@ declare namespace lib_plankton.server {
}; };
/** /**
*/ */
function make(handle: ((input: string, metadata?: type_metadata) => Promise<string>), options?: { function make(handle: ((input: string, metadata?: type_metadata) => Promise<string>), { "host": host, "port": port, "threshold": threshold, }?: {
host?: string; host?: string;
port?: int; port?: int;
threshold?: (null | float); threshold?: (null | float);

View file

@ -428,17 +428,31 @@ var lib_plankton;
base.object_merge = object_merge; base.object_merge = object_merge;
/** /**
*/ */
function buffer_show(buffer, { "block_size": option_block_size = 20, "break_char": option_break_char = "\n", } = {}) { function buffer_show(buffer, { "block_size": option_block_size = 20, "break_char": option_break_char = "\n", "render_readable_characters": render_readable_characters = true, } = {}) {
function is_readable(code) {
return ((code > 0x20)
&&
(code <= 0x7E));
}
let output = ""; let output = "";
let count = 0; let count = 0;
// @ts-ignore // @ts-ignore
for (const entry of buffer) { for (const entry of buffer) {
count = ((count + 1) % option_block_size); count = ((count + 1) % option_block_size);
output += ((typeof (entry) === "string") /*
*/
const code = ((typeof (entry) === "string")
? ?
entry.charCodeAt(0) entry.charCodeAt(0)
: :
entry).toString(16).toUpperCase().padStart(2, "0"); entry);
output += ((render_readable_characters
&&
is_readable(code))
?
String.fromCharCode(code)
:
("[" + code.toString(16).toUpperCase().padStart(2, "0") + "]"));
output += ((count === 0) ? option_break_char : ""); output += ((count === 0) ? option_break_char : "");
} }
return output; return output;
@ -2167,11 +2181,13 @@ var lib_plankton;
function get_channel_logic(channel_description) { function get_channel_logic(channel_description) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j; var _a, _b, _c, _d, _e, _f, _g, _h, _j;
switch (channel_description.kind) { switch (channel_description.kind) {
default: { default:
{
throw (new Error("unhandled log channel kind: " + channel_description.kind)); throw (new Error("unhandled log channel kind: " + channel_description.kind));
break; break;
} }
case "filtered": { case "filtered":
{
return lib_plankton.log.channel.filtered.logic({ return lib_plankton.log.channel.filtered.logic({
"core": get_channel_logic(channel_description.data.core), "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) { "predicate": lib_plankton.log.channel.filtered.predicate_complex(channel_description.data.predicate.map(function (clause_raw) { return clause_raw.map(function (literal_raw) {
@ -2214,21 +2230,24 @@ var lib_plankton;
}); });
break; break;
} }
case "minlevel": { case "minlevel":
{
return lib_plankton.log.channel.minlevel.logic({ return lib_plankton.log.channel.minlevel.logic({
"core": get_channel_logic(channel_description.data.core), "core": get_channel_logic(channel_description.data.core),
"threshold": log.level_decode(channel_description.data.threshold) "threshold": log.level_decode(channel_description.data.threshold)
}); });
break; break;
} }
case "std": { case "std":
{
return lib_plankton.log.channel.std.logic({ 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"), "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) "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; break;
} }
case "file": { case "file":
{
/** /**
* @todo exceptions on missing parameters * @todo exceptions on missing parameters
*/ */
@ -2238,11 +2257,13 @@ var lib_plankton;
}); });
break; break;
} }
case "notify": { case "notify":
{
return lib_plankton.log.channel.notify.logic({}); return lib_plankton.log.channel.notify.logic({});
break; break;
} }
case "email": { case "email":
{
/** /**
* @todo exceptions on missing parameters * @todo exceptions on missing parameters
*/ */
@ -11504,30 +11525,30 @@ var lib_plankton;
/** /**
*/ */
function date_decode(date_encoded) { function date_decode(date_encoded) {
return { return ({
"year": parseInt(date_encoded.slice(0, 4)), "year": parseInt(date_encoded.slice(0, 4)),
"month": parseInt(date_encoded.slice(4, 6)), "month": parseInt(date_encoded.slice(4, 6)),
"day": parseInt(date_encoded.slice(6, 8)), "day": parseInt(date_encoded.slice(6, 8)),
}; });
} }
/** /**
*/ */
function time_decode(time_encoded) { function time_decode(time_encoded) {
return { return ({
"hour": parseInt(time_encoded.slice(0, 2)), "hour": parseInt(time_encoded.slice(0, 2)),
"minute": parseInt(time_encoded.slice(2, 4)), "minute": parseInt(time_encoded.slice(2, 4)),
"second": parseInt(time_encoded.slice(4, 6)), "second": parseInt(time_encoded.slice(4, 6)),
"utc": ((time_encoded.length >= 7) && (time_encoded[6] === "Z")) "utc": ((time_encoded.length >= 7) && (time_encoded[6] === "Z"))
}; });
} }
/** /**
*/ */
function datetime_decode(datetime_encoded) { function datetime_decode(datetime_encoded) {
const parts = datetime_encoded.split("T", 2); const parts = datetime_encoded.split("T", 2);
return { return ({
"date": date_decode(parts[0]), "date": date_decode(parts[0]),
"time": ((parts.length >= 2) ? time_decode(parts[1]) : null), "time": ((parts.length >= 2) ? time_decode(parts[1]) : null),
}; });
} }
/** /**
*/ */
@ -11560,11 +11581,11 @@ var lib_plankton;
/** /**
*/ */
function class_decode(class_encoded) { function class_decode(class_encoded) {
return { return ({
"PRIVATE": ical.enum_class.private, "PRIVATE": ical.enum_class.private,
"PUBLIC": ical.enum_class.public, "PUBLIC": ical.enum_class.public,
"CONFIDENTIAL": ical.enum_class.confidential, "CONFIDENTIAL": ical.enum_class.confidential,
}[class_encoded]; }[class_encoded]);
} }
/** /**
*/ */
@ -11587,11 +11608,11 @@ var lib_plankton;
/** /**
*/ */
function event_status_decode(event_status_encoded) { function event_status_decode(event_status_encoded) {
return { return ({
"TENTATIVE": ical.enum_event_status.tentative, "TENTATIVE": ical.enum_event_status.tentative,
"CONFIRMED": ical.enum_event_status.confirmed, "CONFIRMED": ical.enum_event_status.confirmed,
"CANCELLED": ical.enum_event_status.cancelled, "CANCELLED": ical.enum_event_status.cancelled,
}[event_status_encoded]; }[event_status_encoded]);
} }
/** /**
*/ */
@ -11610,10 +11631,10 @@ var lib_plankton;
/** /**
*/ */
function transp_decode(transp_encoded) { function transp_decode(transp_encoded) {
return { return ({
"OPAQUE": ical.enum_transp.opaque, "OPAQUE": ical.enum_transp.opaque,
"TRANSPARENT": ical.enum_transp.transparent, "TRANSPARENT": ical.enum_transp.transparent,
}[transp_encoded]; }[transp_encoded]);
} }
/** /**
*/ */
@ -11663,6 +11684,7 @@ var lib_plankton;
let content_lines = []; let content_lines = [];
let content_line_buffer = null; let content_line_buffer = null;
lines.forEach(line => { lines.forEach(line => {
{
if (line.trim() === "") { if (line.trim() === "") {
// do nothing // do nothing
} }
@ -11694,6 +11716,7 @@ var lib_plankton;
content_line_buffer = line; content_line_buffer = line;
} }
} }
}
}); });
if (content_line_buffer === null) { if (content_line_buffer === null) {
// do nothing // do nothing
@ -11702,6 +11725,7 @@ var lib_plankton;
content_lines.push(content_line_buffer); content_lines.push(content_line_buffer);
} }
const instructions = content_lines.map((content_line) => { const instructions = content_lines.map((content_line) => {
{
const parts = content_line.split(":"); const parts = content_line.split(":");
const parts_left = parts[0].split(";"); const parts_left = parts[0].split(";");
return { return {
@ -11711,30 +11735,34 @@ var lib_plankton;
.split(";") .split(";")
.map(x => x.replace(new RegExp("\\\\,", "g"), ","))), .map(x => x.replace(new RegExp("\\\\,", "g"), ","))),
}; };
}
}); });
lib_plankton.log.debug("plankton.ical.ics_decode_multi.instructions", { lib_plankton.log.debug("plankton.ical.ics_decode_multi.instructions", {
"instructions": instructions, "instructions": instructions,
}); });
// core // core
let state = { let state = ({
"label": enum_decode_state_label.expect_vcalendar_begin, "label": enum_decode_state_label.expect_vcalendar_begin,
"vcalendar_list": [], "vcalendar_list": [],
"vcalendar": null, "vcalendar": null,
"vevent": null, "vevent": null,
}; });
instructions.forEach((instruction) => { instructions.forEach((instruction) => {
lib_plankton.log.debug("plankton.ical.ics_decode_multi.step", { lib_plankton.log.debug("plankton.ical.ics_decode_multi.step", {
"state": state, "state": state,
"current_instruction": instruction, "current_instruction": instruction,
}); });
switch (state.label) { switch (state.label) {
default: { default:
{
throw (new Error("unhandled state label: " + state.label)); throw (new Error("unhandled state label: " + state.label));
break; break;
} }
case enum_decode_state_label.expect_vcalendar_begin: { case enum_decode_state_label.expect_vcalendar_begin:
{
switch (instruction.command) { switch (instruction.command) {
default: { default:
{
lib_plankton.log.error("plankton.ical.ics_decode.error.vcalendar.unexpected_instruction_key", { lib_plankton.log.error("plankton.ical.ics_decode.error.vcalendar.unexpected_instruction_key", {
"state": state, "state": state,
"instruction": instruction, "instruction": instruction,
@ -11744,7 +11772,8 @@ var lib_plankton;
} }
case "BEGIN": { case "BEGIN": {
switch (instruction.value[0]) { switch (instruction.value[0]) {
default: { default:
{
lib_plankton.log.error("plankton.ical.ics_decode.error.vcalendar.unexpected_instruction_value", { lib_plankton.log.error("plankton.ical.ics_decode.error.vcalendar.unexpected_instruction_value", {
"state": state, "state": state,
"instruction": instruction, "instruction": instruction,
@ -11752,8 +11781,9 @@ var lib_plankton;
throw (new Error("unexpected instruction value: " + instruction.value[0])); throw (new Error("unexpected instruction value: " + instruction.value[0]));
break; break;
} }
case "VCALENDAR": { case "VCALENDAR":
state = { {
state = ({
"label": enum_decode_state_label.expect_vcalendar_property, "label": enum_decode_state_label.expect_vcalendar_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
"vcalendar": { "vcalendar": {
@ -11762,7 +11792,7 @@ var lib_plankton;
"vevents": [], "vevents": [],
}, },
"vevent": null, "vevent": null,
}; });
break; break;
} }
} }
@ -11771,18 +11801,21 @@ var lib_plankton;
} }
break; break;
} }
case enum_decode_state_label.expect_vcalendar_property: { case enum_decode_state_label.expect_vcalendar_property:
{
switch (instruction.command) { switch (instruction.command) {
case "VERSION": { case "VERSION":
state = { {
state = ({
"label": enum_decode_state_label.expect_vcalendar_property, "label": enum_decode_state_label.expect_vcalendar_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
"vcalendar": Object.assign(state.vcalendar, Object.fromEntries([["version", instruction.value[0]]])), "vcalendar": Object.assign(state.vcalendar, Object.fromEntries([["version", instruction.value[0]]])),
"vevent": state.vevent, "vevent": state.vevent,
}; });
break; break;
} }
case "PRODID": { case "PRODID":
{
state = { state = {
"label": enum_decode_state_label.expect_vcalendar_property, "label": enum_decode_state_label.expect_vcalendar_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
@ -11791,7 +11824,8 @@ var lib_plankton;
}; };
break; break;
} }
case "METHOD": { case "METHOD":
{
state = { state = {
"label": enum_decode_state_label.expect_vcalendar_property, "label": enum_decode_state_label.expect_vcalendar_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
@ -11800,19 +11834,22 @@ var lib_plankton;
}; };
break; break;
} }
case "CALSCALE": { case "CALSCALE":
state = { {
state = ({
"label": enum_decode_state_label.expect_vcalendar_property, "label": enum_decode_state_label.expect_vcalendar_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
"vcalendar": Object.assign(state.vcalendar, Object.fromEntries([["calscale", instruction.value[0]]])), "vcalendar": Object.assign(state.vcalendar, Object.fromEntries([["calscale", instruction.value[0]]])),
"vevent": state.vevent, "vevent": state.vevent,
}; });
break; break;
} }
case "BEGIN": { case "BEGIN":
{
const object = instruction.value[0]; const object = instruction.value[0];
switch (object) { switch (object) {
default: { default:
{
lib_plankton.log.error("plankton.ical.ics_decode.error.vcalendar.unhandled_object", { lib_plankton.log.error("plankton.ical.ics_decode.error.vcalendar.unhandled_object", {
"state": state, "state": state,
"instruction": instruction, "instruction": instruction,
@ -11821,7 +11858,8 @@ var lib_plankton;
throw (new Error("unhandled object: " + object)); throw (new Error("unhandled object: " + object));
break; break;
} }
case "VCALENDAR": { case "VCALENDAR":
{
lib_plankton.log.error("plankton.ical.ics_decode.error.vcalendar.unexpected_object", { lib_plankton.log.error("plankton.ical.ics_decode.error.vcalendar.unexpected_object", {
"state": state, "state": state,
"instruction": instruction, "instruction": instruction,
@ -11830,8 +11868,9 @@ var lib_plankton;
throw (new Error("unexpected object: " + object)); throw (new Error("unexpected object: " + object));
break; break;
} }
case "VEVENT": { case "VEVENT":
state = { {
state = ({
"label": enum_decode_state_label.expect_vevent_property, "label": enum_decode_state_label.expect_vevent_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
"vcalendar": state.vcalendar, "vcalendar": state.vcalendar,
@ -11842,16 +11881,18 @@ var lib_plankton;
"time": { "hour": 0, "minute": 0, "second": 0, "utc": true }, "time": { "hour": 0, "minute": 0, "second": 0, "utc": true },
}, },
}, },
}; });
break; break;
} }
} }
break; break;
} }
case "END": { case "END":
{
const object = instruction.value[0]; const object = instruction.value[0];
switch (object) { switch (object) {
default: { default:
{
lib_plankton.log.error("plankton.ical.ics_decode.error.vcalendar.unhandled_object", { lib_plankton.log.error("plankton.ical.ics_decode.error.vcalendar.unhandled_object", {
"state": state, "state": state,
"instruction": instruction, "instruction": instruction,
@ -11860,23 +11901,25 @@ var lib_plankton;
throw (new Error("unhandled object: " + object)); throw (new Error("unhandled object: " + object));
break; break;
} }
case "VCALENDAR": { case "VCALENDAR":
state = { {
state = ({
"label": enum_decode_state_label.expect_vcalendar_begin, "label": enum_decode_state_label.expect_vcalendar_begin,
"vcalendar_list": state.vcalendar_list.concat([state.vcalendar]), "vcalendar_list": state.vcalendar_list.concat([state.vcalendar]),
"vcalendar": null, "vcalendar": null,
"vevent": state.vevent, "vevent": state.vevent,
}; });
break; break;
} }
} }
break; break;
} }
default: { default:
{
if (instruction.command.startsWith("X-")) { if (instruction.command.startsWith("X-")) {
const key = instruction.command.slice(2).toLowerCase(); const key = instruction.command.slice(2).toLowerCase();
const value = instruction.value.join(";"); const value = instruction.value.join(";");
state = { state = ({
"label": enum_decode_state_label.expect_vcalendar_property, "label": enum_decode_state_label.expect_vcalendar_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
/** /**
@ -11886,7 +11929,7 @@ var lib_plankton;
"x_props": Object.assign((state.vcalendar.x_props ?? {}), Object.fromEntries([[key, value]])) "x_props": Object.assign((state.vcalendar.x_props ?? {}), Object.fromEntries([[key, value]]))
}), }),
"vevent": state.vevent, "vevent": state.vevent,
}; });
} }
else { else {
lib_plankton.log.warning("plankton.ical.ics_decode.error.vcalendar.unhandled_instruction_key", { lib_plankton.log.warning("plankton.ical.ics_decode.error.vcalendar.unhandled_instruction_key", {
@ -11905,19 +11948,22 @@ var lib_plankton;
} }
break; break;
} }
case enum_decode_state_label.expect_vevent_property: { case enum_decode_state_label.expect_vevent_property:
{
switch (instruction.command) { switch (instruction.command) {
case "UID": { case "UID":
state = { {
state = ({
"label": enum_decode_state_label.expect_vevent_property, "label": enum_decode_state_label.expect_vevent_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
"vcalendar": state.vcalendar, "vcalendar": state.vcalendar,
"vevent": Object.assign(state.vevent, Object.fromEntries([["uid", instruction.value[0]]])), "vevent": Object.assign(state.vevent, Object.fromEntries([["uid", instruction.value[0]]])),
}; });
break; break;
} }
case "DTSTART": { case "DTSTART":
state = { {
state = ({
"label": enum_decode_state_label.expect_vevent_property, "label": enum_decode_state_label.expect_vevent_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
"vcalendar": state.vcalendar, "vcalendar": state.vcalendar,
@ -11935,11 +11981,12 @@ var lib_plankton;
{})) {}))
] ]
])), ])),
}; });
break; break;
} }
case "DTEND": { case "DTEND":
state = { {
state = ({
"label": enum_decode_state_label.expect_vevent_property, "label": enum_decode_state_label.expect_vevent_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
"vcalendar": state.vcalendar, "vcalendar": state.vcalendar,
@ -11957,11 +12004,12 @@ var lib_plankton;
{})) {}))
] ]
])), ])),
}; });
break; break;
} }
case "DTSTAMP": { case "DTSTAMP":
state = { {
state = ({
"label": enum_decode_state_label.expect_vevent_property, "label": enum_decode_state_label.expect_vevent_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
"vcalendar": state.vcalendar, "vcalendar": state.vcalendar,
@ -11971,74 +12019,82 @@ var lib_plankton;
datetime_decode(instruction.value[0]) datetime_decode(instruction.value[0])
] ]
])), ])),
}; });
break; break;
} }
case "SEQUENCE": { case "SEQUENCE":
state = { {
state = ({
"label": enum_decode_state_label.expect_vevent_property, "label": enum_decode_state_label.expect_vevent_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
"vcalendar": state.vcalendar, "vcalendar": state.vcalendar,
"vevent": Object.assign(state.vevent, Object.fromEntries([["sequence", parseInt(instruction.value[0])]])), "vevent": Object.assign(state.vevent, Object.fromEntries([["sequence", parseInt(instruction.value[0])]])),
}; });
break; break;
} }
case "TRANSP": { case "TRANSP":
state = { {
state = ({
"label": enum_decode_state_label.expect_vevent_property, "label": enum_decode_state_label.expect_vevent_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
"vcalendar": state.vcalendar, "vcalendar": state.vcalendar,
"vevent": Object.assign(state.vevent, Object.fromEntries([["transp", transp_decode(instruction.value[0])]])), "vevent": Object.assign(state.vevent, Object.fromEntries([["transp", transp_decode(instruction.value[0])]])),
}; });
break; break;
} }
case "SUMMARY": { case "SUMMARY":
state = { {
state = ({
"label": enum_decode_state_label.expect_vevent_property, "label": enum_decode_state_label.expect_vevent_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
"vcalendar": state.vcalendar, "vcalendar": state.vcalendar,
"vevent": Object.assign(state.vevent, Object.fromEntries([["summary", instruction.value[0]]])), "vevent": Object.assign(state.vevent, Object.fromEntries([["summary", instruction.value[0]]])),
}; });
break; break;
} }
case "CLASS": { case "CLASS":
state = { {
state = ({
"label": enum_decode_state_label.expect_vevent_property, "label": enum_decode_state_label.expect_vevent_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
"vcalendar": state.vcalendar, "vcalendar": state.vcalendar,
"vevent": Object.assign(state.vevent, Object.fromEntries([["class", class_decode(instruction.value[0])]])), "vevent": Object.assign(state.vevent, Object.fromEntries([["class", class_decode(instruction.value[0])]])),
}; });
break; break;
} }
case "STATUS": { case "STATUS":
state = { {
state = ({
"label": enum_decode_state_label.expect_vevent_property, "label": enum_decode_state_label.expect_vevent_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
"vcalendar": state.vcalendar, "vcalendar": state.vcalendar,
"vevent": Object.assign(state.vevent, Object.fromEntries([["status", event_status_decode(instruction.value[0])]])), "vevent": Object.assign(state.vevent, Object.fromEntries([["status", event_status_decode(instruction.value[0])]])),
}; });
break; break;
} }
case "DESCRIPTION": { case "DESCRIPTION":
state = { {
state = ({
"label": enum_decode_state_label.expect_vevent_property, "label": enum_decode_state_label.expect_vevent_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
"vcalendar": state.vcalendar, "vcalendar": state.vcalendar,
"vevent": Object.assign(state.vevent, Object.fromEntries([["description", instruction.value[0]]])), "vevent": Object.assign(state.vevent, Object.fromEntries([["description", instruction.value[0]]])),
}; });
break; break;
} }
case "CATEGORIES": { case "CATEGORIES":
state = { {
state = ({
"label": enum_decode_state_label.expect_vevent_property, "label": enum_decode_state_label.expect_vevent_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
"vcalendar": state.vcalendar, "vcalendar": state.vcalendar,
"vevent": Object.assign(state.vevent, Object.fromEntries([["categories", instruction.value[0].split(",")]])), "vevent": Object.assign(state.vevent, Object.fromEntries([["categories", instruction.value[0].split(",")]])),
}; });
break; break;
} }
case "CREATED": { case "CREATED":
state = { {
state = ({
"label": enum_decode_state_label.expect_vevent_property, "label": enum_decode_state_label.expect_vevent_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
"vcalendar": state.vcalendar, "vcalendar": state.vcalendar,
@ -12050,29 +12106,32 @@ var lib_plankton;
} }
] ]
])), ])),
}; });
break; break;
} }
case "LOCATION": { case "LOCATION":
state = { {
state = ({
"label": enum_decode_state_label.expect_vevent_property, "label": enum_decode_state_label.expect_vevent_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
"vcalendar": state.vcalendar, "vcalendar": state.vcalendar,
"vevent": Object.assign(state.vevent, Object.fromEntries([["location", instruction.value[0]]])), "vevent": Object.assign(state.vevent, Object.fromEntries([["location", instruction.value[0]]])),
}; });
break; break;
} }
case "URL": { case "URL":
state = { {
state = ({
"label": enum_decode_state_label.expect_vevent_property, "label": enum_decode_state_label.expect_vevent_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
"vcalendar": state.vcalendar, "vcalendar": state.vcalendar,
"vevent": Object.assign(state.vevent, Object.fromEntries([["url", instruction.value[0]]])), "vevent": Object.assign(state.vevent, Object.fromEntries([["url", instruction.value[0]]])),
}; });
break; break;
} }
case "LAST-MODIFIED": { case "LAST-MODIFIED":
state = { {
state = ({
"label": enum_decode_state_label.expect_vevent_property, "label": enum_decode_state_label.expect_vevent_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
"vcalendar": state.vcalendar, "vcalendar": state.vcalendar,
@ -12084,20 +12143,22 @@ var lib_plankton;
} }
] ]
])), ])),
}; });
break; break;
} }
case "ATTENDEE": { case "ATTENDEE":
state = { {
state = ({
"label": enum_decode_state_label.expect_vevent_property, "label": enum_decode_state_label.expect_vevent_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
"vcalendar": state.vcalendar, "vcalendar": state.vcalendar,
"vevent": Object.assign(state.vevent, Object.fromEntries([["attendee", instruction.value[0]]])), "vevent": Object.assign(state.vevent, Object.fromEntries([["attendee", instruction.value[0]]])),
}; });
break; break;
} }
case "ORGANIZER": { case "ORGANIZER":
state = { {
state = ({
"label": enum_decode_state_label.expect_vevent_property, "label": enum_decode_state_label.expect_vevent_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
"vcalendar": state.vcalendar, "vcalendar": state.vcalendar,
@ -12112,13 +12173,15 @@ var lib_plankton;
} }
] ]
])), ])),
}; });
break; break;
} }
case "BEGIN": { case "BEGIN":
{
const object = instruction.value[0]; const object = instruction.value[0];
switch (object) { switch (object) {
default: { default:
{
lib_plankton.log.error("plankton.ical.ics_decode.error.vevent.unhandled_object", { lib_plankton.log.error("plankton.ical.ics_decode.error.vevent.unhandled_object", {
"state": state, "state": state,
"instruction": instruction, "instruction": instruction,
@ -12127,7 +12190,8 @@ var lib_plankton;
throw (new Error("unhandled object: " + object)); throw (new Error("unhandled object: " + object));
break; break;
} }
case "VCALENDAR": { case "VCALENDAR":
{
lib_plankton.log.error("plankton.ical.ics_decode.error.vevent.unexpected_object", { lib_plankton.log.error("plankton.ical.ics_decode.error.vevent.unexpected_object", {
"state": state, "state": state,
"instruction": instruction, "instruction": instruction,
@ -12136,7 +12200,8 @@ var lib_plankton;
throw (new Error("unexpected object: " + object)); throw (new Error("unexpected object: " + object));
break; break;
} }
case "VEVENT": { case "VEVENT":
{
lib_plankton.log.error("plankton.ical.ics_decode.error.vevent.unexpected_object", { lib_plankton.log.error("plankton.ical.ics_decode.error.vevent.unexpected_object", {
"state": state, "state": state,
"instruction": instruction, "instruction": instruction,
@ -12148,10 +12213,12 @@ var lib_plankton;
} }
break; break;
} }
case "END": { case "END":
{
const object = instruction.value[0]; const object = instruction.value[0];
switch (object) { switch (object) {
default: { default:
{
lib_plankton.log.error("plankton.ical.ics_decode.error.vevent.unhandled_value", { lib_plankton.log.error("plankton.ical.ics_decode.error.vevent.unhandled_value", {
"state": state, "state": state,
"instruction": instruction, "instruction": instruction,
@ -12160,32 +12227,34 @@ var lib_plankton;
throw (new Error("unhandled value: " + object)); throw (new Error("unhandled value: " + object));
break; break;
} }
case "VEVENT": { case "VEVENT":
state = { {
state = ({
"label": enum_decode_state_label.expect_vcalendar_property, "label": enum_decode_state_label.expect_vcalendar_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
"vcalendar": Object.assign(state.vcalendar, { "vcalendar": Object.assign(state.vcalendar, {
"vevents": state.vcalendar.vevents.concat([state.vevent]), "vevents": state.vcalendar.vevents.concat([state.vevent]),
}), }),
"vevent": null, "vevent": null,
}; });
break; break;
} }
} }
break; break;
} }
default: { default:
{
if (instruction.command.startsWith("X-")) { if (instruction.command.startsWith("X-")) {
const key = instruction.command.slice(2).toLowerCase(); const key = instruction.command.slice(2).toLowerCase();
const value = instruction.value.join(";"); const value = instruction.value.join(";");
state = { state = ({
"label": enum_decode_state_label.expect_vevent_property, "label": enum_decode_state_label.expect_vevent_property,
"vcalendar_list": state.vcalendar_list, "vcalendar_list": state.vcalendar_list,
"vcalendar": state.vcalendar, "vcalendar": state.vcalendar,
"vevent": Object.assign(state.vevent, { "vevent": Object.assign(state.vevent, {
"x_props": Object.assign((state.vevent.x_props ?? {}), Object.fromEntries([[key, value]])) "x_props": Object.assign((state.vevent.x_props ?? {}), Object.fromEntries([[key, value]]))
}), }),
}; });
} }
else { else {
lib_plankton.log.warning("plankton.ical.ics_decode.error.vevent.unhandled_instruction_key", { lib_plankton.log.warning("plankton.ical.ics_decode.error.vevent.unhandled_instruction_key", {
@ -12204,7 +12273,8 @@ var lib_plankton;
} }
break; break;
} }
case enum_decode_state_label.done: { case enum_decode_state_label.done:
{
lib_plankton.log.error("plankton.ical.ics_decode.error.end_expected", { lib_plankton.log.error("plankton.ical.ics_decode.error.end_expected", {
"state": state, "state": state,
"instruction": instruction, "instruction": instruction,
@ -14302,16 +14372,11 @@ var lib_plankton;
(function (server) { (function (server) {
/** /**
*/ */
function make(handle, options = {}) { function make(handle, { "host": host = "::", "port": port = 9999, "threshold": threshold = 0.25, } = {}) {
options = Object.assign({
"host": "::",
"port": 9999,
"threshold": 0.25,
}, options);
return { return {
"host": options.host, "host": host,
"port": options.port, "port": port,
"threshold": options.threshold, "threshold": threshold,
"handle": handle, "handle": handle,
"serverobj": undefined, "serverobj": undefined,
}; };
@ -14401,7 +14466,8 @@ var lib_plankton;
} }
}; };
lib_plankton.log.info("plankton.server.client_connected"); lib_plankton.log.info("plankton.server.client_connected");
socket.on("data", (input_chunk_raw) => { socket.on("data", (input_chunk_raw, x2, x3, x4, x5) => {
process.stderr.write(JSON.stringify({ x2, x3, x4, x5 }) + "\n");
lib_plankton.log.debug("plankton.server.reading_chunk", { lib_plankton.log.debug("plankton.server.reading_chunk", {
"chunk_raw": ((input_chunk_raw instanceof Buffer) "chunk_raw": ((input_chunk_raw instanceof Buffer)
? ?
@ -15744,7 +15810,7 @@ the Free Software Foundation, either version 3 of the License, or
»bacterio-plankton:map« is distributed in the hope that it will be useful, »bacterio-plankton:map« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:map«. If not, see <http://www.gnu.org/licenses/>. along with »bacterio-plankton:map«. If not, see <http://www.gnu.org/licenses/>.

View file

@ -1,6 +1,14 @@
{ {
"version": 1, "version": 1,
"log": [ "log": [
{
"kind": "file",
"data": {
"path": "/tmp/zeitbild/log.jsonl",
"threshold": "info",
"format": "jsonl_structured"
}
},
{ {
"kind": "stdout", "kind": "stdout",
"data": { "data": {

View file

@ -26,6 +26,7 @@
{ {
"id": 1, "id": 1,
"name": "LV Lampukistan", "name": "LV Lampukistan",
"hue": 0.0000,
"access": { "access": {
"public": true, "public": true,
"default_level": "view", "default_level": "view",
@ -120,6 +121,7 @@
{ {
"id": 2, "id": 2,
"name": "KV Zepettel-Region", "name": "KV Zepettel-Region",
"hue": 0.3333,
"access": { "access": {
"public": false, "public": false,
"default_level": "view", "default_level": "view",
@ -191,6 +193,7 @@
{ {
"id": 3, "id": 3,
"name": "OV Kawanda", "name": "OV Kawanda",
"hue": 0.6667,
"access": { "access": {
"public": false, "public": false,
"default_level": "view", "default_level": "view",
@ -235,6 +238,7 @@
{ {
"id": 4, "id": 4,
"name": "KV Zepettel-Region | intern", "name": "KV Zepettel-Region | intern",
"hue": 0.8333,
"access": { "access": {
"public": false, "public": false,
"default_level": "none", "default_level": "none",

View file

@ -33,11 +33,11 @@ namespace _zeitbild.api
hue : float; hue : float;
access : { access : {
public : boolean; public : boolean;
default_level : ("none" | "view" | "edit" | "admin"); default_level : string;
attributed : Array< attributed : Array<
{ {
user_id : int; user_id : int;
level : ("none" | "view" | "edit" | "admin"); level : string;
} }
>; >;
}; };

View file

@ -30,7 +30,10 @@ namespace _zeitbild.api
register< register<
_zeitbild.type_event_object, // TODO aufdröseln _zeitbild.type_event_object, // TODO aufdröseln
( (
null {
local_resource_event_id : (null | int);
hash : string;
}
| |
string string
) )
@ -88,10 +91,12 @@ namespace _zeitbild.api
const session : {key : string; value : lib_plankton.session.type_session;} = await session_from_stuff(stuff); const session : {key : string; value : lib_plankton.session.type_session;} = await session_from_stuff(stuff);
const user_id : _zeitbild.type_user_id = await _zeitbild.service.user.identify(session.value.name); const user_id : _zeitbild.type_user_id = await _zeitbild.service.user.identify(session.value.name);
if (stuff.input === null) { if (stuff.input === null)
{
return Promise.reject(new Error("impossible")); return Promise.reject(new Error("impossible"));
} }
else { else
{
return ( return (
_zeitbild.service.calendar.event_add( _zeitbild.service.calendar.event_add(
parseInt(stuff.path_parameters["calendar_id"]), parseInt(stuff.path_parameters["calendar_id"]),
@ -99,9 +104,9 @@ namespace _zeitbild.api
user_id user_id
) )
.then( .then(
() => Promise.resolve({ (data) => Promise.resolve({
"status_code": 200, "status_code": 200,
"data": null, "data": data,
}) })
) )
// TODO distinguish // TODO distinguish

View file

@ -88,10 +88,12 @@ namespace _zeitbild.api
const session : {key : string; value : lib_plankton.session.type_session;} = await session_from_stuff(stuff); const session : {key : string; value : lib_plankton.session.type_session;} = await session_from_stuff(stuff);
const user_id : _zeitbild.type_user_id = await _zeitbild.service.user.identify(session.value.name); const user_id : _zeitbild.type_user_id = await _zeitbild.service.user.identify(session.value.name);
if (stuff.input === null) { if (stuff.input === null)
{
return Promise.reject(new Error("impossible")); return Promise.reject(new Error("impossible"));
} }
else { else
{
return ( return (
_zeitbild.service.calendar.event_change( _zeitbild.service.calendar.event_change(
parseInt(stuff.path_parameters["calendar_id"]), parseInt(stuff.path_parameters["calendar_id"]),
@ -100,17 +102,21 @@ namespace _zeitbild.api
user_id user_id
) )
.then( .then(
() => Promise.resolve({ () => Promise.resolve(
{
"status_code": 200, "status_code": 200,
"data": null, "data": null,
}) }
)
) )
// TODO distinguish // TODO distinguish
.catch( .catch(
(reason) => Promise.resolve({ (reason) => Promise.resolve(
{
"status_code": 403, "status_code": 403,
"data": String(reason), "data": String(reason),
}) }
)
) )
); );
} }

View file

@ -33,6 +33,7 @@ namespace _zeitbild.api
name : string; name : string;
hue : float; hue : float;
access : { access : {
public : boolean;
default_level : string; default_level : string;
attributed : Array< attributed : Array<
{ {

View file

@ -31,6 +31,7 @@ namespace _zeitbild.api
null, null,
{ {
logged_in : boolean; logged_in : boolean;
name : (null | string);
} }
>( >(
rest_subject, rest_subject,
@ -47,9 +48,14 @@ namespace _zeitbild.api
"nullable": false, "nullable": false,
"type": "boolean", "type": "boolean",
}, },
"name": {
"nullable": true,
"type": "string"
},
}, },
"required": [ "required": [
"logged_in", "logged_in",
"name",
], ],
}), }),
"restriction": restriction_none, "restriction": restriction_none,
@ -64,11 +70,19 @@ namespace _zeitbild.api
) )
.catch(x => Promise.resolve(null)) .catch(x => Promise.resolve(null))
); );
const user_object : (null | _zeitbild.type_user_object) = (
(user_id === null)
?
null
:
await _zeitbild.service.user.get(user_id)
);
return Promise.resolve( return Promise.resolve(
{ {
"status_code": 200, "status_code": 200,
"data": { "data": {
"logged_in": (user_id !== null), "logged_in": (user_id !== null),
"name": ((user_object === null) ? null : user_object.name),
} }
} }
); );

View file

@ -76,7 +76,51 @@ namespace _zeitbild.conf
] ]
} }
} }
},
{
"type": "object",
"properties": {
"kind": {
"nullable": false,
"type": "string",
"enum": ["file"]
},
"data": {
"nullable": false,
"type": "object",
"properties": {
"path": {
"nullable": false,
"type": "string"
},
"threshold": {
"nullable": false,
"type": "string",
"enum": [
"debug",
"info",
"notice",
"warning",
"error"
],
"default": "info"
},
"format": {
"nullable": false,
"type": "string",
"enum": [
"human_readable",
"jsonl",
"jsonl_structured",
],
"default": "human_readable",
},
},
"required": [
]
} }
}
},
] ]
}, },
"default": [ "default": [
@ -291,7 +335,8 @@ namespace _zeitbild.conf
"url_token", "url_token",
"url_userinfo", "url_userinfo",
"client_id", "client_id",
"client_secret" "client_secret",
"backend_url_base"
] ]
} }
}, },

View file

@ -172,6 +172,46 @@ async function main(
}; };
break; break;
} }
case "file": {
return {
"kind": "minlevel",
"data": {
"core": {
"kind": "file",
"data": {
"path": log_output.data.path,
"format": lib_plankton.call.distinguish(
{
"kind": log_output.data.format,
"data": null,
},
{
"jsonl": () => ({
"kind": "jsonl",
"data": {
"structured": false,
}
}),
"jsonl_structured": () => ({
"kind": "jsonl",
"data": {
"structured": true,
}
}),
"human_readable": () => ({
"kind": "human_readable",
"data": {
}
}),
}
),
}
},
"threshold": log_output.data.threshold,
}
};
break;
}
default: { default: {
throw (new Error("unhandled")); throw (new Error("unhandled"));
break; break;

View file

@ -223,6 +223,7 @@ namespace _zeitbild.repository.calendar
} }
/** /**
*/ */
export function read( export function read(

View file

@ -212,21 +212,31 @@ namespace _zeitbild.service.calendar
calendar_id : _zeitbild.type_calendar_id, calendar_id : _zeitbild.type_calendar_id,
event_object : _zeitbild.type_event_object, event_object : _zeitbild.type_event_object,
user_id : _zeitbild.type_user_id user_id : _zeitbild.type_user_id
) : Promise<void> ) : Promise<
{
local_resource_event_id : (null | type_local_resource_event_id);
hash : type_event_hash;
}
>
{ {
const calendar_object : _zeitbild.type_calendar_object = await _zeitbild.repository.calendar.read( const calendar_object : _zeitbild.type_calendar_object = await _zeitbild.repository.calendar.read(
calendar_id calendar_id
); );
return wrap_check_access_level<void>( return wrap_check_access_level(
calendar_object, calendar_object,
user_id, user_id,
_zeitbild.enum_access_level.edit, _zeitbild.enum_access_level.edit,
async () => { async () => {
/*const event_id : _zeitbild.type_local_resource_event_id = */await _zeitbild.service.resource.event_add( const local_resource_event_id : _zeitbild.type_local_resource_event_id = await _zeitbild.service.resource.event_add(
calendar_object.resource_id, calendar_object.resource_id,
event_object event_object
); );
return Promise.resolve<void>(undefined); return Promise.resolve(
{
"local_resource_event_id": local_resource_event_id,
"hash": get_event_hash_local(calendar_id, local_resource_event_id),
}
);
} }
); );
} }
@ -286,6 +296,45 @@ namespace _zeitbild.service.calendar
} }
/**
*/
function get_event_hash_local(
calendar_id : _zeitbild.type_calendar_id,
local_resource_event_id : _zeitbild.type_local_resource_event_id
) : string
{
return lib_plankton.string.coin(
"{{calendar_id}}:{{event_id}}",
{
"calendar_id": calendar_id.toFixed(0),
"event_id": local_resource_event_id.toFixed(0),
}
)
}
/**
*/
function get_event_hash_ics_feed(
calendar_id : _zeitbild.type_calendar_id,
event_object : _zeitbild.type_event_object
) : string
{
return lib_plankton.string.coin(
"{{calendar_id}}~{{hash}}",
{
"calendar_id": calendar_id.toFixed(0),
"hash": lib_plankton.call.convey(
event_object,
[
(x : any) => lib_plankton.json.encode(x),
(x : string) => lib_plankton.base64.encode(x),
]
)
}
);
}
/** /**
* @todo optimize by reducing the number of database queries * @todo optimize by reducing the number of database queries
*/ */
@ -326,12 +375,9 @@ namespace _zeitbild.service.calendar
(event_object) => Promise.resolve( (event_object) => Promise.resolve(
{ {
"id": event_id, "id": event_id,
"hash": lib_plankton.string.coin( "hash": get_event_hash_local(
"{{calendar_id}}:{{event_id}}", calendar_id,
{ event_id,
"calendar_id": calendar_id.toFixed(0),
"event_id": event_id.toFixed(0),
}
), ),
"object": event_object, "object": event_object,
} }
@ -457,19 +503,7 @@ namespace _zeitbild.service.calendar
.map( .map(
(event) => ({ (event) => ({
"id": null, "id": null,
"hash": lib_plankton.string.coin( "hash": get_event_hash_ics_feed(calendar_id, event),
"{{calendar_id}}~{{hash}}",
{
"calendar_id": calendar_id.toFixed(0),
"hash": lib_plankton.call.convey(
event,
[
(x : any) => lib_plankton.json.encode(x),
(x : string) => lib_plankton.base64.encode(x),
]
)
}
),
"object": event, "object": event,
}) })
) )