nextblogkit 0.6.2 → 0.7.1

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.
Files changed (111) hide show
  1. package/README.md +83 -21
  2. package/dist/admin/index.cjs +366 -10
  3. package/dist/admin/index.cjs.map +1 -1
  4. package/dist/admin/index.d.cts +7 -3
  5. package/dist/admin/index.d.ts +7 -3
  6. package/dist/admin/index.js +365 -11
  7. package/dist/admin/index.js.map +1 -1
  8. package/dist/api/categories.cjs +32 -32
  9. package/dist/api/categories.cjs.map +1 -1
  10. package/dist/api/categories.d.cts +1 -1
  11. package/dist/api/categories.d.ts +1 -1
  12. package/dist/api/categories.js +6 -6
  13. package/dist/api/categories.js.map +1 -1
  14. package/dist/api/media.cjs +37 -30
  15. package/dist/api/media.cjs.map +1 -1
  16. package/dist/api/media.d.cts +1 -1
  17. package/dist/api/media.d.ts +1 -1
  18. package/dist/api/media.js +13 -6
  19. package/dist/api/media.js.map +1 -1
  20. package/dist/api/posts.cjs +39 -39
  21. package/dist/api/posts.cjs.map +1 -1
  22. package/dist/api/posts.d.cts +1 -1
  23. package/dist/api/posts.d.ts +1 -1
  24. package/dist/api/posts.js +6 -6
  25. package/dist/api/posts.js.map +1 -1
  26. package/dist/api/rss.cjs +3 -3
  27. package/dist/api/rss.js +2 -2
  28. package/dist/api/settings.cjs +13 -13
  29. package/dist/api/settings.cjs.map +1 -1
  30. package/dist/api/settings.d.cts +1 -1
  31. package/dist/api/settings.d.ts +1 -1
  32. package/dist/api/settings.js +5 -5
  33. package/dist/api/settings.js.map +1 -1
  34. package/dist/api/sitemap.cjs +3 -3
  35. package/dist/api/sitemap.js +2 -2
  36. package/dist/api/tokens.cjs +56 -0
  37. package/dist/api/tokens.cjs.map +1 -0
  38. package/dist/api/tokens.d.cts +22 -0
  39. package/dist/api/tokens.d.ts +22 -0
  40. package/dist/api/tokens.js +52 -0
  41. package/dist/api/tokens.js.map +1 -0
  42. package/dist/{chunk-6HKMZOI4.cjs → chunk-3BKPNOES.cjs} +8 -7
  43. package/dist/chunk-3BKPNOES.cjs.map +1 -0
  44. package/dist/{chunk-N5MKAD7J.cjs → chunk-DR7QNI32.cjs} +6 -2
  45. package/dist/chunk-DR7QNI32.cjs.map +1 -0
  46. package/dist/{chunk-QE4VLQYN.cjs → chunk-F47RPOTU.cjs} +13 -10
  47. package/dist/chunk-F47RPOTU.cjs.map +1 -0
  48. package/dist/{chunk-64HUVJOZ.js → chunk-JI2RK6KX.js} +80 -13
  49. package/dist/chunk-JI2RK6KX.js.map +1 -0
  50. package/dist/{chunk-R6MO3QIP.js → chunk-NSR7NYSB.js} +6 -5
  51. package/dist/chunk-NSR7NYSB.js.map +1 -0
  52. package/dist/{chunk-4PY224XM.js → chunk-O3XES5O2.js} +6 -3
  53. package/dist/chunk-O3XES5O2.js.map +1 -0
  54. package/dist/{chunk-4NKOJYWJ.js → chunk-OOUJYUGP.js} +8 -7
  55. package/dist/chunk-OOUJYUGP.js.map +1 -0
  56. package/dist/{chunk-A2S32RZN.js → chunk-OWWWTTUT.js} +8 -3
  57. package/dist/chunk-OWWWTTUT.js.map +1 -0
  58. package/dist/{chunk-E2QLTHKN.cjs → chunk-QBZLGBHQ.cjs} +11 -10
  59. package/dist/chunk-QBZLGBHQ.cjs.map +1 -0
  60. package/dist/{chunk-ZP5XRVVH.cjs → chunk-SUJT6LWH.cjs} +12 -7
  61. package/dist/chunk-SUJT6LWH.cjs.map +1 -0
  62. package/dist/{chunk-JM7QRXXK.js → chunk-TVHY4BR2.js} +10 -7
  63. package/dist/chunk-TVHY4BR2.js.map +1 -0
  64. package/dist/{chunk-JLPJKNRZ.js → chunk-UMIBGO4S.js} +18 -5
  65. package/dist/chunk-UMIBGO4S.js.map +1 -0
  66. package/dist/{chunk-U2ROR6AY.cjs → chunk-VWKVU3SE.cjs} +86 -12
  67. package/dist/chunk-VWKVU3SE.cjs.map +1 -0
  68. package/dist/{chunk-KDZER3PU.cjs → chunk-YTJQ426D.cjs} +19 -5
  69. package/dist/chunk-YTJQ426D.cjs.map +1 -0
  70. package/dist/cli/index.cjs +90 -19
  71. package/dist/components/index.cjs +3 -2
  72. package/dist/components/index.cjs.map +1 -1
  73. package/dist/components/index.d.cts +2 -1
  74. package/dist/components/index.d.ts +2 -1
  75. package/dist/components/index.js +3 -2
  76. package/dist/components/index.js.map +1 -1
  77. package/dist/db-OUSQPM53.js +3 -0
  78. package/dist/db-OUSQPM53.js.map +1 -0
  79. package/dist/db-RFY6O5UE.cjs +108 -0
  80. package/dist/db-RFY6O5UE.cjs.map +1 -0
  81. package/dist/editor/index.cjs +1 -0
  82. package/dist/editor/index.cjs.map +1 -1
  83. package/dist/editor/index.js +1 -0
  84. package/dist/editor/index.js.map +1 -1
  85. package/dist/{index-vjlZDWNr.d.cts → index-Bk8gOqBq.d.cts} +25 -21
  86. package/dist/{index-Cgzphklp.d.ts → index-DsnG2kdW.d.ts} +25 -21
  87. package/dist/index.cjs +47 -47
  88. package/dist/index.d.cts +3 -3
  89. package/dist/index.d.ts +3 -3
  90. package/dist/index.js +5 -5
  91. package/dist/lib/index.cjs +39 -35
  92. package/dist/lib/index.d.cts +2 -2
  93. package/dist/lib/index.d.ts +2 -2
  94. package/dist/lib/index.js +5 -5
  95. package/dist/{types-CBEEBR4A.d.ts → types-Cu515Egx.d.cts} +16 -1
  96. package/dist/{types-CBEEBR4A.d.cts → types-Cu515Egx.d.ts} +16 -1
  97. package/package.json +1 -1
  98. package/dist/chunk-4NKOJYWJ.js.map +0 -1
  99. package/dist/chunk-4PY224XM.js.map +0 -1
  100. package/dist/chunk-64HUVJOZ.js.map +0 -1
  101. package/dist/chunk-6HKMZOI4.cjs.map +0 -1
  102. package/dist/chunk-A2S32RZN.js.map +0 -1
  103. package/dist/chunk-E2QLTHKN.cjs.map +0 -1
  104. package/dist/chunk-JLPJKNRZ.js.map +0 -1
  105. package/dist/chunk-JM7QRXXK.js.map +0 -1
  106. package/dist/chunk-KDZER3PU.cjs.map +0 -1
  107. package/dist/chunk-N5MKAD7J.cjs.map +0 -1
  108. package/dist/chunk-QE4VLQYN.cjs.map +0 -1
  109. package/dist/chunk-R6MO3QIP.js.map +0 -1
  110. package/dist/chunk-U2ROR6AY.cjs.map +0 -1
  111. package/dist/chunk-ZP5XRVVH.cjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/config.ts","../src/lib/slug.ts","../src/lib/reading-time.ts","../src/lib/db.ts"],"names":["z","MongoClient","ObjectId","createHash","randomBytes"],"mappings":"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","file":"chunk-VWKVU3SE.cjs","sourcesContent":["import { z } from 'zod';\nimport type { NextBlogKitConfig } from './types';\n\nconst envSchema = z.object({\n // Required\n NEXTBLOGKIT_MONGODB_URI: z.string().min(1, 'MongoDB URI is required'),\n NEXTBLOGKIT_API_KEY: z.string().min(32, 'API key must be at least 32 characters'),\n\n // Optional — Database name (defaults to the database in your connection URI)\n NEXTBLOGKIT_MONGODB_DB: z.string().optional(),\n\n // Optional — Cloudflare R2 (image storage)\n NEXTBLOGKIT_R2_ACCOUNT_ID: z.string().optional(),\n NEXTBLOGKIT_R2_ACCESS_KEY: z.string().optional(),\n NEXTBLOGKIT_R2_SECRET_KEY: z.string().optional(),\n NEXTBLOGKIT_R2_BUCKET: z.string().optional(),\n NEXTBLOGKIT_R2_PUBLIC_URL: z.string().optional(),\n\n // Optional — Site info (defaults provided)\n NEXTBLOGKIT_SITE_URL: z.string().optional().default(''),\n NEXTBLOGKIT_SITE_NAME: z.string().optional().default('Blog'),\n});\n\nexport type EnvConfig = z.infer<typeof envSchema>;\n\nlet cachedEnv: EnvConfig | null = null;\n\nexport function getEnvConfig(): EnvConfig {\n if (cachedEnv) return cachedEnv;\n\n const result = envSchema.safeParse(process.env);\n if (!result.success) {\n const missing = result.error.issues.map((i) => ` - ${i.path.join('.')}: ${i.message}`);\n throw new Error(`NextBlogKit configuration error:\\n${missing.join('\\n')}`);\n }\n\n cachedEnv = result.data;\n return cachedEnv;\n}\n\nexport function isR2Configured(): boolean {\n const env = getEnvConfig();\n return !!(\n env.NEXTBLOGKIT_R2_ACCOUNT_ID &&\n env.NEXTBLOGKIT_R2_ACCESS_KEY &&\n env.NEXTBLOGKIT_R2_SECRET_KEY &&\n env.NEXTBLOGKIT_R2_BUCKET &&\n env.NEXTBLOGKIT_R2_PUBLIC_URL\n );\n}\n\nconst defaultConfig: NextBlogKitConfig = {\n basePath: '/blog',\n adminPath: '/admin/blog',\n apiPath: '/api/blog',\n postsPerPage: 10,\n excerptLength: 160,\n codeHighlighter: 'shiki',\n editor: {\n blocks: [\n 'paragraph',\n 'heading',\n 'image',\n 'codeBlock',\n 'blockquote',\n 'bulletList',\n 'orderedList',\n 'taskList',\n 'table',\n 'embed',\n 'horizontalRule',\n 'callout',\n 'tableOfContents',\n 'faq',\n 'html',\n ],\n maxImageSize: 10 * 1024 * 1024,\n imageFormats: ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'],\n autosaveInterval: 30000,\n },\n seo: {\n titleTemplate: '%s | %siteName%',\n generateRSS: true,\n generateSitemap: true,\n structuredData: true,\n minContentLength: 300,\n },\n auth: {\n strategy: 'api-key',\n },\n features: {\n search: true,\n relatedPosts: true,\n readingProgress: true,\n tableOfContents: true,\n shareButtons: true,\n darkMode: true,\n scheduling: true,\n revisionHistory: true,\n imageOptimization: true,\n },\n theme: {\n darkMode: true,\n variables: {\n '--nbk-primary': '#2563eb',\n '--nbk-primary-hover': '#1d4ed8',\n '--nbk-text': '#1f2937',\n '--nbk-text-muted': '#6b7280',\n '--nbk-bg': '#ffffff',\n '--nbk-bg-secondary': '#f9fafb',\n '--nbk-card-bg': '#ffffff',\n '--nbk-border': '#e5e7eb',\n '--nbk-radius': '0.5rem',\n '--nbk-font-heading': '\"Inter\", system-ui, sans-serif',\n '--nbk-font-body': '\"Inter\", system-ui, sans-serif',\n '--nbk-font-code': '\"JetBrains Mono\", \"Fira Code\", monospace',\n },\n },\n hooks: {},\n};\n\nlet cachedConfig: NextBlogKitConfig | null = null;\n\nexport function defineConfig(config: Partial<NextBlogKitConfig>): Partial<NextBlogKitConfig> {\n return config;\n}\n\nexport function getConfig(userConfig?: Partial<NextBlogKitConfig>): NextBlogKitConfig {\n if (cachedConfig && !userConfig) return cachedConfig;\n\n const merged: NextBlogKitConfig = {\n ...defaultConfig,\n ...userConfig,\n editor: { ...defaultConfig.editor, ...userConfig?.editor },\n seo: { ...defaultConfig.seo, ...userConfig?.seo },\n auth: { ...defaultConfig.auth, ...userConfig?.auth },\n features: { ...defaultConfig.features, ...userConfig?.features },\n theme: {\n ...defaultConfig.theme,\n ...userConfig?.theme,\n variables: { ...defaultConfig.theme.variables, ...userConfig?.theme?.variables },\n },\n hooks: { ...defaultConfig.hooks, ...userConfig?.hooks },\n };\n\n if (!userConfig) {\n cachedConfig = merged;\n }\n\n return merged;\n}\n\nexport function getBlogConfig() {\n const env = getEnvConfig();\n const config = getConfig();\n\n return {\n ...config,\n siteUrl: env.NEXTBLOGKIT_SITE_URL,\n siteName: env.NEXTBLOGKIT_SITE_NAME,\n metadata: {\n title: `Blog | ${env.NEXTBLOGKIT_SITE_NAME}`,\n description: `Latest posts from ${env.NEXTBLOGKIT_SITE_NAME}`,\n openGraph: {\n title: `Blog | ${env.NEXTBLOGKIT_SITE_NAME}`,\n description: `Latest posts from ${env.NEXTBLOGKIT_SITE_NAME}`,\n url: `${env.NEXTBLOGKIT_SITE_URL}${config.basePath}`,\n siteName: env.NEXTBLOGKIT_SITE_NAME,\n type: 'website',\n },\n },\n };\n}\n","import type { Collection } from 'mongodb';\n\nexport function generateSlug(text: string): string {\n return text\n .toLowerCase()\n .trim()\n .replace(/[^\\w\\s-]/g, '')\n .replace(/[\\s_]+/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n\nexport async function ensureUniqueSlug(\n slug: string,\n collection: Collection,\n excludeId?: string\n): Promise<string> {\n let candidate = slug;\n let counter = 1;\n\n while (true) {\n const query: Record<string, unknown> = { slug: candidate };\n if (excludeId) {\n query._id = { $ne: excludeId };\n }\n\n const existing = await collection.findOne(query);\n if (!existing) return candidate;\n\n candidate = `${slug}-${counter}`;\n counter++;\n }\n}\n","const WORDS_PER_MINUTE = 200;\n\nexport function calculateReadingTime(text: string): number {\n const words = countWords(text);\n return Math.max(1, Math.ceil(words / WORDS_PER_MINUTE));\n}\n\nexport function countWords(text: string): number {\n if (!text || !text.trim()) return 0;\n return text.trim().split(/\\s+/).length;\n}\n\nexport function extractTextFromHTML(html: string): string {\n return html\n .replace(/<script[^>]*>[\\s\\S]*?<\\/script>/gi, '')\n .replace(/<style[^>]*>[\\s\\S]*?<\\/style>/gi, '')\n .replace(/<[^>]+>/g, ' ')\n .replace(/&nbsp;/g, ' ')\n .replace(/&amp;/g, '&')\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\")\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nexport function extractTextFromBlocks(blocks: unknown[]): string {\n if (!Array.isArray(blocks)) return '';\n\n const parts: string[] = [];\n\n function walk(node: unknown) {\n if (!node || typeof node !== 'object') return;\n const n = node as Record<string, unknown>;\n\n if (typeof n.text === 'string') {\n parts.push(n.text);\n }\n\n if (Array.isArray(n.content)) {\n for (const child of n.content) {\n walk(child);\n }\n }\n }\n\n for (const block of blocks) {\n walk(block);\n }\n\n return parts.join(' ');\n}\n","import { MongoClient, type Db, type Collection, type Document, ObjectId } from 'mongodb';\nimport { createHash, randomBytes } from 'crypto';\nimport { getEnvConfig } from './config';\nimport type {\n BlogPost,\n Category,\n Media,\n BlogSettings,\n ApiToken,\n CreatePostInput,\n UpdatePostInput,\n CreateCategoryInput,\n UpdateCategoryInput,\n PostListQuery,\n MediaListQuery,\n} from './types';\nimport { generateSlug, ensureUniqueSlug } from './slug';\nimport { calculateReadingTime, countWords, extractTextFromBlocks } from './reading-time';\n\nlet client: MongoClient | null = null;\nlet db: Db | null = null;\n\nexport async function getDb(): Promise<Db> {\n if (db) return db;\n\n const env = getEnvConfig();\n client = new MongoClient(env.NEXTBLOGKIT_MONGODB_URI);\n await client.connect();\n db = client.db(env.NEXTBLOGKIT_MONGODB_DB || undefined);\n return db;\n}\n\nexport async function getCollection<T extends Document = Document>(\n name: string\n): Promise<Collection<T>> {\n const database = await getDb();\n return database.collection<T>(name);\n}\n\nexport async function ensureIndexes(): Promise<void> {\n const database = await getDb();\n\n const posts = database.collection('nbk_posts');\n await posts.createIndex({ slug: 1 }, { unique: true });\n await posts.createIndex({ status: 1, publishedAt: -1 });\n await posts.createIndex({ categories: 1, status: 1 });\n await posts.createIndex({ tags: 1, status: 1 });\n await posts.createIndex({ 'seo.focusKeyword': 1 });\n await posts.createIndex({ contentText: 'text', title: 'text', excerpt: 'text' });\n\n const categories = database.collection('nbk_categories');\n await categories.createIndex({ slug: 1 }, { unique: true });\n await categories.createIndex({ order: 1 });\n\n const media = database.collection('nbk_media');\n await media.createIndex({ createdAt: -1 });\n await media.createIndex({ r2Key: 1 }, { unique: true });\n\n const tokens = database.collection('nbk_api_tokens');\n await tokens.createIndex({ tokenHash: 1 }, { unique: true });\n await tokens.createIndex({ createdAt: -1 });\n}\n\n// ============================================================\n// Posts\n// ============================================================\n\nexport async function createPost(input: CreatePostInput, defaultAuthor?: BlogPost['author']): Promise<BlogPost> {\n const col = await getCollection('nbk_posts');\n\n const slug = await ensureUniqueSlug(\n input.slug || generateSlug(input.title),\n col\n );\n\n const contentText = input.contentText || extractTextFromBlocks(input.content || []);\n const wordCount = countWords(contentText);\n const readingTime = calculateReadingTime(contentText);\n\n const excerpt =\n input.excerpt || contentText.slice(0, 160).replace(/\\s+\\S*$/, '') + '...';\n\n const now = new Date();\n const doc = {\n title: input.title,\n slug,\n excerpt,\n content: input.content || [],\n contentHTML: input.contentHTML || '',\n contentText,\n coverImage: input.coverImage,\n categories: input.categories || [],\n tags: input.tags || [],\n author: input.author || defaultAuthor || { name: 'Admin' },\n seo: {\n ogType: 'article',\n noIndex: false,\n ...input.seo,\n },\n status: input.status || 'draft',\n publishedAt: input.status === 'published' ? now : input.publishedAt,\n scheduledAt: input.scheduledAt,\n readingTime,\n wordCount,\n version: 1,\n revisions: [],\n createdAt: now,\n updatedAt: now,\n };\n\n const result = await col.insertOne(doc);\n return { _id: result.insertedId, ...doc } as unknown as BlogPost;\n}\n\nexport async function updatePost(\n id: string,\n input: UpdatePostInput\n): Promise<BlogPost | null> {\n const col = await getCollection('nbk_posts');\n const objectId = new ObjectId(id);\n const existing = await col.findOne({ _id: objectId });\n if (!existing) return null;\n\n const updates: Record<string, unknown> = { ...input, updatedAt: new Date() };\n\n if (input.slug && input.slug !== existing.slug) {\n updates.slug = await ensureUniqueSlug(input.slug, col, id);\n }\n\n if (input.content) {\n const contentText = input.contentText || extractTextFromBlocks(input.content);\n updates.contentText = contentText;\n updates.wordCount = countWords(contentText);\n updates.readingTime = calculateReadingTime(contentText);\n\n if (!input.excerpt) {\n updates.excerpt =\n contentText.slice(0, 160).replace(/\\s+\\S*$/, '') + '...';\n }\n\n // Save revision\n const revision = {\n version: existing.version || 1,\n title: existing.title,\n content: existing.content,\n contentHTML: existing.contentHTML,\n savedAt: new Date(),\n };\n const revisions = [...(existing.revisions || []), revision].slice(-10);\n updates.revisions = revisions;\n updates.version = (existing.version || 1) + 1;\n }\n\n if (input.status === 'published' && existing.status !== 'published') {\n updates.publishedAt = new Date();\n }\n\n await col.updateOne({ _id: objectId }, { $set: updates });\n return (await col.findOne({ _id: objectId })) as unknown as BlogPost;\n}\n\nexport async function deletePost(id: string): Promise<boolean> {\n const col = await getCollection('nbk_posts');\n const result = await col.updateOne(\n { _id: new ObjectId(id) },\n { $set: { status: 'archived', updatedAt: new Date() } }\n );\n return result.modifiedCount > 0;\n}\n\nexport async function hardDeletePost(id: string): Promise<boolean> {\n const col = await getCollection('nbk_posts');\n const result = await col.deleteOne({ _id: new ObjectId(id) });\n return result.deletedCount > 0;\n}\n\nexport async function getPostBySlug(slug: string): Promise<BlogPost | null> {\n const col = await getCollection('nbk_posts');\n return (await col.findOne({ slug })) as unknown as BlogPost | null;\n}\n\nexport async function getPostById(id: string): Promise<BlogPost | null> {\n const col = await getCollection('nbk_posts');\n return (await col.findOne({ _id: new ObjectId(id) })) as unknown as BlogPost | null;\n}\n\nexport async function listPosts(\n query: PostListQuery = {}\n): Promise<{ posts: BlogPost[]; total: number }> {\n const col = await getCollection('nbk_posts');\n const {\n page = 1,\n limit = 10,\n category,\n tag,\n status,\n search,\n sortBy = 'publishedAt',\n sortOrder = 'desc',\n } = query;\n\n const filter: Record<string, unknown> = {};\n\n if (status) {\n filter.status = status;\n } else {\n filter.status = { $ne: 'archived' };\n }\n\n if (category) filter.categories = category;\n if (tag) filter.tags = tag;\n if (search) {\n filter.$text = { $search: search };\n }\n\n const sort: Record<string, 1 | -1> = {\n [sortBy]: sortOrder === 'asc' ? 1 : -1,\n };\n\n const skip = (page - 1) * limit;\n\n const [posts, total] = await Promise.all([\n col.find(filter).sort(sort).skip(skip).limit(limit).toArray(),\n col.countDocuments(filter),\n ]);\n\n return {\n posts: posts as unknown as BlogPost[],\n total,\n };\n}\n\n// ============================================================\n// Categories\n// ============================================================\n\nexport async function createCategory(input: CreateCategoryInput): Promise<Category> {\n const col = await getCollection('nbk_categories');\n const slug = await ensureUniqueSlug(\n input.slug || generateSlug(input.name),\n col\n );\n\n const doc = {\n name: input.name,\n slug,\n description: input.description,\n seo: input.seo,\n order: input.order ?? 0,\n parentId: input.parentId ? new ObjectId(input.parentId) : undefined,\n postCount: 0,\n };\n\n const result = await col.insertOne(doc);\n return { _id: result.insertedId, ...doc } as unknown as Category;\n}\n\nexport async function updateCategory(\n id: string,\n input: UpdateCategoryInput\n): Promise<Category | null> {\n const col = await getCollection('nbk_categories');\n const objectId = new ObjectId(id);\n\n const updates: Record<string, unknown> = { ...input };\n if (input.slug) {\n updates.slug = await ensureUniqueSlug(input.slug, col, id);\n }\n if (input.parentId) {\n updates.parentId = new ObjectId(input.parentId);\n }\n\n await col.updateOne({ _id: objectId }, { $set: updates });\n return (await col.findOne({ _id: objectId })) as unknown as Category | null;\n}\n\nexport async function deleteCategory(id: string): Promise<boolean> {\n const col = await getCollection('nbk_categories');\n const result = await col.deleteOne({ _id: new ObjectId(id) });\n return result.deletedCount > 0;\n}\n\nexport async function listCategories(): Promise<Category[]> {\n const col = await getCollection('nbk_categories');\n return (await col.find({}).sort({ order: 1 }).toArray()) as unknown as Category[];\n}\n\nexport async function getCategoryBySlug(slug: string): Promise<Category | null> {\n const col = await getCollection('nbk_categories');\n return (await col.findOne({ slug })) as unknown as Category | null;\n}\n\nexport async function updateCategoryPostCount(categorySlug: string): Promise<void> {\n const posts = await getCollection('nbk_posts');\n const categories = await getCollection('nbk_categories');\n const count = await posts.countDocuments({\n categories: categorySlug,\n status: 'published',\n });\n await categories.updateOne({ slug: categorySlug }, { $set: { postCount: count } });\n}\n\n// ============================================================\n// Media\n// ============================================================\n\nexport async function createMedia(data: Omit<Media, '_id'>): Promise<Media> {\n const col = await getCollection('nbk_media');\n const result = await col.insertOne(data);\n return { _id: result.insertedId, ...data } as unknown as Media;\n}\n\nexport async function deleteMedia(id: string): Promise<Media | null> {\n const col = await getCollection('nbk_media');\n const media = await col.findOne({ _id: new ObjectId(id) });\n if (!media) return null;\n await col.deleteOne({ _id: new ObjectId(id) });\n return media as unknown as Media;\n}\n\nexport async function listMedia(\n query: MediaListQuery = {}\n): Promise<{ media: Media[]; total: number }> {\n const col = await getCollection('nbk_media');\n const { page = 1, limit = 20, mimeType } = query;\n\n const filter: Record<string, unknown> = {};\n if (mimeType) filter.mimeType = { $regex: mimeType };\n\n const skip = (page - 1) * limit;\n const [media, total] = await Promise.all([\n col.find(filter).sort({ createdAt: -1 }).skip(skip).limit(limit).toArray(),\n col.countDocuments(filter),\n ]);\n\n return { media: media as unknown as Media[], total };\n}\n\n// ============================================================\n// Settings\n// ============================================================\n\nexport async function getSettings(): Promise<BlogSettings> {\n const col = await getCollection('nbk_settings');\n const settings = await col.findOne({ _id: 'global' as unknown as ObjectId });\n if (!settings) {\n const defaults: Record<string, unknown> = {\n _id: 'global',\n postsPerPage: 10,\n commentSystem: 'none',\n };\n await col.insertOne(defaults as Document);\n return defaults as unknown as BlogSettings;\n }\n return settings as unknown as BlogSettings;\n}\n\nexport async function updateSettings(\n data: Partial<BlogSettings>\n): Promise<BlogSettings> {\n const col = await getCollection('nbk_settings');\n const { _id, ...updates } = data as Record<string, unknown>;\n await col.updateOne(\n { _id: 'global' as unknown as ObjectId },\n { $set: updates },\n { upsert: true }\n );\n return getSettings();\n}\n\n// ============================================================\n// API Tokens\n// ============================================================\n\nfunction hashToken(plain: string): string {\n return createHash('sha256').update(plain).digest('hex');\n}\n\nexport async function createApiToken(name: string): Promise<{ token: ApiToken; plainToken: string }> {\n const col = await getCollection('nbk_api_tokens');\n const plainToken = 'nbk_' + randomBytes(24).toString('hex');\n const tokenHash = hashToken(plainToken);\n const prefix = plainToken.slice(0, 8);\n const now = new Date();\n\n const doc = {\n name,\n tokenHash,\n prefix,\n createdAt: now,\n };\n\n const result = await col.insertOne(doc);\n const token = { _id: result.insertedId, ...doc } as unknown as ApiToken;\n return { token, plainToken };\n}\n\nexport async function listApiTokens(): Promise<ApiToken[]> {\n const col = await getCollection('nbk_api_tokens');\n return (await col.find({}, { projection: { tokenHash: 0 } }).sort({ createdAt: -1 }).toArray()) as unknown as ApiToken[];\n}\n\nexport async function deleteApiToken(id: string): Promise<boolean> {\n const col = await getCollection('nbk_api_tokens');\n const result = await col.deleteOne({ _id: new ObjectId(id) });\n return result.deletedCount > 0;\n}\n\nexport async function verifyApiToken(plainToken: string): Promise<ApiToken | null> {\n const col = await getCollection('nbk_api_tokens');\n const tokenHash = hashToken(plainToken);\n const token = await col.findOneAndUpdate(\n { tokenHash },\n { $set: { lastUsedAt: new Date() } },\n { returnDocument: 'after' }\n );\n return token as unknown as ApiToken | null;\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkU2ROR6AY_cjs = require('./chunk-U2ROR6AY.cjs');
3
+ var chunkVWKVU3SE_cjs = require('./chunk-VWKVU3SE.cjs');
4
4
  var server = require('next/server');
5
5
 
6
6
  function jsonSuccess(data, meta, status = 200) {
@@ -12,8 +12,21 @@ function jsonError(code, message, status = 400) {
12
12
  { status }
13
13
  );
14
14
  }
15
- function requireAuth(request) {
16
- const env = chunkU2ROR6AY_cjs.getEnvConfig();
15
+ async function requireAuth(request) {
16
+ const env = chunkVWKVU3SE_cjs.getEnvConfig();
17
+ const authHeader = request.headers.get("authorization");
18
+ if (!authHeader) {
19
+ return jsonError("UNAUTHORIZED", "Authorization header is required", 401);
20
+ }
21
+ const token = authHeader.replace(/^Bearer\s+/i, "");
22
+ if (token === env.NEXTBLOGKIT_API_KEY) return null;
23
+ const { verifyApiToken } = await import('./db-RFY6O5UE.cjs');
24
+ const dbToken = await verifyApiToken(token);
25
+ if (dbToken) return null;
26
+ return jsonError("FORBIDDEN", "Invalid API key", 403);
27
+ }
28
+ function requireMasterAuth(request) {
29
+ const env = chunkVWKVU3SE_cjs.getEnvConfig();
17
30
  const authHeader = request.headers.get("authorization");
18
31
  if (!authHeader) {
19
32
  return jsonError("UNAUTHORIZED", "Authorization header is required", 401);
@@ -39,5 +52,6 @@ exports.jsonError = jsonError;
39
52
  exports.jsonSuccess = jsonSuccess;
40
53
  exports.parseIntParam = parseIntParam;
41
54
  exports.requireAuth = requireAuth;
42
- //# sourceMappingURL=chunk-KDZER3PU.cjs.map
43
- //# sourceMappingURL=chunk-KDZER3PU.cjs.map
55
+ exports.requireMasterAuth = requireMasterAuth;
56
+ //# sourceMappingURL=chunk-YTJQ426D.cjs.map
57
+ //# sourceMappingURL=chunk-YTJQ426D.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/api/middleware.ts"],"names":["NextResponse","getEnvConfig"],"mappings":";;;;;AAIO,SAAS,WAAA,CAAY,IAAA,EAAe,IAAA,EAAgC,MAAA,GAAS,GAAA,EAAK;AACvF,EAAA,OAAOA,mBAAA,CAAa,IAAA,CAAK,EAAE,OAAA,EAAS,IAAA,EAAM,MAAM,IAAA,EAAK,EAAG,EAAE,MAAA,EAAQ,CAAA;AACpE;AAEO,SAAS,SAAA,CAAU,IAAA,EAAc,OAAA,EAAiB,MAAA,GAAS,GAAA,EAAqC;AACrG,EAAA,OAAOA,mBAAA,CAAa,IAAA;AAAA,IAClB,EAAE,OAAA,EAAS,KAAA,EAAO,OAAO,EAAE,IAAA,EAAM,SAAQ,EAAE;AAAA,IAC3C,EAAE,MAAA;AAAO,GACX;AACF;AAEA,eAAsB,YAAY,OAAA,EAAkE;AAClG,EAAA,MAAM,MAAMC,8BAAA,EAAa;AACzB,EAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,eAAe,CAAA;AAEtD,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA,OAAO,SAAA,CAAU,cAAA,EAAgB,kCAAA,EAAoC,GAAG,CAAA;AAAA,EAC1E;AAEA,EAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,OAAA,CAAQ,aAAA,EAAe,EAAE,CAAA;AAGlD,EAAA,IAAI,KAAA,KAAU,GAAA,CAAI,mBAAA,EAAqB,OAAO,IAAA;AAG9C,EAAA,MAAM,EAAE,cAAA,EAAe,GAAI,MAAM,OAAO,mBAAW,CAAA;AACnD,EAAA,MAAM,OAAA,GAAU,MAAM,cAAA,CAAe,KAAK,CAAA;AAC1C,EAAA,IAAI,SAAS,OAAO,IAAA;AAEpB,EAAA,OAAO,SAAA,CAAU,WAAA,EAAa,iBAAA,EAAmB,GAAG,CAAA;AACtD;AAEO,SAAS,kBAAkB,OAAA,EAAyD;AACzF,EAAA,MAAM,MAAMA,8BAAA,EAAa;AACzB,EAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,eAAe,CAAA;AAEtD,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA,OAAO,SAAA,CAAU,cAAA,EAAgB,kCAAA,EAAoC,GAAG,CAAA;AAAA,EAC1E;AAEA,EAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,OAAA,CAAQ,aAAA,EAAe,EAAE,CAAA;AAClD,EAAA,IAAI,KAAA,KAAU,IAAI,mBAAA,EAAqB;AACrC,IAAA,OAAO,SAAA,CAAU,WAAA,EAAa,iBAAA,EAAmB,GAAG,CAAA;AAAA,EACtD;AAEA,EAAA,OAAO,IAAA;AACT;AAEO,SAAS,gBAAgB,OAAA,EAAkB;AAChD,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,OAAA,CAAQ,GAAG,CAAA;AAC/B,EAAA,OAAO,MAAA,CAAO,WAAA,CAAY,GAAA,CAAI,YAAA,CAAa,SAAS,CAAA;AACtD;AAEO,SAAS,aAAA,CAAc,OAA2B,YAAA,EAA8B;AACrF,EAAA,IAAI,CAAC,OAAO,OAAO,YAAA;AACnB,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,KAAA,EAAO,EAAE,CAAA;AACjC,EAAA,OAAO,KAAA,CAAM,MAAM,CAAA,GAAI,YAAA,GAAe,MAAA;AACxC","file":"chunk-YTJQ426D.cjs","sourcesContent":["import { NextResponse } from 'next/server';\nimport { getEnvConfig } from '../lib/config';\nimport type { ApiErrorResponse } from '../lib/types';\n\nexport function jsonSuccess(data: unknown, meta?: Record<string, unknown>, status = 200) {\n return NextResponse.json({ success: true, data, meta }, { status });\n}\n\nexport function jsonError(code: string, message: string, status = 400): NextResponse<ApiErrorResponse> {\n return NextResponse.json(\n { success: false, error: { code, message } },\n { status }\n ) as NextResponse<ApiErrorResponse>;\n}\n\nexport async function requireAuth(request: Request): Promise<NextResponse<ApiErrorResponse> | null> {\n const env = getEnvConfig();\n const authHeader = request.headers.get('authorization');\n\n if (!authHeader) {\n return jsonError('UNAUTHORIZED', 'Authorization header is required', 401);\n }\n\n const token = authHeader.replace(/^Bearer\\s+/i, '');\n\n // Fast path: master key\n if (token === env.NEXTBLOGKIT_API_KEY) return null;\n\n // Check DB tokens\n const { verifyApiToken } = await import('../lib/db');\n const dbToken = await verifyApiToken(token);\n if (dbToken) return null;\n\n return jsonError('FORBIDDEN', 'Invalid API key', 403);\n}\n\nexport function requireMasterAuth(request: Request): NextResponse<ApiErrorResponse> | null {\n const env = getEnvConfig();\n const authHeader = request.headers.get('authorization');\n\n if (!authHeader) {\n return jsonError('UNAUTHORIZED', 'Authorization header is required', 401);\n }\n\n const token = authHeader.replace(/^Bearer\\s+/i, '');\n if (token !== env.NEXTBLOGKIT_API_KEY) {\n return jsonError('FORBIDDEN', 'Invalid API key', 403);\n }\n\n return null;\n}\n\nexport function getSearchParams(request: Request) {\n const url = new URL(request.url);\n return Object.fromEntries(url.searchParams.entries());\n}\n\nexport function parseIntParam(value: string | undefined, defaultValue: number): number {\n if (!value) return defaultValue;\n const parsed = parseInt(value, 10);\n return isNaN(parsed) ? defaultValue : parsed;\n}\n"]}
@@ -36,7 +36,8 @@ __export(config_exports, {
36
36
  defineConfig: () => defineConfig,
37
37
  getBlogConfig: () => getBlogConfig,
38
38
  getConfig: () => getConfig,
39
- getEnvConfig: () => getEnvConfig
39
+ getEnvConfig: () => getEnvConfig,
40
+ isR2Configured: () => isR2Configured
40
41
  });
41
42
  function getEnvConfig() {
42
43
  if (cachedEnv) return cachedEnv;
@@ -49,6 +50,10 @@ ${missing.join("\n")}`);
49
50
  cachedEnv = result.data;
50
51
  return cachedEnv;
51
52
  }
53
+ function isR2Configured() {
54
+ const env = getEnvConfig();
55
+ return !!(env.NEXTBLOGKIT_R2_ACCOUNT_ID && env.NEXTBLOGKIT_R2_ACCESS_KEY && env.NEXTBLOGKIT_R2_SECRET_KEY && env.NEXTBLOGKIT_R2_BUCKET && env.NEXTBLOGKIT_R2_PUBLIC_URL);
56
+ }
52
57
  function defineConfig(config) {
53
58
  return config;
54
59
  }
@@ -99,15 +104,20 @@ var init_config = __esm({
99
104
  "use strict";
100
105
  import_zod = require("zod");
101
106
  envSchema = import_zod.z.object({
107
+ // Required
102
108
  NEXTBLOGKIT_MONGODB_URI: import_zod.z.string().min(1, "MongoDB URI is required"),
103
- NEXTBLOGKIT_R2_ACCOUNT_ID: import_zod.z.string().min(1, "R2 Account ID is required"),
104
- NEXTBLOGKIT_R2_ACCESS_KEY: import_zod.z.string().min(1, "R2 Access Key is required"),
105
- NEXTBLOGKIT_R2_SECRET_KEY: import_zod.z.string().min(1, "R2 Secret Key is required"),
106
- NEXTBLOGKIT_R2_BUCKET: import_zod.z.string().min(1, "R2 Bucket name is required"),
107
- NEXTBLOGKIT_R2_PUBLIC_URL: import_zod.z.string().url("R2 Public URL must be a valid URL"),
108
109
  NEXTBLOGKIT_API_KEY: import_zod.z.string().min(32, "API key must be at least 32 characters"),
109
- NEXTBLOGKIT_SITE_URL: import_zod.z.string().url("Site URL must be a valid URL"),
110
- NEXTBLOGKIT_SITE_NAME: import_zod.z.string().min(1, "Site name is required")
110
+ // Optional — Database name (defaults to the database in your connection URI)
111
+ NEXTBLOGKIT_MONGODB_DB: import_zod.z.string().optional(),
112
+ // Optional — Cloudflare R2 (image storage)
113
+ NEXTBLOGKIT_R2_ACCOUNT_ID: import_zod.z.string().optional(),
114
+ NEXTBLOGKIT_R2_ACCESS_KEY: import_zod.z.string().optional(),
115
+ NEXTBLOGKIT_R2_SECRET_KEY: import_zod.z.string().optional(),
116
+ NEXTBLOGKIT_R2_BUCKET: import_zod.z.string().optional(),
117
+ NEXTBLOGKIT_R2_PUBLIC_URL: import_zod.z.string().optional(),
118
+ // Optional — Site info (defaults provided)
119
+ NEXTBLOGKIT_SITE_URL: import_zod.z.string().optional().default(""),
120
+ NEXTBLOGKIT_SITE_NAME: import_zod.z.string().optional().default("Blog")
111
121
  });
112
122
  cachedEnv = null;
113
123
  defaultConfig = {
@@ -247,9 +257,11 @@ var init_reading_time = __esm({
247
257
  // src/lib/db.ts
248
258
  var db_exports = {};
249
259
  __export(db_exports, {
260
+ createApiToken: () => createApiToken,
250
261
  createCategory: () => createCategory,
251
262
  createMedia: () => createMedia,
252
263
  createPost: () => createPost,
264
+ deleteApiToken: () => deleteApiToken,
253
265
  deleteCategory: () => deleteCategory,
254
266
  deleteMedia: () => deleteMedia,
255
267
  deletePost: () => deletePost,
@@ -261,20 +273,22 @@ __export(db_exports, {
261
273
  getPostBySlug: () => getPostBySlug,
262
274
  getSettings: () => getSettings,
263
275
  hardDeletePost: () => hardDeletePost,
276
+ listApiTokens: () => listApiTokens,
264
277
  listCategories: () => listCategories,
265
278
  listMedia: () => listMedia,
266
279
  listPosts: () => listPosts,
267
280
  updateCategory: () => updateCategory,
268
281
  updateCategoryPostCount: () => updateCategoryPostCount,
269
282
  updatePost: () => updatePost,
270
- updateSettings: () => updateSettings
283
+ updateSettings: () => updateSettings,
284
+ verifyApiToken: () => verifyApiToken
271
285
  });
272
286
  async function getDb() {
273
287
  if (db) return db;
274
288
  const env = getEnvConfig();
275
289
  client = new import_mongodb.MongoClient(env.NEXTBLOGKIT_MONGODB_URI);
276
290
  await client.connect();
277
- db = client.db();
291
+ db = client.db(env.NEXTBLOGKIT_MONGODB_DB || void 0);
278
292
  return db;
279
293
  }
280
294
  async function getCollection(name) {
@@ -296,6 +310,9 @@ async function ensureIndexes() {
296
310
  const media = database.collection("nbk_media");
297
311
  await media.createIndex({ createdAt: -1 });
298
312
  await media.createIndex({ r2Key: 1 }, { unique: true });
313
+ const tokens = database.collection("nbk_api_tokens");
314
+ await tokens.createIndex({ tokenHash: 1 }, { unique: true });
315
+ await tokens.createIndex({ createdAt: -1 });
299
316
  }
300
317
  async function createPost(input, defaultAuthor) {
301
318
  const col = await getCollection("nbk_posts");
@@ -529,11 +546,50 @@ async function updateSettings(data) {
529
546
  );
530
547
  return getSettings();
531
548
  }
532
- var import_mongodb, client, db;
549
+ function hashToken(plain) {
550
+ return (0, import_crypto.createHash)("sha256").update(plain).digest("hex");
551
+ }
552
+ async function createApiToken(name) {
553
+ const col = await getCollection("nbk_api_tokens");
554
+ const plainToken = "nbk_" + (0, import_crypto.randomBytes)(24).toString("hex");
555
+ const tokenHash = hashToken(plainToken);
556
+ const prefix = plainToken.slice(0, 8);
557
+ const now = /* @__PURE__ */ new Date();
558
+ const doc = {
559
+ name,
560
+ tokenHash,
561
+ prefix,
562
+ createdAt: now
563
+ };
564
+ const result = await col.insertOne(doc);
565
+ const token = { _id: result.insertedId, ...doc };
566
+ return { token, plainToken };
567
+ }
568
+ async function listApiTokens() {
569
+ const col = await getCollection("nbk_api_tokens");
570
+ return await col.find({}, { projection: { tokenHash: 0 } }).sort({ createdAt: -1 }).toArray();
571
+ }
572
+ async function deleteApiToken(id) {
573
+ const col = await getCollection("nbk_api_tokens");
574
+ const result = await col.deleteOne({ _id: new import_mongodb.ObjectId(id) });
575
+ return result.deletedCount > 0;
576
+ }
577
+ async function verifyApiToken(plainToken) {
578
+ const col = await getCollection("nbk_api_tokens");
579
+ const tokenHash = hashToken(plainToken);
580
+ const token = await col.findOneAndUpdate(
581
+ { tokenHash },
582
+ { $set: { lastUsedAt: /* @__PURE__ */ new Date() } },
583
+ { returnDocument: "after" }
584
+ );
585
+ return token;
586
+ }
587
+ var import_mongodb, import_crypto, client, db;
533
588
  var init_db = __esm({
534
589
  "src/lib/db.ts"() {
535
590
  "use strict";
536
591
  import_mongodb = require("mongodb");
592
+ import_crypto = require("crypto");
537
593
  init_config();
538
594
  init_slug();
539
595
  init_reading_time();
@@ -549,6 +605,11 @@ __export(storage_exports, {
549
605
  });
550
606
  function getS3Client() {
551
607
  if (clientInstance) return clientInstance;
608
+ if (!isR2Configured()) {
609
+ throw new Error(
610
+ "Cloudflare R2 is not configured. Set NEXTBLOGKIT_R2_ACCOUNT_ID, NEXTBLOGKIT_R2_ACCESS_KEY, NEXTBLOGKIT_R2_SECRET_KEY, NEXTBLOGKIT_R2_BUCKET, and NEXTBLOGKIT_R2_PUBLIC_URL environment variables to enable image uploads."
611
+ );
612
+ }
552
613
  const env = getEnvConfig();
553
614
  clientInstance = new import_client_s3.S3Client({
554
615
  region: "auto",
@@ -564,17 +625,17 @@ function generateKey(filename) {
564
625
  const now = /* @__PURE__ */ new Date();
565
626
  const year = now.getFullYear();
566
627
  const month = String(now.getMonth() + 1).padStart(2, "0");
567
- const uuid = (0, import_crypto.randomUUID)().split("-")[0];
628
+ const uuid = (0, import_crypto2.randomUUID)().split("-")[0];
568
629
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "-").toLowerCase();
569
630
  return `blog/${year}/${month}/${uuid}-${safeName}`;
570
631
  }
571
- var import_client_s3, import_crypto, clientInstance, R2StorageProvider;
632
+ var import_client_s3, import_crypto2, clientInstance, R2StorageProvider;
572
633
  var init_storage = __esm({
573
634
  "src/lib/storage.ts"() {
574
635
  "use strict";
575
636
  import_client_s3 = require("@aws-sdk/client-s3");
576
637
  init_config();
577
- import_crypto = require("crypto");
638
+ import_crypto2 = require("crypto");
578
639
  clientInstance = null;
579
640
  R2StorageProvider = class {
580
641
  async upload(file, filename, contentType) {
@@ -1021,6 +1082,11 @@ export default function AdminSettings() {
1021
1082
  {
1022
1083
  path: "api/blog/settings/route.ts",
1023
1084
  content: `export { GET, PUT } from 'nextblogkit/api/settings';
1085
+ `
1086
+ },
1087
+ {
1088
+ path: "api/blog/tokens/route.ts",
1089
+ content: `export { GET, POST, DELETE } from 'nextblogkit/api/tokens';
1024
1090
  `
1025
1091
  },
1026
1092
  {
@@ -1231,10 +1297,15 @@ async function health() {
1231
1297
  allPassed = false;
1232
1298
  }
1233
1299
  try {
1234
- const { R2StorageProvider: R2StorageProvider2 } = await Promise.resolve().then(() => (init_storage(), storage_exports));
1235
- const storage = new R2StorageProvider2();
1236
- await storage.list("blog/");
1237
- console.log(" \u2713 Cloudflare R2: Connected");
1300
+ const { isR2Configured: isR2Configured2 } = await Promise.resolve().then(() => (init_config(), config_exports));
1301
+ if (!isR2Configured2()) {
1302
+ console.log(" \u25CB Cloudflare R2: Not configured (optional)");
1303
+ } else {
1304
+ const { R2StorageProvider: R2StorageProvider2 } = await Promise.resolve().then(() => (init_storage(), storage_exports));
1305
+ const storage = new R2StorageProvider2();
1306
+ await storage.list("blog/");
1307
+ console.log(" \u2713 Cloudflare R2: Connected");
1308
+ }
1238
1309
  } catch (err) {
1239
1310
  console.log(` \u2717 Cloudflare R2: ${err.message}`);
1240
1311
  allPassed = false;
@@ -1242,7 +1313,7 @@ async function health() {
1242
1313
  try {
1243
1314
  const { getEnvConfig: getEnvConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
1244
1315
  getEnvConfig2();
1245
- console.log(" \u2713 Environment: All variables set");
1316
+ console.log(" \u2713 Environment: Required variables set");
1246
1317
  } catch (err) {
1247
1318
  console.log(` \u2717 Environment: ${err.message}`);
1248
1319
  allPassed = false;
@@ -55,6 +55,7 @@ function BlogCard({
55
55
  function BlogSearch({
56
56
  onSearch,
57
57
  apiPath = "/api/blog",
58
+ basePath = "/blog",
58
59
  placeholder = "Search posts...",
59
60
  className = ""
60
61
  }) {
@@ -128,7 +129,7 @@ function BlogSearch({
128
129
  showResults && results.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nbk-search-results", children: results.map((result) => /* @__PURE__ */ jsxRuntime.jsxs(
129
130
  "a",
130
131
  {
131
- href: `/blog/${result.slug}`,
132
+ href: `${basePath}/${result.slug}`,
132
133
  className: "nbk-search-result",
133
134
  onClick: () => setShowResults(false),
134
135
  children: [
@@ -514,7 +515,7 @@ function BlogPostPage({
514
515
  tag
515
516
  ] }, tag)) }),
516
517
  showShareButtons && /* @__PURE__ */ jsxRuntime.jsx(ShareButtons, { url: postUrl, title: post.title }),
517
- showAuthor && post.author && /* @__PURE__ */ jsxRuntime.jsx(AuthorCard, { author: post.author }),
518
+ showAuthor && post.author && (post.author.bio || post.author.avatar) && /* @__PURE__ */ jsxRuntime.jsx(AuthorCard, { author: post.author }),
518
519
  showRelatedPosts && relatedPosts.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "nbk-related", children: [
519
520
  /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "nbk-related-title", children: "Related Posts" }),
520
521
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nbk-related-grid", children: relatedPosts.map((p) => /* @__PURE__ */ jsxRuntime.jsx(BlogCard, { post: p, basePath }, String(p._id || p.slug))) })