aboutsummaryrefslogtreecommitdiff
path: root/packages/astro-rss/src/util.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/astro-rss/src/util.ts')
-rw-r--r--packages/astro-rss/src/util.ts53
1 files changed, 53 insertions, 0 deletions
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 };
+};