@settlemint/sdk-utils
Version:
Shared utilities and helper functions for SettleMint SDK modules
137 lines (133 loc) • 4.32 kB
JavaScript
//#region src/logging/mask-tokens.ts
/**
* Masks sensitive SettleMint tokens in output text by replacing them with asterisks.
* Handles personal access tokens (PAT), application access tokens (AAT), and service account tokens (SAT).
*
* @param output - The text string that may contain sensitive tokens
* @returns The text with any sensitive tokens masked with asterisks
* @example
* import { maskTokens } from "@settlemint/sdk-utils/terminal";
*
* // Masks a token in text
* const masked = maskTokens("Token: sm_pat_****"); // "Token: ***"
*/
const maskTokens = (output) => {
return output.replace(/sm_(pat|aat|sat)_[0-9a-zA-Z]+/g, "***");
};
//#endregion
//#region src/logging/logger.ts
/**
* Creates a simple logger with configurable log level
*
* @param options - Configuration options for the logger
* @param options.level - The minimum log level to output (default: warn)
* @param options.prefix - The prefix to add to the log message (default: "")
* @returns A logger instance with debug, info, warn, and error methods
*
* @example
* import { createLogger } from "@/utils/logging/logger";
*
* const logger = createLogger({ level: 'info' });
*
* logger.info('User logged in', { userId: '123' });
* logger.error('Operation failed', new Error('Connection timeout'));
*/
function createLogger(options = {}) {
const { level = "warn", prefix = "" } = options;
const logLevels = {
debug: 0,
info: 1,
warn: 2,
error: 3,
none: 4
};
const currentLevelValue = logLevels[level];
const formatArgs = (args) => {
if (args.length === 0 || args.every((arg) => arg === undefined || arg === null)) {
return "";
}
const formatted = args.map((arg) => {
if (arg instanceof Error) {
return `\n${arg.stack || arg.message}`;
}
if (typeof arg === "object" && arg !== null) {
return `\n${JSON.stringify(arg, null, 2)}`;
}
return ` ${String(arg)}`;
}).join("");
return `, args:${formatted}`;
};
const shouldLog = (level$1) => {
return logLevels[level$1] >= currentLevelValue;
};
return {
debug: (message, ...args) => {
if (shouldLog("debug")) {
console.debug(`\x1b[32m${prefix}[DEBUG] ${maskTokens(message)}${maskTokens(formatArgs(args))}\x1b[0m`);
}
},
info: (message, ...args) => {
if (shouldLog("info")) {
console.info(`\x1b[34m${prefix}[INFO] ${maskTokens(message)}${maskTokens(formatArgs(args))}\x1b[0m`);
}
},
warn: (message, ...args) => {
if (shouldLog("warn")) {
console.warn(`\x1b[33m${prefix}[WARN] ${maskTokens(message)}${maskTokens(formatArgs(args))}\x1b[0m`);
}
},
error: (message, ...args) => {
if (shouldLog("error")) {
console.error(`\x1b[31m${prefix}[ERROR] ${maskTokens(message)}${maskTokens(formatArgs(args))}\x1b[0m`);
}
}
};
}
/**
* Default logger instance with standard configuration
*/
const logger = createLogger();
//#endregion
//#region src/retry.ts
/**
* Retry a function when it fails.
* @param fn - The function to retry.
* @param maxRetries - The maximum number of retries.
* @param initialSleepTime - The initial time to sleep between exponential backoff retries.
* @param stopOnError - The function to stop on error.
* @returns The result of the function or undefined if it fails.
* @example
* import { retryWhenFailed } from "@settlemint/sdk-utils";
* import { readFile } from "node:fs/promises";
*
* const result = await retryWhenFailed(() => readFile("/path/to/file.txt"), 3, 1_000);
*/
async function retryWhenFailed(fn, maxRetries = 5, initialSleepTime = 1e3, stopOnError) {
let retries = 0;
const maxAttempts = maxRetries + 1;
while (retries < maxAttempts) {
try {
return await fn();
} catch (e) {
const error = e;
if (typeof stopOnError === "function") {
if (stopOnError(error)) {
throw error;
}
}
if (retries >= maxRetries) {
throw e;
}
const baseDelay = 2 ** retries * initialSleepTime;
const jitterAmount = initialSleepTime * (Math.random() / 10);
const delay = baseDelay + jitterAmount;
retries += 1;
logger.warn(`An error occurred ${error.message}, retrying in ${delay.toFixed(0)}ms (retry ${retries} of ${maxRetries})...`);
await new Promise((resolve) => setTimeout(resolve, delay));
}
}
throw new Error("Retry failed");
}
//#endregion
exports.retryWhenFailed = retryWhenFailed;
//# sourceMappingURL=retry.cjs.map