vaza-content 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/astro/index.cjs +9 -15
- package/dist/adapters/astro/index.cjs.map +1 -1
- package/dist/adapters/astro/index.d.cts +4 -3
- package/dist/adapters/astro/index.d.ts +4 -3
- package/dist/adapters/astro/index.js +6 -12
- package/dist/adapters/astro/index.js.map +1 -1
- package/dist/adapters/next/index.cjs +11 -12
- package/dist/adapters/next/index.cjs.map +1 -1
- package/dist/adapters/next/index.d.cts +5 -3
- package/dist/adapters/next/index.d.ts +5 -3
- package/dist/adapters/next/index.js +8 -9
- package/dist/adapters/next/index.js.map +1 -1
- package/dist/adapters/nuxt/index.cjs +22 -22
- package/dist/adapters/nuxt/index.cjs.map +1 -1
- package/dist/adapters/nuxt/index.d.cts +11 -7
- package/dist/adapters/nuxt/index.d.ts +11 -7
- package/dist/adapters/nuxt/index.js +13 -13
- package/dist/adapters/nuxt/index.js.map +1 -1
- package/dist/adapters/sveltekit/index.cjs +9 -15
- package/dist/adapters/sveltekit/index.cjs.map +1 -1
- package/dist/adapters/sveltekit/index.d.cts +3 -2
- package/dist/adapters/sveltekit/index.d.ts +3 -2
- package/dist/adapters/sveltekit/index.js +5 -11
- package/dist/adapters/sveltekit/index.js.map +1 -1
- package/dist/{blog-7EEJJG26.js → blog-L7HRY3QC.js} +2 -4
- package/dist/{blog-7EEJJG26.js.map → blog-L7HRY3QC.js.map} +1 -1
- package/dist/{blog-Z3R5GOMP.cjs → blog-SEXXJJSV.cjs} +3 -5
- package/dist/blog-SEXXJJSV.cjs.map +1 -0
- package/dist/{chunk-YV2ZYIAD.cjs → chunk-H3D7F4TA.cjs} +544 -503
- package/dist/chunk-H3D7F4TA.cjs.map +1 -0
- package/dist/{chunk-FALSVGPG.js → chunk-OKXBDPYF.js} +511 -470
- package/dist/chunk-OKXBDPYF.js.map +1 -0
- package/dist/cli/index.cjs +30 -24
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +29 -23
- package/dist/cli/index.js.map +1 -1
- package/dist/{dark-EX2GRAYK.cjs → dark-66ZWYLT7.cjs} +2 -4
- package/dist/dark-66ZWYLT7.cjs.map +1 -0
- package/dist/{dark-6E36AKLN.js → dark-SZOURAMM.js} +1 -3
- package/dist/{dark-6E36AKLN.js.map → dark-SZOURAMM.js.map} +1 -1
- package/dist/index.cjs +8 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -29
- package/dist/index.d.ts +29 -29
- package/dist/index.js +3 -6
- package/dist/index.js.map +1 -1
- package/dist/{minimal-D2PRAVG6.js → minimal-CGXF737F.js} +1 -3
- package/dist/{minimal-D2PRAVG6.js.map → minimal-CGXF737F.js.map} +1 -1
- package/dist/{minimal-RHOK4XEZ.cjs → minimal-XTTHXE3T.cjs} +2 -4
- package/dist/minimal-XTTHXE3T.cjs.map +1 -0
- package/dist/process-VXDWM664.cjs +7 -0
- package/dist/process-VXDWM664.cjs.map +1 -0
- package/dist/process-ZQV5M2TB.js +7 -0
- package/dist/{product-OT3XYMWD.cjs → product-BY3GVQGV.cjs} +2 -4
- package/dist/product-BY3GVQGV.cjs.map +1 -0
- package/dist/{product-NCUW3U72.js → product-UQXUI5YL.js} +1 -3
- package/dist/{product-NCUW3U72.js.map → product-UQXUI5YL.js.map} +1 -1
- package/dist/{types-CgaidvaB.d.cts → types-DAfWIHiD.d.cts} +1 -1
- package/dist/{types-CgaidvaB.d.ts → types-DAfWIHiD.d.ts} +1 -1
- package/package.json +6 -4
- package/dist/blog-Z3R5GOMP.cjs.map +0 -1
- package/dist/chunk-DGUM43GV.js +0 -11
- package/dist/chunk-FALSVGPG.js.map +0 -1
- package/dist/chunk-JEQ2X3Z6.cjs +0 -11
- package/dist/chunk-JEQ2X3Z6.cjs.map +0 -1
- package/dist/chunk-PCRQY47G.js +0 -35
- package/dist/chunk-PCRQY47G.js.map +0 -1
- package/dist/chunk-WOCXEBQC.cjs +0 -35
- package/dist/chunk-WOCXEBQC.cjs.map +0 -1
- package/dist/chunk-YV2ZYIAD.cjs.map +0 -1
- package/dist/dark-EX2GRAYK.cjs.map +0 -1
- package/dist/logger-7WBTEDED.cjs +0 -10
- package/dist/logger-7WBTEDED.cjs.map +0 -1
- package/dist/logger-BGP7C274.js +0 -10
- package/dist/logger-BGP7C274.js.map +0 -1
- package/dist/minimal-RHOK4XEZ.cjs.map +0 -1
- package/dist/process-B4PJ6CWC.cjs +0 -9
- package/dist/process-B4PJ6CWC.cjs.map +0 -1
- package/dist/process-KSSXQJE6.js +0 -9
- package/dist/process-KSSXQJE6.js.map +0 -1
- package/dist/product-OT3XYMWD.cjs.map +0 -1
- /package/dist/{chunk-DGUM43GV.js.map → process-ZQV5M2TB.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/generate/json-ld/article.ts","../src/generate/breadcrumbs.ts","../src/generate/json-ld/breadcrumb.ts","../src/generate/json-ld/event.ts","../src/generate/json-ld/faq.ts","../src/generate/json-ld/how-to.ts","../src/generate/json-ld/product.ts","../src/generate/json-ld/recipe.ts","../src/generate/json-ld/index.ts","../src/generate/og-images.ts","../src/constants.ts","../src/logger.ts","../src/utils/concurrency.ts","../src/generate/redirects.ts","../src/utils/levenshtein.ts","../src/generate/rss.ts","../src/generate/sitemap.ts","../src/generate/taxonomy.ts","../src/integrity/alt-text.ts","../src/integrity/broken-links.ts","../src/integrity/duplicate-content.ts","../src/integrity/duplicate-slugs.ts","../src/integrity/freshness.ts","../src/integrity/meta-length.ts","../src/integrity/orphan-pages.ts","../src/integrity/index.ts","../src/normalize/blur-placeholder.ts","../src/normalize/excerpt.ts","../src/normalize/description.ts","../src/normalize/image-dimensions.ts","../src/normalize/word-count.ts","../src/normalize/reading-time.ts","../src/normalize/slug.ts","../src/normalize/toc.ts","../src/normalize/index.ts","../src/process.ts"],"sourcesContent":["import type { SiteConfig, VazaEntry } from \"../../types.js\";\n\n/**\n * Generate Article/BlogPosting schema.\n * Triggered when entry has title + publishDate.\n */\nexport function generateArticleSchema(\n entry: VazaEntry,\n site: SiteConfig,\n): Record<string, unknown> | null {\n if (!entry.title || !entry.publishDate) {\n return null;\n }\n\n const schema: Record<string, unknown> = {\n \"@context\": \"https://schema.org\",\n \"@type\": entry.jsonLdType === \"Article\" ? \"Article\" : \"BlogPosting\",\n headline: entry.title,\n description: entry.description || entry.excerpt,\n datePublished: entry.publishDate.toISOString(),\n publisher: {\n \"@type\": \"Organization\",\n name: site.name,\n ...(site.url && { url: site.url }),\n },\n };\n\n if (entry.author) {\n schema.author = {\n \"@type\": \"Person\",\n name: entry.author.name,\n ...(entry.author.url && { url: entry.author.url }),\n };\n }\n\n if (entry.updateDate) {\n schema.dateModified = entry.updateDate.toISOString();\n }\n\n if (entry.image) {\n schema.image = {\n \"@type\": \"ImageObject\",\n url: entry.image.src.startsWith(\"http\")\n ? entry.image.src\n : `${site.url.replace(/\\/$/, \"\")}${entry.image.src}`,\n ...(entry.image.width && { width: entry.image.width }),\n ...(entry.image.height && { height: entry.image.height }),\n };\n }\n\n if (entry.wordCount) {\n schema.wordCount = entry.wordCount;\n }\n\n return schema;\n}\n","export interface BreadcrumbItem {\n name: string;\n url: string;\n}\n\n/**\n * Generate breadcrumb items from a slug.\n * Splits by \"/\" and creates array of {name, url} pairs.\n * Includes Home as first item.\n */\nexport function generateBreadcrumbs(\n slug: string,\n title: string,\n siteUrl: string,\n basePath: string,\n): BreadcrumbItem[] {\n const url = siteUrl.replace(/\\/$/, \"\");\n const path = basePath.replace(/\\/$/, \"\");\n\n const items: BreadcrumbItem[] = [{ name: \"Home\", url: `${url}/` }];\n\n // Add base path segments if they exist\n if (path) {\n const pathSegments = path.split(\"/\").filter(Boolean);\n let accumulated = url;\n for (const segment of pathSegments) {\n accumulated += `/${segment}`;\n items.push({\n name: segment.charAt(0).toUpperCase() + segment.slice(1),\n url: `${accumulated}/`,\n });\n }\n }\n\n // Split slug by \"/\" for nested slugs\n const slugSegments = slug.split(\"/\").filter(Boolean);\n\n if (slugSegments.length > 1) {\n let accumulated = `${url}${path}`;\n // Add intermediate slug segments (not the last one)\n for (let i = 0; i < slugSegments.length - 1; i++) {\n accumulated += `/${slugSegments[i]}`;\n const segmentName = slugSegments[i]\n .replace(/-/g, \" \")\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n items.push({\n name: segmentName,\n url: `${accumulated}/`,\n });\n }\n }\n\n // Add the current page (final item uses the provided title)\n items.push({\n name: title,\n url: `${url}${path}/${slug}`,\n });\n\n return items;\n}\n","import type { SiteConfig, VazaEntry } from \"../../types.js\";\nimport { generateBreadcrumbs } from \"../breadcrumbs.js\";\n\n/**\n * Generate BreadcrumbList schema.\n * Always generated for every entry.\n */\nexport function generateBreadcrumbSchema(\n entry: VazaEntry,\n site: SiteConfig,\n basePath: string,\n): Record<string, unknown> {\n const siteUrl = site.url.replace(/\\/$/, \"\");\n const crumbs = generateBreadcrumbs(\n entry.slug,\n entry.title,\n siteUrl,\n basePath,\n );\n\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"BreadcrumbList\",\n itemListElement: crumbs.map((crumb, index) => ({\n \"@type\": \"ListItem\",\n position: index + 1,\n name: crumb.name,\n item: crumb.url,\n })),\n };\n}\n","import type { SiteConfig, VazaEntry } from \"../../types.js\";\n\n/**\n * Generate Event schema.\n * Triggered when entry has eventDate.\n */\nexport function generateEventSchema(\n entry: VazaEntry,\n site: SiteConfig,\n): Record<string, unknown> | null {\n if (!entry.eventDate) {\n return null;\n }\n\n const schema: Record<string, unknown> = {\n \"@context\": \"https://schema.org\",\n \"@type\": \"Event\",\n name: entry.title,\n description: entry.description || entry.excerpt,\n startDate: entry.eventDate.toISOString(),\n organizer: {\n \"@type\": \"Organization\",\n name: site.name,\n url: site.url,\n },\n };\n\n if (entry.eventLocation) {\n schema.location = {\n \"@type\": \"Place\",\n name: entry.eventLocation,\n };\n }\n\n if (entry.image) {\n schema.image = entry.image.src.startsWith(\"http\")\n ? entry.image.src\n : `${site.url.replace(/\\/$/, \"\")}${entry.image.src}`;\n }\n\n return schema;\n}\n","import type { SiteConfig, VazaEntry } from \"../../types.js\";\n\n/**\n * Generate FAQPage schema.\n * Triggered when entry has faqs array with items.\n */\nexport function generateFaqSchema(\n entry: VazaEntry,\n _site: SiteConfig,\n): Record<string, unknown> | null {\n if (!entry.faqs || entry.faqs.length === 0) {\n return null;\n }\n\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"FAQPage\",\n mainEntity: entry.faqs.map((faq) => ({\n \"@type\": \"Question\",\n name: faq.question,\n acceptedAnswer: {\n \"@type\": \"Answer\",\n text: faq.answer,\n },\n })),\n };\n}\n","import type { SiteConfig, VazaEntry } from \"../../types.js\";\n\n/**\n * Generate HowTo schema.\n * Triggered when entry has steps array.\n */\nexport function generateHowToSchema(\n entry: VazaEntry,\n _site: SiteConfig,\n): Record<string, unknown> | null {\n if (!entry.steps || entry.steps.length === 0) {\n return null;\n }\n\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"HowTo\",\n name: entry.title,\n description: entry.description || entry.excerpt,\n step: entry.steps.map((step, index) => ({\n \"@type\": \"HowToStep\",\n position: index + 1,\n name: step.name,\n text: step.text,\n })),\n };\n}\n","import type { SiteConfig, VazaEntry } from \"../../types.js\";\n\n/**\n * Generate Product schema.\n * Triggered when entry has price.\n */\nexport function generateProductSchema(\n entry: VazaEntry,\n site: SiteConfig,\n): Record<string, unknown> | null {\n if (!entry.price) {\n return null;\n }\n\n const schema: Record<string, unknown> = {\n \"@context\": \"https://schema.org\",\n \"@type\": \"Product\",\n name: entry.title,\n description: entry.description || entry.excerpt,\n offers: {\n \"@type\": \"Offer\",\n price: entry.price.amount,\n priceCurrency: entry.price.currency,\n availability: \"https://schema.org/InStock\",\n },\n };\n\n if (entry.image) {\n schema.image = entry.image.src.startsWith(\"http\")\n ? entry.image.src\n : `${site.url.replace(/\\/$/, \"\")}${entry.image.src}`;\n }\n\n return schema;\n}\n","import type { SiteConfig, VazaEntry } from \"../../types.js\";\n\n/**\n * Generate Recipe schema.\n * Triggered when entry has ingredients.\n */\nexport function generateRecipeSchema(\n entry: VazaEntry,\n site: SiteConfig,\n): Record<string, unknown> | null {\n if (!entry.ingredients || entry.ingredients.length === 0) {\n return null;\n }\n\n const schema: Record<string, unknown> = {\n \"@context\": \"https://schema.org\",\n \"@type\": \"Recipe\",\n name: entry.title,\n description: entry.description || entry.excerpt,\n recipeIngredient: entry.ingredients,\n };\n\n if (entry.cookTime) {\n schema.cookTime = entry.cookTime;\n }\n\n if (entry.author) {\n schema.author = {\n \"@type\": \"Person\",\n name: entry.author.name,\n };\n }\n\n if (entry.image) {\n schema.image = entry.image.src.startsWith(\"http\")\n ? entry.image.src\n : `${site.url.replace(/\\/$/, \"\")}${entry.image.src}`;\n }\n\n return schema;\n}\n","import type { SiteConfig, VazaConfig, VazaEntry } from \"../../types.js\";\nimport { generateArticleSchema } from \"./article.js\";\nimport { generateBreadcrumbSchema } from \"./breadcrumb.js\";\nimport { generateEventSchema } from \"./event.js\";\nimport { generateFaqSchema } from \"./faq.js\";\nimport { generateHowToSchema } from \"./how-to.js\";\nimport { generateProductSchema } from \"./product.js\";\nimport { generateRecipeSchema } from \"./recipe.js\";\n\ntype SchemaGenerator = (\n entry: VazaEntry,\n site: SiteConfig,\n basePath: string,\n) => Record<string, unknown> | null;\n\n/**\n * Built-in schema generators. Each is tried for every entry;\n * if it returns non-null the schema is included.\n */\nconst builtinGenerators: SchemaGenerator[] = [\n (entry, site) => generateArticleSchema(entry, site),\n (entry, site) => generateFaqSchema(entry, site),\n (entry, site, basePath) => generateBreadcrumbSchema(entry, site, basePath),\n (entry, site) => generateHowToSchema(entry, site),\n (entry, site) => generateProductSchema(entry, site),\n (entry, site) => generateRecipeSchema(entry, site),\n (entry, site) => generateEventSchema(entry, site),\n];\n\n/**\n * Auto-detect which schemas apply to each entry and generate them.\n * Returns slug -> array of schema objects.\n */\nexport function generateJsonLd(\n entries: VazaEntry[],\n config: VazaConfig,\n): Record<string, Record<string, unknown>[]> {\n const result: Record<string, Record<string, unknown>[]> = {};\n const site = config.site;\n\n // Fallback basePath if entries aren't tagged with _basePath\n const collectionKeys = Object.keys(config.collections);\n const fallbackBasePath =\n collectionKeys.length > 0\n ? config.collections[collectionKeys[0]].basePath\n : \"\";\n\n // Collect custom schema generators from config\n const customGenerators: SchemaGenerator[] = [];\n if (config.jsonLd?.customSchemas) {\n for (const [, generator] of Object.entries(config.jsonLd.customSchemas)) {\n customGenerators.push((entry, s) => generator(entry, s));\n }\n }\n\n const allGenerators = [...builtinGenerators, ...customGenerators];\n\n for (const entry of entries) {\n const schemas: Record<string, unknown>[] = [];\n const basePath = entry._basePath ?? fallbackBasePath;\n\n for (const generator of allGenerators) {\n const schema = generator(entry, site, basePath);\n if (schema) {\n schemas.push(schema);\n }\n }\n\n if (schemas.length > 0) {\n result[entry.slug] = schemas;\n }\n }\n\n return result;\n}\n","import {\n existsSync,\n mkdirSync,\n readFileSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport {\n OG_IMAGE_CONCURRENCY,\n OG_IMAGE_HEIGHT,\n OG_IMAGE_WIDTH,\n} from \"../constants.js\";\nimport { logger } from \"../logger.js\";\nimport type { OgImagesConfig, VazaConfig, VazaEntry } from \"../types.js\";\nimport { pMap } from \"../utils/concurrency.js\";\n\nconst FONT_CACHE_DIR = \".vaza-content/fonts\";\nconst INTER_FONT_URL =\n \"https://fonts.gstatic.com/s/inter/v18/UcCO3FwrK3iLTeHuS_nVMrMxCp50SjIw2boKoduKmMEVuLyfAZ9hiA.woff2\";\n\n/**\n * Generate OG images using satori + @resvg/resvg-js.\n * Returns slug -> output path map.\n * Skips if file already exists and entry hasn't changed.\n */\nexport async function generateOgImages(\n entries: VazaEntry[],\n config: VazaConfig,\n): Promise<Record<string, string>> {\n const ogConfig = config.ogImages;\n if (!ogConfig?.enabled) return {};\n\n const outputDir = ogConfig.outputDir ?? join(process.cwd(), \"public\", \"og\");\n const template = ogConfig.template ?? \"minimal\";\n const concurrency = Math.max(1, ogConfig.concurrency ?? OG_IMAGE_CONCURRENCY);\n\n // Ensure output directory exists\n if (!existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n\n // Dynamic imports for optional dependencies\n const satori = await import(\"satori\").then((m) => m.default ?? m);\n const { Resvg } = await import(\"@resvg/resvg-js\");\n\n // Load font\n const fontData = await loadFont(ogConfig);\n\n // Load template renderer\n const templateRenderer = ogConfig.render ?? (await loadTemplate(template));\n\n const results: Record<string, string> = {};\n\n // Separate entries into cached and uncached\n const toGenerate: VazaEntry[] = [];\n for (const entry of entries) {\n const outputPath = join(outputDir, `${entry.slug}.png`);\n if (existsSync(outputPath)) {\n const stat = statSync(outputPath);\n const entryDate = entry.updateDate ?? entry.publishDate;\n if (stat.mtime >= entryDate) {\n results[entry.slug] = outputPath;\n continue;\n }\n }\n toGenerate.push(entry);\n }\n\n if (toGenerate.length === 0) {\n logger.debug(\"OG images: all cached, nothing to generate\");\n return results;\n }\n\n logger.info(\n `Generating ${toGenerate.length} OG images (concurrency: ${concurrency})`,\n );\n\n await pMap(\n toGenerate,\n async (entry) => {\n const outputPath = join(outputDir, `${entry.slug}.png`);\n\n try {\n // Render the template\n const element = templateRenderer(entry, ogConfig);\n\n // Convert to SVG with satori\n const svg = await satori(element as Parameters<typeof satori>[0], {\n width: OG_IMAGE_WIDTH,\n height: OG_IMAGE_HEIGHT,\n fonts: [\n {\n name: \"Inter\",\n data: fontData,\n weight: 400,\n style: \"normal\" as const,\n },\n ],\n });\n\n // Convert SVG to PNG with resvg\n const resvg = new Resvg(svg, {\n fitTo: { mode: \"width\" as const, value: OG_IMAGE_WIDTH },\n });\n const pngData = resvg.render();\n const pngBuffer = pngData.asPng();\n\n // Ensure parent directory exists for nested slugs\n const parentDir = dirname(outputPath);\n if (!existsSync(parentDir)) {\n mkdirSync(parentDir, { recursive: true });\n }\n\n writeFileSync(outputPath, pngBuffer);\n results[entry.slug] = outputPath;\n logger.debug(`OG image generated: ${entry.slug}`);\n } catch (err) {\n logger.error(`Failed to generate OG image for \"${entry.slug}\":`, err);\n }\n },\n concurrency,\n );\n\n return results;\n}\n\n/**\n * Load font data. Priority:\n * 1. Custom fontPath from config\n * 2. Cached Inter font\n * 3. Fetch Inter from Google Fonts and cache\n */\nasync function loadFont(config: OgImagesConfig): Promise<ArrayBuffer> {\n // 1. Custom font\n if (config.fontPath && existsSync(config.fontPath)) {\n logger.debug(`Using custom font: ${config.fontPath}`);\n const buffer = readFileSync(config.fontPath);\n return buffer.buffer.slice(\n buffer.byteOffset,\n buffer.byteOffset + buffer.byteLength,\n );\n }\n\n // 2. Cached font\n const cacheDir = join(process.cwd(), FONT_CACHE_DIR);\n const cachedPath = join(cacheDir, \"inter-regular.woff2\");\n\n if (existsSync(cachedPath)) {\n logger.debug(\"Using cached Inter font\");\n const buffer = readFileSync(cachedPath);\n return buffer.buffer.slice(\n buffer.byteOffset,\n buffer.byteOffset + buffer.byteLength,\n );\n }\n\n // 3. Fetch and cache\n logger.info(\"Downloading Inter font for OG images...\");\n try {\n const response = await fetch(INTER_FONT_URL);\n if (!response.ok) {\n throw new Error(`Font fetch failed: ${response.status}`);\n }\n const arrayBuffer = await response.arrayBuffer();\n\n if (!existsSync(cacheDir)) {\n mkdirSync(cacheDir, { recursive: true });\n }\n writeFileSync(cachedPath, Buffer.from(arrayBuffer));\n logger.debug(\"Inter font cached\");\n\n return arrayBuffer;\n } catch (err) {\n logger.warn(\"Could not fetch Inter font, using empty fallback:\", err);\n return new ArrayBuffer(0);\n }\n}\n\n/**\n * Load a built-in template renderer.\n */\nasync function loadTemplate(\n template: string,\n): Promise<(entry: VazaEntry, config: OgImagesConfig) => unknown> {\n switch (template) {\n case \"blog\": {\n const mod = await import(\"./og-templates/blog.js\");\n return mod.blogTemplate;\n }\n case \"product\": {\n const mod = await import(\"./og-templates/product.js\");\n return mod.productTemplate;\n }\n case \"dark\": {\n const mod = await import(\"./og-templates/dark.js\");\n return mod.darkTemplate;\n }\n default: {\n const mod = await import(\"./og-templates/minimal.js\");\n return mod.minimalTemplate;\n }\n }\n}\n","// Content processing\nexport const WORDS_PER_MINUTE = 200;\nexport const EXCERPT_MAX_LENGTH = 160;\n\n// SEO defaults\nexport const DEFAULT_META_TITLE_MAX = 60;\nexport const DEFAULT_META_DESC_MAX = 120;\nexport const DEFAULT_FRESHNESS_MAX_AGE = \"6m\";\nexport const DEFAULT_RSS_LIMIT = 50;\nexport const DEFAULT_SITEMAP_PRIORITY = 0.7;\nexport const DEFAULT_SITEMAP_CHANGE_FREQ = \"weekly\";\n\n// OG Images\nexport const OG_IMAGE_WIDTH = 1200;\nexport const OG_IMAGE_HEIGHT = 630;\nexport const OG_IMAGE_CONCURRENCY = 5;\n","export type LogLevel = \"silent\" | \"error\" | \"warn\" | \"info\" | \"debug\";\n\nconst LEVELS: Record<LogLevel, number> = {\n silent: 0,\n error: 1,\n warn: 2,\n info: 3,\n debug: 4,\n};\n\nlet currentLevel: LogLevel = \"info\";\n\nexport function setLogLevel(level: LogLevel): void {\n currentLevel = level;\n}\n\nfunction shouldLog(level: LogLevel): boolean {\n return LEVELS[level] <= LEVELS[currentLevel];\n}\n\nexport const logger = {\n error(...args: unknown[]) {\n if (shouldLog(\"error\")) console.error(\"[vaza-content]\", ...args);\n },\n warn(...args: unknown[]) {\n if (shouldLog(\"warn\")) console.warn(\"[vaza-content]\", ...args);\n },\n info(...args: unknown[]) {\n if (shouldLog(\"info\")) console.log(\"[vaza-content]\", ...args);\n },\n debug(...args: unknown[]) {\n if (shouldLog(\"debug\")) console.log(\"[vaza-content] [debug]\", ...args);\n },\n};\n","/**\n * Run async tasks with a concurrency limit.\n */\nexport async function pMap<T, R>(\n items: T[],\n fn: (item: T) => Promise<R>,\n concurrency: number,\n): Promise<R[]> {\n const results: R[] = new Array(items.length);\n let nextIndex = 0;\n\n async function worker() {\n while (nextIndex < items.length) {\n const index = nextIndex++;\n results[index] = await fn(items[index]);\n }\n }\n\n const workers = Array.from(\n { length: Math.min(concurrency, items.length) },\n () => worker(),\n );\n await Promise.all(workers);\n return results;\n}\n","import { execSync } from \"node:child_process\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { basename, dirname, join } from \"node:path\";\nimport { logger } from \"../logger.js\";\nimport type { RedirectEntry, VazaConfig, VazaEntry } from \"../types.js\";\nimport { similarity } from \"../utils/levenshtein.js\";\n\nconst MANIFEST_DIR = \".vaza-content\";\nconst MANIFEST_FILE = \"slugs.json\";\nconst MIN_SIMILARITY = 0.5;\n\n/**\n * Detect slug changes that need redirects.\n * Tries git diff first, falls back to reading/writing a slugs.json manifest.\n */\nexport async function detectRedirects(\n entries: VazaEntry[],\n config: VazaConfig,\n): Promise<RedirectEntry[]> {\n const strategy = config.redirects?.strategy ?? \"both\";\n const redirects: RedirectEntry[] = [];\n\n if (strategy === \"git\" || strategy === \"both\") {\n const gitRedirects = detectGitRenames();\n redirects.push(...gitRedirects);\n }\n\n if (strategy === \"manifest\" || strategy === \"both\") {\n const manifestRedirects = detectManifestChanges(entries);\n redirects.push(...manifestRedirects);\n }\n\n // Deduplicate by \"from\" path\n const seen = new Set<string>();\n const unique: RedirectEntry[] = [];\n for (const r of redirects) {\n if (!seen.has(r.from)) {\n seen.add(r.from);\n unique.push(r);\n }\n }\n\n if (unique.length > 0) {\n logger.info(`Detected ${unique.length} redirect(s)`);\n }\n\n return unique;\n}\n\n/**\n * Detect renames via git log.\n */\nfunction detectGitRenames(): RedirectEntry[] {\n const redirects: RedirectEntry[] = [];\n\n try {\n const output = execSync(\n \"git log --all --diff-filter=R --summary --format=\",\n {\n encoding: \"utf-8\",\n timeout: 10_000,\n },\n );\n\n const renameRegex = /rename\\s+(.+?)\\{(.+?)\\s*=>\\s*(.+?)\\}\\s*\\((\\d+)%\\)/g;\n const simpleRenameRegex = /rename\\s+(.+?)\\s+=>\\s+(.+?)\\s+\\((\\d+)%\\)/g;\n\n let match: RegExpExecArray | null;\n\n match = renameRegex.exec(output);\n while (match) {\n const prefix = match[1];\n const oldPart = match[2].trim();\n const newPart = match[3].trim();\n\n const oldPath = `${prefix}${oldPart}`;\n const newPath = `${prefix}${newPart}`;\n\n const oldSlug = extractSlug(oldPath);\n const newSlug = extractSlug(newPath);\n\n if (oldSlug && newSlug && oldSlug !== newSlug) {\n redirects.push({\n from: oldSlug,\n to: newSlug,\n status: 301,\n });\n }\n match = renameRegex.exec(output);\n }\n\n match = simpleRenameRegex.exec(output);\n while (match) {\n const oldPath = match[1].trim();\n const newPath = match[2].trim();\n\n const oldSlug = extractSlug(oldPath);\n const newSlug = extractSlug(newPath);\n\n if (oldSlug && newSlug && oldSlug !== newSlug) {\n redirects.push({\n from: oldSlug,\n to: newSlug,\n status: 301,\n });\n }\n match = simpleRenameRegex.exec(output);\n }\n } catch {\n logger.debug(\n \"Git not available or not a git repo, skipping git rename detection\",\n );\n }\n\n return redirects;\n}\n\n/**\n * Detect changes by comparing current slugs against a stored manifest.\n * Uses Levenshtein distance to match removed slugs to added slugs.\n */\nfunction detectManifestChanges(entries: VazaEntry[]): RedirectEntry[] {\n const redirects: RedirectEntry[] = [];\n const manifestPath = join(process.cwd(), MANIFEST_DIR, MANIFEST_FILE);\n\n const currentSlugs = entries.map((e) => e.slug).sort();\n\n if (existsSync(manifestPath)) {\n try {\n const raw = readFileSync(manifestPath, \"utf-8\");\n const previousSlugs: string[] = JSON.parse(raw);\n\n const currentSet = new Set(currentSlugs);\n const previousSet = new Set(previousSlugs);\n\n const removedSlugs = previousSlugs.filter((s) => !currentSet.has(s));\n const addedSlugs = currentSlugs.filter((s) => !previousSet.has(s));\n\n if (removedSlugs.length > 0 && addedSlugs.length > 0) {\n // Match each removed slug to its best match among added slugs\n const usedAdded = new Set<string>();\n\n for (const removed of removedSlugs) {\n let bestMatch = \"\";\n let bestScore = 0;\n\n for (const added of addedSlugs) {\n if (usedAdded.has(added)) continue;\n const score = similarity(removed, added);\n if (score > bestScore) {\n bestScore = score;\n bestMatch = added;\n }\n }\n\n if (bestMatch && bestScore >= MIN_SIMILARITY) {\n usedAdded.add(bestMatch);\n redirects.push({\n from: removed,\n to: bestMatch,\n status: 301,\n });\n logger.debug(\n `Redirect: ${removed} -> ${bestMatch} (similarity: ${bestScore.toFixed(2)})`,\n );\n }\n }\n }\n } catch {\n logger.warn(\"Corrupted slug manifest, will be overwritten\");\n }\n }\n\n // Write current slugs to manifest\n const dir = dirname(manifestPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(manifestPath, JSON.stringify(currentSlugs, null, 2));\n\n return redirects;\n}\n\n/**\n * Extract a slug from a file path by removing directory prefix and extension.\n */\nfunction extractSlug(filePath: string): string | null {\n const name = basename(filePath);\n if (!name) return null;\n return name.replace(/\\.(mdx?|tsx?|jsx?)$/, \"\");\n}\n","/**\n * Compute the Levenshtein distance between two strings.\n */\nexport function levenshtein(a: string, b: string): number {\n const m = a.length;\n const n = b.length;\n const dp: number[][] = Array.from({ length: m + 1 }, () =>\n new Array(n + 1).fill(0),\n );\n\n for (let i = 0; i <= m; i++) dp[i][0] = i;\n for (let j = 0; j <= n; j++) dp[0][j] = j;\n\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n if (a[i - 1] === b[j - 1]) {\n dp[i][j] = dp[i - 1][j - 1];\n } else {\n dp[i][j] = 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);\n }\n }\n }\n\n return dp[m][n];\n}\n\n/**\n * Compute similarity ratio between two strings (0 to 1).\n */\nexport function similarity(a: string, b: string): number {\n const maxLen = Math.max(a.length, b.length);\n if (maxLen === 0) return 1;\n return 1 - levenshtein(a, b) / maxLen;\n}\n","import { DEFAULT_RSS_LIMIT } from \"../constants.js\";\nimport type { RssItem, VazaConfig, VazaEntry } from \"../types.js\";\n\n/**\n * Generate RSS items from entries, sorted by publishDate desc, limited by config.\n */\nexport function generateRss(\n entries: VazaEntry[],\n config: VazaConfig,\n): RssItem[] {\n const siteUrl = config.site.url.replace(/\\/$/, \"\");\n const limit = config.rss?.limit ?? DEFAULT_RSS_LIMIT;\n\n // Fallback basePath if entries aren't tagged with _basePath\n const collectionKeys = Object.keys(config.collections);\n const fallbackBasePath =\n collectionKeys.length > 0\n ? config.collections[collectionKeys[0]].basePath\n : \"\";\n\n const sorted = [...entries]\n .filter((e) => !e.noindex)\n .sort((a, b) => b.publishDate.getTime() - a.publishDate.getTime());\n\n const limited = sorted.slice(0, limit);\n\n return limited.map((entry) => {\n const basePath = (entry._basePath ?? fallbackBasePath).replace(/\\/$/, \"\");\n const link = `${siteUrl}${basePath}/${entry.slug}`;\n return {\n title: entry.title,\n link,\n description: entry.description || entry.excerpt,\n pubDate: entry.publishDate.toUTCString(),\n guid: link,\n author: entry.author?.name,\n };\n });\n}\n\n/**\n * Render RSS items to valid RSS 2.0 XML.\n */\nexport function renderRssXml(items: RssItem[], config: VazaConfig): string {\n const siteUrl = config.site.url.replace(/\\/$/, \"\");\n\n const lines: string[] = [\n '<?xml version=\"1.0\" encoding=\"UTF-8\"?>',\n '<rss version=\"2.0\" xmlns:atom=\"http://www.w3.org/2005/Atom\">',\n \" <channel>\",\n ` <title>${escapeXml(config.site.name)}</title>`,\n ` <link>${escapeXml(siteUrl)}</link>`,\n ` <description>${escapeXml(config.site.description ?? \"\")}</description>`,\n ` <language>${config.site.language ?? \"en\"}</language>`,\n ` <lastBuildDate>${new Date().toUTCString()}</lastBuildDate>`,\n ];\n\n if (config.rss?.path) {\n lines.push(\n ` <atom:link href=\"${escapeXml(siteUrl + config.rss.path)}\" rel=\"self\" type=\"application/rss+xml\" />`,\n );\n }\n\n for (const item of items) {\n lines.push(\" <item>\");\n lines.push(` <title>${escapeXml(item.title)}</title>`);\n lines.push(` <link>${escapeXml(item.link)}</link>`);\n lines.push(\n ` <description>${escapeXml(item.description)}</description>`,\n );\n lines.push(` <pubDate>${item.pubDate}</pubDate>`);\n lines.push(` <guid isPermaLink=\"true\">${escapeXml(item.guid)}</guid>`);\n if (item.author) {\n lines.push(` <author>${escapeXml(item.author)}</author>`);\n }\n lines.push(\" </item>\");\n }\n\n lines.push(\" </channel>\");\n lines.push(\"</rss>\");\n return lines.join(\"\\n\");\n}\n\nfunction escapeXml(str: string): string {\n return str\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n","import {\n DEFAULT_SITEMAP_CHANGE_FREQ,\n DEFAULT_SITEMAP_PRIORITY,\n} from \"../constants.js\";\nimport type { SitemapEntry, VazaConfig, VazaEntry } from \"../types.js\";\n\n/**\n * Generate sitemap entries from VazaEntry[].\n */\nexport function generateSitemap(\n entries: VazaEntry[],\n config: VazaConfig,\n): SitemapEntry[] {\n const siteUrl = config.site.url.replace(/\\/$/, \"\");\n const defaultChangeFreq =\n config.sitemap?.changeFrequency ?? DEFAULT_SITEMAP_CHANGE_FREQ;\n const defaultPriority = config.sitemap?.priority ?? DEFAULT_SITEMAP_PRIORITY;\n\n // Fallback basePath if entries aren't tagged with _basePath\n const collectionKeys = Object.keys(config.collections);\n const fallbackBasePath =\n collectionKeys.length > 0\n ? config.collections[collectionKeys[0]].basePath\n : \"\";\n\n const sitemapEntries: SitemapEntry[] = [];\n\n for (const entry of entries) {\n if (entry.noindex) continue;\n\n const basePath = (entry._basePath ?? fallbackBasePath).replace(/\\/$/, \"\");\n const loc = `${siteUrl}${basePath}/${entry.slug}`;\n const lastmod = (entry.updateDate ?? entry.publishDate).toISOString();\n\n const sitemapEntry: SitemapEntry = {\n loc,\n lastmod,\n changefreq: defaultChangeFreq,\n priority: defaultPriority,\n };\n\n if (entry.image) {\n sitemapEntry.images = [\n {\n loc: entry.image.src.startsWith(\"http\")\n ? entry.image.src\n : `${siteUrl}${entry.image.src}`,\n title: entry.image.alt,\n },\n ];\n }\n\n sitemapEntries.push(sitemapEntry);\n }\n\n // Append additional static paths\n if (config.sitemap?.additionalPaths) {\n for (const path of config.sitemap.additionalPaths) {\n sitemapEntries.push({\n loc: `${siteUrl}${path}`,\n changefreq: defaultChangeFreq,\n priority: defaultPriority,\n });\n }\n }\n\n return sitemapEntries;\n}\n\n/**\n * Render sitemap entries to valid XML with image namespace.\n */\nexport function renderSitemapXml(entries: SitemapEntry[]): string {\n const hasImages = entries.some((e) => e.images && e.images.length > 0);\n\n const lines: string[] = [\n '<?xml version=\"1.0\" encoding=\"UTF-8\"?>',\n `<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"${hasImages ? ' xmlns:image=\"http://www.google.com/schemas/sitemap-image/1.1\"' : \"\"}>`,\n ];\n\n for (const entry of entries) {\n lines.push(\" <url>\");\n lines.push(` <loc>${escapeXml(entry.loc)}</loc>`);\n if (entry.lastmod) {\n lines.push(` <lastmod>${entry.lastmod}</lastmod>`);\n }\n if (entry.changefreq) {\n lines.push(` <changefreq>${entry.changefreq}</changefreq>`);\n }\n if (entry.priority !== undefined) {\n lines.push(` <priority>${entry.priority}</priority>`);\n }\n if (entry.images) {\n for (const img of entry.images) {\n lines.push(\" <image:image>\");\n lines.push(` <image:loc>${escapeXml(img.loc)}</image:loc>`);\n if (img.title) {\n lines.push(\n ` <image:title>${escapeXml(img.title)}</image:title>`,\n );\n }\n lines.push(\" </image:image>\");\n }\n }\n lines.push(\" </url>\");\n }\n\n lines.push(\"</urlset>\");\n return lines.join(\"\\n\");\n}\n\nfunction escapeXml(str: string): string {\n return str\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n","import type { TaxonomyData, VazaConfig, VazaEntry } from \"../types.js\";\n\n/**\n * Build tag and category maps from entries.\n */\nexport function generateTaxonomy(\n entries: VazaEntry[],\n _config: VazaConfig,\n): TaxonomyData {\n const tags: Record<string, string[]> = {};\n const categories: Record<string, string[]> = {};\n\n for (const entry of entries) {\n if (entry.tags) {\n for (const tag of entry.tags) {\n const normalized = tag.toLowerCase().trim();\n if (!tags[normalized]) {\n tags[normalized] = [];\n }\n tags[normalized].push(entry.slug);\n }\n }\n\n if (entry.category) {\n const normalized = entry.category.toLowerCase().trim();\n if (!categories[normalized]) {\n categories[normalized] = [];\n }\n categories[normalized].push(entry.slug);\n }\n }\n\n return { tags, categories };\n}\n","import type { IntegrityIssue, Severity, VazaEntry } from \"../types.js\";\n\n/**\n * Check if entries with images have alt text.\n * Also scan body for markdown images  with empty alt text.\n */\nexport function checkAltText(\n entries: VazaEntry[],\n severity: Severity = \"warn\",\n): IntegrityIssue[] {\n const issues: IntegrityIssue[] = [];\n\n // Match markdown images with empty alt: \n const emptyAltRegex = /!\\[\\s*\\]\\([^)]+\\)/g;\n\n for (const entry of entries) {\n // Check featured image alt text\n if (entry.image && !entry.image.alt?.trim()) {\n issues.push({\n type: \"missing-alt-text\",\n severity,\n message: `Featured image is missing alt text (src: \"${entry.image.src}\")`,\n slug: entry.slug,\n });\n }\n\n // Check body for images with empty alt text\n emptyAltRegex.lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = emptyAltRegex.exec(entry.body)) !== null) {\n issues.push({\n type: \"missing-alt-text\",\n severity,\n message: `Markdown image with empty alt text: ${match[0]}`,\n slug: entry.slug,\n });\n }\n }\n\n return issues;\n}\n","import type { IntegrityIssue, Severity, VazaEntry } from \"../types.js\";\n\n/**\n * Scan each entry's body for internal markdown links [text](/path)\n * and check if any entry has a matching slug/path.\n */\nexport function checkBrokenLinks(\n entries: VazaEntry[],\n severity: Severity = \"warn\",\n): IntegrityIssue[] {\n const slugs = new Set(entries.map((e) => e.slug));\n const issues: IntegrityIssue[] = [];\n\n // Match markdown links with internal paths: [text](/some-path)\n const linkRegex = /\\[([^\\]]*)\\]\\(\\/([^)]*)\\)/g;\n\n for (const entry of entries) {\n let match: RegExpExecArray | null;\n linkRegex.lastIndex = 0;\n\n while ((match = linkRegex.exec(entry.body)) !== null) {\n const rawPath = match[2];\n // Strip trailing slash, query string, and hash\n const cleanPath = rawPath.split(/[?#]/)[0].replace(/\\/$/, \"\");\n // Normalize: remove leading slashes, take last segment as potential slug\n const segments = cleanPath.split(\"/\").filter(Boolean);\n const lastSegment = segments[segments.length - 1];\n\n // Check if any slug matches the full clean path or the last segment\n const found =\n slugs.has(cleanPath) ||\n (lastSegment !== undefined && slugs.has(lastSegment));\n\n if (!found) {\n issues.push({\n type: \"broken-link\",\n severity,\n message: `Broken internal link to \"/${rawPath}\"`,\n slug: entry.slug,\n });\n }\n }\n }\n\n return issues;\n}\n","import type { IntegrityIssue, Severity, VazaEntry } from \"../types.js\";\n\n/**\n * Normalize a title for comparison: lowercase, collapse whitespace,\n * strip punctuation.\n */\nfunction normalize(title: string): string {\n return title\n .toLowerCase()\n .replace(/[^\\w\\s]/g, \"\")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\n/**\n * Check for entries with identical or very similar titles.\n * Uses case-insensitive normalized comparison.\n */\nexport function checkDuplicateContent(\n entries: VazaEntry[],\n severity: Severity = \"warn\",\n): IntegrityIssue[] {\n const issues: IntegrityIssue[] = [];\n const seen = new Map<string, string[]>();\n\n for (const entry of entries) {\n const key = normalize(entry.title);\n if (!key) continue;\n\n const existing = seen.get(key);\n if (existing) {\n existing.push(entry.slug);\n } else {\n seen.set(key, [entry.slug]);\n }\n }\n\n for (const [, slugs] of seen) {\n if (slugs.length > 1) {\n issues.push({\n type: \"duplicate-content\",\n severity,\n message: `Entries have near-identical titles: ${slugs.join(\", \")}`,\n slug: slugs[0],\n });\n }\n }\n\n return issues;\n}\n","import type { IntegrityIssue, Severity, VazaEntry } from \"../types.js\";\n\n/**\n * Check for duplicate slugs across all entries.\n */\nexport function checkDuplicateSlugs(\n entries: VazaEntry[],\n severity: Severity = \"error\",\n): IntegrityIssue[] {\n const issues: IntegrityIssue[] = [];\n const seen = new Map<string, number>();\n\n for (const entry of entries) {\n const count = seen.get(entry.slug) ?? 0;\n seen.set(entry.slug, count + 1);\n }\n\n for (const [slug, count] of seen) {\n if (count > 1) {\n issues.push({\n type: \"duplicate-slug\",\n severity,\n message: `Slug \"${slug}\" is used by ${count} entries`,\n slug,\n });\n }\n }\n\n return issues;\n}\n","import type {\n IntegrityConfig,\n IntegrityIssue,\n Severity,\n VazaEntry,\n} from \"../types.js\";\n\n/**\n * Parse a maxAge string like \"6m\", \"1y\", \"90d\" into milliseconds.\n */\nfunction parseMaxAge(maxAge: string): number {\n const match = maxAge.match(/^(\\d+)(d|m|y)$/);\n if (!match) {\n throw new Error(\n `Invalid maxAge format: \"${maxAge}\". Use \"90d\", \"6m\", or \"1y\".`,\n );\n }\n\n const value = Number.parseInt(match[1], 10);\n const unit = match[2];\n\n const MS_PER_DAY = 86_400_000;\n\n switch (unit) {\n case \"d\":\n return value * MS_PER_DAY;\n case \"m\":\n return value * 30 * MS_PER_DAY;\n case \"y\":\n return value * 365 * MS_PER_DAY;\n default:\n return value * MS_PER_DAY;\n }\n}\n\n/**\n * Check if any entry's updateDate (or publishDate) is older than maxAge.\n */\nexport function checkFreshness(\n entries: VazaEntry[],\n config: IntegrityConfig,\n): IntegrityIssue[] {\n const issues: IntegrityIssue[] = [];\n\n const maxAgeStr = config.freshness?.maxAge ?? \"6m\";\n const severity: Severity = config.freshness?.severity ?? \"warn\";\n\n if (severity === \"off\") return issues;\n\n const maxAgeMs = parseMaxAge(maxAgeStr);\n const now = Date.now();\n\n for (const entry of entries) {\n const lastDate = entry.updateDate ?? entry.publishDate;\n const age = now - lastDate.getTime();\n\n if (age > maxAgeMs) {\n const daysOld = Math.floor(age / 86_400_000);\n issues.push({\n type: \"stale-content\",\n severity,\n message: `Content is ${daysOld} days old (max age: ${maxAgeStr})`,\n slug: entry.slug,\n });\n }\n }\n\n return issues;\n}\n","import type { IntegrityConfig, IntegrityIssue, VazaEntry } from \"../types.js\";\n\n/**\n * Check title length and description length against configured maximums.\n */\nexport function checkMetaLength(\n entries: VazaEntry[],\n config: IntegrityConfig,\n): IntegrityIssue[] {\n const issues: IntegrityIssue[] = [];\n\n const titleMax = config.metaTitleLength?.max ?? 60;\n const titleSeverity = config.metaTitleLength?.severity ?? \"warn\";\n\n const descMax = config.metaDescriptionLength?.max ?? 120;\n const descSeverity = config.metaDescriptionLength?.severity ?? \"warn\";\n\n for (const entry of entries) {\n if (titleSeverity !== \"off\" && entry.title.length > titleMax) {\n issues.push({\n type: \"meta-title-length\",\n severity: titleSeverity,\n message: `Title is ${entry.title.length} chars (max ${titleMax}): \"${entry.title}\"`,\n slug: entry.slug,\n });\n }\n\n if (descSeverity !== \"off\" && entry.description.length > descMax) {\n issues.push({\n type: \"meta-description-length\",\n severity: descSeverity,\n message: `Description is ${entry.description.length} chars (max ${descMax})`,\n slug: entry.slug,\n });\n }\n }\n\n return issues;\n}\n","import type { IntegrityIssue, Severity, VazaEntry } from \"../types.js\";\n\n/**\n * Check if any entry has zero inbound internal links from other entries.\n */\nexport function checkOrphanPages(\n entries: VazaEntry[],\n severity: Severity = \"warn\",\n): IntegrityIssue[] {\n const issues: IntegrityIssue[] = [];\n\n // Build a set of slugs that are linked to by at least one other entry\n const linkedSlugs = new Set<string>();\n const linkRegex = /\\[([^\\]]*)\\]\\(\\/([^)]*)\\)/g;\n\n for (const entry of entries) {\n linkRegex.lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = linkRegex.exec(entry.body)) !== null) {\n const rawPath = match[2];\n const cleanPath = rawPath.split(/[?#]/)[0].replace(/\\/$/, \"\");\n const segments = cleanPath.split(\"/\").filter(Boolean);\n const lastSegment = segments[segments.length - 1];\n\n // Add both the full path and last segment as potential targets\n linkedSlugs.add(cleanPath);\n if (lastSegment !== undefined) {\n linkedSlugs.add(lastSegment);\n }\n }\n }\n\n // Check which entries have no inbound links\n for (const entry of entries) {\n if (!linkedSlugs.has(entry.slug)) {\n issues.push({\n type: \"orphan-page\",\n severity,\n message: `No other entry links to \"${entry.slug}\"`,\n slug: entry.slug,\n });\n }\n }\n\n return issues;\n}\n","import type {\n IntegrityConfig,\n IntegrityIssue,\n IntegrityReport,\n VazaConfig,\n VazaEntry,\n} from \"../types.js\";\nimport { checkAltText } from \"./alt-text.js\";\nimport { checkBrokenLinks } from \"./broken-links.js\";\nimport { checkDuplicateContent } from \"./duplicate-content.js\";\nimport { checkDuplicateSlugs } from \"./duplicate-slugs.js\";\nimport { checkFreshness } from \"./freshness.js\";\nimport { checkMetaLength } from \"./meta-length.js\";\nimport { checkOrphanPages } from \"./orphan-pages.js\";\n\n/**\n * Run all integrity checks based on config severity settings.\n * Checks with severity \"off\" are skipped entirely.\n */\nexport function checkIntegrity(\n entries: VazaEntry[],\n config: VazaConfig,\n): IntegrityReport {\n const ic: IntegrityConfig = config.integrity ?? {};\n const issues: IntegrityIssue[] = [];\n\n // Broken links\n if (ic.brokenLinks !== \"off\") {\n issues.push(...checkBrokenLinks(entries, ic.brokenLinks ?? \"warn\"));\n }\n\n // Meta length (has its own internal severity handling)\n const titleOff = ic.metaTitleLength?.severity === \"off\";\n const descOff = ic.metaDescriptionLength?.severity === \"off\";\n if (!titleOff || !descOff) {\n issues.push(...checkMetaLength(entries, ic));\n }\n\n // Alt text\n if (ic.altText !== \"off\") {\n issues.push(...checkAltText(entries, ic.altText ?? \"warn\"));\n }\n\n // Duplicate slugs\n if (ic.duplicateSlugs !== \"off\") {\n issues.push(...checkDuplicateSlugs(entries, ic.duplicateSlugs ?? \"error\"));\n }\n\n // Duplicate content\n if (ic.duplicateContent !== \"off\") {\n issues.push(\n ...checkDuplicateContent(entries, ic.duplicateContent ?? \"warn\"),\n );\n }\n\n // Orphan pages\n if (ic.orphanPages !== \"off\") {\n issues.push(...checkOrphanPages(entries, ic.orphanPages ?? \"warn\"));\n }\n\n // Freshness\n if (ic.freshness?.severity !== \"off\") {\n issues.push(...checkFreshness(entries, ic));\n }\n\n // Compute summary\n let errors = 0;\n let warnings = 0;\n for (const issue of issues) {\n if (issue.severity === \"error\") errors++;\n else if (issue.severity === \"warn\") warnings++;\n }\n\n return { issues, summary: { errors, warnings } };\n}\n\nexport { checkAltText } from \"./alt-text.js\";\nexport { checkBrokenLinks } from \"./broken-links.js\";\nexport { checkDuplicateContent } from \"./duplicate-content.js\";\nexport { checkDuplicateSlugs } from \"./duplicate-slugs.js\";\nexport { checkFreshness } from \"./freshness.js\";\nexport { checkMetaLength } from \"./meta-length.js\";\nexport { checkOrphanPages } from \"./orphan-pages.js\";\n","import sharp from \"sharp\";\n\n/**\n * Generate a tiny blurred placeholder image and return it as a base64 data URL.\n * Returns undefined if the image cannot be read.\n */\nexport async function generateBlurPlaceholder(\n imagePath: string,\n): Promise<string | undefined> {\n try {\n const buffer = await sharp(imagePath)\n .resize(8, 8, { fit: \"inside\" })\n .blur()\n .png()\n .toBuffer();\n\n return `data:image/png;base64,${buffer.toString(\"base64\")}`;\n } catch {\n return undefined;\n }\n}\n","import { EXCERPT_MAX_LENGTH } from \"../constants.js\";\n\n/**\n * Strip common markdown syntax from text.\n */\nfunction stripMarkdown(text: string): string {\n return (\n text\n // Remove code blocks\n .replace(/```[\\s\\S]*?```/g, \"\")\n // Remove images \n .replace(/!\\[.*?\\]\\(.*?\\)/g, \"\")\n // Remove links but keep text [text](url)\n .replace(/\\[([^\\]]*)\\]\\(.*?\\)/g, \"$1\")\n // Remove headings (## etc.)\n .replace(/^#{1,6}\\s+/gm, \"\")\n // Remove bold/italic markers\n .replace(/\\*{1,3}(.*?)\\*{1,3}/g, \"$1\")\n .replace(/_{1,3}(.*?)_{1,3}/g, \"$1\")\n // Remove inline code\n .replace(/`([^`]*)`/g, \"$1\")\n // Remove blockquotes\n .replace(/^>\\s+/gm, \"\")\n // Remove horizontal rules\n .replace(/^[-*_]{3,}\\s*$/gm, \"\")\n // Remove HTML tags\n .replace(/<[^>]+>/g, \"\")\n // Collapse whitespace\n .replace(/\\s+/g, \" \")\n .trim()\n );\n}\n\n/**\n * Extract the first ~maxLength characters from body text,\n * trimmed at a word boundary. Strips markdown syntax.\n */\nexport function generateExcerpt(\n body: string,\n maxLength = EXCERPT_MAX_LENGTH,\n): string {\n const clean = stripMarkdown(body);\n\n if (clean.length <= maxLength) {\n return clean;\n }\n\n const truncated = clean.slice(0, maxLength);\n const lastSpace = truncated.lastIndexOf(\" \");\n\n // If no space found, hard-truncate at maxLength\n if (lastSpace === -1) {\n return truncated.slice(0, maxLength);\n }\n\n return truncated.slice(0, lastSpace);\n}\n","import { generateExcerpt } from \"./excerpt.js\";\n\n/**\n * Generate a meta description. If an excerpt is provided, use it.\n * Otherwise, generate one from the body text.\n */\nexport function generateDescription(body: string, excerpt?: string): string {\n return excerpt ?? generateExcerpt(body);\n}\n","import sharp from \"sharp\";\n\n/**\n * Read the width and height of an image file using sharp.\n * Returns undefined if the image cannot be read.\n */\nexport async function getImageDimensions(\n imagePath: string,\n): Promise<{ width: number; height: number } | undefined> {\n try {\n const metadata = await sharp(imagePath).metadata();\n if (metadata.width && metadata.height) {\n return { width: metadata.width, height: metadata.height };\n }\n return undefined;\n } catch {\n return undefined;\n }\n}\n","/**\n * Count the number of words in a body of text.\n */\nexport function calcWordCount(body: string): number {\n return body.trim().split(/\\s+/).filter(Boolean).length;\n}\n","import { WORDS_PER_MINUTE } from \"../constants.js\";\nimport { calcWordCount } from \"./word-count.js\";\n\n/**\n * Calculate estimated reading time in minutes from body text.\n */\nexport function calcReadingTime(body: string): number {\n const words = calcWordCount(body);\n return Math.max(1, Math.ceil(words / WORDS_PER_MINUTE));\n}\n","/**\n * Generate a URL slug from a title string.\n * Lowercases, replaces spaces with hyphens, removes special characters,\n * and trims leading/trailing hyphens.\n */\nexport function generateSlug(title: string): string {\n return title\n .toLowerCase()\n .replace(/\\s+/g, \"-\")\n .replace(/[^a-z0-9-]/g, \"\")\n .replace(/-+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n}\n","import type { TocItem } from \"../types.js\";\n\n/**\n * Generate a URL-friendly anchor slug from heading text.\n */\nfunction toAnchorSlug(text: string): string {\n return text\n .toLowerCase()\n .replace(/[^\\w\\s-]/g, \"\")\n .replace(/\\s+/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n}\n\n/**\n * Extract headings (## and ###) from markdown body and generate\n * a table of contents with anchor slugs.\n */\nexport function extractToc(body: string): TocItem[] {\n const headingRegex = /^(#{2,3})\\s+(.+)$/gm;\n const items: TocItem[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = headingRegex.exec(body)) !== null) {\n const depth = match[1].length;\n const text = match[2].trim();\n items.push({\n depth,\n text,\n slug: toAnchorSlug(text),\n });\n }\n\n return items;\n}\n","import type { PartialVazaEntry, VazaEntry } from \"../types.js\";\nimport { generateBlurPlaceholder } from \"./blur-placeholder.js\";\nimport { generateDescription } from \"./description.js\";\nimport { generateExcerpt } from \"./excerpt.js\";\nimport { getImageDimensions } from \"./image-dimensions.js\";\nimport { calcReadingTime } from \"./reading-time.js\";\nimport { generateSlug } from \"./slug.js\";\nimport { extractToc } from \"./toc.js\";\nimport { calcWordCount } from \"./word-count.js\";\n\nexport {\n calcReadingTime,\n calcWordCount,\n extractToc,\n generateBlurPlaceholder,\n generateDescription,\n generateExcerpt,\n generateSlug,\n getImageDimensions,\n};\n\n/**\n * Convert a date value (string or Date) to a Date object.\n */\nfunction toDate(value: Date | string | undefined): Date | undefined {\n if (value === undefined) return undefined;\n if (value instanceof Date) return value;\n return new Date(value);\n}\n\n/**\n * Normalize a partial entry into a full VazaEntry.\n * For each field, keeps the existing value if present, otherwise generates it.\n */\nexport async function normalize(partial: PartialVazaEntry): Promise<VazaEntry> {\n const { body, title } = partial;\n\n const slug = partial.slug || generateSlug(title);\n const wordCount = partial.wordCount ?? calcWordCount(body);\n const readingTime = partial.readingTime ?? calcReadingTime(body);\n const excerpt = partial.excerpt ?? generateExcerpt(body);\n const toc = partial.toc ?? extractToc(body);\n const description = partial.description ?? generateDescription(body, excerpt);\n const publishDate = toDate(partial.publishDate) ?? new Date();\n const updateDate = toDate(partial.updateDate);\n const eventDate = toDate(partial.eventDate);\n\n // Process image blur placeholder and dimensions if needed\n const image = partial.image ? { ...partial.image } : undefined;\n\n if (image?.src) {\n if (!image.blurDataURL) {\n image.blurDataURL = await generateBlurPlaceholder(image.src);\n }\n if (!image.width || !image.height) {\n const dims = await getImageDimensions(image.src);\n if (dims) {\n image.width = dims.width;\n image.height = dims.height;\n }\n }\n }\n\n const entry: VazaEntry = {\n slug,\n title,\n body,\n description,\n publishDate,\n readingTime,\n wordCount,\n excerpt,\n toc,\n ...(updateDate && { updateDate }),\n ...(image && { image: image as VazaEntry[\"image\"] }),\n ...(partial.tags && { tags: partial.tags }),\n ...(partial.category && { category: partial.category }),\n ...(partial.author && { author: partial.author as VazaEntry[\"author\"] }),\n ...(partial.relatedEntries && { relatedEntries: partial.relatedEntries }),\n ...(partial.canonical && { canonical: partial.canonical }),\n ...(partial.noindex !== undefined && { noindex: partial.noindex }),\n ...(partial.jsonLdType && { jsonLdType: partial.jsonLdType }),\n ...(partial.faqs && { faqs: partial.faqs }),\n ...(partial.steps && { steps: partial.steps }),\n ...(partial.price && { price: partial.price }),\n ...(partial.ingredients && { ingredients: partial.ingredients }),\n ...(partial.cookTime && { cookTime: partial.cookTime }),\n ...(eventDate && { eventDate }),\n ...(partial.eventLocation && { eventLocation: partial.eventLocation }),\n };\n\n return entry;\n}\n","import { generateJsonLd } from \"./generate/json-ld/index.js\";\nimport { generateOgImages } from \"./generate/og-images.js\";\nimport { detectRedirects } from \"./generate/redirects.js\";\nimport { generateRss } from \"./generate/rss.js\";\nimport { generateSitemap } from \"./generate/sitemap.js\";\nimport { generateTaxonomy } from \"./generate/taxonomy.js\";\nimport { checkIntegrity } from \"./integrity/index.js\";\nimport { logger, setLogLevel } from \"./logger.js\";\nimport { normalize } from \"./normalize/index.js\";\nimport type {\n PartialVazaEntry,\n VazaConfig,\n VazaEntry,\n VazaOutput,\n} from \"./types.js\";\n\nexport async function processCollections(\n config: VazaConfig,\n): Promise<VazaOutput> {\n if (config.logLevel) {\n setLogLevel(config.logLevel);\n }\n\n const allEntries: VazaEntry[] = [];\n\n // Collect and normalize entries from all collections\n for (const [name, collection] of Object.entries(config.collections)) {\n logger.debug(`Processing collection: ${name}`);\n const rawEntries = await collection.entries();\n const partialEntries: PartialVazaEntry[] = rawEntries.map(collection.map);\n\n for (const partial of partialEntries) {\n const normalized = await normalize(partial);\n normalized._collection = name;\n normalized._basePath = collection.basePath;\n allEntries.push(normalized);\n }\n logger.debug(`Collection \"${name}\": ${rawEntries.length} entries`);\n }\n\n logger.info(`Normalized ${allEntries.length} entries`);\n\n // Generate all SEO outputs in parallel\n const [sitemap, rss, jsonLd, ogImagePaths, taxonomy, redirects, integrity] =\n await Promise.all([\n config.sitemap?.enabled !== false\n ? generateSitemap(allEntries, config)\n : Promise.resolve([]),\n config.rss?.enabled !== false\n ? generateRss(allEntries, config)\n : Promise.resolve([]),\n config.jsonLd?.enabled !== false\n ? generateJsonLd(allEntries, config)\n : Promise.resolve({}),\n config.ogImages?.enabled !== false\n ? generateOgImages(allEntries, config)\n : Promise.resolve({}),\n config.taxonomy?.enabled !== false\n ? generateTaxonomy(allEntries, config)\n : Promise.resolve({ tags: {}, categories: {} }),\n config.redirects?.enabled !== false\n ? detectRedirects(allEntries, config)\n : Promise.resolve([]),\n checkIntegrity(allEntries, config),\n ]);\n\n // Print integrity report to terminal\n if (integrity.summary.errors > 0 || integrity.summary.warnings > 0) {\n printIntegrityReport(integrity);\n }\n\n return {\n entries: allEntries,\n sitemap,\n rss,\n jsonLd,\n ogImagePaths,\n taxonomy,\n redirects,\n integrity,\n };\n}\n\nfunction printIntegrityReport(report: VazaOutput[\"integrity\"]): void {\n const { issues, summary } = report;\n\n logger.info(\"\");\n logger.info(\"Integrity Report\");\n logger.info(\"─\".repeat(50));\n\n for (const issue of issues) {\n const location = issue.slug ? ` (${issue.slug})` : \"\";\n if (issue.severity === \"error\") {\n logger.error(`${issue.message}${location}`);\n } else {\n logger.warn(`${issue.message}${location}`);\n }\n }\n\n logger.info(\"─\".repeat(50));\n logger.info(`${summary.errors} error(s), ${summary.warnings} warning(s)`);\n\n if (summary.errors > 0) {\n throw new Error(\n `[vaza-content] Build failed: ${summary.errors} integrity error(s) found.`,\n );\n }\n}\n"],"mappings":"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","names":["existsSync","mkdirSync","readFileSync","writeFileSync","dirname","join","join","existsSync","readFileSync","dirname","mkdirSync","writeFileSync","escapeXml","sharp","normalize","normalize"]}
|
package/dist/cli/index.cjs
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict"; function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
|
|
3
|
-
|
|
4
|
-
var _chunkJEQ2X3Z6cjs = require('../chunk-JEQ2X3Z6.cjs');
|
|
5
|
-
|
|
6
3
|
// src/cli/index.ts
|
|
7
4
|
var _fs = require('fs');
|
|
8
5
|
var _path = require('path');
|
|
@@ -26,10 +23,8 @@ async function main() {
|
|
|
26
23
|
printHelp();
|
|
27
24
|
break;
|
|
28
25
|
default:
|
|
29
|
-
console.log(
|
|
30
|
-
|
|
31
|
-
`
|
|
32
|
-
);
|
|
26
|
+
console.log(`[vaza-content] Unknown command: ${_nullishCoalesce(command, () => ( "(none)"))}
|
|
27
|
+
`);
|
|
33
28
|
printHelp();
|
|
34
29
|
process.exit(1);
|
|
35
30
|
}
|
|
@@ -78,7 +73,9 @@ async function init() {
|
|
|
78
73
|
console.log(`[vaza-content] Detected framework: ${framework}`);
|
|
79
74
|
switch (framework) {
|
|
80
75
|
case "next": {
|
|
81
|
-
console.log(
|
|
76
|
+
console.log(
|
|
77
|
+
"[vaza-content] Installing @content-collections/core @content-collections/next..."
|
|
78
|
+
);
|
|
82
79
|
const { execSync } = await Promise.resolve().then(() => _interopRequireWildcard(require("child_process")));
|
|
83
80
|
const pm = detectPackageManager();
|
|
84
81
|
const installCmd = pm === "npm" ? "npm install @content-collections/core @content-collections/next" : pm === "bun" ? "bun add @content-collections/core @content-collections/next" : pm === "pnpm" ? "pnpm add @content-collections/core @content-collections/next" : "yarn add @content-collections/core @content-collections/next";
|
|
@@ -87,7 +84,9 @@ async function init() {
|
|
|
87
84
|
break;
|
|
88
85
|
}
|
|
89
86
|
case "sveltekit": {
|
|
90
|
-
console.log(
|
|
87
|
+
console.log(
|
|
88
|
+
"[vaza-content] Installing @content-collections/core @content-collections/vite..."
|
|
89
|
+
);
|
|
91
90
|
const { execSync } = await Promise.resolve().then(() => _interopRequireWildcard(require("child_process")));
|
|
92
91
|
const pm = detectPackageManager();
|
|
93
92
|
const installCmd = pm === "npm" ? "npm install @content-collections/core @content-collections/vite" : pm === "bun" ? "bun add @content-collections/core @content-collections/vite" : pm === "pnpm" ? "pnpm add @content-collections/core @content-collections/vite" : "yarn add @content-collections/core @content-collections/vite";
|
|
@@ -97,23 +96,29 @@ async function init() {
|
|
|
97
96
|
}
|
|
98
97
|
case "astro":
|
|
99
98
|
writeInitFiles("astro");
|
|
100
|
-
console.log(
|
|
99
|
+
console.log(
|
|
100
|
+
"[vaza-content] Astro detected -- using built-in content collections."
|
|
101
|
+
);
|
|
101
102
|
break;
|
|
102
103
|
case "nuxt":
|
|
103
104
|
writeInitFiles("nuxt");
|
|
104
|
-
console.log(
|
|
105
|
+
console.log(
|
|
106
|
+
"[vaza-content] Nuxt detected -- using built-in Nuxt Content."
|
|
107
|
+
);
|
|
105
108
|
break;
|
|
106
109
|
default:
|
|
107
|
-
console.error(
|
|
110
|
+
console.error(
|
|
111
|
+
"[vaza-content] Could not detect framework. Create vaza.config.ts manually."
|
|
112
|
+
);
|
|
108
113
|
process.exit(1);
|
|
109
114
|
}
|
|
110
|
-
console.log(
|
|
115
|
+
console.log(
|
|
116
|
+
"[vaza-content] Setup complete! Edit vaza.config.ts to configure your collections."
|
|
117
|
+
);
|
|
111
118
|
}
|
|
112
119
|
function detectFramework() {
|
|
113
120
|
try {
|
|
114
|
-
const pkg = JSON.parse(
|
|
115
|
-
_chunkJEQ2X3Z6cjs.__require.call(void 0, "fs").readFileSync("package.json", "utf-8")
|
|
116
|
-
);
|
|
121
|
+
const pkg = JSON.parse(_fs.readFileSync.call(void 0, "package.json", "utf-8"));
|
|
117
122
|
const deps = {
|
|
118
123
|
...pkg.dependencies,
|
|
119
124
|
...pkg.devDependencies
|
|
@@ -132,8 +137,7 @@ function detectPackageManager() {
|
|
|
132
137
|
if (_fs.existsSync.call(void 0, "yarn.lock")) return "yarn";
|
|
133
138
|
return "npm";
|
|
134
139
|
}
|
|
135
|
-
function writeInitFiles(
|
|
136
|
-
const { writeFileSync } = _chunkJEQ2X3Z6cjs.__require.call(void 0, "fs");
|
|
140
|
+
function writeInitFiles(_framework) {
|
|
137
141
|
if (!_fs.existsSync.call(void 0, "vaza.config.ts")) {
|
|
138
142
|
const configTemplate = `import { defineConfig } from 'vaza-content'
|
|
139
143
|
|
|
@@ -173,16 +177,18 @@ export default defineConfig({
|
|
|
173
177
|
},
|
|
174
178
|
})
|
|
175
179
|
`;
|
|
176
|
-
writeFileSync("vaza.config.ts", configTemplate, "utf-8");
|
|
180
|
+
_fs.writeFileSync.call(void 0, "vaza.config.ts", configTemplate, "utf-8");
|
|
177
181
|
console.log("[vaza-content] Created vaza.config.ts");
|
|
178
182
|
}
|
|
179
183
|
const gitignorePath = ".gitignore";
|
|
180
184
|
if (_fs.existsSync.call(void 0, gitignorePath)) {
|
|
181
|
-
const gitignore =
|
|
185
|
+
const gitignore = _fs.readFileSync.call(void 0, gitignorePath, "utf-8");
|
|
182
186
|
if (!gitignore.includes(".vaza-content")) {
|
|
183
|
-
writeFileSync(
|
|
187
|
+
_fs.writeFileSync.call(void 0,
|
|
184
188
|
gitignorePath,
|
|
185
|
-
gitignore.trimEnd()
|
|
189
|
+
`${gitignore.trimEnd()}
|
|
190
|
+
.vaza-content/
|
|
191
|
+
`,
|
|
186
192
|
"utf-8"
|
|
187
193
|
);
|
|
188
194
|
console.log("[vaza-content] Added .vaza-content/ to .gitignore");
|
|
@@ -191,7 +197,7 @@ export default defineConfig({
|
|
|
191
197
|
}
|
|
192
198
|
async function check(flags) {
|
|
193
199
|
const config = await loadConfig();
|
|
194
|
-
const { processCollections } = await Promise.resolve().then(() => _interopRequireWildcard(require("../process-
|
|
200
|
+
const { processCollections } = await Promise.resolve().then(() => _interopRequireWildcard(require("../process-VXDWM664.cjs")));
|
|
195
201
|
const output = await processCollections(config);
|
|
196
202
|
const issues = output.integrity.issues;
|
|
197
203
|
let filtered = issues;
|
|
@@ -212,7 +218,7 @@ async function check(flags) {
|
|
|
212
218
|
console.log("[vaza-content] All checks passed!");
|
|
213
219
|
} else {
|
|
214
220
|
for (const issue of filtered) {
|
|
215
|
-
const icon = issue.severity === "error" ? "
|
|
221
|
+
const icon = issue.severity === "error" ? "x" : "!";
|
|
216
222
|
console.log(` ${icon} [${issue.type}] ${issue.message}`);
|
|
217
223
|
}
|
|
218
224
|
const errors = filtered.filter((i) => i.severity === "error").length;
|
package/dist/cli/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/mehdi/vaza-content/dist/cli/index.cjs","../../src/cli/index.ts"],"names":[],"mappings":"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","file":"/Users/mehdi/vaza-content/dist/cli/index.cjs","sourcesContent":[null,"#!/usr/bin/env node\n\nimport { existsSync } from \"node:fs\";\nimport { resolve, join } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\nasync function main() {\n switch (command) {\n case \"init\":\n await init();\n break;\n case \"check\":\n await check(args.slice(1));\n break;\n case \"generate\":\n await generate();\n break;\n case \"help\":\n case \"--help\":\n case \"-h\":\n printHelp();\n break;\n default:\n console.log(\n `[vaza-content] Unknown command: ${command ?? \"(none)\"}\\n`,\n );\n printHelp();\n process.exit(1);\n }\n}\n\nfunction printHelp() {\n console.log(`\nUsage: vaza-content <command> [options]\n\nCommands:\n init Auto-detect framework, install deps, create config\n check Run integrity checks on content\n generate Generate all SEO outputs\n help Show this help message\n\nCheck options:\n --links Check broken internal links only\n --meta Check meta title/description lengths only\n --freshness Check content freshness only\n --alt Check image alt text only\n --duplicates Check duplicate slugs/content only\n`);\n}\n\nasync function loadConfig() {\n const configPath = resolve(\"vaza.config.ts\");\n const configPathJs = resolve(\"vaza.config.js\");\n const configPathMjs = resolve(\"vaza.config.mjs\");\n\n let actualPath: string | undefined;\n for (const p of [configPathMjs, configPathJs, configPath]) {\n if (existsSync(p)) {\n actualPath = p;\n break;\n }\n }\n\n if (!actualPath) {\n console.error(\n \"[vaza-content] No config file found. Run `vaza-content init` first.\",\n );\n process.exit(1);\n }\n\n const configUrl = pathToFileURL(actualPath).href;\n const mod = await import(configUrl);\n return mod.default;\n}\n\nasync function init() {\n const framework = detectFramework();\n console.log(`[vaza-content] Detected framework: ${framework}`);\n\n switch (framework) {\n case \"next\": {\n console.log(\"[vaza-content] Installing @content-collections/core @content-collections/next...\");\n const { execSync } = await import(\"node:child_process\");\n const pm = detectPackageManager();\n const installCmd =\n pm === \"npm\"\n ? \"npm install @content-collections/core @content-collections/next\"\n : pm === \"bun\"\n ? \"bun add @content-collections/core @content-collections/next\"\n : pm === \"pnpm\"\n ? \"pnpm add @content-collections/core @content-collections/next\"\n : \"yarn add @content-collections/core @content-collections/next\";\n execSync(installCmd, { stdio: \"inherit\" });\n writeInitFiles(\"next\");\n break;\n }\n case \"sveltekit\": {\n console.log(\"[vaza-content] Installing @content-collections/core @content-collections/vite...\");\n const { execSync } = await import(\"node:child_process\");\n const pm = detectPackageManager();\n const installCmd =\n pm === \"npm\"\n ? \"npm install @content-collections/core @content-collections/vite\"\n : pm === \"bun\"\n ? \"bun add @content-collections/core @content-collections/vite\"\n : pm === \"pnpm\"\n ? \"pnpm add @content-collections/core @content-collections/vite\"\n : \"yarn add @content-collections/core @content-collections/vite\";\n execSync(installCmd, { stdio: \"inherit\" });\n writeInitFiles(\"sveltekit\");\n break;\n }\n case \"astro\":\n writeInitFiles(\"astro\");\n console.log(\"[vaza-content] Astro detected — using built-in content collections.\");\n break;\n case \"nuxt\":\n writeInitFiles(\"nuxt\");\n console.log(\"[vaza-content] Nuxt detected — using built-in Nuxt Content.\");\n break;\n default:\n console.error(\"[vaza-content] Could not detect framework. Create vaza.config.ts manually.\");\n process.exit(1);\n }\n\n console.log(\"[vaza-content] Setup complete! Edit vaza.config.ts to configure your collections.\");\n}\n\nfunction detectFramework(): string {\n try {\n const pkg = JSON.parse(\n require(\"node:fs\").readFileSync(\"package.json\", \"utf-8\"),\n );\n const deps = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n };\n if (deps.next) return \"next\";\n if (deps[\"@sveltejs/kit\"]) return \"sveltekit\";\n if (deps.astro) return \"astro\";\n if (deps.nuxt) return \"nuxt\";\n } catch {\n // ignore\n }\n return \"unknown\";\n}\n\nfunction detectPackageManager(): string {\n if (existsSync(\"bun.lockb\") || existsSync(\"bun.lock\")) return \"bun\";\n if (existsSync(\"pnpm-lock.yaml\")) return \"pnpm\";\n if (existsSync(\"yarn.lock\")) return \"yarn\";\n return \"npm\";\n}\n\nfunction writeInitFiles(framework: string) {\n const { writeFileSync } = require(\"node:fs\") as typeof import(\"node:fs\");\n\n if (!existsSync(\"vaza.config.ts\")) {\n const configTemplate = `import { defineConfig } from 'vaza-content'\n\nexport default defineConfig({\n site: {\n url: 'https://example.com',\n name: 'My Site',\n description: 'My site description',\n language: 'en',\n },\n\n collections: {\n // Configure your collections here\n // blog: {\n // entries: () => getPosts(),\n // map: (post) => ({\n // slug: post.slug,\n // title: post.title,\n // body: post.content,\n // description: post.description,\n // publishDate: new Date(post.date),\n // }),\n // basePath: '/blog',\n // },\n },\n\n sitemap: { enabled: true },\n rss: { enabled: true },\n jsonLd: { enabled: true },\n ogImages: { enabled: true, template: 'blog' },\n taxonomy: { enabled: true },\n redirects: { enabled: true },\n integrity: {\n brokenLinks: 'warn',\n duplicateSlugs: 'error',\n altText: 'warn',\n },\n})\n`;\n writeFileSync(\"vaza.config.ts\", configTemplate, \"utf-8\");\n console.log(\"[vaza-content] Created vaza.config.ts\");\n }\n\n // Add .vaza-content to gitignore if not present\n const gitignorePath = \".gitignore\";\n if (existsSync(gitignorePath)) {\n const gitignore = require(\"node:fs\").readFileSync(gitignorePath, \"utf-8\") as string;\n if (!gitignore.includes(\".vaza-content\")) {\n writeFileSync(\n gitignorePath,\n gitignore.trimEnd() + \"\\n.vaza-content/\\n\",\n \"utf-8\",\n );\n console.log(\"[vaza-content] Added .vaza-content/ to .gitignore\");\n }\n }\n}\n\nasync function check(flags: string[]) {\n const config = await loadConfig();\n const { processCollections } = await import(\"../process.js\");\n const output = await processCollections(config);\n\n const issues = output.integrity.issues;\n let filtered = issues;\n\n if (flags.length > 0) {\n const typeMap: Record<string, string[]> = {\n \"--links\": [\"broken-link\"],\n \"--meta\": [\"meta-title-length\", \"meta-description-length\"],\n \"--freshness\": [\"stale-content\"],\n \"--alt\": [\"missing-alt-text\"],\n \"--duplicates\": [\"duplicate-slug\", \"duplicate-content\"],\n };\n\n const allowedTypes = flags.flatMap((f) => typeMap[f] ?? []);\n if (allowedTypes.length > 0) {\n filtered = issues.filter((i) => allowedTypes.includes(i.type));\n }\n }\n\n if (filtered.length === 0) {\n console.log(\"[vaza-content] All checks passed!\");\n } else {\n for (const issue of filtered) {\n const icon = issue.severity === \"error\" ? \"✖\" : \"⚠\";\n console.log(` ${icon} [${issue.type}] ${issue.message}`);\n }\n const errors = filtered.filter((i) => i.severity === \"error\").length;\n if (errors > 0) process.exit(1);\n }\n}\n\nasync function generate() {\n const config = await loadConfig();\n const framework = detectFramework();\n\n switch (framework) {\n case \"next\": {\n const { buildVazaContent } = await import(\"../adapters/next/index.js\");\n await buildVazaContent(config);\n break;\n }\n case \"sveltekit\": {\n const { buildVazaContent } = await import(\"../adapters/sveltekit/index.js\");\n await buildVazaContent(config);\n break;\n }\n case \"astro\": {\n const { buildVazaContent } = await import(\"../adapters/astro/index.js\");\n await buildVazaContent(config);\n break;\n }\n case \"nuxt\": {\n const { buildVazaContent } = await import(\"../adapters/nuxt/index.js\");\n await buildVazaContent(config);\n break;\n }\n default: {\n // Generic: just process and write to .vaza-content/\n const { buildVazaContent } = await import(\"../adapters/next/index.js\");\n await buildVazaContent(config);\n }\n }\n}\n\nmain().catch((err) => {\n console.error(\"[vaza-content]\", err);\n process.exit(1);\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["/Users/mehdi/vaza-content/dist/cli/index.cjs","../../src/cli/index.ts"],"names":[],"mappings":"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","file":"/Users/mehdi/vaza-content/dist/cli/index.cjs","sourcesContent":[null,"#!/usr/bin/env node\n\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\nasync function main() {\n switch (command) {\n case \"init\":\n await init();\n break;\n case \"check\":\n await check(args.slice(1));\n break;\n case \"generate\":\n await generate();\n break;\n case \"help\":\n case \"--help\":\n case \"-h\":\n printHelp();\n break;\n default:\n console.log(`[vaza-content] Unknown command: ${command ?? \"(none)\"}\\n`);\n printHelp();\n process.exit(1);\n }\n}\n\nfunction printHelp() {\n console.log(`\nUsage: vaza-content <command> [options]\n\nCommands:\n init Auto-detect framework, install deps, create config\n check Run integrity checks on content\n generate Generate all SEO outputs\n help Show this help message\n\nCheck options:\n --links Check broken internal links only\n --meta Check meta title/description lengths only\n --freshness Check content freshness only\n --alt Check image alt text only\n --duplicates Check duplicate slugs/content only\n`);\n}\n\nasync function loadConfig() {\n const configPath = resolve(\"vaza.config.ts\");\n const configPathJs = resolve(\"vaza.config.js\");\n const configPathMjs = resolve(\"vaza.config.mjs\");\n\n let actualPath: string | undefined;\n for (const p of [configPathMjs, configPathJs, configPath]) {\n if (existsSync(p)) {\n actualPath = p;\n break;\n }\n }\n\n if (!actualPath) {\n console.error(\n \"[vaza-content] No config file found. Run `vaza-content init` first.\",\n );\n process.exit(1);\n }\n\n const configUrl = pathToFileURL(actualPath).href;\n const mod = await import(configUrl);\n return mod.default;\n}\n\nasync function init() {\n const framework = detectFramework();\n console.log(`[vaza-content] Detected framework: ${framework}`);\n\n switch (framework) {\n case \"next\": {\n console.log(\n \"[vaza-content] Installing @content-collections/core @content-collections/next...\",\n );\n const { execSync } = await import(\"node:child_process\");\n const pm = detectPackageManager();\n const installCmd =\n pm === \"npm\"\n ? \"npm install @content-collections/core @content-collections/next\"\n : pm === \"bun\"\n ? \"bun add @content-collections/core @content-collections/next\"\n : pm === \"pnpm\"\n ? \"pnpm add @content-collections/core @content-collections/next\"\n : \"yarn add @content-collections/core @content-collections/next\";\n execSync(installCmd, { stdio: \"inherit\" });\n writeInitFiles(\"next\");\n break;\n }\n case \"sveltekit\": {\n console.log(\n \"[vaza-content] Installing @content-collections/core @content-collections/vite...\",\n );\n const { execSync } = await import(\"node:child_process\");\n const pm = detectPackageManager();\n const installCmd =\n pm === \"npm\"\n ? \"npm install @content-collections/core @content-collections/vite\"\n : pm === \"bun\"\n ? \"bun add @content-collections/core @content-collections/vite\"\n : pm === \"pnpm\"\n ? \"pnpm add @content-collections/core @content-collections/vite\"\n : \"yarn add @content-collections/core @content-collections/vite\";\n execSync(installCmd, { stdio: \"inherit\" });\n writeInitFiles(\"sveltekit\");\n break;\n }\n case \"astro\":\n writeInitFiles(\"astro\");\n console.log(\n \"[vaza-content] Astro detected -- using built-in content collections.\",\n );\n break;\n case \"nuxt\":\n writeInitFiles(\"nuxt\");\n console.log(\n \"[vaza-content] Nuxt detected -- using built-in Nuxt Content.\",\n );\n break;\n default:\n console.error(\n \"[vaza-content] Could not detect framework. Create vaza.config.ts manually.\",\n );\n process.exit(1);\n }\n\n console.log(\n \"[vaza-content] Setup complete! Edit vaza.config.ts to configure your collections.\",\n );\n}\n\nfunction detectFramework(): string {\n try {\n const pkg = JSON.parse(readFileSync(\"package.json\", \"utf-8\"));\n const deps = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n };\n if (deps.next) return \"next\";\n if (deps[\"@sveltejs/kit\"]) return \"sveltekit\";\n if (deps.astro) return \"astro\";\n if (deps.nuxt) return \"nuxt\";\n } catch {\n // ignore\n }\n return \"unknown\";\n}\n\nfunction detectPackageManager(): string {\n if (existsSync(\"bun.lockb\") || existsSync(\"bun.lock\")) return \"bun\";\n if (existsSync(\"pnpm-lock.yaml\")) return \"pnpm\";\n if (existsSync(\"yarn.lock\")) return \"yarn\";\n return \"npm\";\n}\n\nfunction writeInitFiles(_framework: string) {\n if (!existsSync(\"vaza.config.ts\")) {\n const configTemplate = `import { defineConfig } from 'vaza-content'\n\nexport default defineConfig({\n site: {\n url: 'https://example.com',\n name: 'My Site',\n description: 'My site description',\n language: 'en',\n },\n\n collections: {\n // Configure your collections here\n // blog: {\n // entries: () => getPosts(),\n // map: (post) => ({\n // slug: post.slug,\n // title: post.title,\n // body: post.content,\n // description: post.description,\n // publishDate: new Date(post.date),\n // }),\n // basePath: '/blog',\n // },\n },\n\n sitemap: { enabled: true },\n rss: { enabled: true },\n jsonLd: { enabled: true },\n ogImages: { enabled: true, template: 'blog' },\n taxonomy: { enabled: true },\n redirects: { enabled: true },\n integrity: {\n brokenLinks: 'warn',\n duplicateSlugs: 'error',\n altText: 'warn',\n },\n})\n`;\n writeFileSync(\"vaza.config.ts\", configTemplate, \"utf-8\");\n console.log(\"[vaza-content] Created vaza.config.ts\");\n }\n\n // Add .vaza-content to gitignore if not present\n const gitignorePath = \".gitignore\";\n if (existsSync(gitignorePath)) {\n const gitignore = readFileSync(gitignorePath, \"utf-8\");\n if (!gitignore.includes(\".vaza-content\")) {\n writeFileSync(\n gitignorePath,\n `${gitignore.trimEnd()}\\n.vaza-content/\\n`,\n \"utf-8\",\n );\n console.log(\"[vaza-content] Added .vaza-content/ to .gitignore\");\n }\n }\n}\n\nasync function check(flags: string[]) {\n const config = await loadConfig();\n const { processCollections } = await import(\"../process.js\");\n const output = await processCollections(config);\n\n const issues = output.integrity.issues;\n let filtered = issues;\n\n if (flags.length > 0) {\n const typeMap: Record<string, string[]> = {\n \"--links\": [\"broken-link\"],\n \"--meta\": [\"meta-title-length\", \"meta-description-length\"],\n \"--freshness\": [\"stale-content\"],\n \"--alt\": [\"missing-alt-text\"],\n \"--duplicates\": [\"duplicate-slug\", \"duplicate-content\"],\n };\n\n const allowedTypes = flags.flatMap((f) => typeMap[f] ?? []);\n if (allowedTypes.length > 0) {\n filtered = issues.filter((i) => allowedTypes.includes(i.type));\n }\n }\n\n if (filtered.length === 0) {\n console.log(\"[vaza-content] All checks passed!\");\n } else {\n for (const issue of filtered) {\n const icon = issue.severity === \"error\" ? \"x\" : \"!\";\n console.log(` ${icon} [${issue.type}] ${issue.message}`);\n }\n const errors = filtered.filter((i) => i.severity === \"error\").length;\n if (errors > 0) process.exit(1);\n }\n}\n\nasync function generate() {\n const config = await loadConfig();\n const framework = detectFramework();\n\n switch (framework) {\n case \"next\": {\n const { buildVazaContent } = await import(\"../adapters/next/index.js\");\n await buildVazaContent(config);\n break;\n }\n case \"sveltekit\": {\n const { buildVazaContent } = await import(\n \"../adapters/sveltekit/index.js\"\n );\n await buildVazaContent(config);\n break;\n }\n case \"astro\": {\n const { buildVazaContent } = await import(\"../adapters/astro/index.js\");\n await buildVazaContent(config);\n break;\n }\n case \"nuxt\": {\n const { buildVazaContent } = await import(\"../adapters/nuxt/index.js\");\n await buildVazaContent(config);\n break;\n }\n default: {\n // Generic: just process and write to .vaza-content/\n const { buildVazaContent } = await import(\"../adapters/next/index.js\");\n await buildVazaContent(config);\n }\n }\n}\n\nmain().catch((err) => {\n console.error(\"[vaza-content]\", err);\n process.exit(1);\n});\n"]}
|
package/dist/cli/index.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
__require
|
|
4
|
-
} from "../chunk-DGUM43GV.js";
|
|
5
2
|
|
|
6
3
|
// src/cli/index.ts
|
|
7
|
-
import { existsSync } from "fs";
|
|
4
|
+
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
8
5
|
import { resolve } from "path";
|
|
9
6
|
import { pathToFileURL } from "url";
|
|
10
7
|
var args = process.argv.slice(2);
|
|
@@ -26,10 +23,8 @@ async function main() {
|
|
|
26
23
|
printHelp();
|
|
27
24
|
break;
|
|
28
25
|
default:
|
|
29
|
-
console.log(
|
|
30
|
-
|
|
31
|
-
`
|
|
32
|
-
);
|
|
26
|
+
console.log(`[vaza-content] Unknown command: ${command ?? "(none)"}
|
|
27
|
+
`);
|
|
33
28
|
printHelp();
|
|
34
29
|
process.exit(1);
|
|
35
30
|
}
|
|
@@ -78,7 +73,9 @@ async function init() {
|
|
|
78
73
|
console.log(`[vaza-content] Detected framework: ${framework}`);
|
|
79
74
|
switch (framework) {
|
|
80
75
|
case "next": {
|
|
81
|
-
console.log(
|
|
76
|
+
console.log(
|
|
77
|
+
"[vaza-content] Installing @content-collections/core @content-collections/next..."
|
|
78
|
+
);
|
|
82
79
|
const { execSync } = await import("child_process");
|
|
83
80
|
const pm = detectPackageManager();
|
|
84
81
|
const installCmd = pm === "npm" ? "npm install @content-collections/core @content-collections/next" : pm === "bun" ? "bun add @content-collections/core @content-collections/next" : pm === "pnpm" ? "pnpm add @content-collections/core @content-collections/next" : "yarn add @content-collections/core @content-collections/next";
|
|
@@ -87,7 +84,9 @@ async function init() {
|
|
|
87
84
|
break;
|
|
88
85
|
}
|
|
89
86
|
case "sveltekit": {
|
|
90
|
-
console.log(
|
|
87
|
+
console.log(
|
|
88
|
+
"[vaza-content] Installing @content-collections/core @content-collections/vite..."
|
|
89
|
+
);
|
|
91
90
|
const { execSync } = await import("child_process");
|
|
92
91
|
const pm = detectPackageManager();
|
|
93
92
|
const installCmd = pm === "npm" ? "npm install @content-collections/core @content-collections/vite" : pm === "bun" ? "bun add @content-collections/core @content-collections/vite" : pm === "pnpm" ? "pnpm add @content-collections/core @content-collections/vite" : "yarn add @content-collections/core @content-collections/vite";
|
|
@@ -97,23 +96,29 @@ async function init() {
|
|
|
97
96
|
}
|
|
98
97
|
case "astro":
|
|
99
98
|
writeInitFiles("astro");
|
|
100
|
-
console.log(
|
|
99
|
+
console.log(
|
|
100
|
+
"[vaza-content] Astro detected -- using built-in content collections."
|
|
101
|
+
);
|
|
101
102
|
break;
|
|
102
103
|
case "nuxt":
|
|
103
104
|
writeInitFiles("nuxt");
|
|
104
|
-
console.log(
|
|
105
|
+
console.log(
|
|
106
|
+
"[vaza-content] Nuxt detected -- using built-in Nuxt Content."
|
|
107
|
+
);
|
|
105
108
|
break;
|
|
106
109
|
default:
|
|
107
|
-
console.error(
|
|
110
|
+
console.error(
|
|
111
|
+
"[vaza-content] Could not detect framework. Create vaza.config.ts manually."
|
|
112
|
+
);
|
|
108
113
|
process.exit(1);
|
|
109
114
|
}
|
|
110
|
-
console.log(
|
|
115
|
+
console.log(
|
|
116
|
+
"[vaza-content] Setup complete! Edit vaza.config.ts to configure your collections."
|
|
117
|
+
);
|
|
111
118
|
}
|
|
112
119
|
function detectFramework() {
|
|
113
120
|
try {
|
|
114
|
-
const pkg = JSON.parse(
|
|
115
|
-
__require("fs").readFileSync("package.json", "utf-8")
|
|
116
|
-
);
|
|
121
|
+
const pkg = JSON.parse(readFileSync("package.json", "utf-8"));
|
|
117
122
|
const deps = {
|
|
118
123
|
...pkg.dependencies,
|
|
119
124
|
...pkg.devDependencies
|
|
@@ -132,8 +137,7 @@ function detectPackageManager() {
|
|
|
132
137
|
if (existsSync("yarn.lock")) return "yarn";
|
|
133
138
|
return "npm";
|
|
134
139
|
}
|
|
135
|
-
function writeInitFiles(
|
|
136
|
-
const { writeFileSync } = __require("fs");
|
|
140
|
+
function writeInitFiles(_framework) {
|
|
137
141
|
if (!existsSync("vaza.config.ts")) {
|
|
138
142
|
const configTemplate = `import { defineConfig } from 'vaza-content'
|
|
139
143
|
|
|
@@ -178,11 +182,13 @@ export default defineConfig({
|
|
|
178
182
|
}
|
|
179
183
|
const gitignorePath = ".gitignore";
|
|
180
184
|
if (existsSync(gitignorePath)) {
|
|
181
|
-
const gitignore =
|
|
185
|
+
const gitignore = readFileSync(gitignorePath, "utf-8");
|
|
182
186
|
if (!gitignore.includes(".vaza-content")) {
|
|
183
187
|
writeFileSync(
|
|
184
188
|
gitignorePath,
|
|
185
|
-
gitignore.trimEnd()
|
|
189
|
+
`${gitignore.trimEnd()}
|
|
190
|
+
.vaza-content/
|
|
191
|
+
`,
|
|
186
192
|
"utf-8"
|
|
187
193
|
);
|
|
188
194
|
console.log("[vaza-content] Added .vaza-content/ to .gitignore");
|
|
@@ -191,7 +197,7 @@ export default defineConfig({
|
|
|
191
197
|
}
|
|
192
198
|
async function check(flags) {
|
|
193
199
|
const config = await loadConfig();
|
|
194
|
-
const { processCollections } = await import("../process-
|
|
200
|
+
const { processCollections } = await import("../process-ZQV5M2TB.js");
|
|
195
201
|
const output = await processCollections(config);
|
|
196
202
|
const issues = output.integrity.issues;
|
|
197
203
|
let filtered = issues;
|
|
@@ -212,7 +218,7 @@ async function check(flags) {
|
|
|
212
218
|
console.log("[vaza-content] All checks passed!");
|
|
213
219
|
} else {
|
|
214
220
|
for (const issue of filtered) {
|
|
215
|
-
const icon = issue.severity === "error" ? "
|
|
221
|
+
const icon = issue.severity === "error" ? "x" : "!";
|
|
216
222
|
console.log(` ${icon} [${issue.type}] ${issue.message}`);
|
|
217
223
|
}
|
|
218
224
|
const errors = filtered.filter((i) => i.severity === "error").length;
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { existsSync } from \"node:fs\";\nimport { resolve, join } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\nasync function main() {\n switch (command) {\n case \"init\":\n await init();\n break;\n case \"check\":\n await check(args.slice(1));\n break;\n case \"generate\":\n await generate();\n break;\n case \"help\":\n case \"--help\":\n case \"-h\":\n printHelp();\n break;\n default:\n console.log(\n `[vaza-content] Unknown command: ${command ?? \"(none)\"}\\n`,\n );\n printHelp();\n process.exit(1);\n }\n}\n\nfunction printHelp() {\n console.log(`\nUsage: vaza-content <command> [options]\n\nCommands:\n init Auto-detect framework, install deps, create config\n check Run integrity checks on content\n generate Generate all SEO outputs\n help Show this help message\n\nCheck options:\n --links Check broken internal links only\n --meta Check meta title/description lengths only\n --freshness Check content freshness only\n --alt Check image alt text only\n --duplicates Check duplicate slugs/content only\n`);\n}\n\nasync function loadConfig() {\n const configPath = resolve(\"vaza.config.ts\");\n const configPathJs = resolve(\"vaza.config.js\");\n const configPathMjs = resolve(\"vaza.config.mjs\");\n\n let actualPath: string | undefined;\n for (const p of [configPathMjs, configPathJs, configPath]) {\n if (existsSync(p)) {\n actualPath = p;\n break;\n }\n }\n\n if (!actualPath) {\n console.error(\n \"[vaza-content] No config file found. Run `vaza-content init` first.\",\n );\n process.exit(1);\n }\n\n const configUrl = pathToFileURL(actualPath).href;\n const mod = await import(configUrl);\n return mod.default;\n}\n\nasync function init() {\n const framework = detectFramework();\n console.log(`[vaza-content] Detected framework: ${framework}`);\n\n switch (framework) {\n case \"next\": {\n console.log(\"[vaza-content] Installing @content-collections/core @content-collections/next...\");\n const { execSync } = await import(\"node:child_process\");\n const pm = detectPackageManager();\n const installCmd =\n pm === \"npm\"\n ? \"npm install @content-collections/core @content-collections/next\"\n : pm === \"bun\"\n ? \"bun add @content-collections/core @content-collections/next\"\n : pm === \"pnpm\"\n ? \"pnpm add @content-collections/core @content-collections/next\"\n : \"yarn add @content-collections/core @content-collections/next\";\n execSync(installCmd, { stdio: \"inherit\" });\n writeInitFiles(\"next\");\n break;\n }\n case \"sveltekit\": {\n console.log(\"[vaza-content] Installing @content-collections/core @content-collections/vite...\");\n const { execSync } = await import(\"node:child_process\");\n const pm = detectPackageManager();\n const installCmd =\n pm === \"npm\"\n ? \"npm install @content-collections/core @content-collections/vite\"\n : pm === \"bun\"\n ? \"bun add @content-collections/core @content-collections/vite\"\n : pm === \"pnpm\"\n ? \"pnpm add @content-collections/core @content-collections/vite\"\n : \"yarn add @content-collections/core @content-collections/vite\";\n execSync(installCmd, { stdio: \"inherit\" });\n writeInitFiles(\"sveltekit\");\n break;\n }\n case \"astro\":\n writeInitFiles(\"astro\");\n console.log(\"[vaza-content] Astro detected — using built-in content collections.\");\n break;\n case \"nuxt\":\n writeInitFiles(\"nuxt\");\n console.log(\"[vaza-content] Nuxt detected — using built-in Nuxt Content.\");\n break;\n default:\n console.error(\"[vaza-content] Could not detect framework. Create vaza.config.ts manually.\");\n process.exit(1);\n }\n\n console.log(\"[vaza-content] Setup complete! Edit vaza.config.ts to configure your collections.\");\n}\n\nfunction detectFramework(): string {\n try {\n const pkg = JSON.parse(\n require(\"node:fs\").readFileSync(\"package.json\", \"utf-8\"),\n );\n const deps = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n };\n if (deps.next) return \"next\";\n if (deps[\"@sveltejs/kit\"]) return \"sveltekit\";\n if (deps.astro) return \"astro\";\n if (deps.nuxt) return \"nuxt\";\n } catch {\n // ignore\n }\n return \"unknown\";\n}\n\nfunction detectPackageManager(): string {\n if (existsSync(\"bun.lockb\") || existsSync(\"bun.lock\")) return \"bun\";\n if (existsSync(\"pnpm-lock.yaml\")) return \"pnpm\";\n if (existsSync(\"yarn.lock\")) return \"yarn\";\n return \"npm\";\n}\n\nfunction writeInitFiles(framework: string) {\n const { writeFileSync } = require(\"node:fs\") as typeof import(\"node:fs\");\n\n if (!existsSync(\"vaza.config.ts\")) {\n const configTemplate = `import { defineConfig } from 'vaza-content'\n\nexport default defineConfig({\n site: {\n url: 'https://example.com',\n name: 'My Site',\n description: 'My site description',\n language: 'en',\n },\n\n collections: {\n // Configure your collections here\n // blog: {\n // entries: () => getPosts(),\n // map: (post) => ({\n // slug: post.slug,\n // title: post.title,\n // body: post.content,\n // description: post.description,\n // publishDate: new Date(post.date),\n // }),\n // basePath: '/blog',\n // },\n },\n\n sitemap: { enabled: true },\n rss: { enabled: true },\n jsonLd: { enabled: true },\n ogImages: { enabled: true, template: 'blog' },\n taxonomy: { enabled: true },\n redirects: { enabled: true },\n integrity: {\n brokenLinks: 'warn',\n duplicateSlugs: 'error',\n altText: 'warn',\n },\n})\n`;\n writeFileSync(\"vaza.config.ts\", configTemplate, \"utf-8\");\n console.log(\"[vaza-content] Created vaza.config.ts\");\n }\n\n // Add .vaza-content to gitignore if not present\n const gitignorePath = \".gitignore\";\n if (existsSync(gitignorePath)) {\n const gitignore = require(\"node:fs\").readFileSync(gitignorePath, \"utf-8\") as string;\n if (!gitignore.includes(\".vaza-content\")) {\n writeFileSync(\n gitignorePath,\n gitignore.trimEnd() + \"\\n.vaza-content/\\n\",\n \"utf-8\",\n );\n console.log(\"[vaza-content] Added .vaza-content/ to .gitignore\");\n }\n }\n}\n\nasync function check(flags: string[]) {\n const config = await loadConfig();\n const { processCollections } = await import(\"../process.js\");\n const output = await processCollections(config);\n\n const issues = output.integrity.issues;\n let filtered = issues;\n\n if (flags.length > 0) {\n const typeMap: Record<string, string[]> = {\n \"--links\": [\"broken-link\"],\n \"--meta\": [\"meta-title-length\", \"meta-description-length\"],\n \"--freshness\": [\"stale-content\"],\n \"--alt\": [\"missing-alt-text\"],\n \"--duplicates\": [\"duplicate-slug\", \"duplicate-content\"],\n };\n\n const allowedTypes = flags.flatMap((f) => typeMap[f] ?? []);\n if (allowedTypes.length > 0) {\n filtered = issues.filter((i) => allowedTypes.includes(i.type));\n }\n }\n\n if (filtered.length === 0) {\n console.log(\"[vaza-content] All checks passed!\");\n } else {\n for (const issue of filtered) {\n const icon = issue.severity === \"error\" ? \"✖\" : \"⚠\";\n console.log(` ${icon} [${issue.type}] ${issue.message}`);\n }\n const errors = filtered.filter((i) => i.severity === \"error\").length;\n if (errors > 0) process.exit(1);\n }\n}\n\nasync function generate() {\n const config = await loadConfig();\n const framework = detectFramework();\n\n switch (framework) {\n case \"next\": {\n const { buildVazaContent } = await import(\"../adapters/next/index.js\");\n await buildVazaContent(config);\n break;\n }\n case \"sveltekit\": {\n const { buildVazaContent } = await import(\"../adapters/sveltekit/index.js\");\n await buildVazaContent(config);\n break;\n }\n case \"astro\": {\n const { buildVazaContent } = await import(\"../adapters/astro/index.js\");\n await buildVazaContent(config);\n break;\n }\n case \"nuxt\": {\n const { buildVazaContent } = await import(\"../adapters/nuxt/index.js\");\n await buildVazaContent(config);\n break;\n }\n default: {\n // Generic: just process and write to .vaza-content/\n const { buildVazaContent } = await import(\"../adapters/next/index.js\");\n await buildVazaContent(config);\n }\n }\n}\n\nmain().catch((err) => {\n console.error(\"[vaza-content]\", err);\n process.exit(1);\n});\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\nasync function main() {\n switch (command) {\n case \"init\":\n await init();\n break;\n case \"check\":\n await check(args.slice(1));\n break;\n case \"generate\":\n await generate();\n break;\n case \"help\":\n case \"--help\":\n case \"-h\":\n printHelp();\n break;\n default:\n console.log(`[vaza-content] Unknown command: ${command ?? \"(none)\"}\\n`);\n printHelp();\n process.exit(1);\n }\n}\n\nfunction printHelp() {\n console.log(`\nUsage: vaza-content <command> [options]\n\nCommands:\n init Auto-detect framework, install deps, create config\n check Run integrity checks on content\n generate Generate all SEO outputs\n help Show this help message\n\nCheck options:\n --links Check broken internal links only\n --meta Check meta title/description lengths only\n --freshness Check content freshness only\n --alt Check image alt text only\n --duplicates Check duplicate slugs/content only\n`);\n}\n\nasync function loadConfig() {\n const configPath = resolve(\"vaza.config.ts\");\n const configPathJs = resolve(\"vaza.config.js\");\n const configPathMjs = resolve(\"vaza.config.mjs\");\n\n let actualPath: string | undefined;\n for (const p of [configPathMjs, configPathJs, configPath]) {\n if (existsSync(p)) {\n actualPath = p;\n break;\n }\n }\n\n if (!actualPath) {\n console.error(\n \"[vaza-content] No config file found. Run `vaza-content init` first.\",\n );\n process.exit(1);\n }\n\n const configUrl = pathToFileURL(actualPath).href;\n const mod = await import(configUrl);\n return mod.default;\n}\n\nasync function init() {\n const framework = detectFramework();\n console.log(`[vaza-content] Detected framework: ${framework}`);\n\n switch (framework) {\n case \"next\": {\n console.log(\n \"[vaza-content] Installing @content-collections/core @content-collections/next...\",\n );\n const { execSync } = await import(\"node:child_process\");\n const pm = detectPackageManager();\n const installCmd =\n pm === \"npm\"\n ? \"npm install @content-collections/core @content-collections/next\"\n : pm === \"bun\"\n ? \"bun add @content-collections/core @content-collections/next\"\n : pm === \"pnpm\"\n ? \"pnpm add @content-collections/core @content-collections/next\"\n : \"yarn add @content-collections/core @content-collections/next\";\n execSync(installCmd, { stdio: \"inherit\" });\n writeInitFiles(\"next\");\n break;\n }\n case \"sveltekit\": {\n console.log(\n \"[vaza-content] Installing @content-collections/core @content-collections/vite...\",\n );\n const { execSync } = await import(\"node:child_process\");\n const pm = detectPackageManager();\n const installCmd =\n pm === \"npm\"\n ? \"npm install @content-collections/core @content-collections/vite\"\n : pm === \"bun\"\n ? \"bun add @content-collections/core @content-collections/vite\"\n : pm === \"pnpm\"\n ? \"pnpm add @content-collections/core @content-collections/vite\"\n : \"yarn add @content-collections/core @content-collections/vite\";\n execSync(installCmd, { stdio: \"inherit\" });\n writeInitFiles(\"sveltekit\");\n break;\n }\n case \"astro\":\n writeInitFiles(\"astro\");\n console.log(\n \"[vaza-content] Astro detected -- using built-in content collections.\",\n );\n break;\n case \"nuxt\":\n writeInitFiles(\"nuxt\");\n console.log(\n \"[vaza-content] Nuxt detected -- using built-in Nuxt Content.\",\n );\n break;\n default:\n console.error(\n \"[vaza-content] Could not detect framework. Create vaza.config.ts manually.\",\n );\n process.exit(1);\n }\n\n console.log(\n \"[vaza-content] Setup complete! Edit vaza.config.ts to configure your collections.\",\n );\n}\n\nfunction detectFramework(): string {\n try {\n const pkg = JSON.parse(readFileSync(\"package.json\", \"utf-8\"));\n const deps = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n };\n if (deps.next) return \"next\";\n if (deps[\"@sveltejs/kit\"]) return \"sveltekit\";\n if (deps.astro) return \"astro\";\n if (deps.nuxt) return \"nuxt\";\n } catch {\n // ignore\n }\n return \"unknown\";\n}\n\nfunction detectPackageManager(): string {\n if (existsSync(\"bun.lockb\") || existsSync(\"bun.lock\")) return \"bun\";\n if (existsSync(\"pnpm-lock.yaml\")) return \"pnpm\";\n if (existsSync(\"yarn.lock\")) return \"yarn\";\n return \"npm\";\n}\n\nfunction writeInitFiles(_framework: string) {\n if (!existsSync(\"vaza.config.ts\")) {\n const configTemplate = `import { defineConfig } from 'vaza-content'\n\nexport default defineConfig({\n site: {\n url: 'https://example.com',\n name: 'My Site',\n description: 'My site description',\n language: 'en',\n },\n\n collections: {\n // Configure your collections here\n // blog: {\n // entries: () => getPosts(),\n // map: (post) => ({\n // slug: post.slug,\n // title: post.title,\n // body: post.content,\n // description: post.description,\n // publishDate: new Date(post.date),\n // }),\n // basePath: '/blog',\n // },\n },\n\n sitemap: { enabled: true },\n rss: { enabled: true },\n jsonLd: { enabled: true },\n ogImages: { enabled: true, template: 'blog' },\n taxonomy: { enabled: true },\n redirects: { enabled: true },\n integrity: {\n brokenLinks: 'warn',\n duplicateSlugs: 'error',\n altText: 'warn',\n },\n})\n`;\n writeFileSync(\"vaza.config.ts\", configTemplate, \"utf-8\");\n console.log(\"[vaza-content] Created vaza.config.ts\");\n }\n\n // Add .vaza-content to gitignore if not present\n const gitignorePath = \".gitignore\";\n if (existsSync(gitignorePath)) {\n const gitignore = readFileSync(gitignorePath, \"utf-8\");\n if (!gitignore.includes(\".vaza-content\")) {\n writeFileSync(\n gitignorePath,\n `${gitignore.trimEnd()}\\n.vaza-content/\\n`,\n \"utf-8\",\n );\n console.log(\"[vaza-content] Added .vaza-content/ to .gitignore\");\n }\n }\n}\n\nasync function check(flags: string[]) {\n const config = await loadConfig();\n const { processCollections } = await import(\"../process.js\");\n const output = await processCollections(config);\n\n const issues = output.integrity.issues;\n let filtered = issues;\n\n if (flags.length > 0) {\n const typeMap: Record<string, string[]> = {\n \"--links\": [\"broken-link\"],\n \"--meta\": [\"meta-title-length\", \"meta-description-length\"],\n \"--freshness\": [\"stale-content\"],\n \"--alt\": [\"missing-alt-text\"],\n \"--duplicates\": [\"duplicate-slug\", \"duplicate-content\"],\n };\n\n const allowedTypes = flags.flatMap((f) => typeMap[f] ?? []);\n if (allowedTypes.length > 0) {\n filtered = issues.filter((i) => allowedTypes.includes(i.type));\n }\n }\n\n if (filtered.length === 0) {\n console.log(\"[vaza-content] All checks passed!\");\n } else {\n for (const issue of filtered) {\n const icon = issue.severity === \"error\" ? \"x\" : \"!\";\n console.log(` ${icon} [${issue.type}] ${issue.message}`);\n }\n const errors = filtered.filter((i) => i.severity === \"error\").length;\n if (errors > 0) process.exit(1);\n }\n}\n\nasync function generate() {\n const config = await loadConfig();\n const framework = detectFramework();\n\n switch (framework) {\n case \"next\": {\n const { buildVazaContent } = await import(\"../adapters/next/index.js\");\n await buildVazaContent(config);\n break;\n }\n case \"sveltekit\": {\n const { buildVazaContent } = await import(\n \"../adapters/sveltekit/index.js\"\n );\n await buildVazaContent(config);\n break;\n }\n case \"astro\": {\n const { buildVazaContent } = await import(\"../adapters/astro/index.js\");\n await buildVazaContent(config);\n break;\n }\n case \"nuxt\": {\n const { buildVazaContent } = await import(\"../adapters/nuxt/index.js\");\n await buildVazaContent(config);\n break;\n }\n default: {\n // Generic: just process and write to .vaza-content/\n const { buildVazaContent } = await import(\"../adapters/next/index.js\");\n await buildVazaContent(config);\n }\n }\n}\n\nmain().catch((err) => {\n console.error(\"[vaza-content]\", err);\n process.exit(1);\n});\n"],"mappings":"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","names":[]}
|