Einladungs-System #6

Open
roydfalk wants to merge 13 commits from task-193 into main
23 changed files with 3919 additions and 3020 deletions
Showing only changes of commit b522514c26 - Show all commits

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -4,6 +4,21 @@
"verbosity": "info", "verbosity": "info",
"verification_secret": null "verification_secret": null
}, },
"log": [
{
"kind": "stdout",
"data": {
"threshold": "info"
}
},
{
"kind": "file",
"data": {
"threshold": "notice",
"path": "/tmp/espe/log.jsonl"
}
}
],
"server": { "server": {
"port": 4916, "port": 4916,
"path_base": "" "path_base": ""

View file

@ -19,17 +19,20 @@ namespace _espe.api
/** /**
*/ */
export function register_member_delete( export function register_member_delete(
rest_subject : lib_plankton.rest.type_rest rest_subject : lib_plankton.rest_http.type_rest
) : void ) : void
{ {
register<null, null>( lib_plankton.rest_http.register<
null,
null
>(
rest_subject, rest_subject,
lib_plankton.http.enum_method.delete, lib_plankton.http.enum_method.delete,
"/member/delete/:id", _espe.api.full_path("/member/delete/:id"),
{ {
"description": "löscht ein vorhandenes Mitglied", "description": () => "löscht ein vorhandenes Mitglied",
"restriction": restriction_logged_in, "restriction": () => restriction_logged_in,
"execution": async ({"path_parameters": path_parameters}) => { "execution": () => async ({"path_parameters": path_parameters}) => {
const member_id : _espe.type.member_id = parseInt(path_parameters["id"]); const member_id : _espe.type.member_id = parseInt(path_parameters["id"]);
await _espe.service.member.remove(member_id); await _espe.service.member.remove(member_id);
return Promise.resolve({ return Promise.resolve({

View file

@ -20,10 +20,10 @@ namespace _espe.api
* @todo zeitliche Begrenzung? * @todo zeitliche Begrenzung?
*/ */
export function register_member_info( export function register_member_info(
rest_subject : lib_plankton.rest.type_rest rest_subject : lib_plankton.rest_http.type_rest
) : void ) : void
{ {
register< lib_plankton.rest_http.register<
int, int,
( (
null null
@ -39,9 +39,9 @@ namespace _espe.api
>( >(
rest_subject, rest_subject,
lib_plankton.http.enum_method.get, lib_plankton.http.enum_method.get,
"/member/info/:id", _espe.api.full_path("/member/info/:id"),
{ {
"description": "gibt Angaben über ein Mitglied aus, die für die Registrierung verwendet werden dürfen", "description": () => "gibt Angaben über ein Mitglied aus, die für die Registrierung verwendet werden dürfen",
"input_schema": () => ({ "input_schema": () => ({
"type": "number", "type": "number",
"nullable": false, "nullable": false,
@ -80,18 +80,18 @@ namespace _espe.api
"email_address_nominal", "email_address_nominal",
] ]
}), }),
"query_parameters": [ "query_parameters": () => [
{ {
"name": "key", "name": "key",
"required": true, "required": true,
"description": "Zugriffs-Schlüssel", "description": "Zugriffs-Schlüssel",
}, },
], ],
"restriction": restriction_verification( "restriction": () => restriction_verification(
stuff => parseInt(stuff.path_parameters["id"]), stuff => parseInt(stuff.path_parameters["id"]),
stuff => stuff.query_parameters["key"] stuff => stuff.query_parameters["key"]
), ),
"execution": async ({"path_parameters": path_parameters, "input": input}) => { "execution": () => async ({"path_parameters": path_parameters, "input": input}) => {
const member_id : _espe.type.member_id = parseInt(path_parameters["id"]); const member_id : _espe.type.member_id = parseInt(path_parameters["id"]);
const data : ( const data : (
null null

View file

@ -19,10 +19,10 @@ namespace _espe.api
/** /**
*/ */
export function register_member_list( export function register_member_list(
rest_subject : lib_plankton.rest.type_rest rest_subject : lib_plankton.rest_http.type_rest
) : void ) : void
{ {
register< lib_plankton.rest_http.register<
null, null,
Array< Array<
{ {
@ -37,10 +37,10 @@ namespace _espe.api
>( >(
rest_subject, rest_subject,
lib_plankton.http.enum_method.get, lib_plankton.http.enum_method.get,
"/member/list", _espe.api.full_path("/member/list"),
{ {
"description": "listet alle Mitglieder auf", "description": () => "listet alle Mitglieder auf",
"query_parameters": [ "query_parameters": () => [
{ {
"name": "search_term", "name": "search_term",
"required": false, "required": false,
@ -88,8 +88,8 @@ namespace _espe.api
], ],
} }
}), }),
"restriction": restriction_logged_in, "restriction": () => restriction_logged_in,
"execution": ({"query_parameters": query_parameters}) => ( "execution": () => ({"query_parameters": query_parameters}) => (
_espe.service.member.list(query_parameters["search_term"] ?? null) _espe.service.member.list(query_parameters["search_term"] ?? null)
.then( .then(
data => Promise.resolve({ data => Promise.resolve({

View file

@ -19,10 +19,10 @@ namespace _espe.api
/** /**
*/ */
export function register_member_modify( export function register_member_modify(
rest_subject : lib_plankton.rest.type_rest rest_subject : lib_plankton.rest_http.type_rest
) : void ) : void
{ {
register< lib_plankton.rest_http.register<
{ {
email_address_private : (null | string); email_address_private : (null | string);
groups ?: Array<string>; groups ?: Array<string>;
@ -33,9 +33,9 @@ namespace _espe.api
>( >(
rest_subject, rest_subject,
lib_plankton.http.enum_method.patch, lib_plankton.http.enum_method.patch,
"/member/modify/:id", _espe.api.full_path("/member/modify/:id"),
{ {
"description": "ändert die Angaben eines vorhandenen Mitglieds", "description": () => "ändert die Angaben eines vorhandenen Mitglieds",
"input_schema": () => ({ "input_schema": () => ({
"nullable": false, "nullable": false,
"type": "object", "type": "object",
@ -71,8 +71,8 @@ namespace _espe.api
"output_schema": () => ({ "output_schema": () => ({
"nullable": true, "nullable": true,
}), }),
"restriction": restriction_logged_in, "restriction": () => restriction_logged_in,
"execution": async ({"path_parameters": path_parameters, "input": input}) => { "execution": () => async ({"path_parameters": path_parameters, "input": input}) => {
if (input === null) { if (input === null) {
return Promise.reject(new Error("impossible")); return Promise.reject(new Error("impossible"));
} }

View file

@ -20,10 +20,10 @@ namespace _espe.api
* @todo ausgeklügelte Durchsatzratenbegrenzung * @todo ausgeklügelte Durchsatzratenbegrenzung
*/ */
export function register_member_password_change_execute( export function register_member_password_change_execute(
rest_subject : lib_plankton.rest.type_rest rest_subject : lib_plankton.rest_http.type_rest
) : void ) : void
{ {
register< lib_plankton.rest_http.register<
{ {
token : string; token : string;
password_new : string; password_new : string;
@ -37,9 +37,9 @@ namespace _espe.api
>( >(
rest_subject, rest_subject,
lib_plankton.http.enum_method.patch, lib_plankton.http.enum_method.patch,
"/member/password_change/execute/:id", _espe.api.full_path("/member/password_change/execute/:id"),
{ {
"description": "Führt eine Passwort-Änderung für ein Mitglied durch", "description": () => "Führt eine Passwort-Änderung für ein Mitglied durch",
"input_schema": () => ({ "input_schema": () => ({
"nullable": false, "nullable": false,
"type": "object", "type": "object",
@ -88,8 +88,8 @@ namespace _espe.api
] ]
} }
}), }),
"restriction": restriction_none, "restriction": () => restriction_none,
"execution": ({"path_parameters": path_parameters, "input": input}) => { "execution": () => ({"path_parameters": path_parameters, "input": input}) => {
if (input === null) { if (input === null) {
return Promise.reject(new Error("impossible")); return Promise.reject(new Error("impossible"));
} }

View file

@ -21,10 +21,10 @@ namespace _espe.api
* @todo captcha * @todo captcha
*/ */
export function register_member_password_change_initialize( export function register_member_password_change_initialize(
rest_subject : lib_plankton.rest.type_rest rest_subject : lib_plankton.rest_http.type_rest
) : void ) : void
{ {
register< lib_plankton.rest_http.register<
{ {
identifier : string; identifier : string;
url_template : string; url_template : string;
@ -33,9 +33,9 @@ namespace _espe.api
>( >(
rest_subject, rest_subject,
lib_plankton.http.enum_method.post, lib_plankton.http.enum_method.post,
"/member/password_change/initialize", _espe.api.full_path("/member/password_change/initialize"),
{ {
"description": "Versucht dem gegebenen Identifikator ein Mitglied zuzuordnen und sendet dem ermittelten Mitglied einen Passwort-Änderungs-Verweis an die hinterlegte private E-Mail-Adresse", "description": () => "Versucht dem gegebenen Identifikator ein Mitglied zuzuordnen und sendet dem ermittelten Mitglied einen Passwort-Änderungs-Verweis an die hinterlegte private E-Mail-Adresse",
"input_schema": () => ({ "input_schema": () => ({
"nullable": false, "nullable": false,
"type": "object", "type": "object",
@ -60,8 +60,8 @@ namespace _espe.api
"output_schema": () => ({ "output_schema": () => ({
"nullable": true "nullable": true
}), }),
"restriction": restriction_none, "restriction": () => restriction_none,
"execution": async ({"input": input}) => { "execution": () => async ({"input": input}) => {
if (input === null) { if (input === null) {
return Promise.reject(new Error("impossible")); return Promise.reject(new Error("impossible"));
} }

View file

@ -19,10 +19,10 @@ namespace _espe.api
/** /**
*/ */
export function register_member_project( export function register_member_project(
rest_subject : lib_plankton.rest.type_rest rest_subject : lib_plankton.rest_http.type_rest
) : void ) : void
{ {
register< lib_plankton.rest_http.register<
{ {
membership_number : (null | string); membership_number : (null | string);
name_real_value : string; name_real_value : string;
@ -38,9 +38,9 @@ namespace _espe.api
>( >(
rest_subject, rest_subject,
lib_plankton.http.enum_method.post, lib_plankton.http.enum_method.post,
"/member/project", _espe.api.full_path("/member/project"),
{ {
"description": "erstellt ein neues Mitglied und gibt die erzeugte ID aus", "description": () => "erstellt ein neues Mitglied und gibt die erzeugte ID aus",
"input_schema": () => ({ "input_schema": () => ({
"type": "object", "type": "object",
"nullable": false, "nullable": false,
@ -84,8 +84,8 @@ namespace _espe.api
"type": "number", "type": "number",
"nullable": false, "nullable": false,
}), }),
"restriction": restriction_logged_in, "restriction": () => restriction_logged_in,
"execution": async ({"input": input}) => { "execution": () => async ({"input": input}) => {
if (input === null) { if (input === null) {
return Promise.reject(new Error("impossible")); return Promise.reject(new Error("impossible"));
} }

View file

@ -19,10 +19,10 @@ namespace _espe.api
/** /**
*/ */
export function register_member_read( export function register_member_read(
rest_subject : lib_plankton.rest.type_rest rest_subject : lib_plankton.rest_http.type_rest
) : void ) : void
{ {
register< lib_plankton.rest_http.register<
null, null,
{ {
membership_number : (null | string); membership_number : (null | string);
@ -44,9 +44,9 @@ namespace _espe.api
>( >(
rest_subject, rest_subject,
lib_plankton.http.enum_method.get, lib_plankton.http.enum_method.get,
"/member/read/:id", _espe.api.full_path("/member/read/:id"),
{ {
"description": "gibt ein Mitglied anhand seiner ID aus", "description": () => "gibt ein Mitglied anhand seiner ID aus",
"output_schema": () => ({ "output_schema": () => ({
"nullable": false, "nullable": false,
"type": "object", "type": "object",
@ -135,8 +135,8 @@ namespace _espe.api
"name_login", "name_login",
] ]
}), }),
"restriction": restriction_logged_in, "restriction": () => restriction_logged_in,
"execution": async ({"path_parameters": path_parameters, "input": input}) => { "execution": () => async ({"path_parameters": path_parameters, "input": input}) => {
const member_id : _espe.type.member_id = parseInt(path_parameters["id"]); const member_id : _espe.type.member_id = parseInt(path_parameters["id"]);
const member_object : _espe.type.member_object = await _espe.service.member.get(member_id); const member_object : _espe.type.member_object = await _espe.service.member.get(member_id);
return Promise.resolve({ return Promise.resolve({

View file

@ -20,10 +20,10 @@ namespace _espe.api
* @todo zeitliche Begrenzung? * @todo zeitliche Begrenzung?
*/ */
export function register_member_register( export function register_member_register(
rest_subject : lib_plankton.rest.type_rest rest_subject : lib_plankton.rest_http.type_rest
) : void ) : void
{ {
register< lib_plankton.rest_http.register<
{ {
email_use_veiled_address : boolean; email_use_veiled_address : boolean;
email_use_nominal_address : boolean; email_use_nominal_address : boolean;
@ -40,9 +40,9 @@ namespace _espe.api
>( >(
rest_subject, rest_subject,
lib_plankton.http.enum_method.post, lib_plankton.http.enum_method.post,
"/member/register/:id", _espe.api.full_path("/member/register/:id"),
{ {
"description": "nimmt zusätzliche Angaben eines Mitglieds entgegen", "description": () => "nimmt zusätzliche Angaben eines Mitglieds entgegen",
"input_schema": () => ({ "input_schema": () => ({
"type": "object", "type": "object",
"nullable": false, "nullable": false,
@ -109,18 +109,18 @@ namespace _espe.api
] ]
} }
}), }),
"query_parameters": [ "query_parameters": () => [
{ {
"name": "key", "name": "key",
"required": true, "required": true,
"description": "Zugriffs-Schlüssel", "description": "Zugriffs-Schlüssel",
}, },
], ],
"restriction": restriction_verification( "restriction": () => restriction_verification(
stuff => parseInt(stuff.path_parameters["id"]), stuff => parseInt(stuff.path_parameters["id"]),
stuff => stuff.query_parameters["key"] stuff => stuff.query_parameters["key"]
), ),
"execution": ({"path_parameters": path_parameters, "input": input}) => { "execution": () => ({"path_parameters": path_parameters, "input": input}) => {
if (input === null) { if (input === null) {
return Promise.reject(new Error("impossible")); return Promise.reject(new Error("impossible"));
} }

View file

@ -19,10 +19,10 @@ namespace _espe.api
/** /**
*/ */
export function register_member_summon( export function register_member_summon(
rest_subject : lib_plankton.rest.type_rest rest_subject : lib_plankton.rest_http.type_rest
) : void ) : void
{ {
lib_plankton.rest.register< lib_plankton.rest_http.register<
{ {
url_template : string; url_template : string;
}, },
@ -36,9 +36,9 @@ namespace _espe.api
lib_plankton.http.enum_method.post, lib_plankton.http.enum_method.post,
_espe.conf.get().server.path_base + "/member/summon/:id", _espe.conf.get().server.path_base + "/member/summon/:id",
{ {
"description": "sendet an ein Mitglied eine E-Mail mit Aufforderung zur Registrierung", "description": () => "sendet an ein Mitglied eine E-Mail mit Aufforderung zur Registrierung",
"restriction": restriction_logged_in, "restriction": () => restriction_logged_in,
"execution": async ({"path_parameters": path_parameters, "input": input}) => { "execution": () => async ({"path_parameters": path_parameters, "input": input}) => {
if (input === null) { if (input === null) {
return Promise.reject(new Error("impossible")); return Promise.reject(new Error("impossible"));
} }

View file

@ -19,10 +19,10 @@ namespace _espe.api
/** /**
*/ */
export function register_meta_ping( export function register_meta_ping(
rest_subject : lib_plankton.rest.type_rest rest_subject : lib_plankton.rest_http.type_rest
) : void ) : void
{ {
lib_plankton.rest.register< lib_plankton.rest_http.register<
null, null,
string string
> >
@ -31,7 +31,7 @@ namespace _espe.api
lib_plankton.http.enum_method.get, lib_plankton.http.enum_method.get,
_espe.conf.get().server.path_base + "/meta/ping", _espe.conf.get().server.path_base + "/meta/ping",
{ {
"description": "sendet ein 'pong' zurück; gedacht um die Erreichbarkeit des Backends zu prüfen", "description": () => "sendet ein 'pong' zurück; gedacht um die Erreichbarkeit des Backends zu prüfen",
"input_schema": () => ({ "input_schema": () => ({
"nullable": true, "nullable": true,
}), }),
@ -39,8 +39,8 @@ namespace _espe.api
"nullable": false, "nullable": false,
"type": "string", "type": "string",
}), }),
"restriction": restriction_none, "restriction": () => restriction_none,
"execution": () => { "execution": () => () => {
return Promise.resolve({ return Promise.resolve({
"status_code": 200, "status_code": 200,
"data": "pong", "data": "pong",

View file

@ -19,10 +19,10 @@ namespace _espe.api
/** /**
*/ */
export function register_meta_spec( export function register_meta_spec(
rest_subject : lib_plankton.rest.type_rest rest_subject : lib_plankton.rest_http.type_rest
) : void ) : void
{ {
lib_plankton.rest.register< lib_plankton.rest_http.register<
null, null,
any any
> >
@ -31,17 +31,17 @@ namespace _espe.api
lib_plankton.http.enum_method.get, lib_plankton.http.enum_method.get,
_espe.conf.get().server.path_base + "/meta/spec", _espe.conf.get().server.path_base + "/meta/spec",
{ {
"description": "gibt die API-Spezifikation im OpenAPI-Format aus", "description": () => "gibt die API-Spezifikation im OpenAPI-Format aus",
"input_schema": () => ({ "input_schema": () => ({
"nullable": true, "nullable": true,
}), }),
"output_schema": () => ({ "output_schema": () => ({
}), }),
"restriction": restriction_none, "restriction": () => restriction_none,
"execution": () => { "execution": () => () => {
return Promise.resolve({ return Promise.resolve({
"status_code": 200, "status_code": 200,
"data": lib_plankton.rest.to_oas(rest_subject), "data": lib_plankton.rest_http.to_oas(rest_subject),
}); });
}, },
} }

View file

@ -19,10 +19,10 @@ namespace _espe.api
/** /**
*/ */
export function register_session_begin( export function register_session_begin(
rest_subject : lib_plankton.rest.type_rest rest_subject : lib_plankton.rest_http.type_rest
) : void ) : void
{ {
lib_plankton.rest.register< lib_plankton.rest_http.register<
{ {
name : string; name : string;
password : string; password : string;
@ -37,7 +37,7 @@ namespace _espe.api
lib_plankton.http.enum_method.post, lib_plankton.http.enum_method.post,
_espe.conf.get().server.path_base + "/session/begin", _espe.conf.get().server.path_base + "/session/begin",
{ {
"description": "führt die Anmeldung am System aus um geschützte Aktionen nutzen zu können", "description": () => "führt die Anmeldung am System aus um geschützte Aktionen nutzen zu können",
"input_schema": () => ({ "input_schema": () => ({
"type": "object", "type": "object",
"properties": { "properties": {
@ -58,8 +58,8 @@ namespace _espe.api
"type": "string", "type": "string",
"description": "der Sitzungs-Schlüssel, der als Header 'X-Session-Key' gesetzt werden muss um Erlaubnis zur Ausführung geschützter Aktionen zu erhalten", "description": "der Sitzungs-Schlüssel, der als Header 'X-Session-Key' gesetzt werden muss um Erlaubnis zur Ausführung geschützter Aktionen zu erhalten",
}), }),
"restriction": restriction_none, "restriction": () => restriction_none,
"execution": async ({"input": input}) => { "execution": () => async ({"input": input}) => {
if (input === null) { if (input === null) {
return Promise.reject(new Error("impossible")); return Promise.reject(new Error("impossible"));
} }

View file

@ -19,23 +19,26 @@ namespace _espe.api
/** /**
*/ */
export function register_session_end( export function register_session_end(
rest_subject : lib_plankton.rest.type_rest rest_subject : lib_plankton.rest_http.type_rest
) : void ) : void
{ {
register<null, null>( lib_plankton.rest_http.register<
null,
null
>(
rest_subject, rest_subject,
lib_plankton.http.enum_method.delete, lib_plankton.http.enum_method.delete,
"/session/end", "/session/end",
{ {
"description": "beendet eine Sitzung", "description": () => "beendet eine Sitzung",
"input_schema": () => ({ "input_schema": () => ({
"type": "null", "type": "null",
}), }),
"output_schema": () => ({ "output_schema": () => ({
"type": "null", "type": "null",
}), }),
"restriction": restriction_logged_in, "restriction": () => restriction_logged_in,
"execution": async (stuff) => { "execution": () => async (stuff) => {
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);
await lib_plankton.session.end(session.key); await lib_plankton.session.end(session.key);
return Promise.resolve({ return Promise.resolve({

View file

@ -20,7 +20,7 @@ namespace _espe.api
* @todo zu plankton auslagern? * @todo zu plankton auslagern?
*/ */
type type_stuff = { type type_stuff = {
version: (null | string); // version: (null | string);
headers: Record<string, string>; headers: Record<string, string>;
path_parameters: Record<string, string>; path_parameters: Record<string, string>;
query_parameters: Record<string, string>; query_parameters: Record<string, string>;
@ -43,9 +43,9 @@ namespace _espe.api
*/ */
/* /*
export function restriction_disjunction( export function restriction_disjunction(
left : lib_plankton.rest.type_restriction<any>, left : lib_plankton.rest_http.type_restriction<any>,
right : lib_plankton.rest.type_restriction<any> right : lib_plankton.rest_http.type_restriction<any>
) : lib_plankton.rest.type_restriction<any> ) : lib_plankton.rest_http.type_restriction<any>
{ {
return ( return (
(stuff) => Promise.any<boolean>( (stuff) => Promise.any<boolean>(
@ -61,14 +61,14 @@ namespace _espe.api
/** /**
*/ */
export const restriction_none : lib_plankton.rest.type_restriction<any> = ( export const restriction_none : lib_plankton.rest_http.type_restriction<any> = (
(stuff) => Promise.resolve<boolean>(true) (stuff) => Promise.resolve<boolean>(true)
); );
/** /**
*/ */
export const restriction_logged_in : lib_plankton.rest.type_restriction<any> = ( export const restriction_logged_in : lib_plankton.rest_http.type_restriction<any> = (
(stuff) => ( (stuff) => (
session_from_stuff(stuff) session_from_stuff(stuff)
.then(() => Promise.resolve<boolean>(true)) .then(() => Promise.resolve<boolean>(true))
@ -82,7 +82,7 @@ namespace _espe.api
export function restriction_verification( export function restriction_verification(
extract_data : ((stuff : type_stuff) => any), extract_data : ((stuff : type_stuff) => any),
extract_verification : ((stuff : type_stuff) => string) extract_verification : ((stuff : type_stuff) => string)
) : lib_plankton.rest.type_restriction<any> ) : lib_plankton.rest_http.type_restriction<any>
{ {
return ( return (
(stuff) => _espe.helpers.verification_check( (stuff) => _espe.helpers.verification_check(
@ -92,17 +92,27 @@ namespace _espe.api
); );
} }
/**
*/
export function full_path(
path : string
) : string
{
return (_espe.conf.get().server.path_base + path);
}
/** /**
*/ */
/*
export function register<type_input, type_output>( export function register<type_input, type_output>(
rest_subject : lib_plankton.rest.type_rest, rest_subject : lib_plankton.rest_http.type_rest,
http_method : lib_plankton.http.enum_method, http_method : lib_plankton.http.enum_method,
path : string, path : string,
options : { options : {
active ?: ((version : string) => boolean); active ?: ((version : (null | string)) => boolean);
restriction ?: (null | lib_plankton.rest.type_restriction<type_input>); restriction ?: (null | lib_plankton.rest_http.type_restriction<type_input>);
execution ?: lib_plankton.rest.type_execution<type_input, type_output>; execution ?: lib_plankton.rest_http.type_execution<type_input, type_output>;
title ?: (null | string); title ?: (null | string);
description ?: (null | string); description ?: (null | string);
query_parameters ?: Array< query_parameters ?: Array<
@ -112,8 +122,8 @@ namespace _espe.api
required : boolean; required : boolean;
} }
>; >;
input_schema ?: ((version: (null | string)) => lib_plankton.rest.type_oas_schema); input_schema ?: ((version: (null | string)) => lib_plankton.rest_http.type_oas_schema);
output_schema ?: ((version: (null | string)) => lib_plankton.rest.type_oas_schema); output_schema ?: ((version: (null | string)) => lib_plankton.rest_http.type_oas_schema);
request_body_mimetype ?: string; request_body_mimetype ?: string;
request_body_decode ?: ((http_request_body : Buffer, http_request_header_content_type : (null | string)) => any); request_body_decode ?: ((http_request_body : Buffer, http_request_header_content_type : (null | string)) => any);
response_body_mimetype ?: string; response_body_mimetype ?: string;
@ -121,17 +131,12 @@ namespace _espe.api
} = {} } = {}
) : void ) : void
{ {
options = Object.assign( lib_plankton.rest_http.register<type_input, type_output>(
{
},
options
);
lib_plankton.rest.register<type_input, type_output>(
rest_subject, rest_subject,
http_method, http_method,
(_espe.conf.get().server.path_base + path), (_espe.conf.get().server.path_base + path),
options options
); );
} }
*/
} }

View file

@ -19,9 +19,9 @@ namespace _espe.api
/** /**
*/ */
export function make( export function make(
) : lib_plankton.rest.type_rest ) : lib_plankton.rest_http.type_rest
{ {
const rest_subject : lib_plankton.rest.type_rest = lib_plankton.rest.make( const rest_subject : lib_plankton.rest_http.type_rest = lib_plankton.rest_http.make(
{ {
"title": "espe", "title": "espe",
"versioning_method": "header", "versioning_method": "header",
@ -29,7 +29,7 @@ namespace _espe.api
"set_access_control_headers": true, "set_access_control_headers": true,
"authentication": { "authentication": {
"kind": "key_header", "kind": "key_header",
"parameters": {"name": "X-Session-Key"} "data": {"name": "X-Session-Key"}
}, },
} }
); );

View file

@ -42,12 +42,7 @@ namespace _espe.conf
/** /**
*/ */
export type type_conf = { export type type_log_channel = (
general : {
language : (null | string);
verification_secret : (null | string);
};
log : Array<
{ {
kind : "stdout"; kind : "stdout";
data : { data : {
@ -77,6 +72,18 @@ namespace _espe.conf
receivers : Array<string>; receivers : Array<string>;
}; };
} }
);
/**
*/
export type type_conf = {
general : {
language : (null | string);
verification_secret : (null | string);
};
log : Array<
type_log_channel
>; >;
server : { server : {
host : string; host : string;

View file

@ -13,27 +13,131 @@ You should have received a copy of the GNU General Public License along with thi
<https://www.gnu.org/licenses/>. <https://www.gnu.org/licenses/>.
*/ */
namespace _espe
{
/** /**
*/ */
async function main( function setup_log_fallback(
) : void
{
lib_plankton.log.set_main_logger(
[
{
"kind": "filtered",
"data": {
"core": {
"kind": "std",
"data": {
"target": "stdout",
"format": {
"kind": "human_readable",
"data": {}
}
}
},
"predicate": [
[
{
"item": {
"kind": "level",
"data": {"threshold": "info"}
},
}
]
],
}
},
]
);
}
/**
*/
function setup_log_from_conf(
) : void
{
lib_plankton.log.set_main_logger(
_espe.conf.get().log.map(
log_channel => {
switch (log_channel.kind) {
case "stdout": {
return {
"kind": "filtered",
"data": {
"core": {
"kind": "std",
"data": {
"target": "stdout",
"format": {"kind": "human_readable", "data": {}}
}
},
"predicate": [
[
{"item": {"kind": "level", "data": {"threshold": log_channel.data.threshold}}}
]
],
}
};
break;
}
case "file": {
return {
"kind": "filtered",
"data": {
"core": {
"kind": "file",
"data": {
"path": log_channel.data.path,
"format": {"kind": "jsonl", "data": {"structured": false}}
}
},
"predicate": [
[
{"item": {"kind": "level", "data": {"threshold": log_channel.data.threshold}}}
]
],
}
};
break;
}
case "email": {
return {
"kind": "filtered",
"data": {
"core": {
"kind": "email",
"data": log_channel.data
},
"predicate": [
[
{"item": {"kind": "level", "data": {"threshold": log_channel.data.threshold}}}
]
],
}
};
break;
}
default: {
throw (new Error("unhandled log channel"));
break;
}
}
}
)
);
}
/**
*/
export async function main(
args_raw : Array<string> args_raw : Array<string>
) : Promise<void> ) : Promise<void>
{ {
// init // init
lib_plankton.log.conf_push( setup_log_fallback();
[
lib_plankton.log.channel_make(
{
"kind": "stdout",
"data": {
"threshold": "notice",
// "format": "human_readable",
}
}
),
]
);
const language_codes : Array<string> = [ const language_codes : Array<string> = [
"deu", "deu",
"eng", "eng",
@ -198,16 +302,7 @@ async function main(
lib_plankton.translate.promote(language); lib_plankton.translate.promote(language);
} }
} }
lib_plankton.log.conf_push( setup_log_from_conf();
_espe.conf.get().log.map(
log_output => lib_plankton.log.channel_make(
{
"kind": log_output.kind,
"data": log_output.data
}
)
)
);
// exec // exec
if (args["help"] || (args["action"] === "help")) { if (args["help"] || (args["action"] === "help")) {
@ -253,12 +348,12 @@ async function main(
break; break;
} }
case "api-doc": { case "api-doc": {
lib_plankton.log.conf_push([]); // lib_plankton.log.conf_push([]);
const rest_subject : lib_plankton.rest.type_rest = _espe.api.make(); const rest_subject : lib_plankton.rest_http.type_rest = _espe.api.make();
lib_plankton.log.conf_pop(); // lib_plankton.log.conf_pop();
process.stdout.write( process.stdout.write(
JSON.stringify( JSON.stringify(
lib_plankton.rest.to_oas(rest_subject), lib_plankton.rest_http.to_oas(rest_subject),
undefined, undefined,
"\t" "\t"
) )
@ -393,11 +488,11 @@ async function main(
} }
); );
const rest_subject : lib_plankton.rest.type_rest = _espe.api.make(); const rest_subject : lib_plankton.rest_http.type_rest = _espe.api.make();
const server : lib_plankton.server.type_subject = lib_plankton.server.make( const server : lib_plankton.server.type_subject = lib_plankton.server.make(
async (input, metadata) => { async (input, metadata) => {
const http_request : lib_plankton.http.type_request = lib_plankton.http.decode_request(input.toString()); 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( const http_response : lib_plankton.http.type_response = await lib_plankton.rest_http.call(
rest_subject, rest_subject,
http_request, http_request,
{ {
@ -428,9 +523,10 @@ async function main(
} }
} }
}
( (
main(process.argv.slice(2)) _espe.main(process.argv.slice(2))
.then( .then(
() => { () => {
} }

View file

@ -156,7 +156,9 @@ namespace _espe.repository.member
"email_address_private": dispersal.core_row["email_address_private"], "email_address_private": dispersal.core_row["email_address_private"],
"groups": lib_plankton.list.sorted<string>( "groups": lib_plankton.list.sorted<string>(
dispersal.group_rows.map(row => row["group_name"]), dispersal.group_rows.map(row => row["group_name"]),
(group1, group2) => ((group1 <= group2) ? 0 : 1) {
"compare_element": (group1, group2) => (group1 <= group2)
}
), ),
"registered": (dispersal.core_row["registered"] > 0), "registered": (dispersal.core_row["registered"] > 0),
"enabled": (dispersal.core_row["enabled"] > 0), "enabled": (dispersal.core_row["enabled"] > 0),

View file

@ -16,8 +16,8 @@ modules="${modules} storage"
modules="${modules} session" modules="${modules} session"
modules="${modules} json" modules="${modules} json"
modules="${modules} api" modules="${modules} api"
modules="${modules} rest"
modules="${modules} http" modules="${modules} http"
modules="${modules} rest_http"
modules="${modules} server" modules="${modules} server"
modules="${modules} email" modules="${modules} email"
modules="${modules} args" modules="${modules} args"