Files
klz-cables.com/lib/pages.ts

104 lines
3.1 KiB
TypeScript

import fs from 'fs/promises';
import path from 'path';
import matter from 'gray-matter';
import { config } from '@/lib/config';
export interface PageFrontmatter {
title: string;
excerpt: string;
featuredImage: string | null;
focalX?: number;
focalY?: number;
layout?: 'default' | 'fullBleed';
public?: boolean;
}
export interface PageData {
slug: string;
redirectUrl?: string;
redirectPermanent?: boolean;
frontmatter: PageFrontmatter;
content: any; // Lexical AST Document
}
function mapDoc(doc: any): PageData {
return {
slug: doc.slug,
frontmatter: {
title: doc.title,
excerpt: doc.excerpt || '',
featuredImage:
typeof doc.featuredImage === 'object' && doc.featuredImage !== null
? doc.featuredImage.sizes?.card?.url || doc.featuredImage.url
: null,
focalX:
typeof doc.featuredImage === 'object' && doc.featuredImage !== null
? doc.featuredImage.focalX
: 50,
focalY:
typeof doc.featuredImage === 'object' && doc.featuredImage !== null
? doc.featuredImage.focalY
: 50,
layout: doc.layout || 'default',
} as PageFrontmatter,
content: doc.content as any,
};
}
export async function getPageBySlug(slug: string, locale: string): Promise<PageData | null> {
try {
const filePath = path.join(process.cwd(), 'content', 'pages', `${slug}.mdx`);
const fileContent = await fs.readFile(filePath, 'utf-8');
const { data, content } = matter(fileContent);
let parsedContent = content;
try {
if (content.trim().startsWith('{')) {
parsedContent = JSON.parse(content);
}
} catch (e) {
// Not JSON
}
return {
slug,
redirectUrl: data.redirectUrl,
redirectPermanent: data.redirectPermanent ?? true,
frontmatter: {
title: data.title || '',
excerpt: data.excerpt || '',
featuredImage: data.featuredImage?.url || data.featuredImage || null,
focalX: data.featuredImage?.focalX || data.focalX || 50,
focalY: data.featuredImage?.focalY || data.focalY || 50,
layout: data.layout === 'fullBleed' || data.layout === 'default' ? data.layout : 'default',
public: data.public ?? true,
},
content: parsedContent,
};
} catch (error) {
console.error(`getPageBySlug failed for ${slug}:`, error);
return null;
}
}
export async function getAllPages(locale: string): Promise<PageData[]> {
try {
const dir = path.join(process.cwd(), 'content', 'pages');
const files = await fs.readdir(dir);
const slugs = files.filter((f) => f.endsWith('.mdx')).map((f) => f.replace('.mdx', ''));
const pages = await Promise.all(slugs.map((slug) => getPageBySlug(slug, locale)));
return pages.filter((p): p is PageData => p !== null);
} catch (error) {
console.error(`getAllPages failed for ${locale}:`, error);
return [];
}
}
export async function getAllPagesMetadata(locale: string): Promise<Partial<PageData>[]> {
const pages = await getAllPages(locale);
return pages.map((p) => ({
slug: p.slug,
frontmatter: p.frontmatter,
}));
}