UNPKG

@intlayer/config

Version:

Retrieve Intlayer configurations and manage environment variables for both server-side and client-side environments.

139 lines (137 loc) 5.67 kB
import { BEIGE, BLUE, GREEN, GREY, GREY_DARK, GREY_LIGHT, RED, RESET, WHITE } from "./colors.mjs"; //#region src/logger.ts let loggerPrefix; const setPrefix = (prefix) => { loggerPrefix = prefix; }; const getPrefix = (configPrefix) => { if (typeof loggerPrefix !== "undefined") return loggerPrefix; return configPrefix; }; const logger = (content, details) => { const config = details?.config ?? {}; const mode = config.mode ?? "default"; if (mode === "disabled" || details?.isVerbose && mode !== "verbose") return; const prefix = getPrefix(config.prefix); const flatContent = prefix ? [prefix, ...[content].flat()] : [content].flat(); const level = details?.level ?? "info"; (config[level] ?? console[level] ?? config.log ?? console.log)(...flatContent); }; const spinnerFrames = [ "⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏" ]; /** * The appLogger function takes the logger and merges it with the configuration from the intlayer config file. * It allows overriding the default configuration by passing a config object in the details parameter. * The configuration is merged with the default configuration from the intlayer config file. */ const getAppLogger = (configuration, globalDetails) => (content, details) => logger(content, { ...details ?? {}, config: { ...configuration?.log, ...globalDetails?.config, ...details?.config ?? {} } }); const colorize = (string, color, reset) => color ? `${color}${string}${reset ? typeof reset === "boolean" ? RESET : reset : RESET}` : string; const colorizeLocales = (locales, color = GREEN, reset = RESET) => [locales].flat().map((locale) => colorize(locale, color, reset)).join(`, `); const colorizeKey = (keyPath, color = BEIGE, reset = RESET) => [keyPath].flat().map((key) => colorize(key, color, reset)).join(`, `); const colorizePath = (path, color = GREY, reset = RESET) => [path].flat().map((path) => colorize(path, color, reset)).join(`, `); const colorizeNumber = (number, options = { zero: BLUE, one: BLUE, two: BLUE, few: BLUE, many: BLUE, other: BLUE }) => { if (number === 0 || number === "0") { const color = options.zero ?? "\x1B[32m"; return colorize(number.toString(), color); } const color = options[new Intl.PluralRules("en").select(Number(number))]; return colorize(number.toString(), color); }; const colorizeObject = (obj, indentLevel = 0, indentSize = 2, key) => { const indent = " ".repeat(indentLevel * indentSize); const nextIndent = " ".repeat((indentLevel + 1) * indentSize); if (obj === null) return colorize("null", BLUE); if (typeof obj === "boolean") return colorize(obj.toString(), BLUE); if (typeof obj === "number") return colorize(obj.toString(), BLUE); if (typeof obj === "string") { const isDateString = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(obj); const isUrl = obj.startsWith("http://") || obj.startsWith("https://"); const isGlob = obj.includes("*") || obj.includes("?") || obj.includes("{"); const isPath = obj.startsWith("/") || obj.startsWith("./") || obj.startsWith("../") || /\.[a-zA-Z0-9]{2,5}$/.test(obj); const isSecret = /^[0-9a-fA-F]{24,}$/.test(obj) || obj.length >= 40 && !/\s/.test(obj); const hasSpaces = /\s/.test(obj); if (isDateString) return colorize(`"${obj}"`, BEIGE); if (isUrl) return colorize(`"${obj}"`, GREY_DARK); if (isGlob) return colorize(`"${obj}"`, GREY); if (isPath) return colorize(`"${obj}"`, GREY_DARK); if (isSecret) return colorize(`"${obj}"`, GREY); if (hasSpaces) return colorize(`"${obj}"`, WHITE); return colorize(`"${obj}"`, BLUE); } if (Array.isArray(obj)) { if (obj.length === 0) return "[]"; return `[\n${obj.map((item) => `${nextIndent}${colorizeObject(item, indentLevel + 1, indentSize, key)}`).join(",\n")}\n${indent}]`; } if (typeof obj === "object") { const keys = Object.keys(obj); if (keys.length === 0) return "{}"; return `{\n${keys.map((key) => { const coloredKey = colorize(`"${key}"`, GREY_LIGHT); const value = obj[key]; return `${nextIndent}${coloredKey}: ${colorizeObject(value, indentLevel + 1, indentSize, key)}`; }).join(",\n")}\n${indent}}`; } return colorize(String(obj), GREY); }; const removeColor = (text) => text.replace(/\x1b\[[0-9;]*m/g, ""); const getLength = (length) => { let value = 0; if (typeof length === "number") value = length; if (typeof length === "string") value = length.length; if (Array.isArray(length) && length.every((locale) => typeof locale === "string")) value = Math.max(...length.map((str) => str.length)); if (Array.isArray(length) && length.every((locale) => typeof locale === "number")) value = Math.max(...length); return Math.max(value, 0); }; const defaultColonOptions = { colSize: 0, minSize: 0, maxSize: Infinity, pad: "right", padChar: "0" }; /** * Create a string of spaces of a given length. * * @param colSize - The length of the string to create. * @returns A string of spaces. */ const colon = (text, options) => [text].flat().map((text) => { const { colSize, minSize, maxSize, pad } = { ...defaultColonOptions, ...options ?? {} }; const length = getLength(colSize); const spacesLength = Math.max(minSize, Math.min(maxSize, length - removeColor(text).length)); if (pad === "left") return `${" ".repeat(spacesLength)}${text}`; return `${text}${" ".repeat(spacesLength)}`; }).join(""); const x = colorize("✗", RED); const v = colorize("✓", GREEN); const clock = colorize("⏲", BLUE); //#endregion export { clock, colon, colorize, colorizeKey, colorizeLocales, colorizeNumber, colorizeObject, colorizePath, getAppLogger, getPrefix, logger, removeColor, setPrefix, spinnerFrames, v, x }; //# sourceMappingURL=logger.mjs.map