diff --git a/source/conf.ts b/source/conf.ts new file mode 100644 index 0000000..ace3388 --- /dev/null +++ b/source/conf.ts @@ -0,0 +1,120 @@ +/** + * @todo generate generic + */ +function schema( +) : any +{ + return { + "type": "object", + "additionalProperties": false, + "properties": { + "domains": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": ["null", "string"], + "default": null + }, + "key_field": { + "type": ["null","object"], + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": ["null", "string"], + "default": null + } + }, + "required": [ + "name" + ], + "default": null + }, + "data_fields": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": ["null", "string"], + "default": null + }, + "type": { + "type": "string", + "enum": [ + "boolean", + "integer", + "float", + "string_short", + "string_medium", + "string_long" + ] + }, + "nullable": { + "type": "boolean", + "default": true + }, + "default": { + "type": ["null", "boolean", "integer", "float", "string"], + "default": null + } + }, + "required": [ + "name", + "type" + ] + }, + "default": [] + }, + "constraints": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "kind": { + "type": "string", + "enum": [ + "unique", + "foreign_key" + ] + }, + "parameters": { + "type": "object", + "additionalProperties": "string", + "properties": { + }, + "required": [ + ] + } + }, + "required": [ + "kind" + ] + }, + "default": [] + } + }, + "required": [ + "name" + ] + } + } + }, + "required": [ + "domains" + ] + } +} diff --git a/source/main.ts b/source/main.ts index 2d16f30..15e7841 100644 --- a/source/main.ts +++ b/source/main.ts @@ -1,3 +1,5 @@ +/** + */ async function main( args_raw : Array ) : Promise @@ -21,22 +23,66 @@ async function main( }, "info": "output format", }), + "schema": new lib_args.class_argument({ + "name": "schema", + "type": lib_args.enum_type.boolean, + "kind": lib_args.enum_kind.volatile, + "mode": lib_args.enum_mode.replace, + "default": false, + "parameters": { + "indicators_long": ["schema"], + "indicators_short": ["s"], + }, + "info": "print sindri JSON schema to stdout and exit", + }), + "help": new lib_args.class_argument({ + "name": "help", + "type": lib_args.enum_type.boolean, + "kind": lib_args.enum_kind.volatile, + "mode": lib_args.enum_mode.replace, + "default": false, + "parameters": { + "indicators_long": ["help"], + "indicators_short": ["h"], + }, + "info": "print help to stdout and exit", + }), } ); const args : Record = arg_handler.read(lib_args.enum_environment.cli, args_raw.join(" ")); - const input_content : string = await lib_plankton.file.read_stdin(); - const input_data : type_input_data = lib_json.decode(input_content); - - // TODO: sanitize & normalize input_data - - if (! outputs.hasOwnProperty(args["format"])) { - throw (new Error("unhandled output format: " + args["format"])); + if (args["help"]) { + process.stdout.write( + arg_handler.generate_help( + { + "programname": "sindri", + "author": "Christian Fraß ", + "description": "create data model scripts in different output formats (MySQL, SQLite, …) on basis of an abstract description; feed with .sindri.json file via stdin!", + "executable": "sindri", + } + ) + ); } else { - const output_content : string = outputs[args["format"]].render(input_data); - process.stdout.write(output_content); - // return Promise.resolve(undefined); + if (args["schema"]) { + process.stdout.write( + JSON.stringify(schema(), undefined, "\t") + ); + } + else { + const input_content : string = await lib_plankton.file.read_stdin(); + const input_data : type_input_data = lib_json.decode(input_content); + + // TODO: sanitize & normalize input_data + + if (! outputs.hasOwnProperty(args["format"])) { + throw (new Error("unhandled output format: " + args["format"])); + } + else { + const output_content : string = outputs[args["format"]].render(input_data); + process.stdout.write(output_content); + } + } } } diff --git a/tools/makefile b/tools/makefile index c0611a4..7be20ac 100644 --- a/tools/makefile +++ b/tools/makefile @@ -3,6 +3,7 @@ cmd_create_directory := mkdir --parents cmd_typescript_compile := tsc cmd_concatenate := cat +cmd_chmod := chmod cmd_echo := echo -e cmd_log := echo -e "--" @@ -10,21 +11,23 @@ cmd_log := echo -e "--" ## rules .PHONY: all -all: build/datamodel.js +all: build/sindri -temp/datamodel-unlinked.js: \ +temp/sindri-unlinked.js: \ lib/plankton/plankton.d.ts \ source/types.ts \ source/outputs/sqlite.ts \ source/outputs/mysql.ts \ +source/conf.ts \ source/main.ts @ ${cmd_log} "compiling …" @ ${cmd_create_directory} temp @ ${cmd_typescript_compile} $^ --lib es2020 --target es6 --outFile $@ -build/datamodel.js: lib/plankton/plankton.js temp/datamodel-unlinked.js +build/sindri: lib/plankton/plankton.js temp/sindri-unlinked.js @ ${cmd_log} "linking …" @ ${cmd_create_directory} build @ ${cmd_echo} "#!/usr/bin/env node\n" > temp/head.js @ ${cmd_concatenate} temp/head.js $^ > $@ + @ ${cmd_chmod} +x $@