Files
nexcurrency/lib/share-link.ts

85 lines
1.8 KiB
TypeScript

import { validateAmount } from "@/lib/validation";
interface QueryParamReader {
get(name: string): string | null;
}
interface ConversionShareParams {
amount?: string;
fromCode?: string;
toCode?: string;
}
const CODE_PATTERN = /^[A-Z0-9]{2,12}$/;
function normalizeCurrencyCode(value: string | null): string | undefined {
if (!value) {
return undefined;
}
const normalized = value.trim().toUpperCase();
if (!CODE_PATTERN.test(normalized)) {
return undefined;
}
return normalized;
}
function normalizeAmount(value: string | null): string | undefined {
if (!value) {
return undefined;
}
const trimmed = value.trim().replace(/\s+/g, "");
if (!trimmed || trimmed.length > 64) {
return undefined;
}
return validateAmount(trimmed).ok ? trimmed : undefined;
}
export function parseConversionShareParams(
searchParams: QueryParamReader,
): ConversionShareParams {
const amount = normalizeAmount(searchParams.get("amount"));
const fromCode = normalizeCurrencyCode(searchParams.get("from"));
let toCode = normalizeCurrencyCode(searchParams.get("to"));
if (fromCode && toCode && fromCode === toCode) {
toCode = undefined;
}
return {
amount,
fromCode,
toCode,
};
}
export function buildConversionShareUrl(input: {
origin: string;
pathname: string;
amount: string;
fromCode: string;
toCode: string;
}): string {
const url = new URL(input.pathname, input.origin);
const amount = normalizeAmount(input.amount) ?? "1";
const fromCode = normalizeCurrencyCode(input.fromCode);
const toCode = normalizeCurrencyCode(input.toCode);
url.searchParams.set("amount", amount);
if (fromCode) {
url.searchParams.set("from", fromCode);
}
if (toCode && toCode !== fromCode) {
url.searchParams.set("to", toCode);
}
return url.toString();
}