/** */ type type_data = { users : Array< { id : int; name : string; email_address : string; password : string; } >; calendars : Array< { id : int; name : string; access : { default_level : ("none" | "view" | "edit" | "admin"); attributed : Array< { user_id : int; level : ("none" | "view" | "edit" | "admin"); } >; }; resource : ( { kind : "local"; data : { events : Array< _zeitbild.type_event_object > }; } | { kind : "caldav"; data : { url : string; read_only : boolean; }; } ); } >; }; /** */ async function data_init( data : type_data ) : Promise { let track : { user : Record< int, _zeitbild.type_user_id >; calendar : Record< int, _zeitbild.type_user_id >; } = { "user": {}, "calendar": {}, }; for await (const user_raw of data.users) { const user_object : _zeitbild.type_user_object = { "name": user_raw.name, "email_address": user_raw.email_address, }; const user_id : _zeitbild.type_user_id = await _zeitbild.service.user.add( user_object ); await _zeitbild.service.auth_internal.set( user_raw.name, user_raw.password ); track.user[user_raw.id] = user_id; } for await (const calendar_raw of data.calendars) { let resource_object : _zeitbild.type_resource_object; let resource_id : _zeitbild.type_resource_id; switch (calendar_raw.resource.kind) { case "local": { resource_object = { "kind": "local", "data": { "event_ids": [], } }; resource_id = await _zeitbild.service.resource.add( resource_object ); /*const event_ids : Array<_zeitbild.type_local_resource_event_id> = */await Promise.all( calendar_raw.resource.data.events .map( (event_raw : _zeitbild.type_event_object) => _zeitbild.service.resource.event_add( resource_id, { "name": event_raw["name"], "public": (event_raw["public"] ?? false), "begin": event_raw["begin"], "end": (event_raw["end"] ?? null), "location": (event_raw["location"] ?? null), "description": (event_raw["description"] ?? null), } ) ) ); break; } case "caldav": { resource_object = { "kind": "caldav", "data": { "url": calendar_raw.resource.data.url, "read_only": calendar_raw.resource.data.read_only, } }; resource_id = await _zeitbild.service.resource.add( resource_object ); break; } } const calendar_object : _zeitbild.type_calendar_object = { "name": calendar_raw.name, "access": { "default_level": _zeitbild.value_object.access_level.from_string(calendar_raw.access.default_level), "attributed": lib_plankton.map.hashmap.implementation_map( lib_plankton.map.hashmap.make( x => x.toFixed(0), { "pairs": ( calendar_raw.access.attributed .map( (entry) => ({ "key": track.user[entry.user_id], "value": _zeitbild.value_object.access_level.from_string(entry.level), }) ) ), } ) ), }, "resource_id": resource_id, }; const calendar_id : _zeitbild.type_calendar_id = await _zeitbild.service.calendar.add( calendar_object ); track.calendar[calendar_raw.id] = calendar_id; } return Promise.resolve(undefined); } /** */ async function main( args_raw : Array ) : Promise { // init1 lib_plankton.log.conf_push( [ lib_plankton.log.channel_make({"kind": "stdout", "data": {"threshold": "info"}}), ] ); // args const arg_handler : lib_plankton.args.class_handler = new lib_plankton.args.class_handler({ "action": lib_plankton.args.class_argument.positional({ "index": 0, "type": lib_plankton.args.enum_type.string, "mode": lib_plankton.args.enum_mode.replace, "default": "serve", "name": "action", "info": lib_plankton.string.coin( "{{description}}:\n{{options}}\n\t\t", { "description": "action", "options": ( [ { "name": "serve", "description": "serve" }, { "name": "api-doc", "description": "api-doc" }, { "name": "conf-schema", "description": "conf-schema" }, { "name": "conf-expose", "description": "conf-expose" }, { "name": "fill", "description": "fill" }, { "name": "help", "description": "help" }, ] .map( entry => lib_plankton.string.coin( "\t\t- {{name}}\n\t\t\t{{description}}\n", { "name": entry.name, "description": entry.description, } ) ) .join("") ), } ), }), "conf_path": lib_plankton.args.class_argument.volatile({ "indicators_long": ["conf_path"], "indicators_short": ["c"], "type": lib_plankton.args.enum_type.string, "mode": lib_plankton.args.enum_mode.replace, "default": "conf.json", // "info": null, "name": "conf-path", }), "data_path": lib_plankton.args.class_argument.volatile({ "indicators_long": ["data-path"], "indicators_short": ["d"], "type": lib_plankton.args.enum_type.string, "mode": lib_plankton.args.enum_mode.replace, "default": "data.json", // "info": null, "name": "data-path", }), "help": lib_plankton.args.class_argument.volatile({ "indicators_long": ["help"], "indicators_short": ["h"], "type": lib_plankton.args.enum_type.boolean, "mode": lib_plankton.args.enum_mode.replace, "default": false, // "info": null, "name": "help", }), }); const args : Record = arg_handler.read(lib_plankton.args.enum_environment.cli, args_raw.join(" ")); // init2 await _zeitbild.conf.init( args["conf_path"] ); lib_plankton.log.conf_push( _zeitbild.conf.get().log.map( (log_output : any) => lib_plankton.log.channel_make( { "kind": log_output.kind, "data": log_output.data } ) ) ); // exec if (args["help"]) { process.stdout.write( arg_handler.generate_help( { "programname": "zeitbild", "description": "zeitbild-backend", "executable": "zeitbild", } ) + "\n" ); } else { switch (args["action"]) { default: { lib_plankton.log.error( "main_invalid_action", { "action": args["action"], } ); break; } case "conf-schema": { process.stdout.write( JSON.stringify( _zeitbild.conf.schema(), undefined, "\t" ) + "\n" ); break; } case "conf-expose": { process.stdout.write( JSON.stringify( _zeitbild.conf.get(), undefined, "\t" ) + "\n" ); break; } case "api-doc": { lib_plankton.log.conf_push([]); const rest_subject : lib_plankton.rest.type_rest = _zeitbild.api.make(); lib_plankton.log.conf_pop(); process.stdout.write( JSON.stringify( lib_plankton.rest.to_oas(rest_subject), undefined, "\t" ) ); break; } case "fill": { await data_init( lib_plankton.json.decode( await lib_plankton.file.read(args.data_path) ) ); process.stdout.write("-- done\n"); break; } case "serve": { // prepare database await _zeitbild.database.check(); await lib_plankton.session.setup( { "data_chest": ( _zeitbild.conf.get().session_management.in_memory ? lib_plankton.storage.memory.implementation_chest({}) : lib_plankton.call.convey( lib_plankton.storage.sql_table_common.chest( { "database_implementation": _zeitbild.database.get_implementation(), "table_name": "sessions", "key_names": ["key"], } ), [ (core : any) => ({ "setup": (input : any) => core.setup(undefined), "clear": () => core.clear(), "write": (key : any, value : any) => core.write([key], {"data": JSON.stringify(value)}), "delete": (key : any) => core.delete([key]), "read": (key : any) => core.read([key]).then((row : any) => JSON.parse(row["data"])), // "search": (term : any) => core.search(term).then(() => []), "search": (term : any) => Promise.reject(new Error("not implemented")), }), ] ) ), "default_lifetime": _zeitbild.conf.get().session_management.lifetime, } ); await _zeitbild.auth.init(); const rest_subject : lib_plankton.rest.type_rest = _zeitbild.api.make(); const server : lib_plankton.server.type_subject = lib_plankton.server.make( async (input, metadata) => { const http_request : lib_plankton.http.type_request = lib_plankton.http.decode_request(input.toString()); const http_response : lib_plankton.http.type_response = await lib_plankton.rest.call( rest_subject, http_request, { "checklevel_restriction": lib_plankton.api.enum_checklevel.hard, // "checklevel_input": lib_plankton.api.enum_checklevel.soft, // "checklevel_output": lib_plankton.api.enum_checklevel.soft, } ); const output : string = lib_plankton.http.encode_response(http_response); return output; }, { "host": _zeitbild.conf.get().server.host, "port": _zeitbild.conf.get().server.port, // DANGER! DANGER! "threshold": 0.125, } ); lib_plankton.server.start(server); break; } } } return Promise.resolve(undefined); } ( main(process.argv.slice(2)) .then( () => { } ) .catch( (error) => { process.stderr.write(String(error) + "\n"); } ) );