Skip to main content
Glama
util.ts2.91 kB
import crypto from "node:crypto"; import type { ErrorDetail, ToolExecutionError } from "./types.js"; export function envBoolean( key: string, defaultValue: boolean, ): boolean { const value = process.env[key]; if (typeof value === "undefined" || value === "") { return defaultValue; } return ["1", "true", "yes", "on"].includes(value.toLowerCase()); } export function envString( key: string, defaultValue?: string, ): string | undefined { const value = process.env[key]; if (typeof value === "undefined" || value === "") { return defaultValue; } return value; } export function sha256(content: string): string { return crypto.createHash("sha256").update(content).digest("hex"); } export function createError(detail: ErrorDetail): ToolExecutionError { const error = new Error(detail.message) as ToolExecutionError; error.detail = detail; return error; } export function isToolExecutionError( error: unknown, ): error is ToolExecutionError { return ( error instanceof Error && typeof (error as ToolExecutionError).detail !== "undefined" ); } export function guessFrmrTypeFromFilename(filename: string): string { const match = filename.match(/^FRMR\.([A-Z]+)\./i); if (match) { return match[1].toUpperCase(); } return "unknown"; } export function normalizePath(path: string): string { return path.replace(/\\/g, "/"); } export function detectIdKey(obj: unknown): string | null { if (!Array.isArray(obj)) { return null; } const keys = ["id", "uid", "name"]; for (const key of keys) { if (obj.some((item) => item && typeof item === "object" && key in item)) { return key; } } return null; } export function extractControlLikeStrings(input: unknown): string[] { if (typeof input === "string") { return findControlIds(input); } if (Array.isArray(input)) { return input.flatMap((value) => extractControlLikeStrings(value)); } if (input && typeof input === "object") { return Object.values(input).flatMap((value) => extractControlLikeStrings(value), ); } return []; } const CONTROL_PATTERN = /\b([A-Z]{2}-\d{1,3}(?:\([\dA-Za-z]+\))*)\b/g; export function findControlIds(text: string): string[] { const matches = new Set<string>(); let match: RegExpExecArray | null; while ((match = CONTROL_PATTERN.exec(text)) !== null) { matches.add(match[1]); } return [...matches]; } export function unique<T>(values: Iterable<T>): T[] { return Array.from(new Set(values)); } export function clamp(value: number, min: number, max: number): number { return Math.min(Math.max(value, min), max); } export interface Timer { stop: () => number; } export function startTimer(): Timer { const start = process.hrtime.bigint(); return { stop: () => { const diff = process.hrtime.bigint() - start; return Number(diff) / 1_000_000; // ms }, }; }

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/ethanolivertroy/fedramp-docs-mcp'

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