Skip to main content
Module

x/polkadot/util/logger.ts

Package publishing for deno.land/x/polkadot
Go to Latest
File

import type { Logger } from './types.ts';
import { xglobal } from 'https://deno.land/x/polkadot@0.2.40/x-global/mod.ts';
import { formatDate } from './format/formatDate.ts';import { isBn } from './is/bn.ts';import { isBuffer } from './is/buffer.ts';import { isFunction } from './is/function.ts';import { isObject } from './is/object.ts';import { isU8a } from './is/u8a.ts';import { u8aToHex } from './u8a/toHex.ts';import { u8aToU8a } from './u8a/toU8a.ts';import { hasProcess } from './has.ts';import { noop } from './noop.ts';
type ConsoleType = 'error' | 'log' | 'warn';type LogType = ConsoleType | 'debug';
const logTo = { debug: 'log', error: 'error', log: 'log', warn: 'warn'} as const;
function formatOther (value: unknown): unknown { if (value && isObject(value) && value.constructor === Object) { const result: Record<string, unknown> = {};
for (const [k, v] of Object.entries(value)) { result[k] = loggerFormat(v); }
return result; }
return value;}
export function loggerFormat (value: unknown): unknown { if (Array.isArray(value)) { return value.map(loggerFormat); } else if (isBn(value)) { return value.toString(); } else if (isU8a(value) || isBuffer(value)) { return u8aToHex(u8aToU8a(value)); }
return formatOther(value);}
function formatWithLength (maxLength: number): (v: unknown) => unknown { return (v: unknown): unknown => { if (maxLength <= 0) { return v; }
const r = `${v as string}`;
return r.length < maxLength ? v : `${r.substring(0, maxLength)} ...`; };}
function apply (log: LogType, type: string, values: unknown[], maxSize = -1): void { if (values.length === 1 && isFunction(values[0])) { const fnResult = values[0]() as unknown;
return apply(log, type, Array.isArray(fnResult) ? fnResult : [fnResult], maxSize); }
console[logTo[log]]( formatDate(new Date()), type, ...values .map(loggerFormat) .map(formatWithLength(maxSize)) );}
function isDebugOn (e: string, type: string): boolean { return !!e && ( e === '*' || type === e || ( e.endsWith('*') && type.startsWith(e.slice(0, -1)) ) );}
function isDebugOff (e: string, type: string): boolean { return !!e && ( e.startsWith('-') && ( type === e.slice(1) || ( e.endsWith('*') && type.startsWith(e.slice(1, -1)) ) ) );}
function getDebugFlag (env: readonly string[], type: string): boolean { let flag = false;
for (const e of env) { if (isDebugOn(e, type)) { flag = true; } else if (isDebugOff(e, type)) { flag = false; } }
return flag;}
function parseEnv (type: string): [boolean, number] { const env = (hasProcess ? xglobal.process as { env: Record<string, string> } : {}).env || {}; const maxSize = parseInt(env.DEBUG_MAX || '-1', 10);
return [ getDebugFlag((env.DEBUG || '').toLowerCase().split(','), type), isNaN(maxSize) ? -1 : maxSize ];}
/** * @name Logger * @summary Creates a consistent log interface for messages * @description * Returns a `Logger` that has `.log`, `.error`, `.warn` and `.debug` (controlled with environment `DEBUG=typeA,typeB`) methods. Logging is done with a consistent prefix (type of logger, date) followed by the actual message using the underlying console. * @example * <BR> * * ```javascript * import { logger } from 'https://deno.land/x/polkadot@0.2.40/util/mod.ts'; * * const l = logger('test'); * ``` */export function logger (origin: string): Logger { const type = `${origin.toUpperCase()}:`.padStart(16); const [isDebug, maxSize] = parseEnv(origin.toLowerCase());
return { debug: isDebug ? (...values: unknown[]) => apply('debug', type, values, maxSize) : noop, error: (...values: unknown[]) => apply('error', type, values), log: (...values: unknown[]) => apply('log', type, values), noop, warn: (...values: unknown[]) => apply('warn', type, values) };}