Skip to main content
Glama
logger.ts5.95 kB
import type { CustomIntlayerConfig, Locale } from '@intlayer/types'; export type Details = { isVerbose?: boolean; level?: 'info' | 'warn' | 'error' | 'debug'; config?: CustomIntlayerConfig['log']; }; export type Logger = (content: any, details?: Details) => void; export const logger: Logger = (content, details) => { const isVerbose = details?.isVerbose ?? false; const mode = details?.config?.mode ?? 'default'; const level = details?.level ?? 'info'; const prefix = details?.config?.prefix ? details?.config?.prefix : undefined; const log = details?.config?.log ?? console.log; const info = details?.config?.info ?? console.info; const warn = details?.config?.warn ?? console.warn; const error = details?.config?.error ?? console.error; const debug = details?.config?.debug ?? console.debug; if (mode === 'disabled') return; if (isVerbose && mode !== 'verbose') return; const flatContent = prefix ? [prefix, ...[content].flat()] : [content].flat(); if (level === 'debug') { return debug(...flatContent); } if (level === 'info') { return info(...flatContent); } if (level === 'warn') { return warn(...flatContent); } if (level === 'error') { return error(...flatContent); } log(...flatContent); }; export enum ANSIColors { RESET = '\x1b[0m', GREY = '\x1b[90m', GREY_DARK = '\x1b[38;5;239m', GREY_LIGHT = '\x1b[38;5;252m', BLUE = '\x1b[34m', RED = '\x1b[31m', GREEN = '\x1b[32m', YELLOW = '\x1b[38;5;226m', MAGENTA = '\x1b[35m', BEIGE = '\x1b[38;5;3m', ORANGE = '\x1b[38;5;208m', CYAN = '\x1b[36m', WHITE = '\x1b[37m', BOLD = '\x1b[1m', } export 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. */ export const getAppLogger = (configuration?: CustomIntlayerConfig, globalDetails?: Details) => (content: any, details?: Details) => logger(content, { ...(details ?? {}), config: { ...configuration?.log, ...globalDetails?.config, ...(details?.config ?? {}), }, }); export const colorize = ( s: string, color?: ANSIColors, reset?: boolean | ANSIColors ): string => color ? `${color}${s}${reset ? (typeof reset === 'boolean' ? ANSIColors.RESET : reset) : ANSIColors.RESET}` : s; export const colorizeLocales = ( locales: Locale | Locale[], color = ANSIColors.GREEN, reset: boolean | ANSIColors = ANSIColors.RESET ) => [locales] .flat() .map((locale) => colorize(locale, color, reset)) .join(`, `); export const colorizeKey = ( keyPath: string | string[], color = ANSIColors.BEIGE, reset: boolean | ANSIColors = ANSIColors.RESET ) => [keyPath] .flat() .map((key) => colorize(key, color, reset)) .join(`, `); export const colorizePath = ( path: string | string[], color = ANSIColors.GREY, reset: boolean | ANSIColors = ANSIColors.RESET ) => [path] .flat() .map((p) => colorize(p, color, reset)) .join(`, `); /** * Colorize numeric value using Intl.NumberFormat and optional ANSI colors. * * Examples: * colorizeNumber(2, [{ pluralRule: 'one' , color: ANSIColors.GREEN}, { pluralRule: 'other' , color: ANSIColors.RED}]) // "'\x1b[31m2\x1b[0m" */ export const colorizeNumber = ( number: number, options: Partial<Record<Intl.LDMLPluralRule, ANSIColors>> = { zero: ANSIColors.BLUE, one: ANSIColors.BLUE, two: ANSIColors.BLUE, few: ANSIColors.BLUE, many: ANSIColors.BLUE, other: ANSIColors.BLUE, } ): string => { if (number === 0) { const color = options.zero ?? ANSIColors.GREEN; return colorize(number.toString(), color); } const rule = new Intl.PluralRules('en').select(number); const color = options[rule]; return colorize(number.toString(), color); }; export const removeColor = (text: string) => // biome-ignore lint/suspicious/noControlCharactersInRegex: we need to remove the color codes text.replace(/\x1b\[[0-9;]*m/g, ''); const getLength = (length: number | number[] | string | string[]): number => { let value: number = 0; if (typeof length === 'number') { value = length; } if (typeof length === 'string') { value = length.length; } if (Array.isArray(length) && length.every((l) => typeof l === 'string')) { value = Math.max(...length.map((str) => str.length)); } if (Array.isArray(length) && length.every((l) => typeof l === '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. */ export const colon = ( text: string | string[], options?: { colSize?: number | number[] | string | string[]; minSize?: number; maxSize?: number; pad?: 'left' | 'right'; padChar?: string; } ): string => [text] .flat() .map((text) => { const { colSize, minSize, maxSize, pad, padChar } = { ...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(''); export const x = colorize('✗', ANSIColors.RED); export const v = colorize('✓', ANSIColors.GREEN); export const clock = colorize('⏲', ANSIColors.BLUE);

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/aymericzip/intlayer'

If you have feedback or need assistance with the MCP directory API, please join our Discord server