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.
- package/LICENSE +21 -0
- package/README.md +951 -0
- package/dist/admin/index.cjs +2465 -0
- package/dist/admin/index.cjs.map +1 -0
- package/dist/admin/index.d.cts +44 -0
- package/dist/admin/index.d.ts +44 -0
- package/dist/admin/index.js +2438 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/api/categories.cjs +82 -0
- package/dist/api/categories.cjs.map +1 -0
- package/dist/api/categories.d.cts +27 -0
- package/dist/api/categories.d.ts +27 -0
- package/dist/api/categories.js +77 -0
- package/dist/api/categories.js.map +1 -0
- package/dist/api/media.cjs +113 -0
- package/dist/api/media.cjs.map +1 -0
- package/dist/api/media.d.cts +22 -0
- package/dist/api/media.d.ts +22 -0
- package/dist/api/media.js +109 -0
- package/dist/api/media.js.map +1 -0
- package/dist/api/posts.cjs +103 -0
- package/dist/api/posts.cjs.map +1 -0
- package/dist/api/posts.d.cts +27 -0
- package/dist/api/posts.d.ts +27 -0
- package/dist/api/posts.js +98 -0
- package/dist/api/posts.js.map +1 -0
- package/dist/api/rss.cjs +25 -0
- package/dist/api/rss.cjs.map +1 -0
- package/dist/api/rss.d.cts +5 -0
- package/dist/api/rss.d.ts +5 -0
- package/dist/api/rss.js +23 -0
- package/dist/api/rss.js.map +1 -0
- package/dist/api/settings.cjs +40 -0
- package/dist/api/settings.cjs.map +1 -0
- package/dist/api/settings.d.cts +17 -0
- package/dist/api/settings.d.ts +17 -0
- package/dist/api/settings.js +37 -0
- package/dist/api/settings.js.map +1 -0
- package/dist/api/sitemap.cjs +25 -0
- package/dist/api/sitemap.cjs.map +1 -0
- package/dist/api/sitemap.d.cts +5 -0
- package/dist/api/sitemap.d.ts +5 -0
- package/dist/api/sitemap.js +23 -0
- package/dist/api/sitemap.js.map +1 -0
- package/dist/chunk-4NKOJYWJ.js +68 -0
- package/dist/chunk-4NKOJYWJ.js.map +1 -0
- package/dist/chunk-4PY224XM.js +103 -0
- package/dist/chunk-4PY224XM.js.map +1 -0
- package/dist/chunk-64HUVJOZ.js +446 -0
- package/dist/chunk-64HUVJOZ.js.map +1 -0
- package/dist/chunk-6HKMZOI4.cjs +48 -0
- package/dist/chunk-6HKMZOI4.cjs.map +1 -0
- package/dist/chunk-A2S32RZN.js +138 -0
- package/dist/chunk-A2S32RZN.js.map +1 -0
- package/dist/chunk-E2QLTHKN.cjs +70 -0
- package/dist/chunk-E2QLTHKN.cjs.map +1 -0
- package/dist/chunk-JLPJKNRZ.js +37 -0
- package/dist/chunk-JLPJKNRZ.js.map +1 -0
- package/dist/chunk-JM7QRXXK.js +330 -0
- package/dist/chunk-JM7QRXXK.js.map +1 -0
- package/dist/chunk-KDZER3PU.cjs +43 -0
- package/dist/chunk-KDZER3PU.cjs.map +1 -0
- package/dist/chunk-N5MKAD7J.cjs +109 -0
- package/dist/chunk-N5MKAD7J.cjs.map +1 -0
- package/dist/chunk-QE4VLQYN.cjs +337 -0
- package/dist/chunk-QE4VLQYN.cjs.map +1 -0
- package/dist/chunk-R6MO3QIP.js +46 -0
- package/dist/chunk-R6MO3QIP.js.map +1 -0
- package/dist/chunk-U2ROR6AY.cjs +476 -0
- package/dist/chunk-U2ROR6AY.cjs.map +1 -0
- package/dist/chunk-ZP5XRVVH.cjs +141 -0
- package/dist/chunk-ZP5XRVVH.cjs.map +1 -0
- package/dist/cli/index.cjs +1308 -0
- package/dist/components/index.cjs +541 -0
- package/dist/components/index.cjs.map +1 -0
- package/dist/components/index.d.cts +165 -0
- package/dist/components/index.d.ts +165 -0
- package/dist/components/index.js +527 -0
- package/dist/components/index.js.map +1 -0
- package/dist/editor/index.cjs +1083 -0
- package/dist/editor/index.cjs.map +1 -0
- package/dist/editor/index.d.cts +133 -0
- package/dist/editor/index.d.ts +133 -0
- package/dist/editor/index.js +1051 -0
- package/dist/editor/index.js.map +1 -0
- package/dist/index-Cgzphklp.d.ts +266 -0
- package/dist/index-vjlZDWNr.d.cts +266 -0
- package/dist/index.cjs +368 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +27 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +208 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/index.cjs +120 -0
- package/dist/lib/index.cjs.map +1 -0
- package/dist/lib/index.d.cts +4 -0
- package/dist/lib/index.d.ts +4 -0
- package/dist/lib/index.js +7 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/styles/admin.css +657 -0
- package/dist/styles/blog.css +851 -0
- package/dist/styles/editor.css +452 -0
- package/dist/styles/globals.css +270 -0
- package/dist/styles/prose.css +299 -0
- package/dist/types-CBEEBR4A.d.cts +732 -0
- package/dist/types-CBEEBR4A.d.ts +732 -0
- package/package.json +134 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { CreatePostSchema, UpdatePostSchema } from '../chunk-4PY224XM.js';
|
|
2
|
+
import { getSearchParams, jsonError, jsonSuccess, parseIntParam, requireAuth } from '../chunk-JLPJKNRZ.js';
|
|
3
|
+
import { getPostBySlug, getPostById, listPosts, createPost, updatePost, deletePost } from '../chunk-64HUVJOZ.js';
|
|
4
|
+
|
|
5
|
+
// src/api/posts.ts
|
|
6
|
+
async function GET(request) {
|
|
7
|
+
try {
|
|
8
|
+
const params = getSearchParams(request);
|
|
9
|
+
if (params.slug) {
|
|
10
|
+
const post = await getPostBySlug(params.slug);
|
|
11
|
+
if (!post) return jsonError("NOT_FOUND", "Post not found", 404);
|
|
12
|
+
return jsonSuccess(post);
|
|
13
|
+
}
|
|
14
|
+
if (params.id) {
|
|
15
|
+
const post = await getPostById(params.id);
|
|
16
|
+
if (!post) return jsonError("NOT_FOUND", "Post not found", 404);
|
|
17
|
+
return jsonSuccess(post);
|
|
18
|
+
}
|
|
19
|
+
const result = await listPosts({
|
|
20
|
+
page: parseIntParam(params.page, 1),
|
|
21
|
+
limit: parseIntParam(params.limit, 10),
|
|
22
|
+
category: params.category,
|
|
23
|
+
tag: params.tag,
|
|
24
|
+
status: params.status,
|
|
25
|
+
search: params.q || params.search,
|
|
26
|
+
sortBy: params.sortBy || "publishedAt",
|
|
27
|
+
sortOrder: params.sortOrder || "desc"
|
|
28
|
+
});
|
|
29
|
+
const page = parseIntParam(params.page, 1);
|
|
30
|
+
const limit = parseIntParam(params.limit, 10);
|
|
31
|
+
return jsonSuccess(result.posts, {
|
|
32
|
+
page,
|
|
33
|
+
limit,
|
|
34
|
+
total: result.total,
|
|
35
|
+
totalPages: Math.ceil(result.total / limit)
|
|
36
|
+
});
|
|
37
|
+
} catch (error) {
|
|
38
|
+
console.error("[nextblogkit] GET /posts error:", error);
|
|
39
|
+
return jsonError("INTERNAL_ERROR", "Failed to fetch posts", 500);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async function POST(request) {
|
|
43
|
+
try {
|
|
44
|
+
const authError = requireAuth(request);
|
|
45
|
+
if (authError) return authError;
|
|
46
|
+
const body = await request.json();
|
|
47
|
+
const parsed = CreatePostSchema.safeParse(body);
|
|
48
|
+
if (!parsed.success) {
|
|
49
|
+
const errors = parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`);
|
|
50
|
+
return jsonError("VALIDATION_ERROR", errors.join("; "));
|
|
51
|
+
}
|
|
52
|
+
const post = await createPost(parsed.data);
|
|
53
|
+
return jsonSuccess(post, void 0, 201);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.error("[nextblogkit] POST /posts error:", error);
|
|
56
|
+
return jsonError("INTERNAL_ERROR", "Failed to create post", 500);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async function PUT(request) {
|
|
60
|
+
try {
|
|
61
|
+
const authError = requireAuth(request);
|
|
62
|
+
if (authError) return authError;
|
|
63
|
+
const params = getSearchParams(request);
|
|
64
|
+
const id = params.id;
|
|
65
|
+
if (!id) return jsonError("MISSING_ID", "Post ID is required");
|
|
66
|
+
const body = await request.json();
|
|
67
|
+
const parsed = UpdatePostSchema.safeParse(body);
|
|
68
|
+
if (!parsed.success) {
|
|
69
|
+
const errors = parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`);
|
|
70
|
+
return jsonError("VALIDATION_ERROR", errors.join("; "));
|
|
71
|
+
}
|
|
72
|
+
const post = await updatePost(id, parsed.data);
|
|
73
|
+
if (!post) return jsonError("NOT_FOUND", "Post not found", 404);
|
|
74
|
+
return jsonSuccess(post);
|
|
75
|
+
} catch (error) {
|
|
76
|
+
console.error("[nextblogkit] PUT /posts error:", error);
|
|
77
|
+
return jsonError("INTERNAL_ERROR", "Failed to update post", 500);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async function DELETE(request) {
|
|
81
|
+
try {
|
|
82
|
+
const authError = requireAuth(request);
|
|
83
|
+
if (authError) return authError;
|
|
84
|
+
const params = getSearchParams(request);
|
|
85
|
+
const id = params.id;
|
|
86
|
+
if (!id) return jsonError("MISSING_ID", "Post ID is required");
|
|
87
|
+
const deleted = await deletePost(id);
|
|
88
|
+
if (!deleted) return jsonError("NOT_FOUND", "Post not found", 404);
|
|
89
|
+
return jsonSuccess({ deleted: true });
|
|
90
|
+
} catch (error) {
|
|
91
|
+
console.error("[nextblogkit] DELETE /posts error:", error);
|
|
92
|
+
return jsonError("INTERNAL_ERROR", "Failed to delete post", 500);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export { DELETE, GET, POST, PUT };
|
|
97
|
+
//# sourceMappingURL=posts.js.map
|
|
98
|
+
//# sourceMappingURL=posts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/api/posts.ts"],"names":[],"mappings":"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","file":"posts.js","sourcesContent":["import { NextResponse } from 'next/server';\nimport {\n listPosts,\n getPostBySlug,\n getPostById,\n createPost,\n updatePost,\n deletePost,\n} from '../lib/db';\nimport { CreatePostSchema, UpdatePostSchema, type PostStatus } from '../lib/types';\nimport {\n jsonSuccess,\n jsonError,\n requireAuth,\n getSearchParams,\n parseIntParam,\n} from './middleware';\n\nexport async function GET(request: Request) {\n try {\n const params = getSearchParams(request);\n\n // Single post by slug\n if (params.slug) {\n const post = await getPostBySlug(params.slug);\n if (!post) return jsonError('NOT_FOUND', 'Post not found', 404);\n return jsonSuccess(post);\n }\n\n // Single post by id\n if (params.id) {\n const post = await getPostById(params.id);\n if (!post) return jsonError('NOT_FOUND', 'Post not found', 404);\n return jsonSuccess(post);\n }\n\n // List posts\n const result = await listPosts({\n page: parseIntParam(params.page, 1),\n limit: parseIntParam(params.limit, 10),\n category: params.category,\n tag: params.tag,\n status: params.status as PostStatus | undefined,\n search: params.q || params.search,\n sortBy: (params.sortBy as 'publishedAt' | 'createdAt' | 'title') || 'publishedAt',\n sortOrder: (params.sortOrder as 'asc' | 'desc') || 'desc',\n });\n\n const page = parseIntParam(params.page, 1);\n const limit = parseIntParam(params.limit, 10);\n\n return jsonSuccess(result.posts, {\n page,\n limit,\n total: result.total,\n totalPages: Math.ceil(result.total / limit),\n });\n } catch (error) {\n console.error('[nextblogkit] GET /posts error:', error);\n return jsonError('INTERNAL_ERROR', 'Failed to fetch posts', 500);\n }\n}\n\nexport async function POST(request: Request) {\n try {\n const authError = requireAuth(request);\n if (authError) return authError;\n\n const body = await request.json();\n const parsed = CreatePostSchema.safeParse(body);\n\n if (!parsed.success) {\n const errors = parsed.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`);\n return jsonError('VALIDATION_ERROR', errors.join('; '));\n }\n\n const post = await createPost(parsed.data);\n return jsonSuccess(post, undefined, 201);\n } catch (error) {\n console.error('[nextblogkit] POST /posts error:', error);\n return jsonError('INTERNAL_ERROR', 'Failed to create post', 500);\n }\n}\n\nexport async function PUT(request: Request) {\n try {\n const authError = requireAuth(request);\n if (authError) return authError;\n\n const params = getSearchParams(request);\n const id = params.id;\n if (!id) return jsonError('MISSING_ID', 'Post ID is required');\n\n const body = await request.json();\n const parsed = UpdatePostSchema.safeParse(body);\n\n if (!parsed.success) {\n const errors = parsed.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`);\n return jsonError('VALIDATION_ERROR', errors.join('; '));\n }\n\n const post = await updatePost(id, parsed.data);\n if (!post) return jsonError('NOT_FOUND', 'Post not found', 404);\n\n return jsonSuccess(post);\n } catch (error) {\n console.error('[nextblogkit] PUT /posts error:', error);\n return jsonError('INTERNAL_ERROR', 'Failed to update post', 500);\n }\n}\n\nexport async function DELETE(request: Request) {\n try {\n const authError = requireAuth(request);\n if (authError) return authError;\n\n const params = getSearchParams(request);\n const id = params.id;\n if (!id) return jsonError('MISSING_ID', 'Post ID is required');\n\n const deleted = await deletePost(id);\n if (!deleted) return jsonError('NOT_FOUND', 'Post not found', 404);\n\n return jsonSuccess({ deleted: true });\n } catch (error) {\n console.error('[nextblogkit] DELETE /posts error:', error);\n return jsonError('INTERNAL_ERROR', 'Failed to delete post', 500);\n }\n}\n"]}
|
package/dist/api/rss.cjs
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunk6HKMZOI4_cjs = require('../chunk-6HKMZOI4.cjs');
|
|
4
|
+
require('../chunk-U2ROR6AY.cjs');
|
|
5
|
+
var server = require('next/server');
|
|
6
|
+
|
|
7
|
+
async function GET() {
|
|
8
|
+
try {
|
|
9
|
+
const xml = await chunk6HKMZOI4_cjs.generateRSSFeed();
|
|
10
|
+
return new server.NextResponse(xml, {
|
|
11
|
+
status: 200,
|
|
12
|
+
headers: {
|
|
13
|
+
"Content-Type": "application/rss+xml",
|
|
14
|
+
"Cache-Control": "public, max-age=3600, s-maxage=3600"
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
} catch (error) {
|
|
18
|
+
console.error("[nextblogkit] RSS generation error:", error);
|
|
19
|
+
return new server.NextResponse("RSS generation failed", { status: 500 });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
exports.GET = GET;
|
|
24
|
+
//# sourceMappingURL=rss.cjs.map
|
|
25
|
+
//# sourceMappingURL=rss.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/api/rss.ts"],"names":["generateRSSFeed","NextResponse"],"mappings":";;;;;;AAGA,eAAsB,GAAA,GAAM;AAC1B,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAMA,iCAAA,EAAgB;AAClC,IAAA,OAAO,IAAIC,oBAAa,GAAA,EAAK;AAAA,MAC3B,MAAA,EAAQ,GAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,qBAAA;AAAA,QAChB,eAAA,EAAiB;AAAA;AACnB,KACD,CAAA;AAAA,EACH,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,uCAAuC,KAAK,CAAA;AAC1D,IAAA,OAAO,IAAIA,mBAAA,CAAa,uBAAA,EAAyB,EAAE,MAAA,EAAQ,KAAK,CAAA;AAAA,EAClE;AACF","file":"rss.cjs","sourcesContent":["import { NextResponse } from 'next/server';\nimport { generateRSSFeed } from '../lib/rss';\n\nexport async function GET() {\n try {\n const xml = await generateRSSFeed();\n return new NextResponse(xml, {\n status: 200,\n headers: {\n 'Content-Type': 'application/rss+xml',\n 'Cache-Control': 'public, max-age=3600, s-maxage=3600',\n },\n });\n } catch (error) {\n console.error('[nextblogkit] RSS generation error:', error);\n return new NextResponse('RSS generation failed', { status: 500 });\n }\n}\n"]}
|
package/dist/api/rss.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { generateRSSFeed } from '../chunk-R6MO3QIP.js';
|
|
2
|
+
import '../chunk-64HUVJOZ.js';
|
|
3
|
+
import { NextResponse } from 'next/server';
|
|
4
|
+
|
|
5
|
+
async function GET() {
|
|
6
|
+
try {
|
|
7
|
+
const xml = await generateRSSFeed();
|
|
8
|
+
return new NextResponse(xml, {
|
|
9
|
+
status: 200,
|
|
10
|
+
headers: {
|
|
11
|
+
"Content-Type": "application/rss+xml",
|
|
12
|
+
"Cache-Control": "public, max-age=3600, s-maxage=3600"
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
} catch (error) {
|
|
16
|
+
console.error("[nextblogkit] RSS generation error:", error);
|
|
17
|
+
return new NextResponse("RSS generation failed", { status: 500 });
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { GET };
|
|
22
|
+
//# sourceMappingURL=rss.js.map
|
|
23
|
+
//# sourceMappingURL=rss.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/api/rss.ts"],"names":[],"mappings":";;;;AAGA,eAAsB,GAAA,GAAM;AAC1B,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAM,eAAA,EAAgB;AAClC,IAAA,OAAO,IAAI,aAAa,GAAA,EAAK;AAAA,MAC3B,MAAA,EAAQ,GAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,qBAAA;AAAA,QAChB,eAAA,EAAiB;AAAA;AACnB,KACD,CAAA;AAAA,EACH,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,uCAAuC,KAAK,CAAA;AAC1D,IAAA,OAAO,IAAI,YAAA,CAAa,uBAAA,EAAyB,EAAE,MAAA,EAAQ,KAAK,CAAA;AAAA,EAClE;AACF","file":"rss.js","sourcesContent":["import { NextResponse } from 'next/server';\nimport { generateRSSFeed } from '../lib/rss';\n\nexport async function GET() {\n try {\n const xml = await generateRSSFeed();\n return new NextResponse(xml, {\n status: 200,\n headers: {\n 'Content-Type': 'application/rss+xml',\n 'Cache-Control': 'public, max-age=3600, s-maxage=3600',\n },\n });\n } catch (error) {\n console.error('[nextblogkit] RSS generation error:', error);\n return new NextResponse('RSS generation failed', { status: 500 });\n }\n}\n"]}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkN5MKAD7J_cjs = require('../chunk-N5MKAD7J.cjs');
|
|
4
|
+
var chunkKDZER3PU_cjs = require('../chunk-KDZER3PU.cjs');
|
|
5
|
+
var chunkU2ROR6AY_cjs = require('../chunk-U2ROR6AY.cjs');
|
|
6
|
+
|
|
7
|
+
// src/api/settings.ts
|
|
8
|
+
async function GET(request) {
|
|
9
|
+
try {
|
|
10
|
+
const authError = chunkKDZER3PU_cjs.requireAuth(request);
|
|
11
|
+
if (authError) return authError;
|
|
12
|
+
const settings = await chunkU2ROR6AY_cjs.getSettings();
|
|
13
|
+
return chunkKDZER3PU_cjs.jsonSuccess(settings);
|
|
14
|
+
} catch (error) {
|
|
15
|
+
console.error("[nextblogkit] GET /settings error:", error);
|
|
16
|
+
return chunkKDZER3PU_cjs.jsonError("INTERNAL_ERROR", "Failed to fetch settings", 500);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
async function PUT(request) {
|
|
20
|
+
try {
|
|
21
|
+
const authError = chunkKDZER3PU_cjs.requireAuth(request);
|
|
22
|
+
if (authError) return authError;
|
|
23
|
+
const body = await request.json();
|
|
24
|
+
const parsed = chunkN5MKAD7J_cjs.BlogSettingsSchema.partial().safeParse(body);
|
|
25
|
+
if (!parsed.success) {
|
|
26
|
+
const errors = parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`);
|
|
27
|
+
return chunkKDZER3PU_cjs.jsonError("VALIDATION_ERROR", errors.join("; "));
|
|
28
|
+
}
|
|
29
|
+
const settings = await chunkU2ROR6AY_cjs.updateSettings(parsed.data);
|
|
30
|
+
return chunkKDZER3PU_cjs.jsonSuccess(settings);
|
|
31
|
+
} catch (error) {
|
|
32
|
+
console.error("[nextblogkit] PUT /settings error:", error);
|
|
33
|
+
return chunkKDZER3PU_cjs.jsonError("INTERNAL_ERROR", "Failed to update settings", 500);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
exports.GET = GET;
|
|
38
|
+
exports.PUT = PUT;
|
|
39
|
+
//# sourceMappingURL=settings.cjs.map
|
|
40
|
+
//# sourceMappingURL=settings.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/api/settings.ts"],"names":["requireAuth","getSettings","jsonSuccess","jsonError","BlogSettingsSchema","updateSettings"],"mappings":";;;;;;;AAIA,eAAsB,IAAI,OAAA,EAAkB;AAC1C,EAAA,IAAI;AACF,IAAA,MAAM,SAAA,GAAYA,8BAAY,OAAO,CAAA;AACrC,IAAA,IAAI,WAAW,OAAO,SAAA;AAEtB,IAAA,MAAM,QAAA,GAAW,MAAMC,6BAAA,EAAY;AACnC,IAAA,OAAOC,8BAAY,QAAQ,CAAA;AAAA,EAC7B,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,sCAAsC,KAAK,CAAA;AACzD,IAAA,OAAOC,2BAAA,CAAU,gBAAA,EAAkB,0BAAA,EAA4B,GAAG,CAAA;AAAA,EACpE;AACF;AAEA,eAAsB,IAAI,OAAA,EAAkB;AAC1C,EAAA,IAAI;AACF,IAAA,MAAM,SAAA,GAAYH,8BAAY,OAAO,CAAA;AACrC,IAAA,IAAI,WAAW,OAAO,SAAA;AAEtB,IAAA,MAAM,IAAA,GAAO,MAAM,OAAA,CAAQ,IAAA,EAAK;AAChC,IAAA,MAAM,MAAA,GAASI,oCAAA,CAAmB,OAAA,EAAQ,CAAE,UAAU,IAAI,CAAA;AAE1D,IAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,MAAA,MAAM,SAAS,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,EAAG,CAAA,CAAE,IAAA,CAAK,KAAK,GAAG,CAAC,CAAA,EAAA,EAAK,CAAA,CAAE,OAAO,CAAA,CAAE,CAAA;AACjF,MAAA,OAAOD,2BAAA,CAAU,kBAAA,EAAoB,MAAA,CAAO,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,IACxD;AAEA,IAAA,MAAM,QAAA,GAAW,MAAME,gCAAA,CAAe,MAAA,CAAO,IAAI,CAAA;AACjD,IAAA,OAAOH,8BAAY,QAAQ,CAAA;AAAA,EAC7B,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,sCAAsC,KAAK,CAAA;AACzD,IAAA,OAAOC,2BAAA,CAAU,gBAAA,EAAkB,2BAAA,EAA6B,GAAG,CAAA;AAAA,EACrE;AACF","file":"settings.cjs","sourcesContent":["import { getSettings, updateSettings } from '../lib/db';\nimport { BlogSettingsSchema } from '../lib/types';\nimport { jsonSuccess, jsonError, requireAuth } from './middleware';\n\nexport async function GET(request: Request) {\n try {\n const authError = requireAuth(request);\n if (authError) return authError;\n\n const settings = await getSettings();\n return jsonSuccess(settings);\n } catch (error) {\n console.error('[nextblogkit] GET /settings error:', error);\n return jsonError('INTERNAL_ERROR', 'Failed to fetch settings', 500);\n }\n}\n\nexport async function PUT(request: Request) {\n try {\n const authError = requireAuth(request);\n if (authError) return authError;\n\n const body = await request.json();\n const parsed = BlogSettingsSchema.partial().safeParse(body);\n\n if (!parsed.success) {\n const errors = parsed.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`);\n return jsonError('VALIDATION_ERROR', errors.join('; '));\n }\n\n const settings = await updateSettings(parsed.data);\n return jsonSuccess(settings);\n } catch (error) {\n console.error('[nextblogkit] PUT /settings error:', error);\n return jsonError('INTERNAL_ERROR', 'Failed to update settings', 500);\n }\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as next_server from 'next/server';
|
|
2
|
+
import { A as ApiErrorResponse } from '../types-CBEEBR4A.cjs';
|
|
3
|
+
import 'zod';
|
|
4
|
+
import 'mongodb';
|
|
5
|
+
|
|
6
|
+
declare function GET(request: Request): Promise<next_server.NextResponse<ApiErrorResponse> | next_server.NextResponse<{
|
|
7
|
+
success: boolean;
|
|
8
|
+
data: unknown;
|
|
9
|
+
meta: Record<string, unknown> | undefined;
|
|
10
|
+
}>>;
|
|
11
|
+
declare function PUT(request: Request): Promise<next_server.NextResponse<ApiErrorResponse> | next_server.NextResponse<{
|
|
12
|
+
success: boolean;
|
|
13
|
+
data: unknown;
|
|
14
|
+
meta: Record<string, unknown> | undefined;
|
|
15
|
+
}>>;
|
|
16
|
+
|
|
17
|
+
export { GET, PUT };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as next_server from 'next/server';
|
|
2
|
+
import { A as ApiErrorResponse } from '../types-CBEEBR4A.js';
|
|
3
|
+
import 'zod';
|
|
4
|
+
import 'mongodb';
|
|
5
|
+
|
|
6
|
+
declare function GET(request: Request): Promise<next_server.NextResponse<ApiErrorResponse> | next_server.NextResponse<{
|
|
7
|
+
success: boolean;
|
|
8
|
+
data: unknown;
|
|
9
|
+
meta: Record<string, unknown> | undefined;
|
|
10
|
+
}>>;
|
|
11
|
+
declare function PUT(request: Request): Promise<next_server.NextResponse<ApiErrorResponse> | next_server.NextResponse<{
|
|
12
|
+
success: boolean;
|
|
13
|
+
data: unknown;
|
|
14
|
+
meta: Record<string, unknown> | undefined;
|
|
15
|
+
}>>;
|
|
16
|
+
|
|
17
|
+
export { GET, PUT };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { BlogSettingsSchema } from '../chunk-4PY224XM.js';
|
|
2
|
+
import { requireAuth, jsonSuccess, jsonError } from '../chunk-JLPJKNRZ.js';
|
|
3
|
+
import { getSettings, updateSettings } from '../chunk-64HUVJOZ.js';
|
|
4
|
+
|
|
5
|
+
// src/api/settings.ts
|
|
6
|
+
async function GET(request) {
|
|
7
|
+
try {
|
|
8
|
+
const authError = requireAuth(request);
|
|
9
|
+
if (authError) return authError;
|
|
10
|
+
const settings = await getSettings();
|
|
11
|
+
return jsonSuccess(settings);
|
|
12
|
+
} catch (error) {
|
|
13
|
+
console.error("[nextblogkit] GET /settings error:", error);
|
|
14
|
+
return jsonError("INTERNAL_ERROR", "Failed to fetch settings", 500);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
async function PUT(request) {
|
|
18
|
+
try {
|
|
19
|
+
const authError = requireAuth(request);
|
|
20
|
+
if (authError) return authError;
|
|
21
|
+
const body = await request.json();
|
|
22
|
+
const parsed = BlogSettingsSchema.partial().safeParse(body);
|
|
23
|
+
if (!parsed.success) {
|
|
24
|
+
const errors = parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`);
|
|
25
|
+
return jsonError("VALIDATION_ERROR", errors.join("; "));
|
|
26
|
+
}
|
|
27
|
+
const settings = await updateSettings(parsed.data);
|
|
28
|
+
return jsonSuccess(settings);
|
|
29
|
+
} catch (error) {
|
|
30
|
+
console.error("[nextblogkit] PUT /settings error:", error);
|
|
31
|
+
return jsonError("INTERNAL_ERROR", "Failed to update settings", 500);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export { GET, PUT };
|
|
36
|
+
//# sourceMappingURL=settings.js.map
|
|
37
|
+
//# sourceMappingURL=settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/api/settings.ts"],"names":[],"mappings":";;;;;AAIA,eAAsB,IAAI,OAAA,EAAkB;AAC1C,EAAA,IAAI;AACF,IAAA,MAAM,SAAA,GAAY,YAAY,OAAO,CAAA;AACrC,IAAA,IAAI,WAAW,OAAO,SAAA;AAEtB,IAAA,MAAM,QAAA,GAAW,MAAM,WAAA,EAAY;AACnC,IAAA,OAAO,YAAY,QAAQ,CAAA;AAAA,EAC7B,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,sCAAsC,KAAK,CAAA;AACzD,IAAA,OAAO,SAAA,CAAU,gBAAA,EAAkB,0BAAA,EAA4B,GAAG,CAAA;AAAA,EACpE;AACF;AAEA,eAAsB,IAAI,OAAA,EAAkB;AAC1C,EAAA,IAAI;AACF,IAAA,MAAM,SAAA,GAAY,YAAY,OAAO,CAAA;AACrC,IAAA,IAAI,WAAW,OAAO,SAAA;AAEtB,IAAA,MAAM,IAAA,GAAO,MAAM,OAAA,CAAQ,IAAA,EAAK;AAChC,IAAA,MAAM,MAAA,GAAS,kBAAA,CAAmB,OAAA,EAAQ,CAAE,UAAU,IAAI,CAAA;AAE1D,IAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,MAAA,MAAM,SAAS,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,EAAG,CAAA,CAAE,IAAA,CAAK,KAAK,GAAG,CAAC,CAAA,EAAA,EAAK,CAAA,CAAE,OAAO,CAAA,CAAE,CAAA;AACjF,MAAA,OAAO,SAAA,CAAU,kBAAA,EAAoB,MAAA,CAAO,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,IACxD;AAEA,IAAA,MAAM,QAAA,GAAW,MAAM,cAAA,CAAe,MAAA,CAAO,IAAI,CAAA;AACjD,IAAA,OAAO,YAAY,QAAQ,CAAA;AAAA,EAC7B,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,sCAAsC,KAAK,CAAA;AACzD,IAAA,OAAO,SAAA,CAAU,gBAAA,EAAkB,2BAAA,EAA6B,GAAG,CAAA;AAAA,EACrE;AACF","file":"settings.js","sourcesContent":["import { getSettings, updateSettings } from '../lib/db';\nimport { BlogSettingsSchema } from '../lib/types';\nimport { jsonSuccess, jsonError, requireAuth } from './middleware';\n\nexport async function GET(request: Request) {\n try {\n const authError = requireAuth(request);\n if (authError) return authError;\n\n const settings = await getSettings();\n return jsonSuccess(settings);\n } catch (error) {\n console.error('[nextblogkit] GET /settings error:', error);\n return jsonError('INTERNAL_ERROR', 'Failed to fetch settings', 500);\n }\n}\n\nexport async function PUT(request: Request) {\n try {\n const authError = requireAuth(request);\n if (authError) return authError;\n\n const body = await request.json();\n const parsed = BlogSettingsSchema.partial().safeParse(body);\n\n if (!parsed.success) {\n const errors = parsed.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`);\n return jsonError('VALIDATION_ERROR', errors.join('; '));\n }\n\n const settings = await updateSettings(parsed.data);\n return jsonSuccess(settings);\n } catch (error) {\n console.error('[nextblogkit] PUT /settings error:', error);\n return jsonError('INTERNAL_ERROR', 'Failed to update settings', 500);\n }\n}\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkE2QLTHKN_cjs = require('../chunk-E2QLTHKN.cjs');
|
|
4
|
+
require('../chunk-U2ROR6AY.cjs');
|
|
5
|
+
var server = require('next/server');
|
|
6
|
+
|
|
7
|
+
async function GET() {
|
|
8
|
+
try {
|
|
9
|
+
const xml = await chunkE2QLTHKN_cjs.generateSitemap();
|
|
10
|
+
return new server.NextResponse(xml, {
|
|
11
|
+
status: 200,
|
|
12
|
+
headers: {
|
|
13
|
+
"Content-Type": "application/xml",
|
|
14
|
+
"Cache-Control": "public, max-age=3600, s-maxage=3600"
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
} catch (error) {
|
|
18
|
+
console.error("[nextblogkit] Sitemap generation error:", error);
|
|
19
|
+
return new server.NextResponse("Sitemap generation failed", { status: 500 });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
exports.GET = GET;
|
|
24
|
+
//# sourceMappingURL=sitemap.cjs.map
|
|
25
|
+
//# sourceMappingURL=sitemap.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/api/sitemap.ts"],"names":["generateSitemap","NextResponse"],"mappings":";;;;;;AAGA,eAAsB,GAAA,GAAM;AAC1B,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAMA,iCAAA,EAAgB;AAClC,IAAA,OAAO,IAAIC,oBAAa,GAAA,EAAK;AAAA,MAC3B,MAAA,EAAQ,GAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,iBAAA;AAAA,QAChB,eAAA,EAAiB;AAAA;AACnB,KACD,CAAA;AAAA,EACH,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,2CAA2C,KAAK,CAAA;AAC9D,IAAA,OAAO,IAAIA,mBAAA,CAAa,2BAAA,EAA6B,EAAE,MAAA,EAAQ,KAAK,CAAA;AAAA,EACtE;AACF","file":"sitemap.cjs","sourcesContent":["import { NextResponse } from 'next/server';\nimport { generateSitemap } from '../lib/sitemap';\n\nexport async function GET() {\n try {\n const xml = await generateSitemap();\n return new NextResponse(xml, {\n status: 200,\n headers: {\n 'Content-Type': 'application/xml',\n 'Cache-Control': 'public, max-age=3600, s-maxage=3600',\n },\n });\n } catch (error) {\n console.error('[nextblogkit] Sitemap generation error:', error);\n return new NextResponse('Sitemap generation failed', { status: 500 });\n }\n}\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { generateSitemap } from '../chunk-4NKOJYWJ.js';
|
|
2
|
+
import '../chunk-64HUVJOZ.js';
|
|
3
|
+
import { NextResponse } from 'next/server';
|
|
4
|
+
|
|
5
|
+
async function GET() {
|
|
6
|
+
try {
|
|
7
|
+
const xml = await generateSitemap();
|
|
8
|
+
return new NextResponse(xml, {
|
|
9
|
+
status: 200,
|
|
10
|
+
headers: {
|
|
11
|
+
"Content-Type": "application/xml",
|
|
12
|
+
"Cache-Control": "public, max-age=3600, s-maxage=3600"
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
} catch (error) {
|
|
16
|
+
console.error("[nextblogkit] Sitemap generation error:", error);
|
|
17
|
+
return new NextResponse("Sitemap generation failed", { status: 500 });
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { GET };
|
|
22
|
+
//# sourceMappingURL=sitemap.js.map
|
|
23
|
+
//# sourceMappingURL=sitemap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/api/sitemap.ts"],"names":[],"mappings":";;;;AAGA,eAAsB,GAAA,GAAM;AAC1B,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAM,eAAA,EAAgB;AAClC,IAAA,OAAO,IAAI,aAAa,GAAA,EAAK;AAAA,MAC3B,MAAA,EAAQ,GAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,iBAAA;AAAA,QAChB,eAAA,EAAiB;AAAA;AACnB,KACD,CAAA;AAAA,EACH,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,2CAA2C,KAAK,CAAA;AAC9D,IAAA,OAAO,IAAI,YAAA,CAAa,2BAAA,EAA6B,EAAE,MAAA,EAAQ,KAAK,CAAA;AAAA,EACtE;AACF","file":"sitemap.js","sourcesContent":["import { NextResponse } from 'next/server';\nimport { generateSitemap } from '../lib/sitemap';\n\nexport async function GET() {\n try {\n const xml = await generateSitemap();\n return new NextResponse(xml, {\n status: 200,\n headers: {\n 'Content-Type': 'application/xml',\n 'Cache-Control': 'public, max-age=3600, s-maxage=3600',\n },\n });\n } catch (error) {\n console.error('[nextblogkit] Sitemap generation error:', error);\n return new NextResponse('Sitemap generation failed', { status: 500 });\n }\n}\n"]}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { getEnvConfig, getCollection } from './chunk-64HUVJOZ.js';
|
|
2
|
+
|
|
3
|
+
// src/lib/sitemap.ts
|
|
4
|
+
async function generateSitemap() {
|
|
5
|
+
const env = getEnvConfig();
|
|
6
|
+
const posts = await getCollection("nbk_posts");
|
|
7
|
+
const categories = await getCollection("nbk_categories");
|
|
8
|
+
const entries = [];
|
|
9
|
+
entries.push({
|
|
10
|
+
loc: `${env.NEXTBLOGKIT_SITE_URL}/blog`,
|
|
11
|
+
changefreq: "daily",
|
|
12
|
+
priority: "0.9"
|
|
13
|
+
});
|
|
14
|
+
const publishedPosts = await posts.find({ status: "published" }).sort({ publishedAt: -1 }).project({ slug: 1, updatedAt: 1, publishedAt: 1 }).toArray();
|
|
15
|
+
for (const post of publishedPosts) {
|
|
16
|
+
const lastmod = post.updatedAt || post.publishedAt;
|
|
17
|
+
const daysSincePublish = lastmod ? Math.floor((Date.now() - new Date(lastmod).getTime()) / (1e3 * 60 * 60 * 24)) : 0;
|
|
18
|
+
let changefreq = "monthly";
|
|
19
|
+
if (daysSincePublish < 7) changefreq = "daily";
|
|
20
|
+
else if (daysSincePublish < 30) changefreq = "weekly";
|
|
21
|
+
entries.push({
|
|
22
|
+
loc: `${env.NEXTBLOGKIT_SITE_URL}/blog/${post.slug}`,
|
|
23
|
+
lastmod: lastmod ? new Date(lastmod).toISOString().split("T")[0] : void 0,
|
|
24
|
+
changefreq,
|
|
25
|
+
priority: "0.8"
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
const allCategories = await categories.find({}).sort({ order: 1 }).project({ slug: 1 }).toArray();
|
|
29
|
+
for (const cat of allCategories) {
|
|
30
|
+
entries.push({
|
|
31
|
+
loc: `${env.NEXTBLOGKIT_SITE_URL}/blog/category/${cat.slug}`,
|
|
32
|
+
changefreq: "weekly",
|
|
33
|
+
priority: "0.6"
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
const totalPosts = publishedPosts.length;
|
|
37
|
+
const postsPerPage = 10;
|
|
38
|
+
const totalPages = Math.ceil(totalPosts / postsPerPage);
|
|
39
|
+
for (let page = 2; page <= totalPages; page++) {
|
|
40
|
+
entries.push({
|
|
41
|
+
loc: `${env.NEXTBLOGKIT_SITE_URL}/blog?page=${page}`,
|
|
42
|
+
changefreq: "weekly",
|
|
43
|
+
priority: "0.5"
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return buildXML(entries);
|
|
47
|
+
}
|
|
48
|
+
function buildXML(entries) {
|
|
49
|
+
const urls = entries.map(
|
|
50
|
+
(entry) => ` <url>
|
|
51
|
+
<loc>${escapeXml(entry.loc)}</loc>${entry.lastmod ? `
|
|
52
|
+
<lastmod>${entry.lastmod}</lastmod>` : ""}${entry.changefreq ? `
|
|
53
|
+
<changefreq>${entry.changefreq}</changefreq>` : ""}${entry.priority ? `
|
|
54
|
+
<priority>${entry.priority}</priority>` : ""}
|
|
55
|
+
</url>`
|
|
56
|
+
).join("\n");
|
|
57
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
58
|
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
59
|
+
${urls}
|
|
60
|
+
</urlset>`;
|
|
61
|
+
}
|
|
62
|
+
function escapeXml(str) {
|
|
63
|
+
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { generateSitemap };
|
|
67
|
+
//# sourceMappingURL=chunk-4NKOJYWJ.js.map
|
|
68
|
+
//# sourceMappingURL=chunk-4NKOJYWJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/sitemap.ts"],"names":[],"mappings":"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","file":"chunk-4NKOJYWJ.js","sourcesContent":["import { getCollection } from './db';\nimport { getEnvConfig } from './config';\n\ninterface SitemapEntry {\n loc: string;\n lastmod?: string;\n changefreq?: string;\n priority?: string;\n}\n\nexport async function generateSitemap(): Promise<string> {\n const env = getEnvConfig();\n const posts = await getCollection('nbk_posts');\n const categories = await getCollection('nbk_categories');\n\n const entries: SitemapEntry[] = [];\n\n // Blog listing page\n entries.push({\n loc: `${env.NEXTBLOGKIT_SITE_URL}/blog`,\n changefreq: 'daily',\n priority: '0.9',\n });\n\n // Published posts\n const publishedPosts = await posts\n .find({ status: 'published' })\n .sort({ publishedAt: -1 })\n .project({ slug: 1, updatedAt: 1, publishedAt: 1 })\n .toArray();\n\n for (const post of publishedPosts) {\n const lastmod = post.updatedAt || post.publishedAt;\n const daysSincePublish = lastmod\n ? Math.floor((Date.now() - new Date(lastmod).getTime()) / (1000 * 60 * 60 * 24))\n : 0;\n\n let changefreq = 'monthly';\n if (daysSincePublish < 7) changefreq = 'daily';\n else if (daysSincePublish < 30) changefreq = 'weekly';\n\n entries.push({\n loc: `${env.NEXTBLOGKIT_SITE_URL}/blog/${post.slug}`,\n lastmod: lastmod ? new Date(lastmod).toISOString().split('T')[0] : undefined,\n changefreq,\n priority: '0.8',\n });\n }\n\n // Category pages\n const allCategories = await categories\n .find({})\n .sort({ order: 1 })\n .project({ slug: 1 })\n .toArray();\n\n for (const cat of allCategories) {\n entries.push({\n loc: `${env.NEXTBLOGKIT_SITE_URL}/blog/category/${cat.slug}`,\n changefreq: 'weekly',\n priority: '0.6',\n });\n }\n\n // Paginated listing pages\n const totalPosts = publishedPosts.length;\n const postsPerPage = 10;\n const totalPages = Math.ceil(totalPosts / postsPerPage);\n for (let page = 2; page <= totalPages; page++) {\n entries.push({\n loc: `${env.NEXTBLOGKIT_SITE_URL}/blog?page=${page}`,\n changefreq: 'weekly',\n priority: '0.5',\n });\n }\n\n return buildXML(entries);\n}\n\nfunction buildXML(entries: SitemapEntry[]): string {\n const urls = entries\n .map(\n (entry) => ` <url>\n <loc>${escapeXml(entry.loc)}</loc>${entry.lastmod ? `\\n <lastmod>${entry.lastmod}</lastmod>` : ''}${entry.changefreq ? `\\n <changefreq>${entry.changefreq}</changefreq>` : ''}${entry.priority ? `\\n <priority>${entry.priority}</priority>` : ''}\n </url>`\n )\n .join('\\n');\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n${urls}\n</urlset>`;\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"]}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
// src/lib/types.ts
|
|
4
|
+
z.enum([
|
|
5
|
+
"paragraph",
|
|
6
|
+
"heading",
|
|
7
|
+
"image",
|
|
8
|
+
"codeBlock",
|
|
9
|
+
"blockquote",
|
|
10
|
+
"bulletList",
|
|
11
|
+
"orderedList",
|
|
12
|
+
"taskList",
|
|
13
|
+
"table",
|
|
14
|
+
"embed",
|
|
15
|
+
"horizontalRule",
|
|
16
|
+
"callout",
|
|
17
|
+
"tableOfContents",
|
|
18
|
+
"faq",
|
|
19
|
+
"html"
|
|
20
|
+
]);
|
|
21
|
+
z.object({
|
|
22
|
+
filename: z.string(),
|
|
23
|
+
originalName: z.string(),
|
|
24
|
+
mimeType: z.string(),
|
|
25
|
+
size: z.number(),
|
|
26
|
+
width: z.number().optional(),
|
|
27
|
+
height: z.number().optional(),
|
|
28
|
+
r2Key: z.string(),
|
|
29
|
+
url: z.string().url(),
|
|
30
|
+
alt: z.string().optional(),
|
|
31
|
+
caption: z.string().optional(),
|
|
32
|
+
createdAt: z.date()
|
|
33
|
+
});
|
|
34
|
+
var AuthorSchema = z.object({
|
|
35
|
+
name: z.string().min(1),
|
|
36
|
+
avatar: z.string().url().optional(),
|
|
37
|
+
bio: z.string().optional(),
|
|
38
|
+
url: z.string().url().optional()
|
|
39
|
+
});
|
|
40
|
+
var PostSEOSchema = z.object({
|
|
41
|
+
metaTitle: z.string().optional(),
|
|
42
|
+
metaDescription: z.string().optional(),
|
|
43
|
+
canonicalUrl: z.string().url().optional(),
|
|
44
|
+
ogImage: z.string().url().optional(),
|
|
45
|
+
ogType: z.string().default("article"),
|
|
46
|
+
noIndex: z.boolean().default(false),
|
|
47
|
+
structuredData: z.record(z.unknown()).optional(),
|
|
48
|
+
focusKeyword: z.string().optional()
|
|
49
|
+
});
|
|
50
|
+
var PostStatusSchema = z.enum(["draft", "published", "scheduled", "archived"]);
|
|
51
|
+
var CreatePostSchema = z.object({
|
|
52
|
+
title: z.string().min(1, "Title is required"),
|
|
53
|
+
slug: z.string().optional(),
|
|
54
|
+
excerpt: z.string().optional(),
|
|
55
|
+
content: z.any(),
|
|
56
|
+
// BlockContent[] — validated structurally
|
|
57
|
+
contentHTML: z.string().optional(),
|
|
58
|
+
contentText: z.string().optional(),
|
|
59
|
+
coverImage: z.object({
|
|
60
|
+
_id: z.string(),
|
|
61
|
+
url: z.string().url(),
|
|
62
|
+
alt: z.string().optional(),
|
|
63
|
+
caption: z.string().optional(),
|
|
64
|
+
width: z.number().optional(),
|
|
65
|
+
height: z.number().optional()
|
|
66
|
+
}).optional(),
|
|
67
|
+
categories: z.array(z.string()).default([]),
|
|
68
|
+
tags: z.array(z.string()).default([]),
|
|
69
|
+
author: AuthorSchema.optional(),
|
|
70
|
+
seo: PostSEOSchema.optional(),
|
|
71
|
+
status: PostStatusSchema.default("draft"),
|
|
72
|
+
publishedAt: z.coerce.date().optional(),
|
|
73
|
+
scheduledAt: z.coerce.date().optional()
|
|
74
|
+
});
|
|
75
|
+
var UpdatePostSchema = CreatePostSchema.partial();
|
|
76
|
+
var CreateCategorySchema = z.object({
|
|
77
|
+
name: z.string().min(1, "Category name is required"),
|
|
78
|
+
slug: z.string().optional(),
|
|
79
|
+
description: z.string().optional(),
|
|
80
|
+
seo: z.object({
|
|
81
|
+
metaTitle: z.string().optional(),
|
|
82
|
+
metaDescription: z.string().optional()
|
|
83
|
+
}).optional(),
|
|
84
|
+
order: z.number().default(0),
|
|
85
|
+
parentId: z.string().optional()
|
|
86
|
+
});
|
|
87
|
+
var UpdateCategorySchema = CreateCategorySchema.partial();
|
|
88
|
+
var BlogSettingsSchema = z.object({
|
|
89
|
+
postsPerPage: z.number().min(1).max(100).default(10),
|
|
90
|
+
defaultAuthor: AuthorSchema.optional(),
|
|
91
|
+
defaultOgImage: z.string().url().optional(),
|
|
92
|
+
commentSystem: z.enum(["none", "giscus", "disqus"]).default("none"),
|
|
93
|
+
commentConfig: z.record(z.unknown()).optional(),
|
|
94
|
+
customCSS: z.string().optional(),
|
|
95
|
+
analytics: z.object({
|
|
96
|
+
gaId: z.string().optional(),
|
|
97
|
+
plausibleDomain: z.string().optional()
|
|
98
|
+
}).optional()
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
export { BlogSettingsSchema, CreateCategorySchema, CreatePostSchema, UpdateCategorySchema, UpdatePostSchema };
|
|
102
|
+
//# sourceMappingURL=chunk-4PY224XM.js.map
|
|
103
|
+
//# sourceMappingURL=chunk-4PY224XM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/types.ts"],"names":[],"mappings":"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","file":"chunk-4PY224XM.js","sourcesContent":["import { z } from 'zod';\nimport type { ObjectId } from 'mongodb';\n\n// ============================================================\n// Block Editor Types\n// ============================================================\n\nexport const BlockTypeSchema = z.enum([\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\nexport type BlockType = z.infer<typeof BlockTypeSchema>;\n\nexport interface BlockContent {\n type: string;\n attrs?: Record<string, unknown>;\n content?: BlockContent[];\n text?: string;\n marks?: { type: string; attrs?: Record<string, unknown> }[];\n}\n\n// ============================================================\n// Media\n// ============================================================\n\nexport interface MediaReference {\n _id: string;\n url: string;\n alt?: string;\n caption?: string;\n width?: number;\n height?: number;\n}\n\nexport const MediaSchema = z.object({\n filename: z.string(),\n originalName: z.string(),\n mimeType: z.string(),\n size: z.number(),\n width: z.number().optional(),\n height: z.number().optional(),\n r2Key: z.string(),\n url: z.string().url(),\n alt: z.string().optional(),\n caption: z.string().optional(),\n createdAt: z.date(),\n});\n\nexport interface Media {\n _id: ObjectId;\n filename: string;\n originalName: string;\n mimeType: string;\n size: number;\n width?: number;\n height?: number;\n r2Key: string;\n url: string;\n alt?: string;\n caption?: string;\n createdAt: Date;\n}\n\n// ============================================================\n// Author\n// ============================================================\n\nexport const AuthorSchema = z.object({\n name: z.string().min(1),\n avatar: z.string().url().optional(),\n bio: z.string().optional(),\n url: z.string().url().optional(),\n});\n\nexport interface Author {\n name: string;\n avatar?: string;\n bio?: string;\n url?: string;\n}\n\n// ============================================================\n// SEO\n// ============================================================\n\nexport const PostSEOSchema = z.object({\n metaTitle: z.string().optional(),\n metaDescription: z.string().optional(),\n canonicalUrl: z.string().url().optional(),\n ogImage: z.string().url().optional(),\n ogType: z.string().default('article'),\n noIndex: z.boolean().default(false),\n structuredData: z.record(z.unknown()).optional(),\n focusKeyword: z.string().optional(),\n});\n\nexport interface PostSEO {\n metaTitle?: string;\n metaDescription?: string;\n canonicalUrl?: string;\n ogImage?: string;\n ogType: string;\n noIndex: boolean;\n structuredData?: Record<string, unknown>;\n focusKeyword?: string;\n}\n\n// ============================================================\n// Revision\n// ============================================================\n\nexport interface Revision {\n version: number;\n title: string;\n content: BlockContent[];\n contentHTML: string;\n savedAt: Date;\n}\n\n// ============================================================\n// Post\n// ============================================================\n\nexport const PostStatusSchema = z.enum(['draft', 'published', 'scheduled', 'archived']);\nexport type PostStatus = z.infer<typeof PostStatusSchema>;\n\nexport const CreatePostSchema = z.object({\n title: z.string().min(1, 'Title is required'),\n slug: z.string().optional(),\n excerpt: z.string().optional(),\n content: z.any(), // BlockContent[] — validated structurally\n contentHTML: z.string().optional(),\n contentText: z.string().optional(),\n coverImage: z\n .object({\n _id: z.string(),\n url: z.string().url(),\n alt: z.string().optional(),\n caption: z.string().optional(),\n width: z.number().optional(),\n height: z.number().optional(),\n })\n .optional(),\n categories: z.array(z.string()).default([]),\n tags: z.array(z.string()).default([]),\n author: AuthorSchema.optional(),\n seo: PostSEOSchema.optional(),\n status: PostStatusSchema.default('draft'),\n publishedAt: z.coerce.date().optional(),\n scheduledAt: z.coerce.date().optional(),\n});\n\nexport const UpdatePostSchema = CreatePostSchema.partial();\n\nexport type CreatePostInput = z.infer<typeof CreatePostSchema>;\nexport type UpdatePostInput = z.infer<typeof UpdatePostSchema>;\n\nexport interface BlogPost {\n _id: ObjectId;\n title: string;\n slug: string;\n excerpt: string;\n content: BlockContent[];\n contentHTML: string;\n contentText: string;\n coverImage?: MediaReference;\n categories: string[];\n tags: string[];\n author: Author;\n seo: PostSEO;\n status: PostStatus;\n publishedAt?: Date;\n scheduledAt?: Date;\n readingTime: number;\n wordCount: number;\n version: number;\n revisions: Revision[];\n createdAt: Date;\n updatedAt: Date;\n}\n\n// ============================================================\n// Category\n// ============================================================\n\nexport const CreateCategorySchema = z.object({\n name: z.string().min(1, 'Category name is required'),\n slug: z.string().optional(),\n description: z.string().optional(),\n seo: z\n .object({\n metaTitle: z.string().optional(),\n metaDescription: z.string().optional(),\n })\n .optional(),\n order: z.number().default(0),\n parentId: z.string().optional(),\n});\n\nexport const UpdateCategorySchema = CreateCategorySchema.partial();\n\nexport type CreateCategoryInput = z.infer<typeof CreateCategorySchema>;\nexport type UpdateCategoryInput = z.infer<typeof UpdateCategorySchema>;\n\nexport interface Category {\n _id: ObjectId;\n name: string;\n slug: string;\n description?: string;\n seo?: {\n metaTitle?: string;\n metaDescription?: string;\n };\n order: number;\n parentId?: ObjectId;\n postCount: number;\n}\n\n// ============================================================\n// Settings\n// ============================================================\n\nexport const BlogSettingsSchema = z.object({\n postsPerPage: z.number().min(1).max(100).default(10),\n defaultAuthor: AuthorSchema.optional(),\n defaultOgImage: z.string().url().optional(),\n commentSystem: z.enum(['none', 'giscus', 'disqus']).default('none'),\n commentConfig: z.record(z.unknown()).optional(),\n customCSS: z.string().optional(),\n analytics: z\n .object({\n gaId: z.string().optional(),\n plausibleDomain: z.string().optional(),\n })\n .optional(),\n});\n\nexport interface BlogSettings {\n _id: string;\n postsPerPage: number;\n defaultAuthor?: Author;\n defaultOgImage?: string;\n commentSystem: 'none' | 'giscus' | 'disqus';\n commentConfig?: Record<string, unknown>;\n customCSS?: string;\n analytics?: {\n gaId?: string;\n plausibleDomain?: string;\n };\n}\n\n// ============================================================\n// API Response Types\n// ============================================================\n\nexport interface ApiSuccessResponse<T = unknown> {\n success: true;\n data: T;\n meta?: {\n page: number;\n limit: number;\n total: number;\n totalPages: number;\n };\n}\n\nexport interface ApiErrorResponse {\n success: false;\n error: {\n code: string;\n message: string;\n };\n}\n\nexport type ApiResponse<T = unknown> = ApiSuccessResponse<T> | ApiErrorResponse;\n\n// ============================================================\n// SEO Score Types\n// ============================================================\n\nexport type SEOCheckStatus = 'pass' | 'warn' | 'fail';\nexport type SEOOverallScore = 'good' | 'ok' | 'poor';\n\nexport interface SEOCheck {\n id: string;\n status: SEOCheckStatus;\n message: string;\n}\n\nexport interface SEOScore {\n overall: SEOOverallScore;\n checks: SEOCheck[];\n}\n\n// ============================================================\n// Config Types\n// ============================================================\n\nexport interface NextBlogKitConfig {\n basePath: string;\n adminPath: string;\n apiPath: string;\n postsPerPage: number;\n excerptLength: number;\n codeHighlighter: 'shiki' | 'prism';\n editor: {\n blocks: BlockType[];\n maxImageSize: number;\n imageFormats: string[];\n autosaveInterval: number;\n };\n seo: {\n titleTemplate: string;\n defaultOgImage?: string;\n generateRSS: boolean;\n generateSitemap: boolean;\n structuredData: boolean;\n minContentLength: number;\n };\n auth: {\n strategy: 'api-key' | 'custom' | 'credentials';\n verify?: (request: Request) => Promise<boolean>;\n admins?: string[];\n };\n features: {\n search: boolean;\n relatedPosts: boolean;\n readingProgress: boolean;\n tableOfContents: boolean;\n shareButtons: boolean;\n darkMode: boolean;\n scheduling: boolean;\n revisionHistory: boolean;\n imageOptimization: boolean;\n };\n theme: {\n variables?: Record<string, string>;\n darkMode?: boolean;\n components?: Record<string, React.ComponentType<unknown>>;\n };\n hooks: {\n beforePublish?: (post: BlogPost) => Promise<void>;\n afterPublish?: (post: BlogPost) => Promise<void>;\n beforeDelete?: (post: BlogPost) => Promise<void>;\n onMediaUpload?: (media: Media) => Promise<void>;\n };\n}\n\n// ============================================================\n// Query Types\n// ============================================================\n\nexport interface PostListQuery {\n page?: number;\n limit?: number;\n category?: string;\n tag?: string;\n status?: PostStatus;\n search?: string;\n sortBy?: 'publishedAt' | 'createdAt' | 'title';\n sortOrder?: 'asc' | 'desc';\n}\n\nexport interface MediaListQuery {\n page?: number;\n limit?: number;\n mimeType?: string;\n}\n"]}
|