import { z } from "zod";
export enum ResponseFormat {
MARKDOWN = "markdown",
JSON = "json",
}
export const ResponseFormatSchema = z.nativeEnum(ResponseFormat)
.default(ResponseFormat.MARKDOWN)
.describe("Output format: 'markdown' for human-readable or 'json' for machine-readable");
export const PaginationSchema = z.object({
limit: z.number().int().min(1).max(100).default(25)
.describe("Maximum number of results to return (1-100, default: 25)"),
offset: z.number().int().min(0).default(0)
.describe("Number of results to skip for pagination (default: 0)"),
});
export const IdSchema = z.string().min(1).describe("Resource ID");
export const ResourceIdSchema = z.object({
id: IdSchema,
});
/**
* Format a date string for human-readable display.
*/
export function formatDate(dateStr?: string | null): string {
if (!dateStr) return "N/A";
try {
return new Date(dateStr).toLocaleDateString("en-US", {
year: "numeric",
month: "short",
day: "numeric",
});
} catch {
return dateStr;
}
}
/**
* Format a datetime string for human-readable display.
*/
export function formatDateTime(dateStr?: string | null): string {
if (!dateStr) return "N/A";
try {
return new Date(dateStr).toLocaleString("en-US", {
year: "numeric",
month: "short",
day: "numeric",
hour: "2-digit",
minute: "2-digit",
});
} catch {
return dateStr;
}
}
/**
* Format cents as a dollar amount string.
*/
export function formatCents(cents?: number | null, currency = "USD"): string {
if (cents == null) return "N/A";
return new Intl.NumberFormat("en-US", { style: "currency", currency }).format(cents / 100);
}
/**
* Build pagination metadata for responses.
*/
export function buildPaginationMeta(
total: number,
count: number,
offset: number
) {
const hasMore = total > offset + count;
return {
total,
count,
offset,
has_more: hasMore,
...(hasMore ? { next_offset: offset + count } : {}),
};
}
/**
* Truncate a response string if it exceeds the character limit.
*/
export function truncateIfNeeded(
text: string,
limit: number,
hint: string
): string {
if (text.length <= limit) return text;
return text.slice(0, limit) + `\n\n[Response truncated. ${hint}]`;
}