nextblogkit 0.6.0

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 (107) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +951 -0
  3. package/dist/admin/index.cjs +2465 -0
  4. package/dist/admin/index.cjs.map +1 -0
  5. package/dist/admin/index.d.cts +44 -0
  6. package/dist/admin/index.d.ts +44 -0
  7. package/dist/admin/index.js +2438 -0
  8. package/dist/admin/index.js.map +1 -0
  9. package/dist/api/categories.cjs +82 -0
  10. package/dist/api/categories.cjs.map +1 -0
  11. package/dist/api/categories.d.cts +27 -0
  12. package/dist/api/categories.d.ts +27 -0
  13. package/dist/api/categories.js +77 -0
  14. package/dist/api/categories.js.map +1 -0
  15. package/dist/api/media.cjs +113 -0
  16. package/dist/api/media.cjs.map +1 -0
  17. package/dist/api/media.d.cts +22 -0
  18. package/dist/api/media.d.ts +22 -0
  19. package/dist/api/media.js +109 -0
  20. package/dist/api/media.js.map +1 -0
  21. package/dist/api/posts.cjs +103 -0
  22. package/dist/api/posts.cjs.map +1 -0
  23. package/dist/api/posts.d.cts +27 -0
  24. package/dist/api/posts.d.ts +27 -0
  25. package/dist/api/posts.js +98 -0
  26. package/dist/api/posts.js.map +1 -0
  27. package/dist/api/rss.cjs +25 -0
  28. package/dist/api/rss.cjs.map +1 -0
  29. package/dist/api/rss.d.cts +5 -0
  30. package/dist/api/rss.d.ts +5 -0
  31. package/dist/api/rss.js +23 -0
  32. package/dist/api/rss.js.map +1 -0
  33. package/dist/api/settings.cjs +40 -0
  34. package/dist/api/settings.cjs.map +1 -0
  35. package/dist/api/settings.d.cts +17 -0
  36. package/dist/api/settings.d.ts +17 -0
  37. package/dist/api/settings.js +37 -0
  38. package/dist/api/settings.js.map +1 -0
  39. package/dist/api/sitemap.cjs +25 -0
  40. package/dist/api/sitemap.cjs.map +1 -0
  41. package/dist/api/sitemap.d.cts +5 -0
  42. package/dist/api/sitemap.d.ts +5 -0
  43. package/dist/api/sitemap.js +23 -0
  44. package/dist/api/sitemap.js.map +1 -0
  45. package/dist/chunk-4NKOJYWJ.js +68 -0
  46. package/dist/chunk-4NKOJYWJ.js.map +1 -0
  47. package/dist/chunk-4PY224XM.js +103 -0
  48. package/dist/chunk-4PY224XM.js.map +1 -0
  49. package/dist/chunk-64HUVJOZ.js +446 -0
  50. package/dist/chunk-64HUVJOZ.js.map +1 -0
  51. package/dist/chunk-6HKMZOI4.cjs +48 -0
  52. package/dist/chunk-6HKMZOI4.cjs.map +1 -0
  53. package/dist/chunk-A2S32RZN.js +138 -0
  54. package/dist/chunk-A2S32RZN.js.map +1 -0
  55. package/dist/chunk-E2QLTHKN.cjs +70 -0
  56. package/dist/chunk-E2QLTHKN.cjs.map +1 -0
  57. package/dist/chunk-JLPJKNRZ.js +37 -0
  58. package/dist/chunk-JLPJKNRZ.js.map +1 -0
  59. package/dist/chunk-JM7QRXXK.js +330 -0
  60. package/dist/chunk-JM7QRXXK.js.map +1 -0
  61. package/dist/chunk-KDZER3PU.cjs +43 -0
  62. package/dist/chunk-KDZER3PU.cjs.map +1 -0
  63. package/dist/chunk-N5MKAD7J.cjs +109 -0
  64. package/dist/chunk-N5MKAD7J.cjs.map +1 -0
  65. package/dist/chunk-QE4VLQYN.cjs +337 -0
  66. package/dist/chunk-QE4VLQYN.cjs.map +1 -0
  67. package/dist/chunk-R6MO3QIP.js +46 -0
  68. package/dist/chunk-R6MO3QIP.js.map +1 -0
  69. package/dist/chunk-U2ROR6AY.cjs +476 -0
  70. package/dist/chunk-U2ROR6AY.cjs.map +1 -0
  71. package/dist/chunk-ZP5XRVVH.cjs +141 -0
  72. package/dist/chunk-ZP5XRVVH.cjs.map +1 -0
  73. package/dist/cli/index.cjs +1308 -0
  74. package/dist/components/index.cjs +541 -0
  75. package/dist/components/index.cjs.map +1 -0
  76. package/dist/components/index.d.cts +165 -0
  77. package/dist/components/index.d.ts +165 -0
  78. package/dist/components/index.js +527 -0
  79. package/dist/components/index.js.map +1 -0
  80. package/dist/editor/index.cjs +1083 -0
  81. package/dist/editor/index.cjs.map +1 -0
  82. package/dist/editor/index.d.cts +133 -0
  83. package/dist/editor/index.d.ts +133 -0
  84. package/dist/editor/index.js +1051 -0
  85. package/dist/editor/index.js.map +1 -0
  86. package/dist/index-Cgzphklp.d.ts +266 -0
  87. package/dist/index-vjlZDWNr.d.cts +266 -0
  88. package/dist/index.cjs +368 -0
  89. package/dist/index.cjs.map +1 -0
  90. package/dist/index.d.cts +27 -0
  91. package/dist/index.d.ts +27 -0
  92. package/dist/index.js +208 -0
  93. package/dist/index.js.map +1 -0
  94. package/dist/lib/index.cjs +120 -0
  95. package/dist/lib/index.cjs.map +1 -0
  96. package/dist/lib/index.d.cts +4 -0
  97. package/dist/lib/index.d.ts +4 -0
  98. package/dist/lib/index.js +7 -0
  99. package/dist/lib/index.js.map +1 -0
  100. package/dist/styles/admin.css +657 -0
  101. package/dist/styles/blog.css +851 -0
  102. package/dist/styles/editor.css +452 -0
  103. package/dist/styles/globals.css +270 -0
  104. package/dist/styles/prose.css +299 -0
  105. package/dist/types-CBEEBR4A.d.cts +732 -0
  106. package/dist/types-CBEEBR4A.d.ts +732 -0
  107. package/package.json +134 -0
@@ -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"],"mappings":"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","file":"chunk-U2ROR6AY.cjs","sourcesContent":["import { z } from 'zod';\nimport type { NextBlogKitConfig } from './types';\n\nconst envSchema = z.object({\n NEXTBLOGKIT_MONGODB_URI: z.string().min(1, 'MongoDB URI is required'),\n NEXTBLOGKIT_R2_ACCOUNT_ID: z.string().min(1, 'R2 Account ID is required'),\n NEXTBLOGKIT_R2_ACCESS_KEY: z.string().min(1, 'R2 Access Key is required'),\n NEXTBLOGKIT_R2_SECRET_KEY: z.string().min(1, 'R2 Secret Key is required'),\n NEXTBLOGKIT_R2_BUCKET: z.string().min(1, 'R2 Bucket name is required'),\n NEXTBLOGKIT_R2_PUBLIC_URL: z.string().url('R2 Public URL must be a valid URL'),\n NEXTBLOGKIT_API_KEY: z.string().min(32, 'API key must be at least 32 characters'),\n NEXTBLOGKIT_SITE_URL: z.string().url('Site URL must be a valid URL'),\n NEXTBLOGKIT_SITE_NAME: z.string().min(1, 'Site name is required'),\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\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 { getEnvConfig } from './config';\nimport type {\n BlogPost,\n Category,\n Media,\n BlogSettings,\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();\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\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"]}
@@ -0,0 +1,141 @@
1
+ 'use strict';
2
+
3
+ var chunkU2ROR6AY_cjs = require('./chunk-U2ROR6AY.cjs');
4
+ var clientS3 = require('@aws-sdk/client-s3');
5
+ var crypto = require('crypto');
6
+
7
+ var clientInstance = null;
8
+ function getS3Client() {
9
+ if (clientInstance) return clientInstance;
10
+ const env = chunkU2ROR6AY_cjs.getEnvConfig();
11
+ clientInstance = new clientS3.S3Client({
12
+ region: "auto",
13
+ endpoint: `https://${env.NEXTBLOGKIT_R2_ACCOUNT_ID}.r2.cloudflarestorage.com`,
14
+ credentials: {
15
+ accessKeyId: env.NEXTBLOGKIT_R2_ACCESS_KEY,
16
+ secretAccessKey: env.NEXTBLOGKIT_R2_SECRET_KEY
17
+ }
18
+ });
19
+ return clientInstance;
20
+ }
21
+ function generateKey(filename) {
22
+ const now = /* @__PURE__ */ new Date();
23
+ const year = now.getFullYear();
24
+ const month = String(now.getMonth() + 1).padStart(2, "0");
25
+ const uuid = crypto.randomUUID().split("-")[0];
26
+ const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "-").toLowerCase();
27
+ return `blog/${year}/${month}/${uuid}-${safeName}`;
28
+ }
29
+ var R2StorageProvider = class {
30
+ async upload(file, filename, contentType) {
31
+ const env = chunkU2ROR6AY_cjs.getEnvConfig();
32
+ const client = getS3Client();
33
+ const key = generateKey(filename);
34
+ await client.send(
35
+ new clientS3.PutObjectCommand({
36
+ Bucket: env.NEXTBLOGKIT_R2_BUCKET,
37
+ Key: key,
38
+ Body: file,
39
+ ContentType: contentType
40
+ })
41
+ );
42
+ return {
43
+ key,
44
+ url: `${env.NEXTBLOGKIT_R2_PUBLIC_URL}/${key}`,
45
+ size: file.length,
46
+ contentType
47
+ };
48
+ }
49
+ async delete(key) {
50
+ const env = chunkU2ROR6AY_cjs.getEnvConfig();
51
+ const client = getS3Client();
52
+ await client.send(
53
+ new clientS3.DeleteObjectCommand({
54
+ Bucket: env.NEXTBLOGKIT_R2_BUCKET,
55
+ Key: key
56
+ })
57
+ );
58
+ }
59
+ async list(prefix) {
60
+ const env = chunkU2ROR6AY_cjs.getEnvConfig();
61
+ const client = getS3Client();
62
+ const response = await client.send(
63
+ new clientS3.ListObjectsV2Command({
64
+ Bucket: env.NEXTBLOGKIT_R2_BUCKET,
65
+ Prefix: prefix || "blog/"
66
+ })
67
+ );
68
+ return (response.Contents || []).map((obj) => ({
69
+ key: obj.Key || "",
70
+ size: obj.Size || 0,
71
+ lastModified: obj.LastModified || /* @__PURE__ */ new Date()
72
+ }));
73
+ }
74
+ };
75
+
76
+ // src/lib/image.ts
77
+ var RESPONSIVE_SIZES = [640, 768, 1024, 1280, 1920];
78
+ async function processImage(file, filename, storage) {
79
+ let sharp;
80
+ try {
81
+ sharp = (await import('sharp')).default;
82
+ } catch {
83
+ const result = await storage.upload(file, filename, getMimeType(filename));
84
+ return {
85
+ original: result,
86
+ width: 0,
87
+ height: 0,
88
+ format: getExtension(filename)
89
+ };
90
+ }
91
+ const image = sharp(file);
92
+ const metadata = await image.metadata();
93
+ const webpFilename = filename.replace(/\.[^.]+$/, ".webp");
94
+ const webpBuffer = await image.webp({ quality: 85 }).toBuffer();
95
+ const original = await storage.upload(webpBuffer, webpFilename, "image/webp");
96
+ generateResponsiveSizes(file, webpFilename, storage, metadata.width || 0).catch(
97
+ () => {
98
+ }
99
+ );
100
+ return {
101
+ original,
102
+ width: metadata.width || 0,
103
+ height: metadata.height || 0,
104
+ format: "webp"
105
+ };
106
+ }
107
+ async function generateResponsiveSizes(file, filename, storage, originalWidth) {
108
+ const sharp = (await import('sharp')).default;
109
+ const sizes = RESPONSIVE_SIZES.filter((s) => s < originalWidth);
110
+ await Promise.all(
111
+ sizes.map(async (width) => {
112
+ const resized = await sharp(file).resize(width).webp({ quality: 80 }).toBuffer();
113
+ const sizedFilename = filename.replace(".webp", `-${width}w.webp`);
114
+ await storage.upload(resized, sizedFilename, "image/webp");
115
+ })
116
+ );
117
+ const thumb = await sharp(file).resize(200, 200, { fit: "cover" }).webp({ quality: 70 }).toBuffer();
118
+ const thumbFilename = filename.replace(".webp", "-thumb.webp");
119
+ await storage.upload(thumb, thumbFilename, "image/webp");
120
+ }
121
+ function getMimeType(filename) {
122
+ const ext = getExtension(filename);
123
+ const mimeTypes = {
124
+ jpg: "image/jpeg",
125
+ jpeg: "image/jpeg",
126
+ png: "image/png",
127
+ gif: "image/gif",
128
+ webp: "image/webp",
129
+ svg: "image/svg+xml",
130
+ avif: "image/avif"
131
+ };
132
+ return mimeTypes[ext] || "application/octet-stream";
133
+ }
134
+ function getExtension(filename) {
135
+ return filename.split(".").pop()?.toLowerCase() || "";
136
+ }
137
+
138
+ exports.R2StorageProvider = R2StorageProvider;
139
+ exports.processImage = processImage;
140
+ //# sourceMappingURL=chunk-ZP5XRVVH.cjs.map
141
+ //# sourceMappingURL=chunk-ZP5XRVVH.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/storage.ts","../src/lib/image.ts"],"names":["getEnvConfig","S3Client","randomUUID","PutObjectCommand","DeleteObjectCommand","ListObjectsV2Command"],"mappings":"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","file":"chunk-ZP5XRVVH.cjs","sourcesContent":["import {\n S3Client,\n PutObjectCommand,\n DeleteObjectCommand,\n ListObjectsV2Command,\n} from '@aws-sdk/client-s3';\nimport { getEnvConfig } from './config';\nimport { randomUUID } from 'crypto';\n\nexport interface MediaUploadResult {\n key: string;\n url: string;\n size: number;\n contentType: string;\n}\n\nexport interface StorageObject {\n key: string;\n size: number;\n lastModified: Date;\n}\n\nexport interface StorageProvider {\n upload(file: Buffer, filename: string, contentType: string): Promise<MediaUploadResult>;\n delete(key: string): Promise<void>;\n list(prefix?: string): Promise<StorageObject[]>;\n}\n\nlet clientInstance: S3Client | null = null;\n\nfunction getS3Client(): S3Client {\n if (clientInstance) return clientInstance;\n\n const env = getEnvConfig();\n clientInstance = new S3Client({\n region: 'auto',\n endpoint: `https://${env.NEXTBLOGKIT_R2_ACCOUNT_ID}.r2.cloudflarestorage.com`,\n credentials: {\n accessKeyId: env.NEXTBLOGKIT_R2_ACCESS_KEY,\n secretAccessKey: env.NEXTBLOGKIT_R2_SECRET_KEY,\n },\n });\n\n return clientInstance;\n}\n\nfunction generateKey(filename: string): string {\n const now = new Date();\n const year = now.getFullYear();\n const month = String(now.getMonth() + 1).padStart(2, '0');\n const uuid = randomUUID().split('-')[0];\n const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, '-').toLowerCase();\n return `blog/${year}/${month}/${uuid}-${safeName}`;\n}\n\nexport class R2StorageProvider implements StorageProvider {\n async upload(\n file: Buffer,\n filename: string,\n contentType: string\n ): Promise<MediaUploadResult> {\n const env = getEnvConfig();\n const client = getS3Client();\n const key = generateKey(filename);\n\n await client.send(\n new PutObjectCommand({\n Bucket: env.NEXTBLOGKIT_R2_BUCKET,\n Key: key,\n Body: file,\n ContentType: contentType,\n })\n );\n\n return {\n key,\n url: `${env.NEXTBLOGKIT_R2_PUBLIC_URL}/${key}`,\n size: file.length,\n contentType,\n };\n }\n\n async delete(key: string): Promise<void> {\n const env = getEnvConfig();\n const client = getS3Client();\n\n await client.send(\n new DeleteObjectCommand({\n Bucket: env.NEXTBLOGKIT_R2_BUCKET,\n Key: key,\n })\n );\n }\n\n async list(prefix?: string): Promise<StorageObject[]> {\n const env = getEnvConfig();\n const client = getS3Client();\n\n const response = await client.send(\n new ListObjectsV2Command({\n Bucket: env.NEXTBLOGKIT_R2_BUCKET,\n Prefix: prefix || 'blog/',\n })\n );\n\n return (response.Contents || []).map((obj) => ({\n key: obj.Key || '',\n size: obj.Size || 0,\n lastModified: obj.LastModified || new Date(),\n }));\n }\n}\n","import type { R2StorageProvider, MediaUploadResult } from './storage';\n\nexport interface ProcessedImage {\n original: MediaUploadResult;\n width: number;\n height: number;\n format: string;\n}\n\nconst RESPONSIVE_SIZES = [640, 768, 1024, 1280, 1920];\n\nexport async function processImage(\n file: Buffer,\n filename: string,\n storage: R2StorageProvider\n): Promise<ProcessedImage> {\n let sharp: typeof import('sharp');\n try {\n sharp = (await import('sharp')).default;\n } catch {\n // sharp not available — upload raw file\n const result = await storage.upload(file, filename, getMimeType(filename));\n return {\n original: result,\n width: 0,\n height: 0,\n format: getExtension(filename),\n };\n }\n\n const image = sharp(file);\n const metadata = await image.metadata();\n\n // Convert to WebP\n const webpFilename = filename.replace(/\\.[^.]+$/, '.webp');\n const webpBuffer = await image.webp({ quality: 85 }).toBuffer();\n\n const original = await storage.upload(webpBuffer, webpFilename, 'image/webp');\n\n // Generate responsive sizes in background (non-blocking for the main upload)\n generateResponsiveSizes(file, webpFilename, storage, metadata.width || 0).catch(\n () => {\n // Silently fail responsive generation — originals are sufficient\n }\n );\n\n return {\n original,\n width: metadata.width || 0,\n height: metadata.height || 0,\n format: 'webp',\n };\n}\n\nasync function generateResponsiveSizes(\n file: Buffer,\n filename: string,\n storage: R2StorageProvider,\n originalWidth: number\n): Promise<void> {\n const sharp = (await import('sharp')).default;\n\n const sizes = RESPONSIVE_SIZES.filter((s) => s < originalWidth);\n\n await Promise.all(\n sizes.map(async (width) => {\n const resized = await sharp(file)\n .resize(width)\n .webp({ quality: 80 })\n .toBuffer();\n\n const sizedFilename = filename.replace('.webp', `-${width}w.webp`);\n await storage.upload(resized, sizedFilename, 'image/webp');\n })\n );\n\n // Generate thumbnail\n const thumb = await sharp(file)\n .resize(200, 200, { fit: 'cover' })\n .webp({ quality: 70 })\n .toBuffer();\n\n const thumbFilename = filename.replace('.webp', '-thumb.webp');\n await storage.upload(thumb, thumbFilename, 'image/webp');\n}\n\nfunction getMimeType(filename: string): string {\n const ext = getExtension(filename);\n const mimeTypes: Record<string, string> = {\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n png: 'image/png',\n gif: 'image/gif',\n webp: 'image/webp',\n svg: 'image/svg+xml',\n avif: 'image/avif',\n };\n return mimeTypes[ext] || 'application/octet-stream';\n}\n\nfunction getExtension(filename: string): string {\n return filename.split('.').pop()?.toLowerCase() || '';\n}\n"]}