From e586d7d704d475afe3373a1de6ae20d504f79d6d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 5 Jun 2025 14:25:23 +0000 Subject: Sync from a8e1c0a7402940e0fc5beef669522b315052df1b --- packages/astro-rss/src/util.ts | 53 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 packages/astro-rss/src/util.ts (limited to 'packages/astro-rss/src/util.ts') diff --git a/packages/astro-rss/src/util.ts b/packages/astro-rss/src/util.ts new file mode 100644 index 000000000..43de370dd --- /dev/null +++ b/packages/astro-rss/src/util.ts @@ -0,0 +1,53 @@ +import type { z } from 'astro/zod'; +import type { RSSOptions } from './index.js'; + +/** Normalize URL to its canonical form */ +export function createCanonicalURL( + url: string, + trailingSlash?: RSSOptions['trailingSlash'], + base?: string, +): string { + let pathname = url.replace(/\/index.html$/, ''); // index.html is not canonical + if (!getUrlExtension(url)) { + // add trailing slash if there’s no extension or `trailingSlash` is true + pathname = pathname.replace(/\/*$/, '/'); + } + + pathname = pathname.replace(/\/+/g, '/'); // remove duplicate slashes (URL() won’t) + + const canonicalUrl = new URL(pathname, base).href; + if (trailingSlash === false) { + // remove the trailing slash + return canonicalUrl.replace(/\/*$/, ''); + } + return canonicalUrl; +} + +/** Check if a URL is already valid */ +export function isValidURL(url: string): boolean { + try { + new URL(url); + return true; + } catch {} + return false; +} + +function getUrlExtension(url: string) { + const lastDot = url.lastIndexOf('.'); + const lastSlash = url.lastIndexOf('/'); + return lastDot > lastSlash ? url.slice(lastDot + 1) : ''; +} + +const flattenErrorPath = (errorPath: (string | number)[]) => errorPath.join('.'); + +export const errorMap: z.ZodErrorMap = (error, ctx) => { + if (error.code === 'invalid_type') { + const badKeyPath = JSON.stringify(flattenErrorPath(error.path)); + if (error.received === 'undefined') { + return { message: `${badKeyPath} is required.` }; + } else { + return { message: `${badKeyPath} should be ${error.expected}, not ${error.received}.` }; + } + } + return { message: ctx.defaultError }; +}; -- cgit v1.2.3