From ab9f1a6d6db982a33694e08054814d672cb14b22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Fra=C3=9F?= Date: Tue, 8 Aug 2023 16:35:33 +0200 Subject: [PATCH] [mod] output:backend:typescript:use templates --- source/outputs/backend/typescript/logic.ts | 1668 +++-------------- .../backend/typescript/templates/api.ts.tpl | 88 + .../typescript/templates/entity.ts.tpl | 4 + .../typescript/templates/master.ts.tpl | 74 + .../typescript/templates/repository.ts.tpl | 121 ++ 5 files changed, 567 insertions(+), 1388 deletions(-) create mode 100644 source/outputs/backend/typescript/templates/api.ts.tpl create mode 100644 source/outputs/backend/typescript/templates/entity.ts.tpl create mode 100644 source/outputs/backend/typescript/templates/master.ts.tpl create mode 100644 source/outputs/backend/typescript/templates/repository.ts.tpl diff --git a/source/outputs/backend/typescript/logic.ts b/source/outputs/backend/typescript/logic.ts index 0f69a30..b294086 100644 --- a/source/outputs/backend/typescript/logic.ts +++ b/source/outputs/backend/typescript/logic.ts @@ -3,10 +3,28 @@ namespace _sindri.outputs.backend.typescript /** */ - export function render( - input_data - ) : string + async function get_template( + name : string + ) : Promise { + return _sindri.get_template(_sindri.enum_realm.backend, "typescript", name + ".ts.tpl"); + } + + + /** + */ + export async function render( + input_data + ) : Promise + { + const conf : { + 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 { const mymap : Record = { "boolean": new lib_plankton.prog.struct_type_boolean(), @@ -18,1420 +36,294 @@ namespace _sindri.outputs.backend.typescript }; return mymap[typename]; }; - const prog_output : lib_plankton.prog.type_output = lib_plankton.prog.output_typescript(); const name_table = function (domain) : string {return (domain.name);}; - const name_type = function (domain) : string {return ("type_" + domain.name);}; - const name_collection = function (domain) : string {return ("collection_" + domain.name);}; const database_path = lib_plankton.string.coin( "/tmp/{{name}}.sqlite", { "name": "sindri", } ); - const name_repository_function_list = function (domain) : string { + const namespace_entity = function (domain) { return lib_plankton.string.coin( - "repository_{{name}}_list", + "{{base}}entities.{{domain_name}}", { - "name": domain.name + "base": conf.namespace_base, + "domain_name": domain.name, + } + ); + }; + const name_entity_type = function (fully_qualified, domain) : string { + return lib_plankton.string.coin( + "{{prefix}}type_value", + { + "prefix": ( + fully_qualified + ? (namespace_entity(domain) + ".") + : "" + ), } ); }; - const name_repository_function_read = function (domain) : string { + const namespace_repository = function (domain) { return lib_plankton.string.coin( - "repository_{{name}}_read", + "{{base}}repositories", { - "name": domain.name + "base": conf.namespace_base, + } + ); + }; + const name_repository_function = function (fully_qualified, domain, action) : string { + return lib_plankton.string.coin( + "{{prefix}}{{action}}", + { + "prefix": ( + fully_qualified + ? namespace_repository(domain) + : "" + ), + "action": action, } ); }; - const name_repository_function_create = function (domain) : string { - return lib_plankton.string.coin( - "repository_{{name}}_create", - { - "name": domain.name - } - ); - }; - const name_repository_function_update = function (domain) : string { - return lib_plankton.string.coin( - "repository_{{name}}_update", - { - "name": domain.name - } - ); - }; - const name_repository_function_delete = function (domain) : string { - return lib_plankton.string.coin( - "repository_{{name}}_delete", - { - "name": domain.name - } - ); - }; - return ( - // base - "declare var require;\n" - + - prog_output.render_program( - new lib_plankton.prog.struct_program( - [] - /* - // conf - .concat( - [ - new lib_plankton.prog.struct_statement_declaration( - false, - "conf", - new lib_plankton.prog.struct_type_record( - [ - { - "name": "database_path", - "type": new lib_plankton.prog.struct_type_string(), - "mandatory": true, - }, - { - "name": "server_port", - "type": new lib_plankton.prog.struct_type_string(), - "mandatory": true, - }, - ] - ), - null - ), - ] - ) - */ - // entities - .concat( - input_data["domains"] - .map( - (domain) => new lib_plankton.prog.struct_statement_type_definition( - name_type(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, - }) - ) - ) - ) - ) - ) - // repositories - .concat( + + return lib_plankton.string.coin( + await get_template("master"), + { + "namespace_base": conf.namespace_base, + "entities": ( + (await Promise.all( input_data["domains"] .map( (domain) => ( - (domain.key_field === null) - ? [ - // TODO - ] - : [ - // list - new lib_plankton.prog.struct_statement_function_definition( - name_repository_function_list(domain), - [], - new lib_plankton.prog.struct_type_construction( - "Promise", - [ - new lib_plankton.prog.struct_type_construction( - "Array", - [ + 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( - [ - { - "name": "key", - "type": new lib_plankton.prog.struct_type_integer(), - "mandatory": true, - }, - { - "name": "value", - "type": new lib_plankton.prog.struct_type_construction( - name_type(domain), - null - ), - "mandatory": true, - }, - ] - ), - ] - ) - ] - ), - [ - new lib_plankton.prog.struct_statement_return( - // TODO - new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_variable("lib_plankton.sqlite.query_get"), - [ - new lib_plankton.prog.struct_expression_fieldaccess(new lib_plankton.prog.struct_expression_variable("conf"), "database_path"), - new lib_plankton.prog.struct_expression_dict( - [ - { - "key": "template", - "value": new lib_plankton.prog.struct_expression_literal( - lib_plankton.string.coin( - "SELECT {{fields}} FROM {{name}};", - { - "fields": ( - [domain.key_field.name] - .concat(domain.data_fields.map(field => field.name)) - .join(",") - ), - "name": name_table(domain), - } + 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 ) ), - }, - { - "key": "arguments", - "value": new lib_plankton.prog.struct_expression_dict( - [ - ] - ), - }, - ] - ), - ] - ), - "then" - ), - [ - new lib_plankton.prog.struct_expression_abstraction( - [ - { - "name": "rows", - "type": null, - }, - ], - null, - [ - new lib_plankton.prog.struct_statement_return( - new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable( - "rows" - ), - "map" - ), - [ - new lib_plankton.prog.struct_expression_abstraction( - [ - { - "name": "row", - "type": null, - }, - ], - null, - [ - new lib_plankton.prog.struct_statement_return( - 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) - ) - }) - ) - ), - }, - ] - ) - ), - ] - ), - ] - ) - ), - ] - ), - ] - ), - ), - ] - ), - // read - new lib_plankton.prog.struct_statement_function_definition( - name_repository_function_read(domain), - [ - { - "name": "key", - "type": new lib_plankton.prog.struct_type_integer( - ), - }, - ], - new lib_plankton.prog.struct_type_construction( - "Promise", - [ - new lib_plankton.prog.struct_type_construction( - name_type(domain), - null - ), - ] - ), - [ - new lib_plankton.prog.struct_statement_return( - // TODO - new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_variable("lib_plankton.sqlite.query_get"), - [ - new lib_plankton.prog.struct_expression_fieldaccess(new lib_plankton.prog.struct_expression_variable("conf"), "database_path"), - new lib_plankton.prog.struct_expression_dict( - [ - { - "key": "template", - "value": new lib_plankton.prog.struct_expression_literal( - lib_plankton.string.coin( - "SELECT {{fields}} FROM {{name}} WHERE ({{key}} = :key);", - { - "fields": ( - [] - .concat(domain.data_fields.map(field => field.name)) - .join(",") - ), - "name": name_table(domain), - "key": domain.key_field.name, - } - ) - ), - }, - { - "key": "arguments", - "value": new lib_plankton.prog.struct_expression_dict( - [ - { - "key": "key", - "value": new lib_plankton.prog.struct_expression_variable("key"), - }, - ] - ), - }, - ] - ), - ] - ), - "then" - ), - [ - new lib_plankton.prog.struct_expression_abstraction( - [ - { - "name": "rows", - "type": null, - }, - ], - null, - [ - new lib_plankton.prog.struct_statement_declaration( - true, - "row", - null, - new lib_plankton.prog.struct_expression_projection( - new lib_plankton.prog.struct_expression_variable("rows"), - new lib_plankton.prog.struct_expression_literal(0), - ) - ), - new lib_plankton.prog.struct_statement_return( - 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) - ) - }) + map_primitive_type(data_field["type"]) ) - ) - ), - ] - ), - ] - ) - ), - ] - ), - // create - new lib_plankton.prog.struct_statement_function_definition( - name_repository_function_create(domain), - [ - { - "name": "value", - "type": new lib_plankton.prog.struct_type_construction( - name_type(domain), - null - ), - }, - ], - new lib_plankton.prog.struct_type_construction( - "Promise", - [ - new lib_plankton.prog.struct_type_integer( - ), - ] - ), - [ - new lib_plankton.prog.struct_statement_return( - new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_variable("lib_plankton.sqlite.query_put"), - [ - new lib_plankton.prog.struct_expression_fieldaccess(new lib_plankton.prog.struct_expression_variable("conf"), "database_path"), - new lib_plankton.prog.struct_expression_dict( - [ - { - "key": "template", - "value": new lib_plankton.prog.struct_expression_literal( - lib_plankton.string.coin( - "INSERT INTO {{name}}({{fields}}) VALUES ({{values}});", - { - "name": name_table(domain), - "fields": ( - domain.data_fields - .map(field => field.name) - .join(",") - ), - "values": ( - domain.data_fields - .map(field => (":" + field.name)) - .join(",") - ), - } - ) - ), - }, - { - "key": "arguments", - "value": 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, - ), - }) - ) - ), - }, - ] - ), - ] - ), - "then" - ), - [ - new lib_plankton.prog.struct_expression_abstraction( - [ - { - "name": "result", - "type": null, - } - ], - null, - [ - new lib_plankton.prog.struct_statement_return( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable("result"), - "id" - ) - ), - ] - ), - ] - ) - ), - ] - ), - // update - new lib_plankton.prog.struct_statement_function_definition( - name_repository_function_update(domain), - [ - { - "name": "key", - "type": new lib_plankton.prog.struct_type_integer( - ), - }, - { - "name": "value", - "type": new lib_plankton.prog.struct_type_construction( - name_type(domain), - null - ), - }, - ], - new lib_plankton.prog.struct_type_construction( - "Promise", - [ - new lib_plankton.prog.struct_type_void( - ), - ] - ), - [ - new lib_plankton.prog.struct_statement_return( - new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_variable("lib_plankton.sqlite.query_put"), - [ - new lib_plankton.prog.struct_expression_fieldaccess(new lib_plankton.prog.struct_expression_variable("conf"), "database_path"), - new lib_plankton.prog.struct_expression_dict( - [ - { - "key": "template", - "value": new lib_plankton.prog.struct_expression_literal( - lib_plankton.string.coin( - "UPDATE {{name}} SET {{settings}} WHERE ({{key}} = :key);", - { - "name": name_table(domain), - "key": domain.key_field.name, - "settings": ( - domain.data_fields - .map( - field => lib_plankton.string.coin( - "{{key}} = {{value}}", - { - "key": field.name, - "value": (":" + ("value_" + field.name)), - } - ) - ) - .join(", ") - ), - } - ) - ), - }, - { - "key": "arguments", - "value": 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, - ), - }) - ) - ) - ), - }, - ] - ), - ] - ), - "then" - ), - [ - new lib_plankton.prog.struct_expression_abstraction( - [ - { - "name": "result", - "type": null, - } - ], - null, - [ - ] - ), - ] - ) - ), - ] - ), - // delete - new lib_plankton.prog.struct_statement_function_definition( - name_repository_function_delete(domain), - [ - { - "name": "key", - "type": new lib_plankton.prog.struct_type_integer( - ), - }, - ], - new lib_plankton.prog.struct_type_construction( - "Promise", - [ - new lib_plankton.prog.struct_type_void(), - ] - ), - [ - new lib_plankton.prog.struct_statement_return( - new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_variable("lib_plankton.sqlite.query_put"), - [ - new lib_plankton.prog.struct_expression_fieldaccess(new lib_plankton.prog.struct_expression_variable("conf"), "database_path"), - new lib_plankton.prog.struct_expression_dict( - [ - { - "key": "template", - "value": new lib_plankton.prog.struct_expression_literal( - lib_plankton.string.coin( - "DELETE FROM {{name}} WHERE ({{key}} = :key);", - { - "name": name_table(domain), - "key": domain.key_field.name, - } - ) - ), - }, - { - "key": "arguments", - "value": new lib_plankton.prog.struct_expression_dict( - [ - { - "key": "key", - "value": new lib_plankton.prog.struct_expression_variable("key"), - }, - ] - ), - }, - ] - ), - ] - ), - "then" - ), - [ - new lib_plankton.prog.struct_expression_abstraction( - [ - { - "name": "result", - "type": null, - } - ], - null, - [ - ] - ), - ] - ) - ), - ] - ), - ] - ) - ) - .reduce( - (x, y) => x.concat(y), - [] - ) - ) - // main - .concat( - [ - new lib_plankton.prog.struct_statement_function_definition( - "main", - [ - ], - new lib_plankton.prog.struct_type_void(), - ( - [] - // misc - .concat( - [ - new lib_plankton.prog.struct_statement_procedure_call( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable( - "lib_plankton" - ), - "log" - ), - "conf_push" - ), - [ - new lib_plankton.prog.struct_expression_list( - [ - new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable( - "new lib_plankton" // TODO: HACK! - ), - "log" + : map_primitive_type(data_field["type"]) ), - "class_channel_stdout" - ), - [ - ] - ), - ] - ) - ] - ), - ] - ) - // api - .concat( - [ - new lib_plankton.prog.struct_statement_comment( - false, - [ - "define api", - ] - ), - new lib_plankton.prog.struct_statement_declaration( - true, - "rest", - new lib_plankton.prog.struct_type_construction( - "lib_plankton.rest.type_rest", - null - ), - new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable("lib_plankton"), - "rest" - ), - "make" - ), - [ - new lib_plankton.prog.struct_expression_dict( - [ - { - "key": "set_access_control_headers", - "value": new lib_plankton.prog.struct_expression_literal(true), - }, - ] - ), - ] - ), - ), - new lib_plankton.prog.struct_statement_block( - [ - new lib_plankton.prog.struct_statement_comment( - false, - [ - "meta", - ] - ), - new lib_plankton.prog.struct_statement_block( - [ - new lib_plankton.prog.struct_statement_procedure_call( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable( - "lib_plankton" - ), - "rest" - ), - "register" - ), - [ - new lib_plankton.prog.struct_expression_variable("rest"), - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable( - "lib_plankton" - ), - "http" - ), - "enum_method" - ), - "get" - ), - new lib_plankton.prog.struct_expression_literal( - "/_spec" - ), - new lib_plankton.prog.struct_expression_dict( - [ - { - "key": "execution", - "value": new lib_plankton.prog.struct_expression_abstraction( - [ - { - "name": "stuff", - "type": null, - } - ], - null, - [ - new lib_plankton.prog.struct_statement_return( - new lib_plankton.prog.struct_expression_dict( - [ - { - "key": "status_code", - "value": new lib_plankton.prog.struct_expression_literal(200), - }, - { - "key": "data", - "value": new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable( - "lib_plankton" - ), - "rest" - ), - "to_oas" - ), - [ - new lib_plankton.prog.struct_expression_variable( - "rest" - ), - ] - ), - } - ] - ) - ), - ], - { - "async": true, - } - ), - }, - ] - ), - ] - ), - ] - ), - ] - .concat( - input_data["domains"] - .map( - domain => new lib_plankton.prog.struct_statement_block( - [ - new lib_plankton.prog.struct_statement_comment( - false, - [ - ("domain:" + domain.name), - ] - ), - // list - new lib_plankton.prog.struct_statement_procedure_call( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable( - "lib_plankton" - ), - "rest" - ), - "register" - ), - [ - new lib_plankton.prog.struct_expression_variable("rest"), - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable( - "lib_plankton" - ), - "http" - ), - "enum_method" - ), - "get" - ), - new lib_plankton.prog.struct_expression_literal( - lib_plankton.string.coin( - "/{{name}}", - { - "name": domain.name, - } - ) - ), - new lib_plankton.prog.struct_expression_dict( - [ - { - "key": "execution", - "value": new lib_plankton.prog.struct_expression_abstraction( - [ - { - "name": "stuff", - "type": null, - } - ], - null, - [ - new lib_plankton.prog.struct_statement_return( - new lib_plankton.prog.struct_expression_dict( - [ - { - "key": "status_code", - "value": new lib_plankton.prog.struct_expression_literal(200), - }, - { - "key": "data", - "value": new lib_plankton.prog.struct_expression_await( - new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_variable(name_repository_function_list(domain)), - [ - ] - ) - ), - } - ] - ) - ), - ], - { - "async": true, - } - ), - } - // TODO - ] - ), - ] - ), - // get - new lib_plankton.prog.struct_statement_procedure_call( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable( - "lib_plankton" - ), - "rest" - ), - "register" - ), - [ - new lib_plankton.prog.struct_expression_variable("rest"), - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable( - "lib_plankton" - ), - "http" - ), - "enum_method" - ), - "get" - ), - new lib_plankton.prog.struct_expression_literal( - lib_plankton.string.coin( - "/{{name}}/:id", - { - "name": domain.name, - } - ) - ), - new lib_plankton.prog.struct_expression_dict( - [ - { - "key": "execution", - "value": new lib_plankton.prog.struct_expression_abstraction( - [ - { - "name": "stuff", - "type": null, - } - ], - null, - [ - new lib_plankton.prog.struct_statement_return( - new lib_plankton.prog.struct_expression_dict( - [ - { - "key": "status_code", - "value": new lib_plankton.prog.struct_expression_literal(200), - }, - { - "key": "data", - "value": new lib_plankton.prog.struct_expression_await( - new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_variable(name_repository_function_read(domain)), - [ - new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_variable("parseInt"), - [ - new lib_plankton.prog.struct_expression_projection( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable("stuff"), - "path_parameters" - ), - new lib_plankton.prog.struct_expression_literal("id") - ), - ] - ), - ] - ) - ), - } - ] - ) - ), - ], - { - "async": true, - } - ), - } - ] - ), - ] - ), - // add - new lib_plankton.prog.struct_statement_procedure_call( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable( - "lib_plankton" - ), - "rest" - ), - "register" - ), - [ - new lib_plankton.prog.struct_expression_variable("rest"), - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable( - "lib_plankton" - ), - "http" - ), - "enum_method" - ), - "post" - ), - new lib_plankton.prog.struct_expression_literal( - lib_plankton.string.coin( - "/{{name}}", - { - "name": domain.name, - } - ) - ), - new lib_plankton.prog.struct_expression_dict( - [ - { - "key": "execution", - "value": new lib_plankton.prog.struct_expression_abstraction( - [ - { - "name": "stuff", - "type": null, - } - ], - null, - [ - new lib_plankton.prog.struct_statement_declaration( - true, - "id", - null, - new lib_plankton.prog.struct_expression_await( - new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_variable(name_repository_function_create(domain)), - [ - new lib_plankton.prog.struct_expression_cast( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable("stuff"), - "input" - ), - new lib_plankton.prog.struct_type_construction( - name_type(domain), - null - ), - ), - ] - ) - ) - ), - new lib_plankton.prog.struct_statement_return( - new lib_plankton.prog.struct_expression_dict( - [ - { - "key": "status_code", - "value": new lib_plankton.prog.struct_expression_literal(201), - }, - { - "key": "data", - "value": new lib_plankton.prog.struct_expression_variable("id"), - } - ] - ) - ), - ], - { - "async": true, - } - ), - } - ] - ), - ] - ), - // change - new lib_plankton.prog.struct_statement_procedure_call( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable( - "lib_plankton" - ), - "rest" - ), - "register" - ), - [ - new lib_plankton.prog.struct_expression_variable("rest"), - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable( - "lib_plankton" - ), - "http" - ), - "enum_method" - ), - "patch" - ), - new lib_plankton.prog.struct_expression_literal( - lib_plankton.string.coin( - "/{{name}}/:id", - { - "name": domain.name, - } - ) - ), - new lib_plankton.prog.struct_expression_dict( - [ - { - "key": "execution", - "value": new lib_plankton.prog.struct_expression_abstraction( - [ - { - "name": "stuff", - "type": null, - } - ], - null, - [ - new lib_plankton.prog.struct_statement_declaration( - true, - "dummy", - null, - new lib_plankton.prog.struct_expression_await( - new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_variable(name_repository_function_update(domain)), - [ - new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_variable("parseInt"), - [ - new lib_plankton.prog.struct_expression_projection( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable("stuff"), - "path_parameters" - ), - new lib_plankton.prog.struct_expression_literal("id") - ), - ] - ), - new lib_plankton.prog.struct_expression_cast( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable("stuff"), - "input" - ), - new lib_plankton.prog.struct_type_construction( - name_type(domain), - null - ), - ), - ] - ) - ) - ), - new lib_plankton.prog.struct_statement_return( - new lib_plankton.prog.struct_expression_dict( - [ - { - "key": "status_code", - "value": new lib_plankton.prog.struct_expression_literal(200), - }, - { - "key": "data", - "value": new lib_plankton.prog.struct_expression_literal(null), - } - ] - ) - ), - ], - { - "async": true, - } - ), - } - ] - ), - ] - ), - // remove - new lib_plankton.prog.struct_statement_procedure_call( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable( - "lib_plankton" - ), - "rest" - ), - "register" - ), - [ - new lib_plankton.prog.struct_expression_variable("rest"), - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable( - "lib_plankton" - ), - "http" - ), - "enum_method" - ), - "delete" - ), - new lib_plankton.prog.struct_expression_literal( - lib_plankton.string.coin( - "/{{name}}/:id", - { - "name": domain.name, - } - ) - ), - new lib_plankton.prog.struct_expression_dict( - [ - { - "key": "execution", - "value": new lib_plankton.prog.struct_expression_abstraction( - [ - { - "name": "stuff", - "type": null, - } - ], - null, - [ - new lib_plankton.prog.struct_statement_declaration( - true, - "dummy", - null, - new lib_plankton.prog.struct_expression_await( - new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_variable(name_repository_function_delete(domain)), - [ - new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_variable("parseInt"), - [ - new lib_plankton.prog.struct_expression_projection( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable("stuff"), - "path_parameters" - ), - new lib_plankton.prog.struct_expression_literal("id") - ), - ] - ), - ] - ) - ) - ), - new lib_plankton.prog.struct_statement_return( - new lib_plankton.prog.struct_expression_dict( - [ - { - "key": "status_code", - "value": new lib_plankton.prog.struct_expression_literal(200), - }, - { - "key": "data", - "value": new lib_plankton.prog.struct_expression_literal(null), - }, - ] - ) - ), - ], - { - "async": true, - } - ), - } - ] - ), - ] - ), - ] + "mandatory": true, + }) + ) ) - ) + ), + { + "level": 2, + } ) ) - ] - ) - // server - .concat( - [ - new lib_plankton.prog.struct_statement_comment( - false, - [ - "setup server", - ] - ), - new lib_plankton.prog.struct_statement_declaration( - true, - "server", - null, // TODO - new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable("lib_plankton"), - "server" - ), - "make" - ), - [ - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable("conf"), - "server_port" - ), - new lib_plankton.prog.struct_expression_abstraction( - [ - { - "name": "input", - "type": null, - }, - ], - null, - [ - new lib_plankton.prog.struct_statement_declaration( - true, - "http_request", - new lib_plankton.prog.struct_type_construction( - "lib_plankton.http.type_request", - null - ), - new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable("lib_plankton"), - "http" - ), - "decode_request" - ), - [ - new lib_plankton.prog.struct_expression_variable("input"), - ] - ) - ), - new lib_plankton.prog.struct_statement_declaration( - true, - "http_response", - new lib_plankton.prog.struct_type_construction( - "lib_plankton.http.type_response", - null - ), - new lib_plankton.prog.struct_expression_await( - new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable("lib_plankton"), - "rest" - ), - "call" - ), - [ - new lib_plankton.prog.struct_expression_variable("rest"), - new lib_plankton.prog.struct_expression_variable("http_request"), - ] - ) - ) - ), - new lib_plankton.prog.struct_statement_return( - new lib_plankton.prog.struct_expression_function_application( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable("lib_plankton"), - "http" - ), - "encode_response" - ), - [ - new lib_plankton.prog.struct_expression_variable("http_response"), - ] - ) - ), - ], - { - "async": true, - } - ), - ] - ) - ), - new lib_plankton.prog.struct_statement_procedure_call( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_fieldaccess( - new lib_plankton.prog.struct_expression_variable("lib_plankton"), - "server" - ), - "start" - ), - [ - new lib_plankton.prog.struct_expression_variable("server") - ] - ), - ] + } ) ) - ), - ] - ) - ) - ) + ) + ) + )).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) + ) + }) + ) + ), + }, + ] + ), + { + "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"), + } + ) + ) + ) + ) + )) + .join("") + ), + "api": ( + (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"), + } + ) + ) + ) + ) + )) + .join("") + ), + } ); } @@ -1441,6 +333,6 @@ _sindri.add_output( _sindri.enum_realm.backend, "typescript", { - "render": (x) => Promise.resolve(_sindri.outputs.backend.typescript.render(x)), + "render": _sindri.outputs.backend.typescript.render, } ); diff --git a/source/outputs/backend/typescript/templates/api.ts.tpl b/source/outputs/backend/typescript/templates/api.ts.tpl new file mode 100644 index 0000000..bb7d22d --- /dev/null +++ b/source/outputs/backend/typescript/templates/api.ts.tpl @@ -0,0 +1,88 @@ + // {{domain_name}} + { + lib_plankton.rest.register( + rest, + lib_plankton.http.enum_method.get, + "/{{path_base}}{{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, + "/{{path_base}}{{domain_name}}/:id", + { + "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, + "/{{path_base}}{{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, + "/{{path_base}}{{domain_name}}/:id", + { + "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, + "/{{path_base}}{{domain_name}}/:id", + { + "execution": async function (stuff) { + const dummy = await {{repository_function_delete}}( + parseInt( + stuff.path_parameters["id"] + ) + ); + return { + "status_code": 200, + "data": null + }; + } + } + ); + } diff --git a/source/outputs/backend/typescript/templates/entity.ts.tpl b/source/outputs/backend/typescript/templates/entity.ts.tpl new file mode 100644 index 0000000..6738910 --- /dev/null +++ b/source/outputs/backend/typescript/templates/entity.ts.tpl @@ -0,0 +1,4 @@ + export namespace {{domain_name}} + { +{{defs}} + } diff --git a/source/outputs/backend/typescript/templates/master.ts.tpl b/source/outputs/backend/typescript/templates/master.ts.tpl new file mode 100644 index 0000000..885b8e8 --- /dev/null +++ b/source/outputs/backend/typescript/templates/master.ts.tpl @@ -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( + 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 + ); + } +} diff --git a/source/outputs/backend/typescript/templates/repository.ts.tpl b/source/outputs/backend/typescript/templates/repository.ts.tpl new file mode 100644 index 0000000..2952023 --- /dev/null +++ b/source/outputs/backend/typescript/templates/repository.ts.tpl @@ -0,0 +1,121 @@ + export namespace {{domain_name}} + { + + // list + export function {{list_function_name}}( + ) : Promise> + { + return ( + lib_plankton.sqlite.query_get( + conf.database_path, + { + "template": "SELECT {{list_query_fields}} FROM {{table_name}};", + "arguments": { + + } + } + ) + .then( + function (rows) { + return rows.map( + function (row) { + return {{list_result}}; + } + ); + } + ) + ); + } + + // read + export function {{read_function_name}}( + key : number + ) : Promise<{{type_name}}> + { + return ( + lib_plankton.sqlite.query_get( + conf.database_path, + { + "template": "SELECT {{read_query_fields}} FROM {{table_name}} WHERE (id = :key);", + "arguments": { + "key": key + } + } + ) + .then( + function (rows) { + const row = rows[0]; + return {{read_result_fields}}; + } + ) + ); + } + + // create + export function {{create_function_name}}( + value : {{type_name}} + ) : Promise + { + return ( + lib_plankton.sqlite.query_put( + conf.database_path, + { + "template": "INSERT INTO {{table_name}}({{create_query_field_names}}) VALUES ({{create_query_field_placeholders}});", + "arguments": {{create_query_field_values}} + } + ) + .then( + function (result) { + return result.id; + } + ) + ); + } + + // update + export function {{update_function_name}}( + key : number, + value : {{type_name}} + ) : Promise + { + return ( + lib_plankton.sqlite.query_put( + conf.database_path, + { + "template": "UPDATE {{table_name}} SET {{update_query_assignments}} WHERE (id = :key);", + "arguments": { + "key": key, + {{update_query_values}} + } + } + ) + .then( + function (result) { + } + ) + ); + } + + // delete + export function {{delete_function_name}}( + key : number + ) : Promise + { + return ( + lib_plankton.sqlite.query_put( + conf.database_path, + { + "template": "DELETE FROM {{table_name}} WHERE (id = :key);", + "arguments": { + "key": key + } + } + ) + .then( + function (result) { + } + ) + ); + } + + }