/**
 * Represents a log message, that is an object that contains all metadata from logging something
 */
export interface LogMessage<TSeverity extends string, TData = unknown> {
    message: string;
    data?: TData;
    severity: TSeverity;
    source: string;
    metadata?: LoggerMetadata;
}
export declare type DefaultSeverity = 'error' | 'info' | 'verbose' | 'warn';
export declare type OperationSeverity = 'complete' | 'fail' | 'start';
export declare type OperationLoggingSeverity = DefaultSeverity | OperationSeverity;
export declare const defaultSeverities: readonly DefaultSeverity[];
export declare const operationSeverities: readonly OperationSeverity[];
export declare const operationLoggingSeverities: readonly OperationLoggingSeverity[];
/**
 * A method that gets a string and optional arguments, to log them
 */
export declare type LoggingMethod = (message: string, ...args: unknown[]) => void;
/**
 * Loggers also have property that describe their source, and a method that takes a new source,
 * and returns new logger that logs under the specified source
 */
export interface LoggerFunctionality<TSeverity extends string> {
    /** Gets the logger source */
    readonly loggerSource: string;
    /**
     * Create a new logger, inheriting the current logger severities and metadata,
     * having the specified source
     * @param source The name of the new source
     * @returns A new logger instance
     */
    setSource(source: string): Logger<TSeverity>;
    /**
     * Create a new logger, inheriting the current logger severities and metadata,
     * having a source with the specified suffix at the end, delimited with `' → '`
     * @param source The name of the new source
     * @returns A new logger instance
     */
    appendSource(sourceSuffix: string): Logger<TSeverity>;
    /**
     * Gets a list of severities this logger can log.
     */
    severities: readonly string[];
    /**
     * Gets an object that contains metadata that would be attached to every logged message
     */
    readonly metadata: LoggerMetadata;
    /**
     * Sets the logger metadata
     * @param metadata The metadata to set
     */
    setMetadata(metadata: LoggerMetadata): void;
    /**
     * Metadata to add to the logger metadata
     * @description Metadata is added using `Object.assign()`
     * @param metadata Metadata to add to the logger's metadata
     */
    appendMetadata(metadata: LoggerMetadata): void;
}
/**
 * For each severity that defined by the type TSeverity,
 * a logger object has logging method to log messages with that severity
 */
export declare type SeveritiesLogger<TSeverity extends string> = {
    readonly [K in TSeverity]: LoggingMethod;
};
/**
 * An object that can log messages
 */
export declare type LoggerObject<TSeverity extends string = DefaultSeverity> = LoggerFunctionality<TSeverity> & SeveritiesLogger<TSeverity>;
export declare type LoggerFunction<TSeverity extends string> = (message: LogMessage<TSeverity>) => void;
/**
 * A logger is a logger object that is also a logging function (a function that can log log-messages)
 */
export declare type Logger<TSeverity extends string = DefaultSeverity> = LoggerFunction<TSeverity> & LoggerObject<TSeverity>;
export declare type LoggerMetadata = Readonly<Record<any, unknown>>;
/**
 * Creates a LogMessage from an error
 * @param err The error to create log message from
 * @param source The source of the error (the logger source)
 * @param severity The severity of the created log message
 * @returns A LogMessage object for the specified error
 */
export declare function logMessageFromError<TSeverity extends string = 'error'>(err: any, source: string, severity?: TSeverity): LogMessage<TSeverity>;
/**
 * A function from LogMessage to a string
 */
export declare type Formatter = <TSeverity extends string>(message: LogMessage<TSeverity>) => string;
/**
 * A default formatter function to convert a log message to a string
 * @param message The log message to format
 * @returns A string
 */
export declare const defaultFormatter: Formatter;
export declare function asArray(data: unknown): unknown[];
/**
 * An operation completion object
 */
export interface OperationCompletion<TData> {
    /**
     * Call `complete` to end the operation successfully
     */
    complete: (message?: string, data?: TData) => void;
    /**
     * Call `fail` to end the operation with an error
     */
    fail: (message?: string, data?: TData) => void;
}
/**
 * Report an operation start, and returns an object that allows reporting the end of the specified operation
 * @param logger The logger to report the operation to
 * @param operation The operation to report
 * @param message An optional message to append to the operation-start message
 * @param data An optional data to attach to the operation-start message
 * @returns An operation completion object that can be used to complete the operation
 */
export declare function logOperation<TData>(logger: LoggerObject<OperationSeverity>, operation: string, message?: string, data?: TData): OperationCompletion<TData>;
/**
 * Performs a specified operation, while logging its start, and how it was ended (successfully or failed with an error)
 * @param logger The logger to log the operation status into
 * @param operationName The operation name to be logged
 * @param operation A function that performs the operation to be logged
 * @param successMessage An optional function from successful result to a message
 * that would be logged on successful completion
 * @param errorMessage An optional function from an error to a message that would be logged on operation failure
 * @returns A promise that would be resolved with the operation (either fulfilled or rejected)
 */
export declare function withOperationLogging<T>(logger: LoggerObject<OperationSeverity>, operationName: string, operation: () => PromiseLike<T> | T, successMessage?: (result: T) => string, errorMessage?: (err: any) => string): Promise<T>;
