astro/packages/astro-rss/src/util.ts
Ben Holmes 81dce94f2a
[RSS] Get ready for content collections (#5851)
* chore: strictNullChecks for zod

* feat: expose `rssSchema` helper

* refactor: align types with schema types

* feat: break glob handler to globToRssItems util

* refactor: RSS options validation to Zod

* refactor: avoid intermediate type

* fix: allow numbers and dates in pubDate

* test: update glob and error tests

* feat: add rss to with-content starter

* fix: move globToRssItems back to internal behavior

* chore: JSON.stringify

* Revert "fix: move globToRssItems back to internal behavior"

This reverts commit 85305075e6444907455541b24bccbccd5016951a.

* test: missing url

* docs: `import.meta.env.SITE` -> `context.site`

* docs: update README to content collections example

* fix: url -> link

* docs: add `rssSchema` to README

* chore: consistent formatting

* docs: add `pagesGlobToRssItems()` reference

* chore: globToRssItems -> pagesGlobToRssItems

* chore: changeset

* fix: bad docs line highlighting

* fix: add collections export to example

* nit: remove "our"

* fix: are -> all

* fix: more README edits

* deps: kleur

* chore: add back import.meta.glob handling as deprecated

* docs: bump down to `minor`, update headline to be less content collections-y

* typo: suggest adding

* chore: support URL object on `site`

* docs: add await to pagesGlob ex

* docs: tighten `rssSchema` explainer

* docs: tighten pagesGlobToRssItems section

* docs: add content to README

* docs: replace examples with docs link

* docs: re-we

Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>

Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
2023-01-19 11:24:55 -05:00

39 lines
1.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { z } from 'astro/zod';
/** Normalize URL to its canonical form */
export function createCanonicalURL(url: string, base?: string): URL {
let pathname = url.replace(/\/index.html$/, ''); // index.html is not canonical
pathname = pathname.replace(/\/1\/?$/, ''); // neither is a trailing /1/ (impl. detail of collections)
if (!getUrlExtension(url)) pathname = pathname.replace(/(\/+)?$/, '/'); // add trailing slash if theres no extension
pathname = pathname.replace(/\/+/g, '/'); // remove duplicate slashes (URL() wont)
return new URL(pathname, base);
}
/** Check if a URL is already valid */
export function isValidURL(url: string): boolean {
try {
new URL(url);
return true;
} catch (e) {}
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 };
};