import fs from 'fs'; import path from 'path'; import matter from 'gray-matter'; import { mapSlugToFileSlug } from './slugs'; export interface ProductFrontmatter { title: string; sku: string; description: string; categories: string[]; images: string[]; locale: string; } export interface ProductMdx { slug: string; frontmatter: ProductFrontmatter; content: string; } export async function getProductMetadata( slug: string, locale: string, ): Promise | null> { // Map translated slug to file slug const fileSlug = await mapSlugToFileSlug(slug, locale); const productsDir = path.join(process.cwd(), 'data', 'products', locale); // Try exact slug first let filePath = path.join(productsDir, `${fileSlug}.mdx`); if (!fs.existsSync(filePath)) { // Try with -2 suffix (common in the dumped files) filePath = path.join(productsDir, `${fileSlug}-2.mdx`); } if (!fs.existsSync(filePath)) { // Fallback to English if locale is not 'en' if (locale !== 'en') { const enProductsDir = path.join(process.cwd(), 'data', 'products', 'en'); let enFilePath = path.join(enProductsDir, `${fileSlug}.mdx`); if (!fs.existsSync(enFilePath)) { enFilePath = path.join(enProductsDir, `${fileSlug}-2.mdx`); } if (fs.existsSync(enFilePath)) { const fileContent = fs.readFileSync(enFilePath, 'utf8'); const { data } = matter(fileContent); return { slug: fileSlug, frontmatter: { ...data, isFallback: true, } as ProductFrontmatter & { isFallback?: boolean }, }; } } } else { const fileContent = fs.readFileSync(filePath, 'utf8'); const { data } = matter(fileContent); return { slug: fileSlug, frontmatter: data as ProductFrontmatter, }; } return null; } export async function getProductBySlug(slug: string, locale: string): Promise { // Map translated slug to file slug const fileSlug = await mapSlugToFileSlug(slug, locale); const productsDir = path.join(process.cwd(), 'data', 'products', locale); // Try exact slug first let filePath = path.join(productsDir, `${fileSlug}.mdx`); if (!fs.existsSync(filePath)) { // Try with -2 suffix (common in the dumped files) filePath = path.join(productsDir, `${fileSlug}-2.mdx`); } let product: ProductMdx | null = null; if (!fs.existsSync(filePath)) { // Fallback to English if locale is not 'en' if (locale !== 'en') { const enProductsDir = path.join(process.cwd(), 'data', 'products', 'en'); let enFilePath = path.join(enProductsDir, `${fileSlug}.mdx`); if (!fs.existsSync(enFilePath)) { enFilePath = path.join(enProductsDir, `${fileSlug}-2.mdx`); } if (fs.existsSync(enFilePath)) { const fileContent = fs.readFileSync(enFilePath, 'utf8'); const { data, content } = matter(fileContent); product = { slug: fileSlug, frontmatter: { ...data, isFallback: true, } as ProductFrontmatter & { isFallback?: boolean }, content, }; } } } else { const fileContent = fs.readFileSync(filePath, 'utf8'); const { data, content } = matter(fileContent); product = { slug: fileSlug, frontmatter: data as ProductFrontmatter, content, }; } // Filter out products without images if ( product && (!product.frontmatter.images || product.frontmatter.images.length === 0 || !product.frontmatter.images[0]) ) { return null; } return product; } export async function getAllProductSlugs(locale: string): Promise { const productsDir = path.join(process.cwd(), 'data', 'products', locale); if (!fs.existsSync(productsDir)) return []; const files = fs.readdirSync(productsDir); return files.filter((file) => file.endsWith('.mdx')).map((file) => file.replace(/\.mdx$/, '')); } export async function getAllProducts(locale: string): Promise { const slugs = await getAllProductSlugs(locale); let allSlugs = slugs; if (locale !== 'en') { const enSlugs = await getAllProductSlugs('en'); allSlugs = Array.from(new Set([...slugs, ...enSlugs])); } const products = await Promise.all(allSlugs.map((slug) => getProductBySlug(slug, locale))); return products.filter((p): p is ProductMdx => p !== null); } export async function getAllProductsMetadata(locale: string): Promise[]> { const slugs = await getAllProductSlugs(locale); let allSlugs = slugs; if (locale !== 'en') { const enSlugs = await getAllProductSlugs('en'); allSlugs = Array.from(new Set([...slugs, ...enSlugs])); } const metadata = await Promise.all(allSlugs.map((slug) => getProductMetadata(slug, locale))); return metadata.filter((m): m is Partial => m !== null); }