summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/lint.mts70
1 files changed, 70 insertions, 0 deletions
diff --git a/scripts/lint.mts b/scripts/lint.mts
new file mode 100644
index 0000000..9a9e6df
--- /dev/null
+++ b/scripts/lint.mts
@@ -0,0 +1,70 @@
+import fs from 'node:fs/promises';
+import path from 'node:path';
+import fg from 'fast-glob';
+import { getTableOfContents } from 'fumadocs-core/server';
+import { createGetUrl, getSlugs, parseFilePath } from 'fumadocs-core/source';
+import { remarkInclude } from 'fumadocs-mdx/config';
+import matter from 'gray-matter';
+import { printErrors, scanURLs, validateFiles } from 'next-validate-link';
+import remarkMdx from 'remark-mdx';
+
+async function readFromPath(file: string) {
+ const content = await fs
+ .readFile(path.resolve(file))
+ .then((res) => res.toString());
+ const parsed = matter(content);
+
+ return {
+ path: file,
+ data: parsed.data,
+ content: parsed.content,
+ };
+}
+
+async function checkLinks() {
+ const blogFiles = await Promise.all(
+ await fg('content/**/*.mdx').then((files) => files.map(readFromPath)),
+ );
+
+ const blogs = blogFiles.map(async (file) => {
+ const info = parseFilePath(path.relative('content', file.path));
+
+ return {
+ value: getSlugs(info)[0],
+ hashes: (
+ await getTableOfContents(
+ {
+ path: file.path,
+ value: file.content,
+ },
+ [remarkMdx, remarkInclude],
+ )
+ ).map((item) => item.url.slice(1)),
+ };
+ });
+
+ const scanned = await scanURLs({
+ populate: {
+ '(home)/posts/[slug]': await Promise.all(blogs),
+ },
+ });
+
+ console.log(
+ `collected ${scanned.urls.size} URLs, ${scanned.fallbackUrls.length} fallbacks`,
+ );
+
+ const getUrl = createGetUrl('/posts');
+ printErrors(
+ await validateFiles([...blogFiles], {
+ scanned,
+
+ pathToUrl(value) {
+ const info = parseFilePath(path.relative('content', value));
+ return getUrl(getSlugs(info));
+ },
+ }),
+ true,
+ );
+}
+
+void checkLinks();