2024-09-12 00:03:29 +02:00
|
|
|
|
2024-09-30 19:52:24 +02:00
|
|
|
|
2024-09-18 18:17:25 +02:00
|
|
|
/**
|
|
|
|
*/
|
|
|
|
type type_data = {
|
|
|
|
users : Array<
|
|
|
|
{
|
|
|
|
id : int;
|
|
|
|
name : string;
|
|
|
|
email_address : string;
|
|
|
|
password : string;
|
|
|
|
}
|
|
|
|
>;
|
|
|
|
calendars : Array<
|
|
|
|
{
|
|
|
|
id : int;
|
|
|
|
name : string;
|
2024-09-21 10:56:00 +02:00
|
|
|
access : {
|
|
|
|
default_level : ("none" | "view" | "edit" | "admin");
|
|
|
|
attributed : Array<
|
|
|
|
{
|
|
|
|
user_id : int;
|
|
|
|
level : ("none" | "view" | "edit" | "admin");
|
|
|
|
}
|
|
|
|
>;
|
|
|
|
};
|
2024-09-25 15:28:25 +02:00
|
|
|
resource : (
|
|
|
|
{
|
|
|
|
kind : "local";
|
|
|
|
data : {
|
|
|
|
events : Array<
|
|
|
|
_zeitbild.type_event_object
|
|
|
|
>
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
{
|
|
|
|
kind : "caldav";
|
|
|
|
data : {
|
|
|
|
url : string;
|
|
|
|
read_only : boolean;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
);
|
2024-09-18 18:17:25 +02:00
|
|
|
}
|
|
|
|
>;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
async function data_init(
|
|
|
|
data : type_data
|
|
|
|
) : Promise<void>
|
|
|
|
{
|
|
|
|
let track : {
|
|
|
|
user : Record<
|
|
|
|
int,
|
2024-09-21 11:05:24 +02:00
|
|
|
_zeitbild.type_user_id
|
2024-09-18 18:17:25 +02:00
|
|
|
>;
|
|
|
|
calendar : Record<
|
|
|
|
int,
|
2024-09-21 11:05:24 +02:00
|
|
|
_zeitbild.type_user_id
|
2024-09-18 18:17:25 +02:00
|
|
|
>;
|
|
|
|
} = {
|
|
|
|
"user": {},
|
|
|
|
"calendar": {},
|
|
|
|
};
|
|
|
|
for await (const user_raw of data.users) {
|
2024-09-21 11:05:24 +02:00
|
|
|
const user_object : _zeitbild.type_user_object = {
|
2024-09-21 10:56:00 +02:00
|
|
|
"name": user_raw.name,
|
|
|
|
"email_address": user_raw.email_address,
|
|
|
|
};
|
2024-09-21 11:05:24 +02:00
|
|
|
const user_id : _zeitbild.type_user_id = await _zeitbild.service.user.add(
|
2024-09-21 10:56:00 +02:00
|
|
|
user_object
|
2024-09-18 18:17:25 +02:00
|
|
|
);
|
|
|
|
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) {
|
2024-09-25 15:28:25 +02:00
|
|
|
let resource_object : _zeitbild.type_resource_object;
|
2024-09-26 10:33:33 +02:00
|
|
|
let resource_id : _zeitbild.type_resource_id;
|
2024-09-25 15:28:25 +02:00
|
|
|
switch (calendar_raw.resource.kind) {
|
|
|
|
case "local": {
|
|
|
|
resource_object = {
|
|
|
|
"kind": "local",
|
|
|
|
"data": {
|
2024-09-26 10:33:33 +02:00
|
|
|
"event_ids": [],
|
2024-09-25 15:28:25 +02:00
|
|
|
}
|
|
|
|
};
|
2024-09-26 10:33:33 +02:00
|
|
|
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(
|
2024-10-10 20:24:05 +02:00
|
|
|
(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),
|
|
|
|
}
|
|
|
|
)
|
2024-09-26 10:33:33 +02:00
|
|
|
)
|
|
|
|
);
|
2024-09-25 15:28:25 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case "caldav": {
|
|
|
|
resource_object = {
|
|
|
|
"kind": "caldav",
|
|
|
|
"data": {
|
|
|
|
"url": calendar_raw.resource.data.url,
|
|
|
|
"read_only": calendar_raw.resource.data.read_only,
|
|
|
|
}
|
|
|
|
};
|
2024-09-26 10:33:33 +02:00
|
|
|
resource_id = await _zeitbild.service.resource.add(
|
|
|
|
resource_object
|
|
|
|
);
|
2024-09-25 15:28:25 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2024-09-21 11:05:24 +02:00
|
|
|
const calendar_object : _zeitbild.type_calendar_object = {
|
2024-09-21 10:56:00 +02:00
|
|
|
"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),
|
|
|
|
})
|
|
|
|
)
|
|
|
|
),
|
|
|
|
}
|
2024-09-18 18:17:25 +02:00
|
|
|
)
|
|
|
|
),
|
2024-09-21 10:56:00 +02:00
|
|
|
},
|
|
|
|
"resource_id": resource_id,
|
|
|
|
};
|
2024-09-21 11:05:24 +02:00
|
|
|
const calendar_id : _zeitbild.type_calendar_id = await _zeitbild.service.calendar.add(
|
2024-09-21 10:56:00 +02:00
|
|
|
calendar_object
|
2024-09-18 18:17:25 +02:00
|
|
|
);
|
|
|
|
track.calendar[calendar_raw.id] = calendar_id;
|
|
|
|
}
|
|
|
|
return Promise.resolve<void>(undefined);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-09-12 00:03:29 +02:00
|
|
|
/**
|
|
|
|
*/
|
|
|
|
async function main(
|
|
|
|
args_raw : Array<string>
|
|
|
|
) : Promise<void>
|
|
|
|
{
|
|
|
|
// init1
|
|
|
|
lib_plankton.log.conf_push(
|
|
|
|
[
|
2024-09-12 20:42:06 +02:00
|
|
|
lib_plankton.log.channel_make({"kind": "stdout", "data": {"threshold": "info"}}),
|
2024-09-12 00:03:29 +02:00
|
|
|
]
|
|
|
|
);
|
|
|
|
|
|
|
|
// 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"
|
|
|
|
},
|
|
|
|
{
|
2024-09-18 18:17:25 +02:00
|
|
|
"name": "conf-schema",
|
|
|
|
"description": "conf-schema"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"name": "conf-expose",
|
|
|
|
"description": "conf-expose"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"name": "fill",
|
|
|
|
"description": "fill"
|
2024-09-12 00:03:29 +02:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"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<string, any> = arg_handler.read(lib_plankton.args.enum_environment.cli, args_raw.join(" "));
|
|
|
|
|
|
|
|
// init2
|
2024-09-18 18:17:25 +02:00
|
|
|
await _zeitbild.conf.init(
|
|
|
|
args["conf_path"]
|
|
|
|
);
|
2024-09-12 00:03:29 +02:00
|
|
|
lib_plankton.log.conf_push(
|
|
|
|
_zeitbild.conf.get().log.map(
|
2024-09-18 18:17:25 +02:00
|
|
|
(log_output : any) => lib_plankton.log.channel_make(
|
2024-09-12 00:03:29 +02:00
|
|
|
{
|
|
|
|
"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;
|
|
|
|
}
|
2024-09-18 18:17:25 +02:00
|
|
|
case "conf-schema": {
|
|
|
|
process.stdout.write(
|
|
|
|
JSON.stringify(
|
|
|
|
_zeitbild.conf.schema(),
|
|
|
|
undefined,
|
|
|
|
"\t"
|
|
|
|
)
|
|
|
|
+
|
|
|
|
"\n"
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case "conf-expose": {
|
2024-09-12 00:03:29 +02:00
|
|
|
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;
|
|
|
|
}
|
2024-09-18 18:17:25 +02:00
|
|
|
case "fill": {
|
|
|
|
await data_init(
|
|
|
|
lib_plankton.json.decode(
|
|
|
|
await lib_plankton.file.read(args.data_path)
|
|
|
|
)
|
|
|
|
);
|
|
|
|
process.stdout.write("-- done\n");
|
|
|
|
break;
|
|
|
|
}
|
2024-09-12 00:03:29 +02:00
|
|
|
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.session.type_session>({})
|
|
|
|
: 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,
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
2024-09-18 18:17:25 +02:00
|
|
|
await _zeitbild.auth.init();
|
|
|
|
|
2024-09-12 00:03:29 +02:00
|
|
|
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<void>(undefined);
|
|
|
|
}
|
|
|
|
|
|
|
|
(
|
|
|
|
main(process.argv.slice(2))
|
|
|
|
.then(
|
2024-09-18 18:17:25 +02:00
|
|
|
() => {
|
|
|
|
}
|
2024-09-12 00:03:29 +02:00
|
|
|
)
|
|
|
|
.catch(
|
2024-09-18 18:17:25 +02:00
|
|
|
(error) => {
|
|
|
|
process.stderr.write(String(error) + "\n");
|
|
|
|
}
|
2024-09-12 00:03:29 +02:00
|
|
|
)
|
|
|
|
);
|