Compare commits
10 commits
40f6550246
...
8b121af099
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b121af099 | ||
|
|
5e928f8cab | ||
|
|
ea9d8db0f8 | ||
|
|
d2cfb7206f | ||
|
|
c37b6d2a47 | ||
|
|
8f04e653d8 | ||
|
|
6cbe925d7c | ||
|
|
ab9f1a6d6d | ||
|
|
fd733f69da | ||
|
|
fd2aaea5fa |
60
doc/brock.schema.json
Normal file
60
doc/brock.schema.json
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"database": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"kind": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
},
|
||||||
|
"additionalProperties": {
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": [
|
||||||
|
"kind"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"backend": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["http", "https"]
|
||||||
|
},
|
||||||
|
"host": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"port": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": [
|
||||||
|
"schema",
|
||||||
|
"host",
|
||||||
|
"port"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"frontend": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
},
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": [
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"database",
|
||||||
|
"backend",
|
||||||
|
"frontend"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -31,7 +31,9 @@
|
||||||
{
|
{
|
||||||
"name": "person",
|
"name": "person",
|
||||||
"description": "collection of contacts",
|
"description": "collection of contacts",
|
||||||
"key_field": null,
|
"key_field": {
|
||||||
|
"name": "id"
|
||||||
|
},
|
||||||
"data_fields": [
|
"data_fields": [
|
||||||
{
|
{
|
||||||
"name": "prename",
|
"name": "prename",
|
||||||
|
|
|
||||||
687
lib/plankton/plankton.d.ts
vendored
687
lib/plankton/plankton.d.ts
vendored
|
|
@ -6,18 +6,11 @@ type int = number;
|
||||||
* @author fenris
|
* @author fenris
|
||||||
*/
|
*/
|
||||||
type float = number;
|
type float = number;
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
type type_time = {
|
|
||||||
hours: int;
|
|
||||||
minutes: int;
|
|
||||||
seconds: int;
|
|
||||||
};
|
|
||||||
declare var process: any;
|
declare var process: any;
|
||||||
declare var require: any;
|
declare var require: any;
|
||||||
declare class Buffer {
|
declare class Buffer {
|
||||||
constructor(x: string, modifier?: string);
|
constructor(x: string, modifier?: string);
|
||||||
|
static from(x: string, encoding?: string): any;
|
||||||
toString(modifier?: string): string;
|
toString(modifier?: string): string;
|
||||||
}
|
}
|
||||||
declare namespace lib_plankton.base {
|
declare namespace lib_plankton.base {
|
||||||
|
|
@ -202,154 +195,6 @@ declare class class_observer {
|
||||||
/**
|
/**
|
||||||
* @author frac
|
* @author frac
|
||||||
*/
|
*/
|
||||||
declare module lib_maybe {
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
type type_maybe<type_value> = {
|
|
||||||
kind: string;
|
|
||||||
parameters: Object;
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
function make_nothing<type_value>(): type_maybe<type_value>;
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
function make_just<type_value>(value: type_value): type_maybe<type_value>;
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
function is_nothing<type_value>(maybe: type_maybe<type_value>): boolean;
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
function is_just<type_value>(maybe: type_maybe<type_value>): boolean;
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
function cull<type_value>(maybe: type_maybe<type_value>): type_value;
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
function propagate<type_value, type_value_>(maybe: type_maybe<type_value>, function_: (value: type_value) => type_maybe<type_value_>): type_maybe<type_value_>;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
declare class class_maybe<type_value> implements interface_showable {
|
|
||||||
/**
|
|
||||||
* @desc whether the wrapper is nothing
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
is_nothing(): boolean;
|
|
||||||
/**
|
|
||||||
* @desc whether the wrapper is just
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
is_just(): boolean;
|
|
||||||
/**
|
|
||||||
* @desc return the value, stored in the maybe-wrapper
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
cull(): type_value;
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
toString(): string;
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
distinguish(action_just: (value?: type_value) => void, action_nothing?: (reason?: string) => void): void;
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
propagate<type_value_>(action: (value: type_value) => class_maybe<type_value_>): class_maybe<type_value_>;
|
|
||||||
/**
|
|
||||||
* @desc [implementation]
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
_show(): string;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
declare class class_nothing<type_value> extends class_maybe<type_value> {
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
private reason;
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
constructor(reason?: string);
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
is_nothing(): boolean;
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
is_just(): boolean;
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
cull(): type_value;
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
toString(): string;
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
reason_get(): string;
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
distinguish(action_just: (value?: type_value) => void, action_nothing?: (reason?: string) => void): void;
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
propagate<type_value_>(action: (value: type_value) => class_maybe<type_value_>): class_maybe<type_value_>;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
declare class class_just<type_value> extends class_maybe<type_value> {
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
private value;
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
constructor(value: type_value);
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
is_nothing(): boolean;
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
is_just(): boolean;
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
cull(): type_value;
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
toString(): string;
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
distinguish(action_just: (value?: type_value) => void, action_nothing?: (reason?: string) => void): void;
|
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
propagate<type_value_>(action: (value: type_value) => class_maybe<type_value_>): class_maybe<type_value_>;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* @author frac
|
* @author frac
|
||||||
*/
|
*/
|
||||||
|
|
@ -378,11 +223,21 @@ declare namespace lib_plankton.base {
|
||||||
*
|
*
|
||||||
* @author fenris
|
* @author fenris
|
||||||
*/
|
*/
|
||||||
function get_current_timestamp(rounded?: boolean): int;
|
function get_current_timestamp(rounded?: boolean): float;
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
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>;
|
||||||
}
|
}
|
||||||
|
declare namespace lib_plankton.email {
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
function send(smtp_credentials: {
|
||||||
|
host: string;
|
||||||
|
port: int;
|
||||||
|
username: string;
|
||||||
|
password: string;
|
||||||
|
}, sender: string, receivers: Array<string>, subject: string, content: string): Promise<void>;
|
||||||
|
}
|
||||||
declare namespace lib_plankton.log {
|
declare namespace lib_plankton.log {
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
|
|
@ -456,10 +311,40 @@ declare namespace lib_plankton.log {
|
||||||
* the path of the log file
|
* the path of the log file
|
||||||
*/
|
*/
|
||||||
private path;
|
private path;
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
private human_readable;
|
||||||
/**
|
/**
|
||||||
* [constructor]
|
* [constructor]
|
||||||
*/
|
*/
|
||||||
constructor(path: string);
|
constructor(path: string, human_readable: boolean);
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
add(entry: type_entry): void;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
declare namespace lib_plankton.log {
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
class class_channel_email extends class_channel {
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
private smtp_credentials;
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
private sender;
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
private receivers;
|
||||||
|
/**
|
||||||
|
* [constructor]
|
||||||
|
*/
|
||||||
|
constructor(smtp_credentials: {
|
||||||
|
host: string;
|
||||||
|
port: int;
|
||||||
|
username: string;
|
||||||
|
password: string;
|
||||||
|
}, sender: string, receivers: Array<string>);
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
add(entry: type_entry): void;
|
add(entry: type_entry): void;
|
||||||
|
|
@ -539,6 +424,8 @@ declare namespace lib_plankton.log {
|
||||||
*/
|
*/
|
||||||
function error(incident: string, details?: Record<string, any>): void;
|
function error(incident: string, details?: Record<string, any>): void;
|
||||||
}
|
}
|
||||||
|
declare namespace lib_plankton.log {
|
||||||
|
}
|
||||||
declare var plain_text_to_html: (text: string) => string;
|
declare var plain_text_to_html: (text: string) => string;
|
||||||
/**
|
/**
|
||||||
* @desc makes a valid
|
* @desc makes a valid
|
||||||
|
|
@ -637,7 +524,7 @@ declare namespace lib_plankton.string {
|
||||||
to: string;
|
to: string;
|
||||||
}>, options?: {}): string;
|
}>, options?: {}): string;
|
||||||
/**
|
/**
|
||||||
* @desc replaces occurences of "${name}" in a string by the corresponding values of an argument object
|
* @desc replaces occurences of "{{name}}" in a string by the corresponding values of an argument object
|
||||||
* @author fenris
|
* @author fenris
|
||||||
*/
|
*/
|
||||||
function coin(str: string, args: {
|
function coin(str: string, args: {
|
||||||
|
|
@ -886,13 +773,26 @@ declare namespace lib_plankton.code {
|
||||||
}
|
}
|
||||||
declare namespace lib_plankton.json {
|
declare namespace lib_plankton.json {
|
||||||
/**
|
/**
|
||||||
* @author fenris
|
|
||||||
*/
|
*/
|
||||||
function encode(x: any, formatted?: boolean): string;
|
type type_source = any;
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
type type_target = string;
|
||||||
/**
|
/**
|
||||||
* @author fenris
|
* @author fenris
|
||||||
*/
|
*/
|
||||||
function decode(x: string): any;
|
export function encode(source: type_source, options?: {
|
||||||
|
formatted?: boolean;
|
||||||
|
}): type_target;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
export function decode(target: type_target): type_source;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
export function implementation_code(): lib_plankton.code.type_code<type_source, type_target>;
|
||||||
|
export {};
|
||||||
}
|
}
|
||||||
declare namespace lib_plankton.json {
|
declare namespace lib_plankton.json {
|
||||||
/**
|
/**
|
||||||
|
|
@ -915,7 +815,455 @@ declare namespace lib_plankton.json {
|
||||||
decode(x: string): any;
|
decode(x: string): any;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
declare module lib_plankton.pod {
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
type type_pod<type_value> = {
|
||||||
|
kind: ("empty" | "filled");
|
||||||
|
value?: type_value;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function make_empty<type_value>(): type_pod<type_value>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function make_filled<type_value>(value: type_value): type_pod<type_value>;
|
||||||
|
/**
|
||||||
|
* whether the pod is filled
|
||||||
|
*
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function is_filled<type_value>(pod: type_pod<type_value>): boolean;
|
||||||
|
/**
|
||||||
|
* return the value, stored in the pod-wrapper
|
||||||
|
*
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function cull<type_value>(pod: type_pod<type_value>): type_value;
|
||||||
|
/**
|
||||||
|
* to pass on a empty-pod or to use a filled-pod
|
||||||
|
*
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function propagate<type_value, type_value_>(pod: type_pod<type_value>, function_: ((value: type_value) => type_value_)): type_pod<type_value_>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function distinguish<type_value, type_result>(pod: type_pod<type_value>, function_empty: (() => type_result), function_filled: ((value: type_value) => type_result)): type_result;
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
function show<type_value>(pod: type_pod<type_value>, options?: {
|
||||||
|
show_value?: ((value: type_value) => string);
|
||||||
|
}): string;
|
||||||
|
}
|
||||||
|
declare module lib_plankton.pod {
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
class class_pod<type_value> {
|
||||||
|
private subject;
|
||||||
|
constructor(subject: type_pod<type_value>);
|
||||||
|
tear(): type_pod<type_value>;
|
||||||
|
static empty<type_value>(): class_pod<type_value>;
|
||||||
|
static filled<type_value>(value: type_value): class_pod<type_value>;
|
||||||
|
is_empty(): boolean;
|
||||||
|
is_filled(): boolean;
|
||||||
|
cull(): type_value;
|
||||||
|
show(show_value?: any): string;
|
||||||
|
toString(): string;
|
||||||
|
propagate<type_value_>(function_: ((value: type_value) => type_value_)): class_pod<type_value_>;
|
||||||
|
distinguish<type_result>(function_empty: (() => type_result), function_filled: ((value: type_value) => type_result)): type_result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* might be completely obsolete
|
||||||
|
*/
|
||||||
|
declare namespace lib_plankton.call {
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
type type_promise<type_result, type_reason> = Promise<type_result>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function promise_reject<type_result, type_reason>(reason: type_reason): type_promise<type_result, type_reason>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function promise_resolve<type_result, type_reason>(result: type_result): type_promise<type_result, type_reason>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function promise_make<type_result, type_reason>(executor: (resolve: ((result?: type_result) => void), reject: ((reason?: type_reason) => void)) => void): type_promise<type_result, type_reason>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function promise_then_close<type_result, type_reason>(promise: type_promise<type_result, type_reason>, resolver: ((result: type_result) => void), rejector: ((reason: type_reason) => void)): void;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function promise_then_append<type_result, type_reason, type_result_>(promise: type_promise<type_result, type_reason>, resolver: ((result: type_result) => type_promise<type_result_, type_reason>), rejector?: ((reason: type_reason) => type_promise<type_result_, type_reason>)): type_promise<type_result_, type_result>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function promise_all<type_result, type_reason>(promises: Array<type_promise<type_result, type_reason>>): type_promise<Array<type_result>, type_reason>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function promise_chain<type_result, type_reason>(promises: (Array<(input: type_result) => type_promise<type_result, type_reason>>), start?: type_result): type_promise<type_result, type_reason>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function promise_condense<type_element, type_reason>(promises: Array<() => type_promise<type_element, type_reason>>): type_promise<Array<type_element>, type_reason>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function promise_group<type_reason>(promises: Record<string, (() => type_promise<any, type_reason>)>, options?: {
|
||||||
|
serial?: boolean;
|
||||||
|
}): type_promise<Record<string, any>, type_reason>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function promise_wrap<type_result_inner, type_result_outer, type_reason>(promise: type_promise<type_result_inner, type_reason>, transformator_result: ((reason: type_result_inner) => type_result_outer), transformator_reason?: ((reason: type_reason) => type_reason)): type_promise<type_result_outer, type_reason>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function promise_attach<type_reason>(state: Record<string, any>, promise: type_promise<any, type_reason>, name: string): type_promise<Record<string, any>, type_reason>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function promise_delay<type_result, type_reason>(promise: type_promise<type_result, type_reason>, delay: int): type_promise<type_result, type_reason>;
|
||||||
|
}
|
||||||
|
declare namespace lib_plankton.call {
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
class CancellablePromise<type_result> extends Promise<type_result> {
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
private cancelled;
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
private interval;
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
private subject;
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
constructor(executor: ((resolve: any, reject: any) => void));
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
private clear;
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
then<type_next_resolved, type_next_rejected>(onfulfilled?: ((value: type_result) => (type_next_resolved | PromiseLike<type_next_resolved>)), onrejected?: ((reason: any) => (type_next_rejected | PromiseLike<type_next_rejected>))): Promise<type_next_resolved | type_next_rejected>;
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
catch(x: any): Promise<type_result>;
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
cancel(): void;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* initializer might be obsolete, since promises are reusable after having been resolved or rejected
|
||||||
|
*/
|
||||||
|
declare namespace lib_plankton.call {
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
enum enum_initializer_state {
|
||||||
|
initial = 0,
|
||||||
|
waiting = 1,
|
||||||
|
successful = 2,
|
||||||
|
failed = 3
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
type type_initializer<type_result, type_reason> = {
|
||||||
|
fetcher: (() => type_promise<type_result, type_reason>);
|
||||||
|
state?: enum_initializer_state;
|
||||||
|
queue: Array<{
|
||||||
|
resolve: ((result?: type_result) => void);
|
||||||
|
reject: ((reason?: type_reason) => void);
|
||||||
|
}>;
|
||||||
|
result?: type_result;
|
||||||
|
reason?: type_reason;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function initializer_make<type_result, type_reason>(fetcher: (() => type_promise<type_result, type_reason>)): type_initializer<type_result, type_reason>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function initializer_reset<type_result, type_reason>(subject: type_initializer<type_result, type_reason>): void;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function initializer_state<type_result, type_reason>(subject: type_initializer<type_result, type_reason>): enum_initializer_state;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function initializer_get<type_result, type_reason>(subject: type_initializer<type_result, type_reason>): type_promise<type_result, type_reason>;
|
||||||
|
}
|
||||||
|
declare namespace lib_plankton.call {
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
type type_deferral<type_input, type_output> = {
|
||||||
|
representation: (input: type_input) => Promise<type_output>;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
* @desc activates the deferral and handles its output according to a given procedure
|
||||||
|
* @param {(value : type_value)=>void} procedure a function which receives the output of the deferral as argument
|
||||||
|
*/
|
||||||
|
function deferral_use<type_input, type_output>(deferral: type_deferral<type_input, type_output>, input: type_input, procedure: (output: type_output) => void): void;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
* @desc creates a deferral-subject (similar to "new Promise", where "convey" reflects "resolve"/"reject")
|
||||||
|
*/
|
||||||
|
function deferral_make<type_input, type_output>(handler: (input: type_input, convey: (output: type_output) => void) => void): type_deferral<type_input, type_output>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
* @desc wraps a simple function into a deferral (similar to "Promise.resolve"/"Promise.reject")
|
||||||
|
*/
|
||||||
|
function deferral_wrap<type_input, type_output>(function_: (input: type_input) => type_output): type_deferral<type_input, type_output>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function deferral_id<type_value>(): type_deferral<type_value, type_value>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function deferral_const<type_value>(value: type_value): type_deferral<type_value, type_value>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function deferral_delay<type_output>(output: type_output, delay: int): type_deferral<any, type_output>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
* @desc connects two deferrals to form a new one; the output of the first is taken as input for the second
|
||||||
|
* (similar to "Promise.then" when passing a function which returns a new promise)
|
||||||
|
* @param {type_deferral<type_value1>} first a simple deferral
|
||||||
|
* @param {(value1 : type_value1)=>type_deferral<type_value2>} second a function depending from a value returning a deferral
|
||||||
|
*/
|
||||||
|
function deferral_compose_serial<type_input, type_between, type_output>(first: type_deferral<type_input, type_between>, second: type_deferral<type_between, type_output>): type_deferral<type_input, type_output>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function deferral_compose_parallel<type_input, type_output_left, type_output_right>({ "left": deferral_left, "right": deferral_right, }: {
|
||||||
|
left: type_deferral<type_input, type_output_left>;
|
||||||
|
right: type_deferral<type_input, type_output_right>;
|
||||||
|
}): type_deferral<type_input, {
|
||||||
|
left: type_output_left;
|
||||||
|
right: type_output_right;
|
||||||
|
}>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
* @desc repeatedly applied serial composition
|
||||||
|
*/
|
||||||
|
function deferral_chain<type_value>(members: Array<type_deferral<type_value, type_value>>): type_deferral<type_value, type_value>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
declare namespace lib_plankton.call {
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
class class_deferral<type_input, type_output> {
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
private subject;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
private constructor();
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
private static _cram;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
private static _tear;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
static make<type_input, type_output>(handler: (input: type_input, convey: (value: type_output) => void) => void): class_deferral<type_input, type_output>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
use(input: type_input, procedure: (value: type_output) => void): void;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
compose_serial<type_output_>(second: class_deferral<type_output, type_output_>): class_deferral<type_input, type_output_>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
static chain<type_value>(members: Array<class_deferral<type_value, type_value>>): class_deferral<type_value, type_value>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
static wrap<type_input, type_output>(function_: (input: type_input) => type_output): class_deferral<type_input, type_output>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
static const_<type_value>(value: type_value): class_deferral<type_value, type_value>;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
static delay<type_output>(output: type_output, delay: int): class_deferral<any, type_output>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
declare namespace lib_plankton.call {
|
||||||
|
/**
|
||||||
|
* converts the "arguments"-map into an array
|
||||||
|
*
|
||||||
|
* @param {Object} args
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function args2list(args: any): Array<any>;
|
||||||
|
/**
|
||||||
|
* just the empty function; useful for some callbacks etc.
|
||||||
|
*
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function nothing(): void;
|
||||||
|
/**
|
||||||
|
* just the identity; useful for some callbacks etc.; defined as function instead of const for using type parameters
|
||||||
|
*
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function id<type_value>(x: type_value): type_value;
|
||||||
|
/**
|
||||||
|
* just the identity; useful for some callbacks etc.
|
||||||
|
*
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function const_<type_value>(x: type_value): ((y: any) => type_value);
|
||||||
|
/**
|
||||||
|
* composes two functions (i.e. returns a function that return the result of the successive execution of both input-functions)
|
||||||
|
*
|
||||||
|
* @param {function} function_f
|
||||||
|
* @param {function} function_g
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function compose<type_x, type_y, type_z>(function_f: ((type_x: any) => type_y), function_g: ((type_y: any) => type_z)): ((value: type_x) => type_z);
|
||||||
|
/**
|
||||||
|
* transforms a function with sequential input to a function with leveled input; example: add(2,3) = curryfy(add)(2)(3)
|
||||||
|
*
|
||||||
|
* @param {function} f
|
||||||
|
* @return {function} the currified version of the in put function
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function curryfy(f: Function): Function;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function convey(value: any, functions: Array<Function>): any;
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function timeout(procedure: (() => void), delay_in_seconds: float): int;
|
||||||
|
/**
|
||||||
|
* Promise version of "setTimeout"
|
||||||
|
*
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function defer<type_result>(seconds: float, action: (() => type_result)): Promise<type_result>;
|
||||||
|
/**
|
||||||
|
* a definition for a value being "defined"
|
||||||
|
*
|
||||||
|
* @author neuc
|
||||||
|
*/
|
||||||
|
function is_def<type_value>(obj: type_value, options?: {
|
||||||
|
null_is_valid?: boolean;
|
||||||
|
}): boolean;
|
||||||
|
/**
|
||||||
|
* returns the value if set and, when a type is specified, if the type is correct, if not return default_value
|
||||||
|
*
|
||||||
|
* @author neuc
|
||||||
|
*/
|
||||||
|
function def_val(value: any, default_value: any, options?: {
|
||||||
|
type?: (null | string);
|
||||||
|
null_is_valid?: boolean;
|
||||||
|
}): any;
|
||||||
|
/**
|
||||||
|
* provides the call for an attribute of a class as a regular function; useful for processing lists of objects
|
||||||
|
*
|
||||||
|
* @param {string} name the name of the attribute
|
||||||
|
* @return {function}
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function attribute<type_object, type_attribute>(name: string): ((object: type_object) => type_attribute);
|
||||||
|
/**
|
||||||
|
* provides a method of a class as a regular function; useful for processing lists of objects
|
||||||
|
*
|
||||||
|
* @param {string} name the name of the method
|
||||||
|
* @return {function}
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function method<type_object, type_output>(name: string): ((object: type_object) => type_output);
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
type type_coproduct = {
|
||||||
|
kind: string;
|
||||||
|
data?: any;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function distinguish<type_output>(coproduct: type_coproduct, handlers: Record<string, ((data?: any) => type_output)>, options?: {
|
||||||
|
fallback?: (null | ((coproduct?: type_coproduct) => type_output));
|
||||||
|
}): type_output;
|
||||||
|
/**
|
||||||
|
* for rate_limit_check
|
||||||
|
*
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
type type_mana_snapshot = {
|
||||||
|
timestamp: float;
|
||||||
|
value: float;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* rate limiting algorithm, based on the idea of mana (magic power) in video games:
|
||||||
|
* - an actor has a fixed mana capacity, i.e. the maximum amount of available power
|
||||||
|
* - an actor has a fixed rate of mana regeneration, i.e. how fast the power is filled up (linear growth)
|
||||||
|
* - an action has a defined mana heft, i.e. how much power is required and deducted in order to execute it
|
||||||
|
* - mana states are represented by snapshots, i.e. the amount of power at a certain point in time
|
||||||
|
*
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function rate_limit_check(setup: {
|
||||||
|
capacity: float;
|
||||||
|
regeneration_rate: float;
|
||||||
|
get_snapshot: (() => Promise<(null | type_mana_snapshot)>);
|
||||||
|
set_snapshot: ((snapshot: type_mana_snapshot) => Promise<void>);
|
||||||
|
update_snapshot: ((timestamp: float, value_increment: float) => Promise<void>);
|
||||||
|
}, heft: float): Promise<{
|
||||||
|
granted: boolean;
|
||||||
|
seconds: (null | float);
|
||||||
|
}>;
|
||||||
|
}
|
||||||
declare namespace lib_plankton.file {
|
declare namespace lib_plankton.file {
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function exists(path: string): Promise<boolean>;
|
||||||
/**
|
/**
|
||||||
* @author fenris
|
* @author fenris
|
||||||
*/
|
*/
|
||||||
|
|
@ -938,6 +1286,9 @@ declare namespace lib_plankton.file {
|
||||||
* @author fenris
|
* @author fenris
|
||||||
*/
|
*/
|
||||||
function write_buffer(path: string, content: Buffer, options?: {}): Promise<void>;
|
function write_buffer(path: string, content: Buffer, options?: {}): Promise<void>;
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
function delete_(path: string): Promise<void>;
|
||||||
}
|
}
|
||||||
declare namespace lib_plankton.prog {
|
declare namespace lib_plankton.prog {
|
||||||
/**
|
/**
|
||||||
|
|
@ -1197,7 +1548,10 @@ declare namespace lib_plankton.prog {
|
||||||
class struct_statement_type_definition extends struct_statement {
|
class struct_statement_type_definition extends struct_statement {
|
||||||
name: string;
|
name: string;
|
||||||
type: struct_type;
|
type: struct_type;
|
||||||
constructor(name: string, type: struct_type);
|
export_: boolean;
|
||||||
|
constructor(name: string, type: struct_type, options?: {
|
||||||
|
export?: boolean;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declare namespace lib_plankton.prog {
|
declare namespace lib_plankton.prog {
|
||||||
|
|
@ -1208,7 +1562,10 @@ declare namespace lib_plankton.prog {
|
||||||
name: string;
|
name: string;
|
||||||
type: (null | struct_type);
|
type: (null | struct_type);
|
||||||
value: (null | struct_expression);
|
value: (null | struct_expression);
|
||||||
constructor(constant: boolean, name: string, type: (null | struct_type), value: (null | struct_expression));
|
export_: boolean;
|
||||||
|
constructor(constant: boolean, name: string, type: (null | struct_type), value: (null | struct_expression), options?: {
|
||||||
|
export?: boolean;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declare namespace lib_plankton.prog {
|
declare namespace lib_plankton.prog {
|
||||||
|
|
@ -1275,7 +1632,7 @@ declare namespace lib_plankton.prog {
|
||||||
render_program: ((program: struct_program) => string);
|
render_program: ((program: struct_program) => string);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
declare namespace lib_plankton.prog {
|
declare namespace lib_plankton.prog.typescript {
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
function render_type(type: struct_type, options?: {
|
function render_type(type: struct_type, options?: {
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
118
source/outputs/backend/typescript/templates/api.ts.tpl
Normal file
118
source/outputs/backend/typescript/templates/api.ts.tpl
Normal file
|
|
@ -0,0 +1,118 @@
|
||||||
|
// <<domain_name>>
|
||||||
|
{
|
||||||
|
lib_plankton.rest.register(
|
||||||
|
rest,
|
||||||
|
lib_plankton.http.enum_method.get,
|
||||||
|
lib_plankton.string.coin(
|
||||||
|
"/{{base_path}}{{domain_name}}",
|
||||||
|
{
|
||||||
|
"base_path": _brock.conf.api_base_path,
|
||||||
|
"domain_name": "<<domain_name>>",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
{
|
||||||
|
"execution": async function (stuff) {
|
||||||
|
return {
|
||||||
|
"status_code": 200,
|
||||||
|
"data": await <<repository_function_list>>(
|
||||||
|
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
lib_plankton.rest.register(
|
||||||
|
rest,
|
||||||
|
lib_plankton.http.enum_method.get,
|
||||||
|
lib_plankton.string.coin(
|
||||||
|
"/{{base_path}}{{domain_name}}/:id",
|
||||||
|
{
|
||||||
|
"base_path": _brock.conf.api_base_path,
|
||||||
|
"domain_name": "<<domain_name>>",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
{
|
||||||
|
"execution": async function (stuff) {
|
||||||
|
return {
|
||||||
|
"status_code": 200,
|
||||||
|
"data": await <<repository_function_read>>(
|
||||||
|
parseInt(
|
||||||
|
stuff.path_parameters["id"]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
lib_plankton.rest.register(
|
||||||
|
rest,
|
||||||
|
lib_plankton.http.enum_method.post,
|
||||||
|
lib_plankton.string.coin(
|
||||||
|
"/{{base_path}}{{domain_name}}",
|
||||||
|
{
|
||||||
|
"base_path": _brock.conf.api_base_path,
|
||||||
|
"domain_name": "<<domain_name>>",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
{
|
||||||
|
"execution": async function (stuff) {
|
||||||
|
const id = await <<repository_function_create>>(
|
||||||
|
(stuff.input as <<type_name>>)
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
"status_code": 201,
|
||||||
|
"data": id
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
lib_plankton.rest.register(
|
||||||
|
rest,
|
||||||
|
lib_plankton.http.enum_method.patch,
|
||||||
|
lib_plankton.string.coin(
|
||||||
|
"/{{base_path}}{{domain_name}}/:id",
|
||||||
|
{
|
||||||
|
"base_path": _brock.conf.api_base_path,
|
||||||
|
"domain_name": "<<domain_name>>",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
{
|
||||||
|
"execution": async function (stuff) {
|
||||||
|
const dummy = await <<repository_function_create>>(
|
||||||
|
parseInt(
|
||||||
|
stuff.path_parameters["id"]
|
||||||
|
),
|
||||||
|
(stuff.input as <<type_name>>)
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
"status_code": 200,
|
||||||
|
"data": null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
lib_plankton.rest.register(
|
||||||
|
rest,
|
||||||
|
lib_plankton.http.enum_method.delete,
|
||||||
|
lib_plankton.string.coin(
|
||||||
|
"/{{base_path}}{{domain_name}}/:id",
|
||||||
|
{
|
||||||
|
"base_path": _brock.conf.api_base_path,
|
||||||
|
"domain_name": "<<domain_name>>",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
{
|
||||||
|
"execution": async function (stuff) {
|
||||||
|
const dummy = await <<repository_function_delete>>(
|
||||||
|
parseInt(
|
||||||
|
stuff.path_parameters["id"]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
"status_code": 200,
|
||||||
|
"data": null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
export namespace <<domain_name>>
|
||||||
|
{
|
||||||
|
<<defs>>
|
||||||
|
}
|
||||||
74
source/outputs/backend/typescript/templates/master.ts.tpl
Normal file
74
source/outputs/backend/typescript/templates/master.ts.tpl
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
// declare var require;
|
||||||
|
|
||||||
|
namespace <<namespace_base>>entities
|
||||||
|
{
|
||||||
|
<<entities>>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace <<namespace_base>>repositories
|
||||||
|
{
|
||||||
|
<<repositories>>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace <<namespace_base>>main
|
||||||
|
{
|
||||||
|
// run
|
||||||
|
export function run(
|
||||||
|
) : void
|
||||||
|
{
|
||||||
|
lib_plankton.log.conf_push(
|
||||||
|
[
|
||||||
|
new lib_plankton.log.class_channel_stdout(
|
||||||
|
|
||||||
|
)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
// define api
|
||||||
|
{
|
||||||
|
// meta
|
||||||
|
{
|
||||||
|
lib_plankton.rest.register(
|
||||||
|
rest,
|
||||||
|
lib_plankton.http.enum_method.get,
|
||||||
|
"/_spec",
|
||||||
|
{
|
||||||
|
"execution": async function (stuff) {
|
||||||
|
return {
|
||||||
|
"status_code": 200,
|
||||||
|
"data": lib_plankton.rest.to_oas(
|
||||||
|
rest
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
<<api>>
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup server
|
||||||
|
const server = lib_plankton.server.make(
|
||||||
|
_brock.conf.server_port,
|
||||||
|
async function (input) {
|
||||||
|
const http_request : lib_plankton.http.type_request = lib_plankton.http.decode_request(
|
||||||
|
input
|
||||||
|
);
|
||||||
|
const http_response : lib_plankton.http.type_response = await lib_plankton.rest.call(
|
||||||
|
rest,
|
||||||
|
http_request
|
||||||
|
);
|
||||||
|
return lib_plankton.http.encode_response(
|
||||||
|
http_response
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// start
|
||||||
|
lib_plankton.server.start(
|
||||||
|
server
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
113
source/outputs/backend/typescript/templates/repository.ts.tpl
Normal file
113
source/outputs/backend/typescript/templates/repository.ts.tpl
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
export namespace <<domain_name>>
|
||||||
|
{
|
||||||
|
|
||||||
|
// list
|
||||||
|
export function <<list_function_name>>(
|
||||||
|
) : Promise<Array<{key : number; value : <<type_name>>;}>>
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
lib_plankton.sqlite.query_get(
|
||||||
|
_brock.conf.database_path,
|
||||||
|
{
|
||||||
|
"template": "SELECT <<list_query_fields>> FROM <<table_name>>;",
|
||||||
|
"arguments": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
(rows) => rows.map(
|
||||||
|
(row) => <<list_result>>
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// read
|
||||||
|
export function <<read_function_name>>(
|
||||||
|
key : number
|
||||||
|
) : Promise<<<type_name>>>
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
lib_plankton.sqlite.query_get(
|
||||||
|
_brock.conf.database_path,
|
||||||
|
{
|
||||||
|
"template": "SELECT <<read_query_fields>> FROM <<table_name>> WHERE (id = :key);",
|
||||||
|
"arguments": {
|
||||||
|
"key": key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
(rows) {
|
||||||
|
const row = rows[0];
|
||||||
|
return <<read_result_fields>>;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create
|
||||||
|
export function <<create_function_name>>(
|
||||||
|
value : <<type_name>>
|
||||||
|
) : Promise<number>
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
lib_plankton.sqlite.query_put(
|
||||||
|
_brock.conf.database_path,
|
||||||
|
{
|
||||||
|
"template": "INSERT INTO <<table_name>>(<<create_query_field_names>>) VALUES (<<create_query_field_placeholders>>);",
|
||||||
|
"arguments": <<create_query_field_values>>
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
(result) => result.id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// update
|
||||||
|
export function <<update_function_name>>(
|
||||||
|
key : number,
|
||||||
|
value : <<type_name>>
|
||||||
|
) : Promise<void>
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
lib_plankton.sqlite.query_put(
|
||||||
|
_brock.conf.database_path,
|
||||||
|
{
|
||||||
|
"template": "UPDATE <<table_name>> SET <<update_query_assignments>> WHERE (id = :key);",
|
||||||
|
"arguments": {
|
||||||
|
"key": key,
|
||||||
|
<<update_query_values>>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
(result) => {}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete
|
||||||
|
export function <<delete_function_name>>(
|
||||||
|
key : number
|
||||||
|
) : Promise<void>
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
lib_plankton.sqlite.query_put(
|
||||||
|
_brock.conf.database_path,
|
||||||
|
{
|
||||||
|
"template": "DELETE FROM <<table_name>> WHERE (id = :key);",
|
||||||
|
"arguments": {
|
||||||
|
"key": key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
(result) => {}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -216,6 +216,6 @@ _sindri.add_output(
|
||||||
_sindri.enum_realm.database,
|
_sindri.enum_realm.database,
|
||||||
"mysql",
|
"mysql",
|
||||||
{
|
{
|
||||||
"render": (x) => Promise.resolve<string>(_sindri.outputs.backend.typescript.render(x)),
|
"render": (x) => Promise.resolve<string>(_sindri.outputs.database.mysql.render(x)),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
||||||
255
source/outputs/database/postgresql/logic.ts
Normal file
255
source/outputs/database/postgresql/logic.ts
Normal file
|
|
@ -0,0 +1,255 @@
|
||||||
|
namespace _sindri.outputs.database.postgresql
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
function value_encode(
|
||||||
|
value : any
|
||||||
|
) : string
|
||||||
|
{
|
||||||
|
if (value === null) {
|
||||||
|
return "NULL";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch (typeof(value)) {
|
||||||
|
case "boolean": {
|
||||||
|
return (value ? "TRUE" : "FALSE");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "number": {
|
||||||
|
return value.toString();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "string": {
|
||||||
|
return ("'" + value + "'");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
throw (new Error("unhandled"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export function render(
|
||||||
|
input_data
|
||||||
|
) : string
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
input_data.domains
|
||||||
|
.map(
|
||||||
|
(domain) => lib_plankton.string.coin(
|
||||||
|
"CREATE TABLE\n\t{{name}}(\n{{entries}}\n\t)\n;\n{{comments}}",
|
||||||
|
{
|
||||||
|
"name": domain.name,
|
||||||
|
"entries": (
|
||||||
|
(
|
||||||
|
[]
|
||||||
|
// key field
|
||||||
|
.concat(
|
||||||
|
(domain.key_field === null)
|
||||||
|
? []
|
||||||
|
: lib_plankton.string.coin(
|
||||||
|
"{{name}} {{parameters}}",
|
||||||
|
{
|
||||||
|
"name": ('"' + domain.key_field.name + '"'),
|
||||||
|
"parameters": (
|
||||||
|
[
|
||||||
|
"SERIAL",
|
||||||
|
]
|
||||||
|
.join(" ")
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
// data fields
|
||||||
|
.concat(
|
||||||
|
domain.data_fields
|
||||||
|
.map(
|
||||||
|
(data_field) => lib_plankton.string.coin(
|
||||||
|
"{{name}} {{parameters}}",
|
||||||
|
{
|
||||||
|
"name": ('"' + data_field.name + '"'),
|
||||||
|
"parameters": (
|
||||||
|
(
|
||||||
|
// type
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"boolean": "BOOLEAN",
|
||||||
|
"integer": "INTEGER",
|
||||||
|
"string_short": "VARCHAR(63)",
|
||||||
|
"string_medium": "VARCHAR(255)",
|
||||||
|
"string_long": "TEXT",
|
||||||
|
}[data_field.type],
|
||||||
|
]
|
||||||
|
// nullability
|
||||||
|
.concat(
|
||||||
|
data_field.nullable
|
||||||
|
? []
|
||||||
|
: ["NOT NULL"]
|
||||||
|
)
|
||||||
|
// default
|
||||||
|
.concat(
|
||||||
|
(data_field.default === undefined)
|
||||||
|
? []
|
||||||
|
: [
|
||||||
|
lib_plankton.string.coin(
|
||||||
|
"DEFAULT {{value}}",
|
||||||
|
{
|
||||||
|
"value": value_encode(data_field.default),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.join(" ")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
// constraints
|
||||||
|
.concat(
|
||||||
|
domain["constraints"]
|
||||||
|
.concat(
|
||||||
|
(domain.key_field === null)
|
||||||
|
?
|
||||||
|
[]
|
||||||
|
:
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"kind": "unique",
|
||||||
|
"parameters": {
|
||||||
|
"fields": [
|
||||||
|
domain.key_field.name,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
)
|
||||||
|
.map(
|
||||||
|
(constraint) => {
|
||||||
|
switch (constraint.kind) {
|
||||||
|
default: {
|
||||||
|
throw (new Error("unhandled constraint kind: " + constraint.kind));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "foreign_key": {
|
||||||
|
return lib_plankton.string.coin(
|
||||||
|
"FOREIGN KEY ({{fields}}) REFERENCES {{reference_name}}({{reference_fields}})",
|
||||||
|
{
|
||||||
|
"fields": (
|
||||||
|
constraint.parameters["fields"]
|
||||||
|
.map(x => ('"' + x + '"'))
|
||||||
|
.join(",")
|
||||||
|
),
|
||||||
|
"reference_name": ('"' + constraint.parameters["reference"]["name"] + '"'),
|
||||||
|
"reference_fields": (
|
||||||
|
constraint.parameters["reference"]["fields"]
|
||||||
|
.map(x => ('"' + x + '"'))
|
||||||
|
.join(",")
|
||||||
|
),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "unique": {
|
||||||
|
return lib_plankton.string.coin(
|
||||||
|
"UNIQUE ({{fields}})",
|
||||||
|
{
|
||||||
|
"fields": (
|
||||||
|
constraint.parameters["fields"]
|
||||||
|
.map(x => ('"' + x + '"'))
|
||||||
|
.join(",")
|
||||||
|
),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.map(x => ("\t\t" + x))
|
||||||
|
.join(",\n")
|
||||||
|
),
|
||||||
|
"comments": (
|
||||||
|
(
|
||||||
|
[]
|
||||||
|
.concat(
|
||||||
|
(! (domain.description === null))
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
"kind": "TABLE",
|
||||||
|
"subject": domain.name,
|
||||||
|
"value": domain.description,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
: []
|
||||||
|
)
|
||||||
|
.concat(
|
||||||
|
(
|
||||||
|
(! (domain.key_field === null))
|
||||||
|
&&
|
||||||
|
(! (domain.key_field.description === null))
|
||||||
|
)
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
"kind": "COLUMN",
|
||||||
|
"subject": (domain.name + "." + domain.key_field.name),
|
||||||
|
"value": domain.key_field.description,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
: []
|
||||||
|
)
|
||||||
|
.concat(
|
||||||
|
domain.data_fields
|
||||||
|
.filter(
|
||||||
|
data_field => (! (data_field.description === null))
|
||||||
|
)
|
||||||
|
.map(
|
||||||
|
data_field => ({
|
||||||
|
"kind": "COLUMN",
|
||||||
|
"subject": (domain.name + "." + data_field.name),
|
||||||
|
"value": data_field.description,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.map(
|
||||||
|
entry => lib_plankton.string.coin(
|
||||||
|
"COMMENT ON {{kind}} {{subject}} IS '{{value}}';",
|
||||||
|
{
|
||||||
|
"kind": entry.kind,
|
||||||
|
"subject": entry.subject,
|
||||||
|
"value": entry.value,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.join("\n")
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.map(x => (x + "\n"))
|
||||||
|
.join("\n")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
_sindri.add_output(
|
||||||
|
_sindri.enum_realm.database,
|
||||||
|
"postgresql",
|
||||||
|
{
|
||||||
|
"render": (x) => Promise.resolve<string>(_sindri.outputs.database.postgresql.render(x)),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
@ -91,8 +91,8 @@ namespace _sindri.outputs.database.sqlite
|
||||||
// nullability
|
// nullability
|
||||||
.concat(
|
.concat(
|
||||||
data_field.nullable
|
data_field.nullable
|
||||||
? ["NULL"]
|
? []
|
||||||
: []
|
: ["NOT NULL"]
|
||||||
)
|
)
|
||||||
// default
|
// default
|
||||||
.concat(
|
.concat(
|
||||||
|
|
@ -178,6 +178,6 @@ _sindri.add_output(
|
||||||
_sindri.enum_realm.database,
|
_sindri.enum_realm.database,
|
||||||
"sqlite",
|
"sqlite",
|
||||||
{
|
{
|
||||||
"render": (x) => Promise.resolve<string>(_sindri.outputs.backend.typescript.render(x)),
|
"render": (x) => Promise.resolve<string>(_sindri.outputs.database.sqlite.render(x)),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ namespace _sindri.outputs.frontend.typescript
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_sindri.add_output(
|
_sindri.add_output(
|
||||||
_sindri.enum_realm.frontend,
|
_sindri.enum_realm.frontend,
|
||||||
"typescript",
|
"typescript",
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,9 @@ namespace _sindri.outputs.other.jsonschema
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
true
|
{
|
||||||
|
"formatted": true
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
2
todo.md
2
todo.md
|
|
@ -1 +1,3 @@
|
||||||
- Nutzer-Verwaltung
|
- Nutzer-Verwaltung
|
||||||
|
- auf `plankton:database` setzen
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ source/base.ts \
|
||||||
source/outputs/other/jsonschema/logic.ts \
|
source/outputs/other/jsonschema/logic.ts \
|
||||||
source/outputs/database/sqlite/logic.ts \
|
source/outputs/database/sqlite/logic.ts \
|
||||||
source/outputs/database/mysql/logic.ts \
|
source/outputs/database/mysql/logic.ts \
|
||||||
|
source/outputs/database/postgresql/logic.ts \
|
||||||
source/outputs/backend/typescript/logic.ts \
|
source/outputs/backend/typescript/logic.ts \
|
||||||
source/outputs/frontend/typescript/logic.ts \
|
source/outputs/frontend/typescript/logic.ts \
|
||||||
source/conf.ts \
|
source/conf.ts \
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue