Files
Mykola Mokhnach 2ed7bb04d8 feat(docutils)!: Migrate to ESM (#22585)
BREAKING CHANGE: @appium/docutils is now an ESM-only package. It can no longer be loaded via CommonJS require(); consumers must use import or dynamic import(). Deep imports into the package's internals are no longer possible — only the public entry point is exposed via exports.
2026-08-03 14:22:39 +02:00

91 lines
2.3 KiB
TypeScript

/**
* It's a logger.
*
* Since this is a CLI app only, it doesn't necessarily make sense to consume `@appium/support`'s logger.
*
* @module
*/
import {createConsola} from 'consola';
import type {ConsolaInstance, LogLevel} from 'consola';
import {DEFAULT_LOG_LEVEL, LogLevelMap} from './constants.js';
/**
* The global log level
*
* "Global" inasmuch as any logger created from the root logger will use this level.
*/
let globalLevel: LogLevel = LogLevelMap[DEFAULT_LOG_LEVEL];
/**
* Type guard to see if a string is a recognized log level
* @param level any value
*/
export function isLogLevelString(level: any): level is keyof typeof LogLevelMap {
return level in LogLevelMap;
}
/**
* The logger from which all loggers are created. This one uses a unique tag.
*/
const rootLogger = createConsola({
defaults: {tag: 'docutils'},
fancy: true,
level: globalLevel,
formatOptions: {
colors: true,
date: false,
},
});
// this prevents logging before `initLogger` is called
rootLogger.pauseLogs();
/**
* A map of tags to loggers
*/
const loggers: Map<string, WeakRef<ConsolaInstance>> = new Map();
/**
* Returns a tagged logger, creating and caching one if needed.
* @param tag Logger tag.
* @param parent Parent logger to derive from.
*/
export function getLogger(tag: string, parent = rootLogger) {
if (loggers.has(tag)) {
const logger = loggers.get(tag)?.deref();
if (logger) {
return logger;
}
}
const logger = parent.withTag(tag);
logger.level = globalLevel;
loggers.set(tag, new WeakRef(logger));
return logger;
}
/**
* Initialize the logging system.
*
* This should only be called once. The loglevel cannot be changed once it is set.
*
* @remarks Child loggers seem to inherit the "paused" state of the parent, so when this is called, we must resume all of them.
*/
let hasInitializedLogger = false;
export const initLogger = (level: keyof typeof LogLevelMap | LogLevel) => {
if (hasInitializedLogger) {
return;
}
hasInitializedLogger = true;
globalLevel = isLogLevelString(level) ? LogLevelMap[level] : level;
rootLogger.level = globalLevel;
rootLogger.resumeLogs();
for (const ref of loggers.values()) {
const logger = ref.deref();
if (logger) {
logger.level = globalLevel;
logger.resumeLogs();
}
}
};