UNPKG

typescript-logging

Version:

Library for logging, written in typescript, can be used by normal es5+ javascript as well.

289 lines (237 loc) 6.54 kB
/** * Module containing bunch of JSON related stuff. */ import {LogLevel} from "../log/LoggerOptions"; import {SimpleMap, StringBuilder} from "./DataStructures"; import {Category} from "../log/category/Category"; export interface JSONType<T> { getValue(): T; toString(): string; } export type ArrayType = boolean | string | number | JSONObject | null; abstract class JSONTypeImpl<T> implements JSONType<T> { private _value: T; constructor(value: T) { this._value = value; } public getValue(): T { return this._value; } public toString(): string { const value = this.getValue(); if (value != null) { return value.toString(); } return "null"; } } class JSONBooleanType extends JSONTypeImpl<boolean> { constructor(value: boolean) { super(value); } } class JSONNumberType extends JSONTypeImpl<number> { constructor(value: number) { super(value); } } class JSONStringType extends JSONTypeImpl<string> { constructor(value: string) { super(value); } public toString(): string { const value = this.getValue(); if (value != null) { return JSON.stringify(value.toString()); } return "null"; } } class JSONObjectType extends JSONTypeImpl<JSONObject> { constructor(value: JSONObject) { super(value); } } class JSONArrayType extends JSONTypeImpl<JSONArray<ArrayType>> { constructor(value: JSONArray<ArrayType>) { super(value); } public toString(): string { const value = this.getValue(); if (value != null) { return value.toString(); } return "null"; } } class JSONNullType extends JSONTypeImpl<null> { constructor() { super(null); } public toString(): string { return "null"; } } class JSONTypeConverter { public static toJSONType(value: ArrayType): JSONType<ArrayType> { if (value === null) { return new JSONNullType(); } if (typeof value === "string") { return new JSONStringType(value); } if (typeof value === "number") { return new JSONNumberType(value); } if (typeof value === "boolean") { return new JSONBooleanType(value); } if (value instanceof JSONObject) { return new JSONObjectType(value); } throw new Error("Type not supported for value: " + value); } } export class JSONObject { private values: SimpleMap<JSONTypeImpl<any>> = new SimpleMap<JSONTypeImpl<any>>(); public addBoolean(name: string, value: boolean): JSONObject { this.checkName(name); JSONObject.checkValue(value); this.values.put(name, new JSONBooleanType(value)); return this; } public addNumber(name: string, value: number): JSONObject { this.checkName(name); JSONObject.checkValue(value); this.values.put(name, new JSONNumberType(value)); return this; } public addString(name: string, value: string): JSONObject { this.checkName(name); JSONObject.checkValue(value); this.values.put(name, new JSONStringType(value)); return this; } public addNull(name: string): JSONObject { this.checkName(name); this.values.put(name, new JSONNullType()); return this; } public addArray(name: string, array: JSONArray<ArrayType>): JSONObject { this.checkName(name); JSONObject.checkValue(array); if (array == null) { throw new Error("Cannot add array as null"); } this.values.put(name, new JSONArrayType(array)); return this; } public addObject(name: string, object: JSONObject): JSONObject { this.checkName(name); JSONObject.checkValue(object); if (object == null) { throw new Error("Cannot add object as null"); } this.values.put(name, new JSONObjectType(object)); return this; } public toString(pretty: boolean = false): string { let comma = false; const buffer = new StringBuilder(); buffer.append("{"); this.values.keys().forEach((key: string) => { const value = this.values.get(key); if (value != null) { if (comma) { buffer.append(","); } buffer.append('"').append(key).append('":').append(value.toString()); comma = true; } }); buffer.append("}"); return buffer.toString(); } private checkName(name: string): void { if (name == null || name === undefined) { throw new Error("Name is null or undefined"); } if (this.values.exists(name)) { throw new Error("Name " + name + " is already present for this object"); } } private static checkValue(value: any): void { if (value === undefined) { throw new Error("Value is undefined"); } } } export class JSONArray<T extends ArrayType> { private objects: Array<JSONType<ArrayType>> = []; public add(object: T): JSONArray<T> { if (object === undefined) { throw new Error("Object is not allowed to be undefined"); } this.objects.push(JSONTypeConverter.toJSONType(object)); return this; } public toString(pretty: boolean = false): string { const buffer = new StringBuilder(); buffer.append("["); this.objects.forEach((value: JSONType<T>, index: number) => { if (index > 0) { buffer.append(","); } buffer.append(value.toString()); }); buffer.append("]"); return buffer.toString(); } } /** * Utility class that helps us convert things to and from json (not for normal usage). */ export class JSONHelper { public static categoryToJSON(cat: Category, recursive: boolean): JSONObject { /* { "categories": [ { id=1, name: "x", parent: null, logLevel: "Error" }, { id=2, name: "y", parent: 1, logLevel: "Error" } ] } */ const arr = new JSONArray<JSONObject>(); JSONHelper._categoryToJSON(cat, arr, recursive); const object = new JSONObject(); object.addArray("categories", arr); return object; } private static _categoryToJSON(cat: Category, arr: JSONArray<JSONObject>, recursive: boolean): void { const object = new JSONObject(); object.addNumber("id", cat.id); object.addString("name", cat.name); object.addString("logLevel", LogLevel[cat.logLevel].toString()); if (cat.parent != null) { object.addNumber("parent", cat.parent.id); } else { object.addNull("parent"); } arr.add(object); if (recursive) { cat.children.forEach((child: Category) => { JSONHelper._categoryToJSON(child, arr, recursive); }); } } }