Compare commits
3 Commits
2319347f03
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 5c1525588b | |||
| 3597548b4d | |||
|
f8e2210cc0
|
@ -139,7 +139,7 @@
|
|||||||
"private-static-method",
|
"private-static-method",
|
||||||
"private-method"
|
"private-method"
|
||||||
],
|
],
|
||||||
"order": "alphabetically"
|
"order": "as-written"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
6
.prettierrc
Normal file
6
.prettierrc
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"trailingComma": "es5",
|
||||||
|
"tabWidth": 2,
|
||||||
|
"semi": true,
|
||||||
|
"singleQuote": false
|
||||||
|
}
|
||||||
49
package.json
49
package.json
@ -5,8 +5,8 @@
|
|||||||
"main": "server.ts",
|
"main": "server.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node ./dist/app.js",
|
"start": "node --no-warnings --trace-warnings --es-module-specifier-resolution=node ./dist/app.js",
|
||||||
"dev": "cross-env TS_NODE_COMPILER=ttypescript node --no-warnings --loader ./src/myloader.mjs --experimental-modules --es-module-specifier-resolution=node ./src/app.ts",
|
"dev": "cross-env TS_NODE_COMPILER=ttypescript node --no-warnings --loader ./src/myloader.mjs --es-module-specifier-resolution=node ./src/app.ts",
|
||||||
"build": "ttsc -p tsconfig.json && tsc-alias -p tsconfig.json",
|
"build": "ttsc -p tsconfig.json && tsc-alias -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/",
|
||||||
@ -25,43 +25,44 @@
|
|||||||
"author": "Joshua Schnabel",
|
"author": "Joshua Schnabel",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@automapper/classes": "^8.3.0",
|
"@automapper/classes": "^8.5.0",
|
||||||
"@automapper/core": "^8.3.0",
|
"@automapper/core": "^8.5.0",
|
||||||
"@gquittet/graceful-server": "^2.5.2",
|
"@fastify/helmet": "9.1.0",
|
||||||
"@nestjs/common": "^8.4.3",
|
"@fastify/sensible": "^5.1.0",
|
||||||
"@nestjs/core": "^8.4.3",
|
"@gquittet/graceful-server": "^3.0.2",
|
||||||
"@nestjs/passport": "^8.2.1",
|
"@nestjs/common": "^9.0.2",
|
||||||
"@nestjs/platform-fastify": "^8.4.3",
|
"@nestjs/core": "^9.0.2",
|
||||||
|
"@nestjs/passport": "^9.0.0",
|
||||||
|
"@nestjs/platform-fastify": "^9.0.2",
|
||||||
"args-command-parser": "^1.2.4",
|
"args-command-parser": "^1.2.4",
|
||||||
"cli-color": "^2.0.1",
|
"cli-color": "^2.0.3",
|
||||||
"fastify": "^3.25.3",
|
"fastify-helmet": "^7.1.0",
|
||||||
"fastify-plugin": "^3.0.0",
|
"fastify-plugin": "^3.0.0",
|
||||||
"fastify-sensible": "^3.1.2",
|
"passport": "^0.6.0",
|
||||||
"passport": "^0.5.2",
|
|
||||||
"passport-http": "^0.3.0",
|
"passport-http": "^0.3.0",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"rxjs": "^7.5.5",
|
"rxjs": "^7.5.5",
|
||||||
"winston": "^3.4.0"
|
"typescript-rtti": "^0.8.0",
|
||||||
|
"winston": "^3.8.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tsconfig/node16": "^1.0.2",
|
"@tsconfig/node16": "^1.0.3",
|
||||||
"@types/cli-color": "^2.0.2",
|
"@types/cli-color": "^2.0.2",
|
||||||
"@types/node": "^17.0.9",
|
"@types/node": "^18.0.3",
|
||||||
"@types/passport": "^1.0.7",
|
"@types/passport": "^1.0.9",
|
||||||
"@types/passport-http": "^0.3.9",
|
"@types/passport-http": "^0.3.9",
|
||||||
"@types/triple-beam": "^1.3.2",
|
"@types/triple-beam": "^1.3.2",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.10.0",
|
"@typescript-eslint/eslint-plugin": "^5.30.5",
|
||||||
"@typescript-eslint/parser": "^5.10.0",
|
"@typescript-eslint/parser": "^5.30.5",
|
||||||
"builder-pattern": "^1.3.0",
|
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"eslint": "^8.7.0",
|
"eslint": "^8.19.0",
|
||||||
"eslint-import-resolver-alias": "^1.1.2",
|
"eslint-import-resolver-alias": "^1.1.2",
|
||||||
"eslint-plugin-import": "^2.25.4",
|
"eslint-plugin-import": "^2.25.4",
|
||||||
"eslint-plugin-promise": "^6.0.0",
|
"eslint-plugin-promise": "^6.0.0",
|
||||||
"eslint-plugin-unused-imports": "^2.0.0",
|
"eslint-plugin-unused-imports": "^2.0.0",
|
||||||
"ts-node": "^10.4.0",
|
"ts-node": "^10.8.2",
|
||||||
"tsc-alias": "^1.6.6",
|
"tsc-alias": "^1.6.11",
|
||||||
"ttypescript": "^1.5.13",
|
"ttypescript": "^1.5.13",
|
||||||
"typescript": "^4.5.4"
|
"typescript": "^4.7.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,15 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-magic-numbers */
|
/* eslint-disable @typescript-eslint/no-magic-numbers */
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
|
import "reflect-metadata";
|
||||||
import clc from "cli-color";
|
import clc from "cli-color";
|
||||||
import App, { AppCommand } from "#app";
|
import App, { AppCommand } from "#app";
|
||||||
import ConfigurationDefinition, { DefinitionType } from "#configuration/configurationDefinition";
|
import ConfigurationDefinition, { DefinitionType } from "#configuration/configurationDefinition";
|
||||||
import definitionValidators from "#configuration/configurationValidatior";
|
import definitionValidators from "#configuration/configurationValidatior";
|
||||||
import Server from "#framework/server/server";
|
import Server from "#framework/server/server";
|
||||||
import getlogger, { defaultLogger } from "#logger";
|
import getlogger, { defaultLogger } from "#logger";
|
||||||
|
import {Builder} from "#framework/builder/builder";
|
||||||
|
|
||||||
|
const x = Builder<App>(Server);
|
||||||
|
|
||||||
const app: App = new (class extends App {
|
const app: App = new (class extends App {
|
||||||
public options (setDefinitions: (...definitions: ConfigurationDefinition[]) => void): void {
|
public options (setDefinitions: (...definitions: ConfigurationDefinition[]) => void): void {
|
||||||
|
|||||||
@ -17,15 +17,15 @@ export class RepoId extends Identifier<string> {
|
|||||||
export default class Repo extends Aggregate<RepoId>{
|
export default class Repo extends Aggregate<RepoId>{
|
||||||
|
|
||||||
private readonly _id?: RepoId;
|
private readonly _id?: RepoId;
|
||||||
private readonly _name: string;
|
private _name = "";
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
|
||||||
|
private readonly _count = 1;
|
||||||
|
|
||||||
private readonly _userAssignment: UserAssignment[] = [];
|
private readonly _userAssignment: UserAssignment[] = [];
|
||||||
|
|
||||||
public constructor (id: RepoId| undefined, name: string, userAssignment: UserAssignment[]) {
|
public constructor (id: RepoId | undefined) {
|
||||||
super();
|
super();
|
||||||
this._id = id;
|
this._id = id;
|
||||||
this._name = name;
|
|
||||||
this._userAssignment = userAssignment;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public get id (): RepoId | undefined {
|
public get id (): RepoId | undefined {
|
||||||
@ -36,6 +36,10 @@ export default class Repo extends Aggregate<RepoId>{
|
|||||||
return this._name;
|
return this._name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public set name (name: string) {
|
||||||
|
this._name = name;
|
||||||
|
}
|
||||||
|
|
||||||
public get path (): string {
|
public get path (): string {
|
||||||
return "/" + this._name;
|
return "/" + this._name;
|
||||||
}
|
}
|
||||||
@ -44,17 +48,16 @@ export default class Repo extends Aggregate<RepoId>{
|
|||||||
return this._userAssignment;
|
return this._userAssignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
public addUserAssignment (userAssignment: UserAssignment): void {
|
public addUserAssignment (ua: UserAssignment): UserAssignment[] {
|
||||||
this._userAssignment.push(userAssignment);
|
this._userAssignment.push(ua);
|
||||||
|
return this._userAssignment;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public removeUserAssignment (userAssignment: UserAssignment): void {
|
export interface IRepoBuider {
|
||||||
this._userAssignment.filter(item => item !== userAssignment);
|
name: string;
|
||||||
}
|
id: RepoId;
|
||||||
|
addUserAssignment: UserAssignment;
|
||||||
// public static builder (): IBuilder<Repo> {
|
|
||||||
// return <IBuilder<Repo>> <unknown>Builder(Repo);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class RepoIdGenerator implements IdentifierGenerator<RepoId> {
|
export class RepoIdGenerator implements IdentifierGenerator<RepoId> {
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { ValueObject } from "#ddd";
|
|||||||
import { UserId } from "../user/user.entity";
|
import { UserId } from "../user/user.entity";
|
||||||
// import { Builder, IBuilder } from "builder-pattern";
|
// import { Builder, IBuilder } from "builder-pattern";
|
||||||
|
|
||||||
enum UserRight {
|
export enum UserRight {
|
||||||
Read = "read",
|
Read = "read",
|
||||||
AppendOnly = "append",
|
AppendOnly = "append",
|
||||||
Write = "write"
|
Write = "write"
|
||||||
@ -13,7 +13,7 @@ export class UserAssignment extends ValueObject {
|
|||||||
|
|
||||||
private readonly _userId: UserId;
|
private readonly _userId: UserId;
|
||||||
|
|
||||||
private constructor (userId: UserId, right: UserRight) {
|
public constructor (userId: UserId, right: UserRight) {
|
||||||
super();
|
super();
|
||||||
this._userId = userId;
|
this._userId = userId;
|
||||||
this._right = right;
|
this._right = right;
|
||||||
|
|||||||
@ -25,8 +25,8 @@ export default class User extends Aggregate<UserId>{
|
|||||||
public get password (): string {
|
public get password (): string {
|
||||||
return this._password;
|
return this._password;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class UserId extends Identifier<string> {
|
export class UserId extends Identifier<string> {
|
||||||
private readonly _value: string;
|
private readonly _value: string;
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import User, { UserId } from "./user.entity";
|
import User, { UserId } from "./user.entity";
|
||||||
import {Repository} from "#ddd";
|
import {Repository} from "#ddd";
|
||||||
|
|
||||||
|
export const UserRepositoryToken = "UserRepository";
|
||||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||||
export default interface UserRepository extends Repository<UserId, User> {}
|
export interface UserRepository extends Repository<UserId, User> {}
|
||||||
|
|||||||
@ -9,8 +9,8 @@ export default class RepoFilePersistence implements RepoRepository {
|
|||||||
|
|
||||||
public constructor () {
|
public constructor () {
|
||||||
const x = new RepoId("xxxx");
|
const x = new RepoId("xxxx");
|
||||||
const y = Repo.instantiate(x, "/xxx");
|
// const y = Repo.builder().id(x).name("dddd").build();
|
||||||
this.values.set(x, y);
|
// this.values.set(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public deleteAggregate (aggregate: Repo): void {
|
public deleteAggregate (aggregate: Repo): void {
|
||||||
@ -36,8 +36,9 @@ export default class RepoFilePersistence implements RepoRepository {
|
|||||||
public storeAggregate (aggregate: Repo): Repo {
|
public storeAggregate (aggregate: Repo): Repo {
|
||||||
let id = aggregate.id;
|
let id = aggregate.id;
|
||||||
if(id) {
|
if(id) {
|
||||||
id = new RepoId("");
|
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
|
||||||
aggregate = Repo.instantiate(id, aggregate.path);
|
id = new RepoId(Math.random().toString(16).substr(2, 8));
|
||||||
|
// aggregate = Repo.builder().id(id).name(aggregate.name).build();
|
||||||
}
|
}
|
||||||
this.values.set(id as RepoId, aggregate);
|
this.values.set(id as RepoId, aggregate);
|
||||||
return aggregate;
|
return aggregate;
|
||||||
|
|||||||
@ -0,0 +1,42 @@
|
|||||||
|
import User, { UserId } from "#domain/user/user.entity";
|
||||||
|
import { UserRepository } from "#domain/user/user.repo";
|
||||||
|
import { Injectable } from "@nestjs/common";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export default class UserFilePersistence implements UserRepository {
|
||||||
|
public xxx = "";
|
||||||
|
|
||||||
|
private readonly values: Map<UserId, User> = new Map();
|
||||||
|
|
||||||
|
public deleteAggregate (aggregate: User): void {
|
||||||
|
if(aggregate.id)
|
||||||
|
this.values.delete(aggregate.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public deleteAggregateById (identitiy: UserId): void {
|
||||||
|
this.values.delete(identitiy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getAggregate (identitiy: UserId): User {
|
||||||
|
const v: User | undefined = this.values.get(identitiy);
|
||||||
|
if(v !== undefined)
|
||||||
|
return v;
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
|
|
||||||
|
public getAggregates (): User[] {
|
||||||
|
return Array.from(this.values.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
public storeAggregate (aggregate: User): User {
|
||||||
|
let id = aggregate.id;
|
||||||
|
if(id) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
|
||||||
|
id = new UserId(Math.random().toString(16).substr(2, 8));
|
||||||
|
// aggregate = User.builder().id(id).name(aggregate.name).password(aggregate.password).build();
|
||||||
|
}
|
||||||
|
this.values.set(id as UserId, aggregate);
|
||||||
|
return aggregate;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -4,7 +4,7 @@ import { mapper } from "#framework/mapper/mapper";
|
|||||||
|
|
||||||
export class RepoDto {
|
export class RepoDto {
|
||||||
public id!: string;
|
public id!: string;
|
||||||
public path!: string;
|
public name!: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
createMap(mapper, Repo, RepoDto, forMember(
|
createMap(mapper, Repo, RepoDto, forMember(
|
||||||
@ -13,6 +13,6 @@ createMap(mapper, Repo, RepoDto, forMember(
|
|||||||
|
|
||||||
createMap(mapper, RepoDto, Repo,
|
createMap(mapper, RepoDto, Repo,
|
||||||
constructUsing((sourceObject, _destinationIdentifier): Repo => {
|
constructUsing((sourceObject, _destinationIdentifier): Repo => {
|
||||||
return new Repo(new RepoId(sourceObject.id), sourceObject.path);
|
return new Repo(new RepoId(sourceObject.id));
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@ -1,14 +1,20 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-extraneous-class */
|
/* eslint-disable @typescript-eslint/no-extraneous-class */
|
||||||
|
|
||||||
import {RepoRepository} from "#domain/repo/repo.repo";
|
import {RepoRepository} from "#domain/repo/repo.repo";
|
||||||
|
import {UserRepositoryToken} from "#domain/user/user.repo";
|
||||||
import { Module } from "@nestjs/common";
|
import { Module } from "@nestjs/common";
|
||||||
import RepoFilePersistence from "./infrastructure/persistence/file/repo.persistence";
|
import RepoFilePersistence from "./infrastructure/persistence/file/repo.persistence";
|
||||||
|
import UserFilePersistence from "./infrastructure/persistence/file/user.persistence";
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
providers: [
|
providers: [
|
||||||
{
|
{
|
||||||
useClass: RepoFilePersistence,
|
useClass: RepoFilePersistence,
|
||||||
provide: RepoRepository
|
provide: RepoRepository
|
||||||
|
},
|
||||||
|
{
|
||||||
|
useClass: UserFilePersistence,
|
||||||
|
provide: UserRepositoryToken
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
exports: [RepoRepository]
|
exports: [RepoRepository]
|
||||||
|
|||||||
@ -7,17 +7,20 @@ import getLogger from "#logger";
|
|||||||
import { Logger } from "winston";
|
import { Logger } from "winston";
|
||||||
import AppHelp from "./appHelp";
|
import AppHelp from "./appHelp";
|
||||||
|
|
||||||
|
// TODO: move to App
|
||||||
|
const ENV_PREFIX = "ANT";
|
||||||
|
|
||||||
export abstract class AppCommand {
|
export abstract class AppCommand {
|
||||||
public abstract getDescriptions (): string;
|
public abstract getDescriptions (): string;
|
||||||
|
public abstract getName (): string;
|
||||||
public abstract run (): void;
|
public abstract run (): void;
|
||||||
|
|
||||||
public abstract getName (): string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default abstract class App {
|
export default abstract class App {
|
||||||
|
|
||||||
private readonly commands: Map<string, AppCommand> = new Map();
|
|
||||||
private readonly appHelp: AppHelp;
|
private readonly appHelp: AppHelp;
|
||||||
|
private readonly commands: Map<string, AppCommand> = new Map();
|
||||||
private readonly logger: Logger;
|
private readonly logger: Logger;
|
||||||
|
|
||||||
public constructor () {
|
public constructor () {
|
||||||
@ -26,20 +29,23 @@ export default abstract class App {
|
|||||||
this.appHelp = new AppHelp();
|
this.appHelp = new AppHelp();
|
||||||
this.logger = getLogger("app");
|
this.logger = getLogger("app");
|
||||||
this.addCommmand(new (class implements AppCommand {
|
this.addCommmand(new (class implements AppCommand {
|
||||||
public getName (): string {
|
|
||||||
return "help";
|
|
||||||
}
|
|
||||||
|
|
||||||
public getDescriptions (): string {
|
public getDescriptions (): string {
|
||||||
return "Show help for this application.";
|
return "Show help for this application.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getName (): string {
|
||||||
|
return "help";
|
||||||
|
}
|
||||||
|
|
||||||
public run (): void {
|
public run (): void {
|
||||||
that.appHelp.printHelp(that.commands);
|
that.appHelp.printHelp(that.commands, ENV_PREFIX);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract commmands (setCommands: (...commands: AppCommand[]) => void): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It executes the commands and options.
|
* It executes the commands and options.
|
||||||
*/
|
*/
|
||||||
@ -51,7 +57,7 @@ export default abstract class App {
|
|||||||
console.log();
|
console.log();
|
||||||
});
|
});
|
||||||
this.options((...defs): void => {
|
this.options((...defs): void => {
|
||||||
initConfiguration("XXX", ...defs);
|
initConfiguration(ENV_PREFIX, ...defs);
|
||||||
});
|
});
|
||||||
this.printBanner();
|
this.printBanner();
|
||||||
configuration().validate();
|
configuration().validate();
|
||||||
@ -65,13 +71,12 @@ export default abstract class App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract options (setDefinitions: (...definitions: ConfigurationDefinition[]) => void): void;
|
||||||
|
|
||||||
|
public abstract printBanner (): void;
|
||||||
|
|
||||||
private addCommmand (command: AppCommand): void {
|
private addCommmand (command: AppCommand): void {
|
||||||
this.commands.set(command.getName(), command);
|
this.commands.set(command.getName(), command);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract options (setDefinitions: (...definitions: ConfigurationDefinition[]) => void): void;
|
|
||||||
|
|
||||||
public abstract commmands (setCommands: (...commands: AppCommand[]) => void): void;
|
|
||||||
public abstract printBanner (): void;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -13,7 +13,7 @@ export default class AppHelp {
|
|||||||
* Prints the help message
|
* Prints the help message
|
||||||
* @param commands - A map of all the commands that the program can run.
|
* @param commands - A map of all the commands that the program can run.
|
||||||
*/
|
*/
|
||||||
public printHelp (commands: Map<string, AppCommand>): void {
|
public printHelp (commands: Map<string, AppCommand>, envPrefix: string): void {
|
||||||
const programm = process.argv.slice(0, 2).join(" ");
|
const programm = process.argv.slice(0, 2).join(" ");
|
||||||
const underline = clc.underline;
|
const underline = clc.underline;
|
||||||
console.log(underline("Usage") + "\n");
|
console.log(underline("Usage") + "\n");
|
||||||
@ -23,50 +23,11 @@ export default class AppHelp {
|
|||||||
console.log();
|
console.log();
|
||||||
console.log(underline("Options"));
|
console.log(underline("Options"));
|
||||||
console.log();
|
console.log();
|
||||||
this.printOptions((def) => def.getCommands().length >= 1);
|
this.printOptions(envPrefix, (def) => def.getCommands().length >= 1);
|
||||||
console.log();
|
console.log();
|
||||||
console.log(underline("Rules & Behavior"));
|
console.log(underline("Rules & Behavior"));
|
||||||
console.log();
|
console.log();
|
||||||
this.printOptions((def) => def.getCommands().length == 0);
|
this.printOptions(envPrefix, (def) => def.getCommands().length == 0);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prints all commands and their descriptions
|
|
||||||
* @param commands - Map<string, AppCommand>
|
|
||||||
*/
|
|
||||||
private printCommands (commands: Map<string, AppCommand>): void {
|
|
||||||
commands.forEach((v, k, _m) => {
|
|
||||||
console.log("\t" + k + " - " + v.getDescriptions());
|
|
||||||
const paramaters: string[] = [];
|
|
||||||
// Find parameters for current command
|
|
||||||
for (const def of this.getConfigurationDefinitions()) {
|
|
||||||
if (def.getCommands().includes(k)) {
|
|
||||||
paramaters.push(this.generateParameters(def));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log("\t↳ " + k + " " + paramaters.join(" "));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prints out all the options that are available to the user
|
|
||||||
* @param condition - Select witch options are printed.
|
|
||||||
*/
|
|
||||||
private printOptions (condition: (a: ConfigurationDefinition) => boolean): void {
|
|
||||||
let maxLength = 0;
|
|
||||||
/* Find longest String */
|
|
||||||
for (const def of this.getConfigurationDefinitions()) {
|
|
||||||
if (condition(def)) {
|
|
||||||
const option = " -" + def.getArgName().sort((a, b) => a.length - b.length).join(" -");
|
|
||||||
maxLength = Math.max(maxLength, option.length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const def of this.getConfigurationDefinitions()) {
|
|
||||||
if (condition(def)) {
|
|
||||||
const option = " -" + def.getArgName().sort((a, b) => a.length - b.length).join(" -");
|
|
||||||
console.log("\t↳ " + (option.padEnd(maxLength, " ")) + " - " + def.getDescription());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -107,4 +68,46 @@ export default class AppHelp {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints all commands and their descriptions
|
||||||
|
* @param commands - Map<string, AppCommand>
|
||||||
|
*/
|
||||||
|
private printCommands (commands: Map<string, AppCommand>): void {
|
||||||
|
commands.forEach((v, k, _m) => {
|
||||||
|
console.log("\t" + k + " - " + v.getDescriptions());
|
||||||
|
const paramaters: string[] = [];
|
||||||
|
// Find parameters for current command
|
||||||
|
for (const def of this.getConfigurationDefinitions()) {
|
||||||
|
if (def.getCommands().includes(k)) {
|
||||||
|
paramaters.push(this.generateParameters(def));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log("\t↳ " + k + " " + paramaters.join(" "));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints out all the options that are available to the user
|
||||||
|
* @param condition - Select witch options are printed.
|
||||||
|
*/
|
||||||
|
private printOptions (envPrefix: string, condition: (a: ConfigurationDefinition) => boolean): void {
|
||||||
|
let maxLength = 0;
|
||||||
|
/* Find longest String */
|
||||||
|
for (const def of this.getConfigurationDefinitions()) {
|
||||||
|
if (condition(def)) {
|
||||||
|
let option = " -" + def.getArgName().sort((a, b) => a.length - b.length).join(" -");
|
||||||
|
option += " (" + envPrefix + "_" + def.getEnvName().toUpperCase()+")";
|
||||||
|
maxLength =
|
||||||
|
Math.max(maxLength, option.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const def of this.getConfigurationDefinitions()) {
|
||||||
|
if (condition(def)) {
|
||||||
|
let option = " -" + def.getArgName().sort((a, b) => a.length - b.length).join(" -");
|
||||||
|
option += " (" + envPrefix + "_" + def.getEnvName().toUpperCase()+")";
|
||||||
|
console.log("\t↳ " + (option.padEnd(maxLength, " ")) + " - " + def.getDescription());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
105
src/framework/builder/builder.ts
Normal file
105
src/framework/builder/builder.ts
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
import Repo, { IRepoBuider, RepoId } from "#domain/repo/repo.entity";
|
||||||
|
import { UserAssignment, UserRight } from "#domain/repo/userAssignment.entity";
|
||||||
|
import { UserId } from "#domain/user/user.entity";
|
||||||
|
import { reflect, ReflectedArrayRef, ReflectedClassRef, ReflectedUnionRef } from "typescript-rtti";
|
||||||
|
|
||||||
|
export type IBuilder<T> = {
|
||||||
|
[k in keyof T]-?: (arg: T[k]) => IBuilder<T>
|
||||||
|
}
|
||||||
|
& {
|
||||||
|
build(): T;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Clazz<T> = new (...args: unknown[]) => T;
|
||||||
|
|
||||||
|
type Constructor<Params extends readonly any[] = readonly any[], Result = any> = new (...params: Params) => Result;
|
||||||
|
|
||||||
|
interface Foo {
|
||||||
|
[key: string]: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Builder<Type> (type: Constructor): IBuilder<Type> {
|
||||||
|
const parameters: { name: string; class: any }[] = [];
|
||||||
|
const properties = new Map<string, { name: string; class: any, aggregation?: string, parameter: boolean }>();
|
||||||
|
for (const property of reflect(type).properties) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
|
if (!property.name.startsWith("_") && property.class.super !== null) {
|
||||||
|
if (property.type instanceof ReflectedClassRef) {
|
||||||
|
properties.set(property.name, { name: property.name, class: property.type.class, parameter: false });
|
||||||
|
}
|
||||||
|
else if (property.type instanceof ReflectedUnionRef) {
|
||||||
|
properties.set(property.name, { name: property.name, class: (<ReflectedClassRef<unknown>>property.type.types.filter(t => t instanceof ReflectedClassRef)[0]).class, parameter: false });
|
||||||
|
}
|
||||||
|
else if (property.type instanceof ReflectedArrayRef) {
|
||||||
|
properties.set(property.name, { name: property.name, class: (<ReflectedClassRef<unknown>>property.type.elementType).class, aggregation: "array", parameter: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const parameter of reflect(type).parameters) {
|
||||||
|
const name = parameter.rawMetadata.n;
|
||||||
|
parameters.push({ name: name, class: properties.get(parameter.name) });
|
||||||
|
if (properties.get(name) !== undefined)
|
||||||
|
(properties.get(name) as { parameter: boolean }).parameter = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const values = new Map<string, unknown>();
|
||||||
|
const builder = new Proxy(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
||||||
|
get (_target, prop) {
|
||||||
|
if (typeof prop === "string" && prop.startsWith("add")) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
|
||||||
|
const tprop = prop.charAt(3).toLocaleLowerCase() + prop.substring(4);
|
||||||
|
return (x: unknown): unknown => {
|
||||||
|
if (properties.get(tprop)?.aggregation === "array") {
|
||||||
|
if (!values.has(tprop))
|
||||||
|
values.set(tprop, []);
|
||||||
|
(values.get(tprop) as Array<unknown>).push(x);
|
||||||
|
} else {
|
||||||
|
values.set(tprop, x);
|
||||||
|
}
|
||||||
|
return builder;
|
||||||
|
};
|
||||||
|
} else if ("build" === prop) {
|
||||||
|
const params: unknown[] = [];
|
||||||
|
for (const param of parameters) {
|
||||||
|
params.push(values.get(param.name));
|
||||||
|
}
|
||||||
|
const obj: Foo = new type(params);
|
||||||
|
for (const propertyname of properties.keys()) {
|
||||||
|
const prop = properties.get(propertyname);
|
||||||
|
if (values.has(propertyname) && !prop?.parameter) {
|
||||||
|
if (prop?.aggregation === "array") {
|
||||||
|
const desc = Object.getOwnPropertyDescriptor(obj, propertyname);
|
||||||
|
if (desc?.set === undefined) {
|
||||||
|
const methodeName = "add" + propertyname.charAt(0).toUpperCase() + propertyname.slice(1);
|
||||||
|
for (const value of (values.get(propertyname) as Array<unknown>)) {
|
||||||
|
(obj[methodeName] as ((t: unknown) => unknown))(value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
obj[propertyname] = values.get(propertyname);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
obj[propertyname] = values.get(propertyname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return () => obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (x: unknown): unknown => {
|
||||||
|
values.set(prop.toString(), x);
|
||||||
|
return builder;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return builder as IBuilder<Type>;
|
||||||
|
}
|
||||||
|
const ua1 = new UserAssignment(new UserId("test"), UserRight.Read);
|
||||||
|
const ua2 = new UserAssignment(new UserId("test2"), UserRight.Read);
|
||||||
|
const builder = Builder<IRepoBuider>(Repo);
|
||||||
|
const x = builder.id(new RepoId("test")).name("name").addUserAssignment(ua1).addUserAssignment(ua2).build();
|
||||||
|
console.log(x);
|
||||||
@ -3,11 +3,11 @@ import {parser, ArgCollection} from "args-command-parser";
|
|||||||
|
|
||||||
class Configuration {
|
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;
|
private readonly arguments: ArgCollection;
|
||||||
|
private readonly defaultCommand: string;
|
||||||
|
private readonly definitions: Map<string, ConfigurationDefinition> = new Map();
|
||||||
|
private readonly envPrefix: string;
|
||||||
|
private readonly values: Map<string, string[] | undefined> = new Map();
|
||||||
public constructor (defaultCommand: string, envPrefix: string, ...definitions: ConfigurationDefinition[]) {
|
public constructor (defaultCommand: string, envPrefix: string, ...definitions: ConfigurationDefinition[]) {
|
||||||
this.arguments = parser();
|
this.arguments = parser();
|
||||||
for (const definition of definitions) {
|
for (const definition of definitions) {
|
||||||
@ -18,23 +18,22 @@ class Configuration {
|
|||||||
this.envPrefix = envPrefix;
|
this.envPrefix = envPrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
public validate (): void {
|
/**
|
||||||
this.definitions.forEach((v, _k, _m) => {
|
* Get the value of a boolean parameter
|
||||||
const def = v;
|
* @param {string} name - The name of the parameter.
|
||||||
const values = this.values.get(def.getName()) ?? [];
|
* @returns The value of the parameter.
|
||||||
if(!def.getMultiple() && values.length > 1)
|
*/
|
||||||
throw new Error("No more than one value may be assigned to parameter '" + def.getName() + "'.");
|
public getBooleanValue (name: string): boolean | boolean[] | undefined {
|
||||||
if(def.getRequired() && (def.getCommands().length === 0 || def.getCommands().includes(this.getCommand())) && values.length === 0)
|
const def = this.definitions.get(name);
|
||||||
throw new Error("Parameter '" + def.getName() + "' is required.");
|
if(def?.getType() == DefinitionType.Boolean) {
|
||||||
for (const value of values) {
|
const value = this.values.get(name) ?? [];
|
||||||
if(!def.getValidator().validate(value))
|
const result: boolean[] = this.toBoolean(value);
|
||||||
throw new Error("Parameter '" + def.getName() + "' does not meet the requirements: " + def.getValidator().description());
|
if(def.getMultiple()) {
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
});
|
return result[0];
|
||||||
}
|
}
|
||||||
|
return undefined;
|
||||||
public getDefinitions (): ConfigurationDefinition[] {
|
|
||||||
return Array.from(this.definitions.values());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,6 +47,35 @@ class Configuration {
|
|||||||
return this.defaultCommand;
|
return this.defaultCommand;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getDefinitions (): ConfigurationDefinition[] {
|
||||||
|
return Array.from(this.definitions.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value of a parameter
|
* Get the value of a parameter
|
||||||
* @param {string} name - The name of the parameter.
|
* @param {string} name - The name of the parameter.
|
||||||
@ -80,54 +108,56 @@ class Configuration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public validate (): void {
|
||||||
* Get the value of a boolean parameter
|
this.definitions.forEach((v, _k, _m) => {
|
||||||
* @param {string} name - The name of the parameter.
|
const def = v;
|
||||||
* @returns The value of the parameter.
|
const values = this.values.get(def.getName()) ?? [];
|
||||||
*/
|
if(!def.getMultiple() && values.length > 1)
|
||||||
public getBooleanValue (name: string): boolean | boolean[] | undefined {
|
throw new Error("No more than one value may be assigned to parameter '" + def.getName() + "'.");
|
||||||
const def = this.definitions.get(name);
|
if(def.getRequired() && (def.getCommands().length === 0 || def.getCommands().includes(this.getCommand())) && values.length === 0)
|
||||||
if(def?.getType() == DefinitionType.Boolean) {
|
throw new Error("Parameter '" + def.getName() + "' is required.");
|
||||||
const value = this.values.get(name) ?? [];
|
for (const value of values) {
|
||||||
const result: boolean[] = this.toBoolean(value);
|
if(!def.getValidator().validate(value))
|
||||||
if(def.getMultiple()) {
|
throw new Error("Parameter '" + def.getName() + "' does not meet the requirements: " + def.getValidator().description());
|
||||||
return result;
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
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 result[0];
|
|
||||||
}
|
}
|
||||||
return undefined;
|
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;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Convert a string array to a boolean array
|
* Convert a string array to a boolean array
|
||||||
* @param {string[]} value - The value of the parameter.
|
* @param {string[]} value - The value of the parameter.
|
||||||
* @returns The `toBoolean` function returns an array of booleans.
|
* @returns The `toBoolean` function returns an array of booleans.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
private getEnvValue (def: ConfigurationDefinition): string[] | undefined {
|
||||||
|
const value = process.env[this.envPrefix + "_" + def.getEnvName().toUpperCase()];
|
||||||
|
if(value !== undefined)
|
||||||
|
return [value];
|
||||||
|
else
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getInternalValue (def: ConfigurationDefinition): string[] | undefined {
|
||||||
|
let value = this.getArgValue(def);
|
||||||
|
value = (value === undefined)?this.getEnvValue(def):value;
|
||||||
|
value = (value === undefined)?def.getDefaultValue():value;
|
||||||
|
if(value !== undefined) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
private toBoolean (value: string[]): boolean[] {
|
private toBoolean (value: string[]): boolean[] {
|
||||||
const result: boolean[] = [];
|
const result: boolean[] = [];
|
||||||
for (const v of value) {
|
for (const v of value) {
|
||||||
@ -150,34 +180,6 @@ class Configuration {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getInternalValue (def: ConfigurationDefinition): string[] | undefined {
|
|
||||||
let value = this.getArgValue(def);
|
|
||||||
value = (value === undefined)?this.getEnvValue(def):value;
|
|
||||||
value = (value === undefined)?def.getDefaultValue():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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let configInstance: Configuration;
|
let configInstance: Configuration;
|
||||||
|
|||||||
@ -1,55 +1,10 @@
|
|||||||
/* eslint-disable @typescript-eslint/require-await */
|
/* eslint-disable @typescript-eslint/require-await */
|
||||||
import { FastifyLogFn, FastifyLoggerInstance, FastifyPluginAsync, FastifyRequest} from "fastify";
|
import { FastifyPluginAsync, FastifyRequest} from "fastify";
|
||||||
import fastifyPlugin from "fastify-plugin";
|
import fastifyPlugin from "fastify-plugin";
|
||||||
import { Bindings } from "fastify/types/logger";
|
|
||||||
import getlogger from "./logger";
|
|
||||||
import chalk from "chalk";
|
import chalk from "chalk";
|
||||||
|
import logadapter from "./pinoLoggerAdapter";
|
||||||
|
|
||||||
const logger = getlogger("fastify");
|
// const logger = getlogger("fastify");
|
||||||
const customLogger: FastifyLoggerInstance = {
|
|
||||||
info: function (obj: unknown, msg?: string, ...args: unknown[]): void {
|
|
||||||
if(typeof obj === "string")
|
|
||||||
logger.info(obj, msg, ...args);
|
|
||||||
else if(msg)
|
|
||||||
logger.info(msg, obj, ...args);
|
|
||||||
} as FastifyLogFn,
|
|
||||||
warn: function (obj: unknown, msg?: string, ...args: unknown[]): void {
|
|
||||||
if(typeof obj === "string")
|
|
||||||
logger.warning(obj, msg, ...args);
|
|
||||||
else if(msg)
|
|
||||||
logger.warning(msg, obj, ...args);
|
|
||||||
} as FastifyLogFn,
|
|
||||||
error: function (obj: unknown, msg?: string, ...args: unknown[]): void {
|
|
||||||
if(typeof obj === "string")
|
|
||||||
logger.error(obj, msg, ...args);
|
|
||||||
else if(msg)
|
|
||||||
logger.error(msg, obj, ...args);
|
|
||||||
} as FastifyLogFn,
|
|
||||||
fatal: function (obj: unknown, msg?: string, ...args: unknown[]): void {
|
|
||||||
if(typeof obj === "string")
|
|
||||||
logger.fatal(obj, msg, ...args);
|
|
||||||
else if(msg)
|
|
||||||
logger.fatal(msg, obj, ...args);
|
|
||||||
} as FastifyLogFn,
|
|
||||||
trace: function (obj: unknown, msg?: string, ...args: unknown[]): void {
|
|
||||||
if(typeof obj === "string")
|
|
||||||
logger.trace(obj, msg, ...args);
|
|
||||||
else if(msg)
|
|
||||||
logger.trace(msg, obj, ...args);
|
|
||||||
} as FastifyLogFn,
|
|
||||||
debug: function (obj: unknown, msg?: string, ...args: unknown[]): void {
|
|
||||||
if(typeof obj === "string")
|
|
||||||
logger.debug(obj, msg, ...args);
|
|
||||||
else if(msg)
|
|
||||||
logger.debug(msg, obj, ...args);
|
|
||||||
} as FastifyLogFn,
|
|
||||||
child: function (_bindings: Bindings): FastifyLoggerInstance {
|
|
||||||
return customLogger;
|
|
||||||
},
|
|
||||||
setBindings: function (_bindings: Bindings): void {
|
|
||||||
// OK
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export type FastifyRequestLoggerOptions = {
|
export type FastifyRequestLoggerOptions = {
|
||||||
logBody?: boolean;
|
logBody?: boolean;
|
||||||
@ -153,15 +108,9 @@ export const plugin: FastifyPluginAsync<FastifyRequestLoggerOptions> = async (fa
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
declare module "fastify" {
|
|
||||||
interface FastifyLoggerInstance {
|
|
||||||
setBindings(bindings: Bindings): void;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fastifyRequestLogger = fastifyPlugin(plugin, {
|
export const fastifyRequestLogger = fastifyPlugin(plugin, {
|
||||||
fastify: "3.x",
|
fastify: "4.x",
|
||||||
name: "fastify-request-logger",
|
name: "fastify-request-logger",
|
||||||
});
|
});
|
||||||
|
|
||||||
export const fastifyLogger = customLogger;
|
export const fastifyLogger = logadapter;
|
||||||
@ -1,5 +1,4 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
|
||||||
import { LoggerService } from "@nestjs/common";
|
import { LoggerService } from "@nestjs/common";
|
||||||
import getlogger from "./logger";
|
import getlogger from "./logger";
|
||||||
|
|
||||||
|
|||||||
37
src/framework/logger/pinoLoggerAdapter.ts
Normal file
37
src/framework/logger/pinoLoggerAdapter.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import { FastifyLogFn, FastifyLoggerInstance } from "fastify";
|
||||||
|
import getlogger from "./logger";
|
||||||
|
import pino, { ChildLoggerOptions, LoggerOptions } from "pino";
|
||||||
|
|
||||||
|
const pinoLogger = pino();
|
||||||
|
|
||||||
|
const logger = getlogger("fastify");
|
||||||
|
const customLogger: FastifyLoggerInstance = pinoLogger;
|
||||||
|
customLogger.info = function (obj: unknown, msg?: string, ...args: unknown[]): void {
|
||||||
|
if (typeof obj === "string") logger.info(obj, msg, ...args);
|
||||||
|
else if (msg) logger.info(msg, obj, ...args);
|
||||||
|
} as FastifyLogFn;
|
||||||
|
customLogger.warn = function (obj: unknown, msg?: string, ...args: unknown[]): void {
|
||||||
|
if (typeof obj === "string") logger.warning(obj, msg, ...args);
|
||||||
|
else if (msg) logger.warning(msg, obj, ...args);
|
||||||
|
} as FastifyLogFn;
|
||||||
|
customLogger.error = function (obj: unknown, msg?: string, ...args: unknown[]): void {
|
||||||
|
if (typeof obj === "string") logger.error(obj, msg, ...args);
|
||||||
|
else if (msg) logger.error(msg, obj, ...args);
|
||||||
|
} as FastifyLogFn;
|
||||||
|
customLogger.fatal = function (obj: unknown, msg?: string, ...args: unknown[]): void {
|
||||||
|
if (typeof obj === "string") logger.fatal(obj, msg, ...args);
|
||||||
|
else if (msg) logger.fatal(msg, obj, ...args);
|
||||||
|
} as FastifyLogFn;
|
||||||
|
customLogger.trace = function (obj: unknown, msg?: string, ...args: unknown[]): void {
|
||||||
|
if (typeof obj === "string") logger.trace(obj, msg, ...args);
|
||||||
|
else if (msg) logger.trace(msg, obj, ...args);
|
||||||
|
} as FastifyLogFn;
|
||||||
|
customLogger.debug = function (obj: unknown, msg?: string, ...args: unknown[]): void {
|
||||||
|
if (typeof obj === "string") logger.debug(obj, msg, ...args);
|
||||||
|
else if (msg) logger.debug(msg, obj, ...args);
|
||||||
|
} as FastifyLogFn;
|
||||||
|
customLogger.child = function <ChildOptions extends pino.ChildLoggerOptions>(_bindings: pino.Bindings, _options?: ChildLoggerOptions): pino.Logger<LoggerOptions & ChildOptions> {
|
||||||
|
return <pino.Logger<LoggerOptions & ChildOptions>>customLogger;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default customLogger;
|
||||||
@ -1,14 +1,20 @@
|
|||||||
import fastifySensible from "fastify-sensible";
|
|
||||||
import GracefulServer from "@gquittet/graceful-server";
|
import GracefulServer from "@gquittet/graceful-server";
|
||||||
import getlogger from "#logger";
|
import getlogger from "#logger";
|
||||||
import {fastifyLogger, fastifyRequestLogger} from "#logger/fastifyLogger";
|
import {fastifyRequestLogger, fastifyLogger} from "#logger/fastifyLogger";
|
||||||
import { Logger } from "winston";
|
import { Logger } from "winston";
|
||||||
import IGracefulServer from "@gquittet/graceful-server/lib/types/interface/gracefulServer";
|
|
||||||
import configuration from "#configuration";
|
import configuration from "#configuration";
|
||||||
import { NestFactory } from "@nestjs/core";
|
import { NestFactory } from "@nestjs/core";
|
||||||
import { FastifyAdapter, NestFastifyApplication } from "@nestjs/platform-fastify";
|
import { FastifyAdapter, NestFastifyApplication } from "@nestjs/platform-fastify";
|
||||||
import { AppModule } from "../../app.module";
|
import { AppModule } from "../../app.module";
|
||||||
import NestLogger from "#framework/logger/nestLogger";
|
import NestLogger from "#framework/logger/nestLogger";
|
||||||
|
import { EventEmitter } from "events";
|
||||||
|
import fastifySensible from "@fastify/sensible";
|
||||||
|
|
||||||
|
interface IGracefulServer {
|
||||||
|
isReady: () => boolean;
|
||||||
|
setReady: () => void;
|
||||||
|
on: (name: string, callback: (...args: any[]) => void) => EventEmitter;
|
||||||
|
}
|
||||||
|
|
||||||
export default class Server {
|
export default class Server {
|
||||||
private readonly logger: Logger;
|
private readonly logger: Logger;
|
||||||
@ -40,7 +46,8 @@ export default class Server {
|
|||||||
new FastifyAdapter({
|
new FastifyAdapter({
|
||||||
logger: fastifyLogger,
|
logger: fastifyLogger,
|
||||||
disableRequestLogging: true
|
disableRequestLogging: true
|
||||||
}), {
|
}),
|
||||||
|
{
|
||||||
logger: new NestLogger(),
|
logger: new NestLogger(),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import tsconfig from '../tsconfig.json';
|
import tsconfig from '../tsconfig.json' assert {type: "json"};;
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import { fileURLToPath } from 'url'
|
import { fileURLToPath } from 'url'
|
||||||
import { createRequire } from 'module'
|
import { createRequire } from 'module'
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
"baseUrl": "./src/",
|
"baseUrl": "./src/",
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"emitDecoratorMetadata": true,
|
"emitDecoratorMetadata": true,
|
||||||
|
"noImplicitAny": true,
|
||||||
"paths": {
|
"paths": {
|
||||||
"#ddd": ["framework/ddd/ddd.types"],
|
"#ddd": ["framework/ddd/ddd.types"],
|
||||||
"#framework/*": ["framework/*"],
|
"#framework/*": ["framework/*"],
|
||||||
@ -24,7 +25,8 @@
|
|||||||
{
|
{
|
||||||
"transform": "@automapper/classes/transformer-plugin",
|
"transform": "@automapper/classes/transformer-plugin",
|
||||||
"modelFileNameSuffix": [".types.js", ".entity.ts", ".dto.ts"]
|
"modelFileNameSuffix": [".types.js", ".entity.ts", ".dto.ts"]
|
||||||
}
|
},
|
||||||
|
{ "transform": "typescript-rtti/dist/transformer" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"tsc-alias": {
|
"tsc-alias": {
|
||||||
|
|||||||
Reference in New Issue
Block a user