JSDoc all the things!

This commit is contained in:
2020-08-17 09:44:23 -05:00
parent c2a7c3f914
commit f67ae37923
121 changed files with 2855 additions and 63 deletions

View File

@@ -1,6 +1,10 @@
import AppClass from '../lifecycle/AppClass.ts'
export { Service } from '../../../di/src/decorator/Service.ts'
/**
* Base class for an application service provider.
* @extends AppClass
*/
export class ServiceProvider extends AppClass {
}

View File

@@ -1,25 +1,49 @@
import { LogMessage, LoggingLevel } from './types.ts'
import {make} from "../../../../di/src/global.ts";
import {Logging} from "./Logging.ts";
import {blue, cyan, gray, green, red, yellow} from "../../external/std.ts";
import {make} from '../../../../di/src/global.ts'
import {Logging} from './Logging.ts'
import {blue, cyan, gray, green, red, yellow} from '../../external/std.ts'
/**
* Returns true if the given item is a typeof the Logger class.
* @param something
* @return boolean
*/
const isLoggerClass = (something: any): something is (typeof Logger) => {
return something.prototype instanceof Logger
}
export { isLoggerClass }
/**
* Base class for an application logger.
*/
export default abstract class Logger {
/**
* Write the given message to the log destination.
* @param {LogMessage} message
* @return Promise<void>
*/
public abstract async write(message: LogMessage): Promise<void>;
/**
* Register this logger with the logging service.
*/
public static register() {
make(Logging).register_logger(this)
}
/**
* Remove this logger from the logging service.
*/
public static remove() {
make(Logging).remove_logger(this)
}
/**
* Format the date object to the string output format.
* @param {Date} date
* @return string
*/
protected format_date(date: Date): string {
const hours = date.getHours()
const minutes = date.getMinutes()
@@ -27,6 +51,11 @@ export default abstract class Logger {
return `${date.getFullYear()}-${date.getMonth()+1}-${date.getDate()} ${hours > 9 ? hours : '0' + hours}:${minutes > 9 ? minutes : '0' + minutes}:${seconds > 9 ? seconds : '0' + seconds}`
}
/**
* Given a logging level, get the display string of that level.
* @param {LoggingLevel} level
* @return string
*/
protected level_display(level: LoggingLevel): string {
switch(level) {
case LoggingLevel.Success:

View File

@@ -4,43 +4,99 @@ import {Service} from '../../../../di/src/decorator/Service.ts'
import {make} from '../../../../di/src/global.ts'
import {isInstantiable} from '../../../../di/src/type/Instantiable.ts'
/**
* Service for managing application logging.
*/
@Service()
class Logging {
/**
* The current logging level.
* @type LoggingLevel
*/
private _level = LoggingLevel.Warning
/**
* Loggers registered with this service.
* @type Array<Logger>
*/
private _loggers: Logger[] = []
/**
* Get the current logging level.
* @type LoggingLevel
*/
public get level() {
return this._level
}
/**
* Set the new logging level.
* @param {LoggingLevel} level
*/
public set level(level) {
this._level = level
}
/**
* Write an output with the success level.
* @param output
* @param {boolean} [force = false] - if true, the output will be written, regardless of the output level
*/
public success(output: any, force = false) {
this.write_log(LoggingLevel.Success, output, force)
}
/**
* Write an output with the error level.
* @param output
* @param {boolean} [force = false] - if true, the output will be written, regardless of the output level
*/
public error(output: any, force = false) {
this.write_log(LoggingLevel.Error, output, force)
}
/**
* Write an output with the warning level.
* @param output
* @param {boolean} [force = false] - if true, the output will be written, regardless of the output level
*/
public warn(output: any, force = false) {
this.write_log(LoggingLevel.Warning, output, force)
}
/**
* Write an output with the info level.
* @param output
* @param {boolean} [force = false] - if true, the output will be written, regardless of the output level
*/
public info(output: any, force = false) {
this.write_log(LoggingLevel.Info, output, force)
}
/**
* Write an output with the debug level.
* @param output
* @param {boolean} [force = false] - if true, the output will be written, regardless of the output level
*/
public debug(output: any, force = false) {
this.write_log(LoggingLevel.Debug, output, force)
}
/**
* Write an output with the verbose level.
* @param output
* @param {boolean} [force = false] - if true, the output will be written, regardless of the output level
*/
public verbose(output: any, force = false) {
this.write_log(LoggingLevel.Verbose, output, force)
}
/**
* Writes the output at the given logging level.
* @param {LoggingLevel} level
* @param output
* @param {boolean} [force = false]
*/
protected write_log(level: LoggingLevel, output: any, force = false) {
const message = this.build_message(level, output)
if ( this._level >= level || force ) {
@@ -54,6 +110,12 @@ class Logging {
}
}
/**
* Given an output and level, build a log message object.
* @param {LoggingLevel} level
* @param output
* @return LogMessage
*/
protected build_message(level: LoggingLevel, output: any): LogMessage {
return {
level,
@@ -63,6 +125,10 @@ class Logging {
}
}
/**
* Register a logger with this class.
* @param {typeof Logger} logger_class
*/
public register_logger(logger_class: typeof Logger) {
if ( isInstantiable(logger_class) ) {
const logger = make(logger_class)
@@ -71,10 +137,18 @@ class Logging {
}
}
/**
* Remove a logger from this class.
* @param {typeof Logger} logger_class
*/
public remove_logger(logger_class: typeof Logger) {
this._loggers = this._loggers.filter(x => !(x instanceof logger_class))
}
/**
* Get the information about the caller of a given context.
* @param {number} [level = 5] - how far up in the stacktrace to go
*/
protected get_caller_info(level = 5): string {
let e = new Error
if ( !e.stack ) return 'Unknown'

View File

@@ -2,6 +2,10 @@ import AbstractLogger from './Logger.ts'
import { LogMessage } from './types.ts'
import { gray, cyan } from '../../external/std.ts'
/**
* Logging class that writes to standard output.
* @extends AbstractLogger
*/
export default class StandardLogger extends AbstractLogger {
public async write(message: LogMessage): Promise<void> {
const prefix = this.level_display(message.level)

View File

@@ -1,3 +1,6 @@
/**
* Base type for logging levels.
*/
enum LoggingLevel {
Silent = 0,
Success = 1,
@@ -8,6 +11,11 @@ enum LoggingLevel {
Verbose = 6,
}
/**
* Returns true if the given element is a logging level.
* @param something
* @return boolean
*/
const isLoggingLevel = (something: any): something is LoggingLevel => {
return [
LoggingLevel.Silent,
@@ -20,6 +28,9 @@ const isLoggingLevel = (something: any): something is LoggingLevel => {
].includes(something)
}
/**
* Base type for a message written to the log.
*/
interface LogMessage {
level: LoggingLevel,
date: Date,
@@ -27,6 +38,11 @@ interface LogMessage {
caller_name: string,
}
/**
* Returns true if the given object is a log message.
* @param something
* @return boolean
*/
const isLogMessage = (something: any): something is LogMessage => {
return isLoggingLevel(something?.level) && something?.date instanceof Date;
}

View File

@@ -2,12 +2,19 @@ import { Service } from '../../../../di/src/decorator/Service.ts'
import { Logging } from '../logging/Logging.ts'
import {uuid} from '../../external/std.ts'
/**
* Base service with some utility helpers.
*/
@Service()
export default class Utility {
constructor(
protected logger: Logging
) {}
/**
* Make a deep copy of an object.
* @param target
*/
deep_copy<T>(target: T): T {
if ( target === null )
return target
@@ -33,6 +40,10 @@ export default class Utility {
// TODO deep_merge
/**
* Given a string of a value, try to infer the JavaScript type.
* @param {string} val
*/
infer(val: string): any {
if ( !val ) return undefined
else if ( val.toLowerCase() === 'true' ) return true
@@ -44,6 +55,10 @@ export default class Utility {
else return val
}
/**
* Returns true if the given value is valid JSON.
* @param {string} val
*/
is_json(val: string): boolean {
try {
JSON.parse(val)
@@ -54,6 +69,10 @@ export default class Utility {
}
}
/**
* Get a universally-unique ID string.
* @return string
*/
uuid(): string {
return uuid()
}