From 6cbe925d7c825e0d502c64727c0e4d5fb7d34e07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Fra=C3=9F?= Date: Thu, 10 Aug 2023 10:36:31 +0200 Subject: [PATCH] [int] --- doc/examples/contacts.sindri.json | 4 +- lib/plankton/plankton.d.ts | 12 +- lib/plankton/plankton.js | 32 +- source/outputs/backend/typescript/logic.ts | 411 +++++++++--------- .../backend/typescript/templates/api.ts.tpl | 56 ++- .../typescript/templates/entity.ts.tpl | 4 +- .../typescript/templates/master.ts.tpl | 14 +- .../typescript/templates/repository.ts.tpl | 68 ++- 8 files changed, 325 insertions(+), 276 deletions(-) diff --git a/doc/examples/contacts.sindri.json b/doc/examples/contacts.sindri.json index 849f207..d7b96e3 100644 --- a/doc/examples/contacts.sindri.json +++ b/doc/examples/contacts.sindri.json @@ -31,7 +31,9 @@ { "name": "person", "description": "collection of contacts", - "key_field": null, + "key_field": { + "name": "id" + }, "data_fields": [ { "name": "prename", diff --git a/lib/plankton/plankton.d.ts b/lib/plankton/plankton.d.ts index efeda7a..f3191a8 100644 --- a/lib/plankton/plankton.d.ts +++ b/lib/plankton/plankton.d.ts @@ -637,7 +637,7 @@ declare namespace lib_plankton.string { to: 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 */ function coin(str: string, args: { @@ -1200,7 +1200,10 @@ declare namespace lib_plankton.prog { class struct_statement_type_definition extends struct_statement { name: string; 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 { @@ -1211,7 +1214,10 @@ declare namespace lib_plankton.prog { name: string; type: (null | struct_type); 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 { diff --git a/lib/plankton/plankton.js b/lib/plankton/plankton.js index aca3bcc..f0e7fc3 100644 --- a/lib/plankton/plankton.js +++ b/lib/plankton/plankton.js @@ -1712,7 +1712,7 @@ var lib_plankton; } string.replace = replace; /** - * @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 */ function coin(str, args, options = {}) { @@ -3981,10 +3981,16 @@ var lib_plankton; */ var struct_statement_type_definition = /** @class */ (function (_super) { __extends(struct_statement_type_definition, _super); - function struct_statement_type_definition(name, type) { - var _this = _super.call(this) || this; + function struct_statement_type_definition(name, type, options) { + if (options === void 0) { options = {}; } + var _this = this; + options = Object.assign({ + "export": false, + }, options); + _this = _super.call(this) || this; _this.name = name; _this.type = type; + _this.export_ = options.export; return _this; } return struct_statement_type_definition; @@ -4019,12 +4025,18 @@ var lib_plankton; */ var struct_statement_declaration = /** @class */ (function (_super) { __extends(struct_statement_declaration, _super); - function struct_statement_declaration(constant, name, type, value) { - var _this = _super.call(this) || this; + function struct_statement_declaration(constant, name, type, value, options) { + if (options === void 0) { options = {}; } + var _this = this; + options = Object.assign({ + "export": false, + }, options); + _this = _super.call(this) || this; _this.constant = constant; _this.name = name; _this.type = type; _this.value = value; + _this.export_ = options.export; return _this; } return struct_statement_declaration; @@ -4628,9 +4640,12 @@ var lib_plankton; } else if (statement instanceof prog.struct_statement_type_definition) { var statement_type_definition = statement; - return lib_plankton.string.coin("{{indentation}}type {{name}} = {{type}};\n", { + return lib_plankton.string.coin("{{indentation}}{{macro_export}}type {{name}} = {{type}};\n", { "indentation": indentation(options.indent, options.level), "name": statement_type_definition.name, + "macro_export": ((!statement_type_definition.export_) + ? "" + : "export "), "type": render_type(statement_type_definition.type, { "indent": false, "level": (options.level + 0), @@ -4639,12 +4654,15 @@ var lib_plankton; } else if (statement instanceof prog.struct_statement_declaration) { var statement_declaration = statement; - return lib_plankton.string.coin("{{indentation}}{{kind}} {{name}}{{macro_type}}{{macro_value}};\n", { + return lib_plankton.string.coin("{{indentation}}{{macro_export}}{{kind}} {{name}}{{macro_type}}{{macro_value}};\n", { "indentation": indentation(options.indent, options.level), "kind": (statement_declaration.constant ? "const" : "let"), "name": statement_declaration.name, + "macro_export": ((!statement_declaration.export_) + ? "" + : "export "), "macro_type": ((statement_declaration.type === null) ? "" : lib_plankton.string.coin(" : {{type}}", { diff --git a/source/outputs/backend/typescript/logic.ts b/source/outputs/backend/typescript/logic.ts index b294086..8672f89 100644 --- a/source/outputs/backend/typescript/logic.ts +++ b/source/outputs/backend/typescript/logic.ts @@ -11,18 +11,35 @@ namespace _sindri.outputs.backend.typescript } + /** + */ + async function coin( + template_name : string, + values : Record + ) : Promise + { + return lib_plankton.string.coin( + await get_template(template_name), + values, + { + "open": "<<", + "close": ">>", + } + ); + } + + /** */ export async function render( input_data ) : Promise { - const conf : { + // TODO as command line argument? + const conf_internal : { namespace_base : string; - api_path_base : string; } = { "namespace_base": "_sindri.", - "api_path_base": "sindri/", }; const map_primitive_type = function (typename : string) : lib_plankton.prog.struct_type { @@ -47,7 +64,7 @@ namespace _sindri.outputs.backend.typescript return lib_plankton.string.coin( "{{base}}entities.{{domain_name}}", { - "base": conf.namespace_base, + "base": conf_internal.namespace_base, "domain_name": domain.name, } ); @@ -68,7 +85,7 @@ namespace _sindri.outputs.backend.typescript return lib_plankton.string.coin( "{{base}}repositories", { - "base": conf.namespace_base, + "base": conf_internal.namespace_base, } ); }; @@ -86,212 +103,202 @@ namespace _sindri.outputs.backend.typescript ); }; - return lib_plankton.string.coin( - await get_template("master"), + return coin( + "master", { - "namespace_base": conf.namespace_base, + "namespace_base": conf_internal.namespace_base, "entities": ( (await Promise.all( input_data["domains"] .map( - (domain) => ( - get_template("entity") - .then( - template => lib_plankton.string.coin( - template, - { - "domain_name": domain.name, - "defs": ( - "export " - + - lib_plankton.prog.typescript.render_statement( - new lib_plankton.prog.struct_statement_type_definition( - name_entity_type(false, domain), - new lib_plankton.prog.struct_type_record( - domain.data_fields - .map( - (data_field) => ({ - "name": data_field.name, - "type": ( - data_field.nullable - ? new lib_plankton.prog.struct_type_union( - new lib_plankton.prog.struct_type_literal( - new lib_plankton.prog.struct_expression_literal( - null - ) - ), - map_primitive_type(data_field["type"]) - ) - : map_primitive_type(data_field["type"]) - ), - "mandatory": true, - }) + (domain) => coin( + "entity", + { + "domain_name": domain.name, + "defs": lib_plankton.prog.typescript.render_statement( + new lib_plankton.prog.struct_statement_type_definition( + name_entity_type(false, domain), + new lib_plankton.prog.struct_type_record( + domain.data_fields + .map( + (data_field) => ({ + "name": data_field.name, + "type": ( + data_field.nullable + ? new lib_plankton.prog.struct_type_union( + new lib_plankton.prog.struct_type_literal( + new lib_plankton.prog.struct_expression_literal( + null + ) + ), + map_primitive_type(data_field["type"]) ) - ) - ), - { - "level": 2, - } + : map_primitive_type(data_field["type"]) + ), + "mandatory": true, + }) ) - ) + ), + { + "export": true, + } + ), + { + "level": 2, } ) - ) + } ) ) - )).join("") + )) + .join("") ), "repositories": ( (await Promise.all( input_data["domains"] .map( - (domain) => ( - get_template("repository") - .then( - template => lib_plankton.string.coin( - template, - { - "domain_name": domain.name, - "type_name": name_entity_type(true, domain), - "table_name": name_table(domain), - "list_function_name": name_repository_function(false, domain, "list"), - "list_query_fields": ( - [domain.key_field.name] - .concat(domain.data_fields.map(field => field.name)) - .join(",") - ), - "list_result": lib_plankton.prog.typescript.render_expression( - new lib_plankton.prog.struct_expression_dict( - [ - { - "key": "key", - "value": new lib_plankton.prog.struct_expression_projection( - new lib_plankton.prog.struct_expression_variable("row"), - new lib_plankton.prog.struct_expression_literal(domain.key_field.name) - ), - }, - { - "key": "value", - "value": new lib_plankton.prog.struct_expression_dict( - domain.data_fields - .map( - (field, index) => ({ - "key": field.name, - "value": new lib_plankton.prog.struct_expression_projection( - new lib_plankton.prog.struct_expression_variable("row"), - new lib_plankton.prog.struct_expression_literal(field.name) - ) - }) - ) - ), - }, - ] - ), + (domain) => coin( + "repository", + { + "domain_name": domain.name, + "type_name": name_entity_type(true, domain), + "table_name": name_table(domain), + "list_function_name": name_repository_function(false, domain, "list"), + "list_query_fields": ( + [domain.key_field.name] + .concat(domain.data_fields.map(field => field.name)) + .join(",") + ), + "list_result": lib_plankton.prog.typescript.render_expression( + new lib_plankton.prog.struct_expression_dict( + [ { - "indent": false, - "level": 8, - } - ), - "read_function_name": name_repository_function(false, domain, "read"), - "read_query_fields": ( - [] - .concat(domain.data_fields.map(field => field.name)) - .join(",") - ), - "read_result_fields": lib_plankton.prog.typescript.render_expression( - new lib_plankton.prog.struct_expression_dict( - domain.data_fields - .map( - (field, index) => ({ - "key": field.name, - "value": new lib_plankton.prog.struct_expression_projection( - new lib_plankton.prog.struct_expression_variable("row"), - new lib_plankton.prog.struct_expression_literal(field.name) - ) - }) - ) - ), + "key": "key", + "value": new lib_plankton.prog.struct_expression_projection( + new lib_plankton.prog.struct_expression_variable("row"), + new lib_plankton.prog.struct_expression_literal(domain.key_field.name) + ), + }, { - "indent": false, - "level": 6, - } - ), - "create_function_name": name_repository_function(false, domain, "create"), - "create_query_field_names": ( - domain.data_fields - .map(field => field.name) - .join(",") - ), - "create_query_field_placeholders": ( - domain.data_fields - .map(field => (":" + field.name)) - .join(",") - ), - "create_query_field_values": lib_plankton.prog.typescript.render_expression( - new lib_plankton.prog.struct_expression_dict( - domain.data_fields - .map( - field => ({ - "key": field.name, - "value": new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable("value"), - field.name, - ), - }) - ) - ), - { - "indent": false, - "level": 6, - } - ), - "update_function_name": name_repository_function(false, domain, "update"), - "update_query_assignments": ( - domain.data_fields - .map( - field => lib_plankton.string.coin( - "{{key}} = {{value}}", - { - "key": field.name, - "value": (":" + ("value_" + field.name)), - } - ) - ) - .join(", ") - ), - "update_query_values": lib_plankton.prog.typescript.render_expression( - new lib_plankton.prog.struct_expression_dict( - [] - .concat( - [ - { - "key": "key", - "value": new lib_plankton.prog.struct_expression_variable("key"), - }, - ] - ) - .concat( + "key": "value", + "value": new lib_plankton.prog.struct_expression_dict( domain.data_fields .map( - field => ({ - "key": ("value_" + field.name), - "value": new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable("value"), - field.name, - ), + (field, index) => ({ + "key": field.name, + "value": new lib_plankton.prog.struct_expression_projection( + new lib_plankton.prog.struct_expression_variable("row"), + new lib_plankton.prog.struct_expression_literal(field.name) + ) }) ) - ) - ), - { - "indent": false, - "level": 7, - } - ), - "delete_function_name": name_repository_function(false, domain, "delete"), + ), + }, + ] + ), + { + "indent": false, + "level": 8, } - ) - ) + ), + "read_function_name": name_repository_function(false, domain, "read"), + "read_query_fields": ( + [] + .concat(domain.data_fields.map(field => field.name)) + .join(",") + ), + "read_result_fields": lib_plankton.prog.typescript.render_expression( + new lib_plankton.prog.struct_expression_dict( + domain.data_fields + .map( + (field, index) => ({ + "key": field.name, + "value": new lib_plankton.prog.struct_expression_projection( + new lib_plankton.prog.struct_expression_variable("row"), + new lib_plankton.prog.struct_expression_literal(field.name) + ) + }) + ) + ), + { + "indent": false, + "level": 6, + } + ), + "create_function_name": name_repository_function(false, domain, "create"), + "create_query_field_names": ( + domain.data_fields + .map(field => field.name) + .join(",") + ), + "create_query_field_placeholders": ( + domain.data_fields + .map(field => (":" + field.name)) + .join(",") + ), + "create_query_field_values": lib_plankton.prog.typescript.render_expression( + new lib_plankton.prog.struct_expression_dict( + domain.data_fields + .map( + field => ({ + "key": field.name, + "value": new lib_plankton.prog.struct_expression_fieldaccess( + new lib_plankton.prog.struct_expression_variable("value"), + field.name, + ), + }) + ) + ), + { + "indent": false, + "level": 6, + } + ), + "update_function_name": name_repository_function(false, domain, "update"), + "update_query_assignments": ( + domain.data_fields + .map( + field => lib_plankton.string.coin( + "{{key}} = {{value}}", + { + "key": field.name, + "value": (":" + ("value_" + field.name)), + } + ) + ) + .join(", ") + ), + "update_query_values": lib_plankton.prog.typescript.render_expression( + new lib_plankton.prog.struct_expression_dict( + [] + .concat( + [ + { + "key": "key", + "value": new lib_plankton.prog.struct_expression_variable("key"), + }, + ] + ) + .concat( + domain.data_fields + .map( + field => ({ + "key": ("value_" + field.name), + "value": new lib_plankton.prog.struct_expression_fieldaccess( + new lib_plankton.prog.struct_expression_variable("value"), + field.name, + ), + }) + ) + ) + ), + { + "indent": false, + "level": 7, + } + ), + "delete_function_name": name_repository_function(false, domain, "delete"), + } ) ) )) @@ -301,23 +308,17 @@ namespace _sindri.outputs.backend.typescript (await Promise.all( input_data["domains"] .map( - (domain) => ( - get_template("api") - .then( - template => lib_plankton.string.coin( - template, - { - "domain_name": domain.name, - "type_name": name_entity_type(true, domain), - "path_base": conf.api_path_base, - "repository_function_list": name_repository_function(true, domain, "list"), - "repository_function_read": name_repository_function(true, domain, "read"), - "repository_function_create": name_repository_function(true, domain, "create"), - "repository_function_update": name_repository_function(true, domain, "update"), - "repository_function_delete": name_repository_function(true, domain, "delete"), - } - ) - ) + (domain) => coin( + "api", + { + "domain_name": domain.name, + "type_name": name_entity_type(true, domain), + "repository_function_list": name_repository_function(true, domain, "list"), + "repository_function_read": name_repository_function(true, domain, "read"), + "repository_function_create": name_repository_function(true, domain, "create"), + "repository_function_update": name_repository_function(true, domain, "update"), + "repository_function_delete": name_repository_function(true, domain, "delete"), + } ) ) )) diff --git a/source/outputs/backend/typescript/templates/api.ts.tpl b/source/outputs/backend/typescript/templates/api.ts.tpl index bb7d22d..35767e7 100644 --- a/source/outputs/backend/typescript/templates/api.ts.tpl +++ b/source/outputs/backend/typescript/templates/api.ts.tpl @@ -1,14 +1,20 @@ - // {{domain_name}} + // <> { lib_plankton.rest.register( rest, lib_plankton.http.enum_method.get, - "/{{path_base}}{{domain_name}}", + lib_plankton.string.coin( + "/{{base_path}}{{domain_name}}", + { + "base_path": _brock.conf.api_base_path, + "domain_name": "<>", + } + ), { "execution": async function (stuff) { return { "status_code": 200, - "data": await {{repository_function_list}}( + "data": await <>( ) }; @@ -18,12 +24,18 @@ lib_plankton.rest.register( rest, lib_plankton.http.enum_method.get, - "/{{path_base}}{{domain_name}}/:id", + lib_plankton.string.coin( + "/{{base_path}}{{domain_name}}/:id", + { + "base_path": _brock.conf.api_base_path, + "domain_name": "<>", + } + ), { "execution": async function (stuff) { return { "status_code": 200, - "data": await {{repository_function_read}}( + "data": await <>( parseInt( stuff.path_parameters["id"] ) @@ -35,11 +47,17 @@ lib_plankton.rest.register( rest, lib_plankton.http.enum_method.post, - "/{{path_base}}{{domain_name}}", + lib_plankton.string.coin( + "/{{base_path}}{{domain_name}}", + { + "base_path": _brock.conf.api_base_path, + "domain_name": "<>", + } + ), { "execution": async function (stuff) { - const id = await {{repository_function_create}}( - (stuff.input as {{type_name}}) + const id = await <>( + (stuff.input as <>) ); return { "status_code": 201, @@ -51,14 +69,20 @@ lib_plankton.rest.register( rest, lib_plankton.http.enum_method.patch, - "/{{path_base}}{{domain_name}}/:id", + lib_plankton.string.coin( + "/{{base_path}}{{domain_name}}/:id", + { + "base_path": _brock.conf.api_base_path, + "domain_name": "<>", + } + ), { "execution": async function (stuff) { - const dummy = await {{repository_function_create}}( + const dummy = await <>( parseInt( stuff.path_parameters["id"] ), - (stuff.input as {{type_name}}) + (stuff.input as <>) ); return { "status_code": 200, @@ -70,10 +94,16 @@ lib_plankton.rest.register( rest, lib_plankton.http.enum_method.delete, - "/{{path_base}}{{domain_name}}/:id", + lib_plankton.string.coin( + "/{{base_path}}{{domain_name}}/:id", + { + "base_path": _brock.conf.api_base_path, + "domain_name": "<>", + } + ), { "execution": async function (stuff) { - const dummy = await {{repository_function_delete}}( + const dummy = await <>( parseInt( stuff.path_parameters["id"] ) diff --git a/source/outputs/backend/typescript/templates/entity.ts.tpl b/source/outputs/backend/typescript/templates/entity.ts.tpl index 6738910..a9d6cb7 100644 --- a/source/outputs/backend/typescript/templates/entity.ts.tpl +++ b/source/outputs/backend/typescript/templates/entity.ts.tpl @@ -1,4 +1,4 @@ - export namespace {{domain_name}} + export namespace <> { -{{defs}} +<> } diff --git a/source/outputs/backend/typescript/templates/master.ts.tpl b/source/outputs/backend/typescript/templates/master.ts.tpl index 885b8e8..967d7c5 100644 --- a/source/outputs/backend/typescript/templates/master.ts.tpl +++ b/source/outputs/backend/typescript/templates/master.ts.tpl @@ -1,18 +1,18 @@ // declare var require; -namespace {{namespace_base}}entities +namespace <>entities { -{{entities}} +<> } -namespace {{namespace_base}}repositories +namespace <>repositories { -{{repositories}} +<> } -namespace {{namespace_base}}main +namespace <>main { // run export function run( @@ -46,12 +46,12 @@ namespace {{namespace_base}}main } ); } -{{api}} +<> } // setup server const server = lib_plankton.server.make( - conf.server_port, + _brock.conf.server_port, async function (input) { const http_request : lib_plankton.http.type_request = lib_plankton.http.decode_request( input diff --git a/source/outputs/backend/typescript/templates/repository.ts.tpl b/source/outputs/backend/typescript/templates/repository.ts.tpl index 2952023..0dfc38a 100644 --- a/source/outputs/backend/typescript/templates/repository.ts.tpl +++ b/source/outputs/backend/typescript/templates/repository.ts.tpl @@ -1,119 +1,111 @@ - export namespace {{domain_name}} + export namespace <> { // list - export function {{list_function_name}}( - ) : Promise> + export function <>( + ) : Promise>;}>> { return ( lib_plankton.sqlite.query_get( - conf.database_path, + _brock.conf.database_path, { - "template": "SELECT {{list_query_fields}} FROM {{table_name}};", + "template": "SELECT <> FROM <>;", "arguments": { } } ) .then( - function (rows) { - return rows.map( - function (row) { - return {{list_result}}; - } - ); - } + (rows) => rows.map( + (row) => <> + ) ) ); } // read - export function {{read_function_name}}( + export function <>( key : number - ) : Promise<{{type_name}}> + ) : Promise<<>> { return ( lib_plankton.sqlite.query_get( - conf.database_path, + _brock.conf.database_path, { - "template": "SELECT {{read_query_fields}} FROM {{table_name}} WHERE (id = :key);", + "template": "SELECT <> FROM <> WHERE (id = :key);", "arguments": { "key": key } } ) .then( - function (rows) { + (rows) { const row = rows[0]; - return {{read_result_fields}}; + return <>; } ) ); } // create - export function {{create_function_name}}( - value : {{type_name}} + export function <>( + value : <> ) : Promise { return ( lib_plankton.sqlite.query_put( - conf.database_path, + _brock.conf.database_path, { - "template": "INSERT INTO {{table_name}}({{create_query_field_names}}) VALUES ({{create_query_field_placeholders}});", - "arguments": {{create_query_field_values}} + "template": "INSERT INTO <>(<>) VALUES (<>);", + "arguments": <> } ) .then( - function (result) { - return result.id; - } + (result) => result.id ) ); } // update - export function {{update_function_name}}( + export function <>( key : number, - value : {{type_name}} + value : <> ) : Promise { return ( lib_plankton.sqlite.query_put( - conf.database_path, + _brock.conf.database_path, { - "template": "UPDATE {{table_name}} SET {{update_query_assignments}} WHERE (id = :key);", + "template": "UPDATE <> SET <> WHERE (id = :key);", "arguments": { "key": key, - {{update_query_values}} + <> } } ) .then( - function (result) { - } + (result) => {} ) ); } // delete - export function {{delete_function_name}}( + export function <>( key : number ) : Promise { return ( lib_plankton.sqlite.query_put( - conf.database_path, + _brock.conf.database_path, { - "template": "DELETE FROM {{table_name}} WHERE (id = :key);", + "template": "DELETE FROM <> WHERE (id = :key);", "arguments": { "key": key } } ) .then( - function (result) { - } + (result) => {} ) ); }