add config
This commit is contained in:
@ -171,5 +171,6 @@
|
|||||||
],
|
],
|
||||||
"indent": "off",
|
"indent": "off",
|
||||||
"@typescript-eslint/indent": ["error", 2],
|
"@typescript-eslint/indent": ["error", 2],
|
||||||
|
"import/no-unresolved": [2, { "ignore": ["^@.+$"] }]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -11,7 +11,7 @@
|
|||||||
"editor.formatOnSave": false
|
"editor.formatOnSave": false
|
||||||
},
|
},
|
||||||
"[markdown]": {
|
"[markdown]": {
|
||||||
"editor.formatOnSave": false
|
"editor.formatOnSave": true
|
||||||
},
|
},
|
||||||
"search.exclude": {
|
"search.exclude": {
|
||||||
"**/node_modules": true,
|
"**/node_modules": true,
|
||||||
|
|||||||
@ -6,10 +6,11 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node --no-warnings --loader ./src/myloader.mjs --experimental-modules --es-module-specifier-resolution=node ./dist/server.js",
|
"start": "node --no-warnings --loader ./src/myloader.mjs --experimental-modules --es-module-specifier-resolution=node ./dist/server.js",
|
||||||
"dev": "node --no-warnings --loader ./src/myloader.mjs --experimental-modules --es-module-specifier-resolution=node ./src/server.ts",
|
"dev": "node --no-warnings --loader ./src/myloader.mjs --experimental-modules --es-module-specifier-resolution=node ./src/server.ts start --port 1234",
|
||||||
"build": "tsc -p tsconfig.json",
|
"build": "tsc -p tsconfig.json",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
"lint": "eslint --fix --ext ts src/"
|
"lint": "eslint --fix --ext ts src/",
|
||||||
|
"upgrade": "yarn upgrade --latest"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -24,6 +25,8 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@gquittet/graceful-server": "^2.5.2",
|
"@gquittet/graceful-server": "^2.5.2",
|
||||||
|
"args-command-parser": "^1.2.4",
|
||||||
|
"eslint-import-resolver-alias": "^1.1.2",
|
||||||
"fastify": "^3.25.3",
|
"fastify": "^3.25.3",
|
||||||
"fastify-sensible": "^3.1.2",
|
"fastify-sensible": "^3.1.2",
|
||||||
"winston": "^3.4.0"
|
"winston": "^3.4.0"
|
||||||
@ -34,6 +37,7 @@
|
|||||||
"@types/triple-beam": "^1.3.2",
|
"@types/triple-beam": "^1.3.2",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.10.0",
|
"@typescript-eslint/eslint-plugin": "^5.10.0",
|
||||||
"@typescript-eslint/parser": "^5.10.0",
|
"@typescript-eslint/parser": "^5.10.0",
|
||||||
|
"builder-pattern": "^1.3.0",
|
||||||
"eslint": "^8.7.0",
|
"eslint": "^8.7.0",
|
||||||
"eslint-plugin-import": "^2.25.4",
|
"eslint-plugin-import": "^2.25.4",
|
||||||
"eslint-plugin-promise": "^6.0.0",
|
"eslint-plugin-promise": "^6.0.0",
|
||||||
|
|||||||
@ -1,5 +0,0 @@
|
|||||||
class InfrastructureAutoLoadable {
|
|
||||||
public load (): void {console.log("TEST");}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default new InfrastructureAutoLoadable();
|
|
||||||
91
src/framework/configuration/ConfigurationDefinition.ts
Normal file
91
src/framework/configuration/ConfigurationDefinition.ts
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
export enum DefinitionType {
|
||||||
|
String = "string",
|
||||||
|
Boolean = "boolean",
|
||||||
|
File = "file",
|
||||||
|
Number = "number"
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConfigurationDefinition implements ConfigurationDefinition {
|
||||||
|
private name!: string;
|
||||||
|
private envName!: string;
|
||||||
|
private argName!: string[];
|
||||||
|
private validator!: string;
|
||||||
|
private description!: string;
|
||||||
|
private type!: DefinitionType;
|
||||||
|
private multiple = false;
|
||||||
|
private required = false;
|
||||||
|
|
||||||
|
public getName (): string {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getEnvName (): string {
|
||||||
|
return this.envName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getArgName (): string[] {
|
||||||
|
return this.argName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getValidator (): string {
|
||||||
|
return this.validator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getDescription (): string {
|
||||||
|
return this.description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getType (): DefinitionType {
|
||||||
|
return this.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getRequired (): boolean {
|
||||||
|
return this.required;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getMultiple (): boolean {
|
||||||
|
return this.multiple;
|
||||||
|
}
|
||||||
|
|
||||||
|
public withName (name: string): ConfigurationDefinition {
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public withEnvName (envName: string): ConfigurationDefinition {
|
||||||
|
this.envName = envName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public withArgName (...argName: string[]): ConfigurationDefinition {
|
||||||
|
this.argName = argName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public withValidator (validator: string): ConfigurationDefinition {
|
||||||
|
this.validator = validator;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public withDescription (description: string): ConfigurationDefinition {
|
||||||
|
this.description = description;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public withType (type: DefinitionType): ConfigurationDefinition {
|
||||||
|
this.type = type;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public isRequired (): ConfigurationDefinition {
|
||||||
|
this.required = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public isMultiple (): ConfigurationDefinition {
|
||||||
|
this.multiple = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ConfigurationDefinition;
|
||||||
149
src/framework/configuration/configuration.ts
Normal file
149
src/framework/configuration/configuration.ts
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
import ConfigurationDefinition, {DefinitionType} from "./ConfigurationDefinition";
|
||||||
|
import {parser, ArgCollection} from "args-command-parser";
|
||||||
|
|
||||||
|
const portDefinition = new ConfigurationDefinition()
|
||||||
|
.withName("port")
|
||||||
|
.withType(DefinitionType.Number)
|
||||||
|
.withArgName("port")
|
||||||
|
.withEnvName("port")
|
||||||
|
.withDescription("Port of the server.")
|
||||||
|
.isRequired()
|
||||||
|
.withValidator("");
|
||||||
|
|
||||||
|
class Configuration {
|
||||||
|
|
||||||
|
private readonly definitions: Map<string, ConfigurationDefinition> = new Map();
|
||||||
|
private readonly values: Map<string, string[] | undefined> = new Map();
|
||||||
|
private readonly defaultCommand: string;
|
||||||
|
private readonly envPrefix: string;
|
||||||
|
private readonly arguments: ArgCollection;
|
||||||
|
public constructor (defaultCommand: string, envPrefix: string, ...definitions: ConfigurationDefinition[]) {
|
||||||
|
this.arguments = parser();
|
||||||
|
for (const definition of definitions) {
|
||||||
|
this.definitions.set(definition.getName(), definition);
|
||||||
|
this.values.set(definition.getName(), this.getInternalValue(definition));
|
||||||
|
}
|
||||||
|
this.defaultCommand = defaultCommand;
|
||||||
|
this.envPrefix = envPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCommand (): string {
|
||||||
|
return this.arguments.data.commands.join(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
public getValue (name: string): string | string[] | boolean | boolean[] | number | number[] | undefined {
|
||||||
|
const def = this.definitions.get(name);
|
||||||
|
const value = this.values.get(name) ?? [];
|
||||||
|
switch ( def?.getType() ) {
|
||||||
|
case DefinitionType.Boolean: {
|
||||||
|
const result = this.toBoolean(value);
|
||||||
|
if(def.getMultiple()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return result[0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DefinitionType.Number: {
|
||||||
|
const result: number[] = this.toInteger(value);
|
||||||
|
if(def.getMultiple()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return result[0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DefinitionType.String: {
|
||||||
|
if(def.getMultiple()) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return value[0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public getBooleanValue (name: string): boolean | boolean[] | undefined {
|
||||||
|
const def = this.definitions.get(name);
|
||||||
|
if(def?.getType() == DefinitionType.Boolean) {
|
||||||
|
const value = this.values.get(name) ?? [];
|
||||||
|
const result: boolean[] = this.toBoolean(value);
|
||||||
|
if(def.getMultiple()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return result[0];
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getNumberValue (name: string): number | number[] | undefined {
|
||||||
|
const def = this.definitions.get(name);
|
||||||
|
if(def?.getType() == DefinitionType.Number) {
|
||||||
|
const value = this.values.get(name) ?? [];
|
||||||
|
const result: number[] = this.toInteger(value);
|
||||||
|
if(def.getMultiple()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return result[0];
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getStringValue (name: string): string | string[] | undefined {
|
||||||
|
const def = this.definitions.get(name);
|
||||||
|
if(def?.getType() == DefinitionType.String) {
|
||||||
|
const value = this.values.get(name) ?? [];
|
||||||
|
if(def.getMultiple()) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return value[0];
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
private toBoolean (value: string[]): boolean[] {
|
||||||
|
const result: boolean[] = [];
|
||||||
|
for (const v of value) {
|
||||||
|
result.push(v === "true" || v === "1" || v === "y");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private toInteger (value: string[]): number[] {
|
||||||
|
const result: number[] = [];
|
||||||
|
for (const v of value) {
|
||||||
|
const f = parseFloat(v); const i = parseInt(v);
|
||||||
|
result.push((f == i) ? i : f);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getInternalValue (def: ConfigurationDefinition): string[] | undefined {
|
||||||
|
let value = this.getArgValue(def);
|
||||||
|
value = (value === undefined)?this.getEnvValue(def):value;
|
||||||
|
if(value !== undefined) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getEnvValue (def: ConfigurationDefinition): string[] | undefined {
|
||||||
|
const value = process.env[this.envPrefix + "_" + def.getEnvName().toUpperCase()];
|
||||||
|
if(value !== undefined)
|
||||||
|
return [value];
|
||||||
|
else
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getArgValue (def: ConfigurationDefinition): string[] | undefined{
|
||||||
|
for (const arg of def.getArgName()) {
|
||||||
|
if(arg.length >= 2 && this.arguments.hasLongSwitch(arg)) {
|
||||||
|
return this.arguments.getLongSwitch(arg).values;
|
||||||
|
} else if (this.arguments.hasShortSwitch(arg)) {
|
||||||
|
return this.arguments.getShortSwitch(arg).values;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new Configuration("startServer", "ant", portDefinition);
|
||||||
@ -1,63 +1,46 @@
|
|||||||
import Fastify from "fastify";
|
import Fastify from "fastify";
|
||||||
import fastifySensible from "fastify-sensible";
|
import fastifySensible from "fastify-sensible";
|
||||||
import GracefulServer from "@gquittet/graceful-server";
|
import GracefulServer from "@gquittet/graceful-server";
|
||||||
import getlogger, {defaultLogger} from "@logger";
|
import getlogger from "@logger";
|
||||||
|
import configuration from "@configuration";
|
||||||
|
|
||||||
|
const serverLogger = getlogger("server");
|
||||||
|
console.log(configuration.getCommand());
|
||||||
|
serverLogger.warn("sss");
|
||||||
|
|
||||||
const fastify = Fastify({
|
const fastify = Fastify({
|
||||||
logger: true
|
logger: true
|
||||||
});
|
});
|
||||||
fastify.register(fastifySensible);
|
await fastify.register(fastifySensible);
|
||||||
|
|
||||||
const gracefulServer = GracefulServer(fastify.server);
|
const gracefulServer = GracefulServer(fastify.server);
|
||||||
|
|
||||||
gracefulServer.on(GracefulServer.READY, () => {
|
gracefulServer.on(GracefulServer.READY, () => {
|
||||||
console.log("Server is ready");
|
serverLogger.info("Server is ready");
|
||||||
});
|
});
|
||||||
|
|
||||||
gracefulServer.on(GracefulServer.SHUTTING_DOWN, () => {
|
gracefulServer.on(GracefulServer.SHUTTING_DOWN, () => {
|
||||||
console.log("Server is shutting down");
|
serverLogger.info("Server is shutting down");
|
||||||
});
|
});
|
||||||
|
|
||||||
gracefulServer.on(GracefulServer.SHUTDOWN, error => {
|
gracefulServer.on(GracefulServer.SHUTDOWN, (error: { message: string; }) => {
|
||||||
console.log("Server is down because of", error.message);
|
serverLogger.info("Server is down because of", error.message);
|
||||||
process.exit();
|
process.exit();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Declare a route
|
// Declare a route
|
||||||
fastify.get("/", function (request, reply) {
|
fastify.get("/", async function (request, reply) {
|
||||||
reply.send({ hello: "world" });
|
await reply.send({ hello: "world" });
|
||||||
});
|
});
|
||||||
|
|
||||||
// Run the server!
|
// Run the server!
|
||||||
const start = async () => {
|
const start = async (): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
await fastify.listen(3000);
|
await fastify.listen(<number>configuration.getNumberValue("port"));
|
||||||
gracefulServer.setReady();
|
gracefulServer.setReady();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
fastify.log.error(err);
|
serverLogger.error(err);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
start();
|
await start();
|
||||||
|
|
||||||
const c = function (): void {
|
|
||||||
const v = function (): void {
|
|
||||||
throw new Error("Oh no!");
|
|
||||||
};
|
|
||||||
return v();
|
|
||||||
};
|
|
||||||
|
|
||||||
const abc = getlogger("abc");
|
|
||||||
abc.info("Ich bin ein Test!");
|
|
||||||
abc.warn("Ich bin ein Test!");
|
|
||||||
try {
|
|
||||||
c();
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
abc.warn(e);
|
|
||||||
}
|
|
||||||
const xyz = getlogger("xyz");
|
|
||||||
xyz.error("Ich bin ein Test!");
|
|
||||||
xyz.error("Ich bin ein '%s' Test!", "test");
|
|
||||||
|
|
||||||
defaultLogger.error("Ich bin ein Test!");
|
|
||||||
@ -10,7 +10,8 @@
|
|||||||
"baseUrl": "./src/",
|
"baseUrl": "./src/",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@abc/*": ["abc/*"],
|
"@abc/*": ["abc/*"],
|
||||||
"@logger": ["framework/logger/logger"]
|
"@logger": ["framework/logger/logger"],
|
||||||
|
"@configuration": ["framework/configuration/configuration"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": ["src/**/*.ts"],
|
"include": ["src/**/*.ts"],
|
||||||
|
|||||||
Reference in New Issue
Block a user