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,27 @@
|
|
|
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 POST(request: Request): Promise<next_server.NextResponse<ApiErrorResponse> | next_server.NextResponse<{
|
|
12
|
+
success: boolean;
|
|
13
|
+
data: unknown;
|
|
14
|
+
meta: Record<string, unknown> | undefined;
|
|
15
|
+
}>>;
|
|
16
|
+
declare function PUT(request: Request): Promise<next_server.NextResponse<ApiErrorResponse> | next_server.NextResponse<{
|
|
17
|
+
success: boolean;
|
|
18
|
+
data: unknown;
|
|
19
|
+
meta: Record<string, unknown> | undefined;
|
|
20
|
+
}>>;
|
|
21
|
+
declare function DELETE(request: Request): Promise<next_server.NextResponse<ApiErrorResponse> | next_server.NextResponse<{
|
|
22
|
+
success: boolean;
|
|
23
|
+
data: unknown;
|
|
24
|
+
meta: Record<string, unknown> | undefined;
|
|
25
|
+
}>>;
|
|
26
|
+
|
|
27
|
+
export { DELETE, GET, POST, PUT };
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { CreateCategorySchema, UpdateCategorySchema } from '../chunk-4PY224XM.js';
|
|
2
|
+
import { getSearchParams, jsonError, jsonSuccess, requireAuth } from '../chunk-JLPJKNRZ.js';
|
|
3
|
+
import { getCategoryBySlug, listCategories, createCategory, updateCategory, deleteCategory } from '../chunk-64HUVJOZ.js';
|
|
4
|
+
|
|
5
|
+
// src/api/categories.ts
|
|
6
|
+
async function GET(request) {
|
|
7
|
+
try {
|
|
8
|
+
const params = getSearchParams(request);
|
|
9
|
+
if (params.slug) {
|
|
10
|
+
const category = await getCategoryBySlug(params.slug);
|
|
11
|
+
if (!category) return jsonError("NOT_FOUND", "Category not found", 404);
|
|
12
|
+
return jsonSuccess(category);
|
|
13
|
+
}
|
|
14
|
+
const categories = await listCategories();
|
|
15
|
+
return jsonSuccess(categories);
|
|
16
|
+
} catch (error) {
|
|
17
|
+
console.error("[nextblogkit] GET /categories error:", error);
|
|
18
|
+
return jsonError("INTERNAL_ERROR", "Failed to fetch categories", 500);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
async function POST(request) {
|
|
22
|
+
try {
|
|
23
|
+
const authError = requireAuth(request);
|
|
24
|
+
if (authError) return authError;
|
|
25
|
+
const body = await request.json();
|
|
26
|
+
const parsed = CreateCategorySchema.safeParse(body);
|
|
27
|
+
if (!parsed.success) {
|
|
28
|
+
const errors = parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`);
|
|
29
|
+
return jsonError("VALIDATION_ERROR", errors.join("; "));
|
|
30
|
+
}
|
|
31
|
+
const category = await createCategory(parsed.data);
|
|
32
|
+
return jsonSuccess(category, void 0, 201);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
console.error("[nextblogkit] POST /categories error:", error);
|
|
35
|
+
return jsonError("INTERNAL_ERROR", "Failed to create category", 500);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async function PUT(request) {
|
|
39
|
+
try {
|
|
40
|
+
const authError = requireAuth(request);
|
|
41
|
+
if (authError) return authError;
|
|
42
|
+
const params = getSearchParams(request);
|
|
43
|
+
const id = params.id;
|
|
44
|
+
if (!id) return jsonError("MISSING_ID", "Category ID is required");
|
|
45
|
+
const body = await request.json();
|
|
46
|
+
const parsed = UpdateCategorySchema.safeParse(body);
|
|
47
|
+
if (!parsed.success) {
|
|
48
|
+
const errors = parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`);
|
|
49
|
+
return jsonError("VALIDATION_ERROR", errors.join("; "));
|
|
50
|
+
}
|
|
51
|
+
const category = await updateCategory(id, parsed.data);
|
|
52
|
+
if (!category) return jsonError("NOT_FOUND", "Category not found", 404);
|
|
53
|
+
return jsonSuccess(category);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.error("[nextblogkit] PUT /categories error:", error);
|
|
56
|
+
return jsonError("INTERNAL_ERROR", "Failed to update category", 500);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async function DELETE(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", "Category ID is required");
|
|
66
|
+
const deleted = await deleteCategory(id);
|
|
67
|
+
if (!deleted) return jsonError("NOT_FOUND", "Category not found", 404);
|
|
68
|
+
return jsonSuccess({ deleted: true });
|
|
69
|
+
} catch (error) {
|
|
70
|
+
console.error("[nextblogkit] DELETE /categories error:", error);
|
|
71
|
+
return jsonError("INTERNAL_ERROR", "Failed to delete category", 500);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export { DELETE, GET, POST, PUT };
|
|
76
|
+
//# sourceMappingURL=categories.js.map
|
|
77
|
+
//# sourceMappingURL=categories.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/api/categories.ts"],"names":[],"mappings":"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","file":"categories.js","sourcesContent":["import {\n listCategories,\n getCategoryBySlug,\n createCategory,\n updateCategory,\n deleteCategory,\n} from '../lib/db';\nimport { CreateCategorySchema, UpdateCategorySchema } from '../lib/types';\nimport { jsonSuccess, jsonError, requireAuth, getSearchParams } from './middleware';\n\nexport async function GET(request: Request) {\n try {\n const params = getSearchParams(request);\n\n if (params.slug) {\n const category = await getCategoryBySlug(params.slug);\n if (!category) return jsonError('NOT_FOUND', 'Category not found', 404);\n return jsonSuccess(category);\n }\n\n const categories = await listCategories();\n return jsonSuccess(categories);\n } catch (error) {\n console.error('[nextblogkit] GET /categories error:', error);\n return jsonError('INTERNAL_ERROR', 'Failed to fetch categories', 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 = CreateCategorySchema.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 category = await createCategory(parsed.data);\n return jsonSuccess(category, undefined, 201);\n } catch (error) {\n console.error('[nextblogkit] POST /categories error:', error);\n return jsonError('INTERNAL_ERROR', 'Failed to create category', 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', 'Category ID is required');\n\n const body = await request.json();\n const parsed = UpdateCategorySchema.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 category = await updateCategory(id, parsed.data);\n if (!category) return jsonError('NOT_FOUND', 'Category not found', 404);\n\n return jsonSuccess(category);\n } catch (error) {\n console.error('[nextblogkit] PUT /categories error:', error);\n return jsonError('INTERNAL_ERROR', 'Failed to update category', 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', 'Category ID is required');\n\n const deleted = await deleteCategory(id);\n if (!deleted) return jsonError('NOT_FOUND', 'Category not found', 404);\n\n return jsonSuccess({ deleted: true });\n } catch (error) {\n console.error('[nextblogkit] DELETE /categories error:', error);\n return jsonError('INTERNAL_ERROR', 'Failed to delete category', 500);\n }\n}\n"]}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkZP5XRVVH_cjs = require('../chunk-ZP5XRVVH.cjs');
|
|
4
|
+
var chunkKDZER3PU_cjs = require('../chunk-KDZER3PU.cjs');
|
|
5
|
+
var chunkU2ROR6AY_cjs = require('../chunk-U2ROR6AY.cjs');
|
|
6
|
+
|
|
7
|
+
// src/api/media.ts
|
|
8
|
+
async function GET(request) {
|
|
9
|
+
try {
|
|
10
|
+
const authError = chunkKDZER3PU_cjs.requireAuth(request);
|
|
11
|
+
if (authError) return authError;
|
|
12
|
+
const params = chunkKDZER3PU_cjs.getSearchParams(request);
|
|
13
|
+
const result = await chunkU2ROR6AY_cjs.listMedia({
|
|
14
|
+
page: chunkKDZER3PU_cjs.parseIntParam(params.page, 1),
|
|
15
|
+
limit: chunkKDZER3PU_cjs.parseIntParam(params.limit, 20),
|
|
16
|
+
mimeType: params.mimeType
|
|
17
|
+
});
|
|
18
|
+
const page = chunkKDZER3PU_cjs.parseIntParam(params.page, 1);
|
|
19
|
+
const limit = chunkKDZER3PU_cjs.parseIntParam(params.limit, 20);
|
|
20
|
+
return chunkKDZER3PU_cjs.jsonSuccess(result.media, {
|
|
21
|
+
page,
|
|
22
|
+
limit,
|
|
23
|
+
total: result.total,
|
|
24
|
+
totalPages: Math.ceil(result.total / limit)
|
|
25
|
+
});
|
|
26
|
+
} catch (error) {
|
|
27
|
+
console.error("[nextblogkit] GET /media error:", error);
|
|
28
|
+
return chunkKDZER3PU_cjs.jsonError("INTERNAL_ERROR", "Failed to fetch media", 500);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async function POST(request) {
|
|
32
|
+
try {
|
|
33
|
+
const authError = chunkKDZER3PU_cjs.requireAuth(request);
|
|
34
|
+
if (authError) return authError;
|
|
35
|
+
const formData = await request.formData();
|
|
36
|
+
const file = formData.get("file");
|
|
37
|
+
if (!file) {
|
|
38
|
+
return chunkKDZER3PU_cjs.jsonError("MISSING_FILE", "File is required");
|
|
39
|
+
}
|
|
40
|
+
const env = chunkU2ROR6AY_cjs.getEnvConfig();
|
|
41
|
+
const maxSize = 10 * 1024 * 1024;
|
|
42
|
+
if (file.size > maxSize) {
|
|
43
|
+
return chunkKDZER3PU_cjs.jsonError("FILE_TOO_LARGE", "File must be under 10MB");
|
|
44
|
+
}
|
|
45
|
+
const allowedTypes = [
|
|
46
|
+
"image/jpeg",
|
|
47
|
+
"image/png",
|
|
48
|
+
"image/gif",
|
|
49
|
+
"image/webp",
|
|
50
|
+
"image/svg+xml",
|
|
51
|
+
"image/avif"
|
|
52
|
+
];
|
|
53
|
+
if (!allowedTypes.includes(file.type)) {
|
|
54
|
+
return chunkKDZER3PU_cjs.jsonError("INVALID_TYPE", `Allowed types: ${allowedTypes.join(", ")}`);
|
|
55
|
+
}
|
|
56
|
+
const buffer = Buffer.from(await file.arrayBuffer());
|
|
57
|
+
const storage = new chunkZP5XRVVH_cjs.R2StorageProvider();
|
|
58
|
+
const isImage = file.type.startsWith("image/") && file.type !== "image/svg+xml";
|
|
59
|
+
let uploadResult;
|
|
60
|
+
let width;
|
|
61
|
+
let height;
|
|
62
|
+
if (isImage) {
|
|
63
|
+
const processed = await chunkZP5XRVVH_cjs.processImage(buffer, file.name, storage);
|
|
64
|
+
uploadResult = processed.original;
|
|
65
|
+
width = processed.width;
|
|
66
|
+
height = processed.height;
|
|
67
|
+
} else {
|
|
68
|
+
uploadResult = await storage.upload(buffer, file.name, file.type);
|
|
69
|
+
}
|
|
70
|
+
const media = await chunkU2ROR6AY_cjs.createMedia({
|
|
71
|
+
filename: uploadResult.key.split("/").pop() || file.name,
|
|
72
|
+
originalName: file.name,
|
|
73
|
+
mimeType: uploadResult.contentType,
|
|
74
|
+
size: uploadResult.size,
|
|
75
|
+
width,
|
|
76
|
+
height,
|
|
77
|
+
r2Key: uploadResult.key,
|
|
78
|
+
url: uploadResult.url,
|
|
79
|
+
alt: formData.get("alt") || "",
|
|
80
|
+
caption: formData.get("caption") || "",
|
|
81
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
82
|
+
});
|
|
83
|
+
return chunkKDZER3PU_cjs.jsonSuccess(media, void 0, 201);
|
|
84
|
+
} catch (error) {
|
|
85
|
+
console.error("[nextblogkit] POST /media error:", error);
|
|
86
|
+
return chunkKDZER3PU_cjs.jsonError("INTERNAL_ERROR", "Failed to upload media", 500);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async function DELETE(request) {
|
|
90
|
+
try {
|
|
91
|
+
const authError = chunkKDZER3PU_cjs.requireAuth(request);
|
|
92
|
+
if (authError) return authError;
|
|
93
|
+
const params = chunkKDZER3PU_cjs.getSearchParams(request);
|
|
94
|
+
const id = params.id;
|
|
95
|
+
if (!id) return chunkKDZER3PU_cjs.jsonError("MISSING_ID", "Media ID is required");
|
|
96
|
+
const media = await chunkU2ROR6AY_cjs.deleteMedia(id);
|
|
97
|
+
if (!media) return chunkKDZER3PU_cjs.jsonError("NOT_FOUND", "Media not found", 404);
|
|
98
|
+
const storage = new chunkZP5XRVVH_cjs.R2StorageProvider();
|
|
99
|
+
await storage.delete(media.r2Key).catch((err) => {
|
|
100
|
+
console.error("[nextblogkit] Failed to delete from R2:", err);
|
|
101
|
+
});
|
|
102
|
+
return chunkKDZER3PU_cjs.jsonSuccess({ deleted: true });
|
|
103
|
+
} catch (error) {
|
|
104
|
+
console.error("[nextblogkit] DELETE /media error:", error);
|
|
105
|
+
return chunkKDZER3PU_cjs.jsonError("INTERNAL_ERROR", "Failed to delete media", 500);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
exports.DELETE = DELETE;
|
|
110
|
+
exports.GET = GET;
|
|
111
|
+
exports.POST = POST;
|
|
112
|
+
//# sourceMappingURL=media.cjs.map
|
|
113
|
+
//# sourceMappingURL=media.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/api/media.ts"],"names":["requireAuth","getSearchParams","listMedia","parseIntParam","jsonSuccess","jsonError","getEnvConfig","R2StorageProvider","processImage","createMedia","deleteMedia"],"mappings":"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","file":"media.cjs","sourcesContent":["import { createMedia, deleteMedia, listMedia } from '../lib/db';\nimport { R2StorageProvider } from '../lib/storage';\nimport { processImage } from '../lib/image';\nimport { getEnvConfig } from '../lib/config';\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 authError = requireAuth(request);\n if (authError) return authError;\n\n const params = getSearchParams(request);\n const result = await listMedia({\n page: parseIntParam(params.page, 1),\n limit: parseIntParam(params.limit, 20),\n mimeType: params.mimeType,\n });\n\n const page = parseIntParam(params.page, 1);\n const limit = parseIntParam(params.limit, 20);\n\n return jsonSuccess(result.media, {\n page,\n limit,\n total: result.total,\n totalPages: Math.ceil(result.total / limit),\n });\n } catch (error) {\n console.error('[nextblogkit] GET /media error:', error);\n return jsonError('INTERNAL_ERROR', 'Failed to fetch media', 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 formData = await request.formData();\n const file = formData.get('file') as File | null;\n\n if (!file) {\n return jsonError('MISSING_FILE', 'File is required');\n }\n\n const env = getEnvConfig();\n const maxSize = 10 * 1024 * 1024; // 10MB\n if (file.size > maxSize) {\n return jsonError('FILE_TOO_LARGE', 'File must be under 10MB');\n }\n\n const allowedTypes = [\n 'image/jpeg',\n 'image/png',\n 'image/gif',\n 'image/webp',\n 'image/svg+xml',\n 'image/avif',\n ];\n if (!allowedTypes.includes(file.type)) {\n return jsonError('INVALID_TYPE', `Allowed types: ${allowedTypes.join(', ')}`);\n }\n\n const buffer = Buffer.from(await file.arrayBuffer());\n const storage = new R2StorageProvider();\n\n const isImage = file.type.startsWith('image/') && file.type !== 'image/svg+xml';\n let uploadResult;\n let width: number | undefined;\n let height: number | undefined;\n\n if (isImage) {\n const processed = await processImage(buffer, file.name, storage);\n uploadResult = processed.original;\n width = processed.width;\n height = processed.height;\n } else {\n uploadResult = await storage.upload(buffer, file.name, file.type);\n }\n\n const media = await createMedia({\n filename: uploadResult.key.split('/').pop() || file.name,\n originalName: file.name,\n mimeType: uploadResult.contentType,\n size: uploadResult.size,\n width,\n height,\n r2Key: uploadResult.key,\n url: uploadResult.url,\n alt: (formData.get('alt') as string) || '',\n caption: (formData.get('caption') as string) || '',\n createdAt: new Date(),\n });\n\n return jsonSuccess(media, undefined, 201);\n } catch (error) {\n console.error('[nextblogkit] POST /media error:', error);\n return jsonError('INTERNAL_ERROR', 'Failed to upload media', 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', 'Media ID is required');\n\n const media = await deleteMedia(id);\n if (!media) return jsonError('NOT_FOUND', 'Media not found', 404);\n\n // Delete from R2\n const storage = new R2StorageProvider();\n await storage.delete(media.r2Key).catch((err) => {\n console.error('[nextblogkit] Failed to delete from R2:', err);\n });\n\n return jsonSuccess({ deleted: true });\n } catch (error) {\n console.error('[nextblogkit] DELETE /media error:', error);\n return jsonError('INTERNAL_ERROR', 'Failed to delete media', 500);\n }\n}\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
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 POST(request: Request): Promise<next_server.NextResponse<ApiErrorResponse> | next_server.NextResponse<{
|
|
12
|
+
success: boolean;
|
|
13
|
+
data: unknown;
|
|
14
|
+
meta: Record<string, unknown> | undefined;
|
|
15
|
+
}>>;
|
|
16
|
+
declare function DELETE(request: Request): Promise<next_server.NextResponse<ApiErrorResponse> | next_server.NextResponse<{
|
|
17
|
+
success: boolean;
|
|
18
|
+
data: unknown;
|
|
19
|
+
meta: Record<string, unknown> | undefined;
|
|
20
|
+
}>>;
|
|
21
|
+
|
|
22
|
+
export { DELETE, GET, POST };
|
|
@@ -0,0 +1,22 @@
|
|
|
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 POST(request: Request): Promise<next_server.NextResponse<ApiErrorResponse> | next_server.NextResponse<{
|
|
12
|
+
success: boolean;
|
|
13
|
+
data: unknown;
|
|
14
|
+
meta: Record<string, unknown> | undefined;
|
|
15
|
+
}>>;
|
|
16
|
+
declare function DELETE(request: Request): Promise<next_server.NextResponse<ApiErrorResponse> | next_server.NextResponse<{
|
|
17
|
+
success: boolean;
|
|
18
|
+
data: unknown;
|
|
19
|
+
meta: Record<string, unknown> | undefined;
|
|
20
|
+
}>>;
|
|
21
|
+
|
|
22
|
+
export { DELETE, GET, POST };
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { R2StorageProvider, processImage } from '../chunk-A2S32RZN.js';
|
|
2
|
+
import { requireAuth, getSearchParams, parseIntParam, jsonSuccess, jsonError } from '../chunk-JLPJKNRZ.js';
|
|
3
|
+
import { listMedia, getEnvConfig, createMedia, deleteMedia } from '../chunk-64HUVJOZ.js';
|
|
4
|
+
|
|
5
|
+
// src/api/media.ts
|
|
6
|
+
async function GET(request) {
|
|
7
|
+
try {
|
|
8
|
+
const authError = requireAuth(request);
|
|
9
|
+
if (authError) return authError;
|
|
10
|
+
const params = getSearchParams(request);
|
|
11
|
+
const result = await listMedia({
|
|
12
|
+
page: parseIntParam(params.page, 1),
|
|
13
|
+
limit: parseIntParam(params.limit, 20),
|
|
14
|
+
mimeType: params.mimeType
|
|
15
|
+
});
|
|
16
|
+
const page = parseIntParam(params.page, 1);
|
|
17
|
+
const limit = parseIntParam(params.limit, 20);
|
|
18
|
+
return jsonSuccess(result.media, {
|
|
19
|
+
page,
|
|
20
|
+
limit,
|
|
21
|
+
total: result.total,
|
|
22
|
+
totalPages: Math.ceil(result.total / limit)
|
|
23
|
+
});
|
|
24
|
+
} catch (error) {
|
|
25
|
+
console.error("[nextblogkit] GET /media error:", error);
|
|
26
|
+
return jsonError("INTERNAL_ERROR", "Failed to fetch media", 500);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async function POST(request) {
|
|
30
|
+
try {
|
|
31
|
+
const authError = requireAuth(request);
|
|
32
|
+
if (authError) return authError;
|
|
33
|
+
const formData = await request.formData();
|
|
34
|
+
const file = formData.get("file");
|
|
35
|
+
if (!file) {
|
|
36
|
+
return jsonError("MISSING_FILE", "File is required");
|
|
37
|
+
}
|
|
38
|
+
const env = getEnvConfig();
|
|
39
|
+
const maxSize = 10 * 1024 * 1024;
|
|
40
|
+
if (file.size > maxSize) {
|
|
41
|
+
return jsonError("FILE_TOO_LARGE", "File must be under 10MB");
|
|
42
|
+
}
|
|
43
|
+
const allowedTypes = [
|
|
44
|
+
"image/jpeg",
|
|
45
|
+
"image/png",
|
|
46
|
+
"image/gif",
|
|
47
|
+
"image/webp",
|
|
48
|
+
"image/svg+xml",
|
|
49
|
+
"image/avif"
|
|
50
|
+
];
|
|
51
|
+
if (!allowedTypes.includes(file.type)) {
|
|
52
|
+
return jsonError("INVALID_TYPE", `Allowed types: ${allowedTypes.join(", ")}`);
|
|
53
|
+
}
|
|
54
|
+
const buffer = Buffer.from(await file.arrayBuffer());
|
|
55
|
+
const storage = new R2StorageProvider();
|
|
56
|
+
const isImage = file.type.startsWith("image/") && file.type !== "image/svg+xml";
|
|
57
|
+
let uploadResult;
|
|
58
|
+
let width;
|
|
59
|
+
let height;
|
|
60
|
+
if (isImage) {
|
|
61
|
+
const processed = await processImage(buffer, file.name, storage);
|
|
62
|
+
uploadResult = processed.original;
|
|
63
|
+
width = processed.width;
|
|
64
|
+
height = processed.height;
|
|
65
|
+
} else {
|
|
66
|
+
uploadResult = await storage.upload(buffer, file.name, file.type);
|
|
67
|
+
}
|
|
68
|
+
const media = await createMedia({
|
|
69
|
+
filename: uploadResult.key.split("/").pop() || file.name,
|
|
70
|
+
originalName: file.name,
|
|
71
|
+
mimeType: uploadResult.contentType,
|
|
72
|
+
size: uploadResult.size,
|
|
73
|
+
width,
|
|
74
|
+
height,
|
|
75
|
+
r2Key: uploadResult.key,
|
|
76
|
+
url: uploadResult.url,
|
|
77
|
+
alt: formData.get("alt") || "",
|
|
78
|
+
caption: formData.get("caption") || "",
|
|
79
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
80
|
+
});
|
|
81
|
+
return jsonSuccess(media, void 0, 201);
|
|
82
|
+
} catch (error) {
|
|
83
|
+
console.error("[nextblogkit] POST /media error:", error);
|
|
84
|
+
return jsonError("INTERNAL_ERROR", "Failed to upload media", 500);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
async function DELETE(request) {
|
|
88
|
+
try {
|
|
89
|
+
const authError = requireAuth(request);
|
|
90
|
+
if (authError) return authError;
|
|
91
|
+
const params = getSearchParams(request);
|
|
92
|
+
const id = params.id;
|
|
93
|
+
if (!id) return jsonError("MISSING_ID", "Media ID is required");
|
|
94
|
+
const media = await deleteMedia(id);
|
|
95
|
+
if (!media) return jsonError("NOT_FOUND", "Media not found", 404);
|
|
96
|
+
const storage = new R2StorageProvider();
|
|
97
|
+
await storage.delete(media.r2Key).catch((err) => {
|
|
98
|
+
console.error("[nextblogkit] Failed to delete from R2:", err);
|
|
99
|
+
});
|
|
100
|
+
return jsonSuccess({ deleted: true });
|
|
101
|
+
} catch (error) {
|
|
102
|
+
console.error("[nextblogkit] DELETE /media error:", error);
|
|
103
|
+
return jsonError("INTERNAL_ERROR", "Failed to delete media", 500);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export { DELETE, GET, POST };
|
|
108
|
+
//# sourceMappingURL=media.js.map
|
|
109
|
+
//# sourceMappingURL=media.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/api/media.ts"],"names":[],"mappings":"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","file":"media.js","sourcesContent":["import { createMedia, deleteMedia, listMedia } from '../lib/db';\nimport { R2StorageProvider } from '../lib/storage';\nimport { processImage } from '../lib/image';\nimport { getEnvConfig } from '../lib/config';\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 authError = requireAuth(request);\n if (authError) return authError;\n\n const params = getSearchParams(request);\n const result = await listMedia({\n page: parseIntParam(params.page, 1),\n limit: parseIntParam(params.limit, 20),\n mimeType: params.mimeType,\n });\n\n const page = parseIntParam(params.page, 1);\n const limit = parseIntParam(params.limit, 20);\n\n return jsonSuccess(result.media, {\n page,\n limit,\n total: result.total,\n totalPages: Math.ceil(result.total / limit),\n });\n } catch (error) {\n console.error('[nextblogkit] GET /media error:', error);\n return jsonError('INTERNAL_ERROR', 'Failed to fetch media', 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 formData = await request.formData();\n const file = formData.get('file') as File | null;\n\n if (!file) {\n return jsonError('MISSING_FILE', 'File is required');\n }\n\n const env = getEnvConfig();\n const maxSize = 10 * 1024 * 1024; // 10MB\n if (file.size > maxSize) {\n return jsonError('FILE_TOO_LARGE', 'File must be under 10MB');\n }\n\n const allowedTypes = [\n 'image/jpeg',\n 'image/png',\n 'image/gif',\n 'image/webp',\n 'image/svg+xml',\n 'image/avif',\n ];\n if (!allowedTypes.includes(file.type)) {\n return jsonError('INVALID_TYPE', `Allowed types: ${allowedTypes.join(', ')}`);\n }\n\n const buffer = Buffer.from(await file.arrayBuffer());\n const storage = new R2StorageProvider();\n\n const isImage = file.type.startsWith('image/') && file.type !== 'image/svg+xml';\n let uploadResult;\n let width: number | undefined;\n let height: number | undefined;\n\n if (isImage) {\n const processed = await processImage(buffer, file.name, storage);\n uploadResult = processed.original;\n width = processed.width;\n height = processed.height;\n } else {\n uploadResult = await storage.upload(buffer, file.name, file.type);\n }\n\n const media = await createMedia({\n filename: uploadResult.key.split('/').pop() || file.name,\n originalName: file.name,\n mimeType: uploadResult.contentType,\n size: uploadResult.size,\n width,\n height,\n r2Key: uploadResult.key,\n url: uploadResult.url,\n alt: (formData.get('alt') as string) || '',\n caption: (formData.get('caption') as string) || '',\n createdAt: new Date(),\n });\n\n return jsonSuccess(media, undefined, 201);\n } catch (error) {\n console.error('[nextblogkit] POST /media error:', error);\n return jsonError('INTERNAL_ERROR', 'Failed to upload media', 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', 'Media ID is required');\n\n const media = await deleteMedia(id);\n if (!media) return jsonError('NOT_FOUND', 'Media not found', 404);\n\n // Delete from R2\n const storage = new R2StorageProvider();\n await storage.delete(media.r2Key).catch((err) => {\n console.error('[nextblogkit] Failed to delete from R2:', err);\n });\n\n return jsonSuccess({ deleted: true });\n } catch (error) {\n console.error('[nextblogkit] DELETE /media error:', error);\n return jsonError('INTERNAL_ERROR', 'Failed to delete media', 500);\n }\n}\n"]}
|
|
@@ -0,0 +1,103 @@
|
|
|
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/posts.ts
|
|
8
|
+
async function GET(request) {
|
|
9
|
+
try {
|
|
10
|
+
const params = chunkKDZER3PU_cjs.getSearchParams(request);
|
|
11
|
+
if (params.slug) {
|
|
12
|
+
const post = await chunkU2ROR6AY_cjs.getPostBySlug(params.slug);
|
|
13
|
+
if (!post) return chunkKDZER3PU_cjs.jsonError("NOT_FOUND", "Post not found", 404);
|
|
14
|
+
return chunkKDZER3PU_cjs.jsonSuccess(post);
|
|
15
|
+
}
|
|
16
|
+
if (params.id) {
|
|
17
|
+
const post = await chunkU2ROR6AY_cjs.getPostById(params.id);
|
|
18
|
+
if (!post) return chunkKDZER3PU_cjs.jsonError("NOT_FOUND", "Post not found", 404);
|
|
19
|
+
return chunkKDZER3PU_cjs.jsonSuccess(post);
|
|
20
|
+
}
|
|
21
|
+
const result = await chunkU2ROR6AY_cjs.listPosts({
|
|
22
|
+
page: chunkKDZER3PU_cjs.parseIntParam(params.page, 1),
|
|
23
|
+
limit: chunkKDZER3PU_cjs.parseIntParam(params.limit, 10),
|
|
24
|
+
category: params.category,
|
|
25
|
+
tag: params.tag,
|
|
26
|
+
status: params.status,
|
|
27
|
+
search: params.q || params.search,
|
|
28
|
+
sortBy: params.sortBy || "publishedAt",
|
|
29
|
+
sortOrder: params.sortOrder || "desc"
|
|
30
|
+
});
|
|
31
|
+
const page = chunkKDZER3PU_cjs.parseIntParam(params.page, 1);
|
|
32
|
+
const limit = chunkKDZER3PU_cjs.parseIntParam(params.limit, 10);
|
|
33
|
+
return chunkKDZER3PU_cjs.jsonSuccess(result.posts, {
|
|
34
|
+
page,
|
|
35
|
+
limit,
|
|
36
|
+
total: result.total,
|
|
37
|
+
totalPages: Math.ceil(result.total / limit)
|
|
38
|
+
});
|
|
39
|
+
} catch (error) {
|
|
40
|
+
console.error("[nextblogkit] GET /posts error:", error);
|
|
41
|
+
return chunkKDZER3PU_cjs.jsonError("INTERNAL_ERROR", "Failed to fetch posts", 500);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async function POST(request) {
|
|
45
|
+
try {
|
|
46
|
+
const authError = chunkKDZER3PU_cjs.requireAuth(request);
|
|
47
|
+
if (authError) return authError;
|
|
48
|
+
const body = await request.json();
|
|
49
|
+
const parsed = chunkN5MKAD7J_cjs.CreatePostSchema.safeParse(body);
|
|
50
|
+
if (!parsed.success) {
|
|
51
|
+
const errors = parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`);
|
|
52
|
+
return chunkKDZER3PU_cjs.jsonError("VALIDATION_ERROR", errors.join("; "));
|
|
53
|
+
}
|
|
54
|
+
const post = await chunkU2ROR6AY_cjs.createPost(parsed.data);
|
|
55
|
+
return chunkKDZER3PU_cjs.jsonSuccess(post, void 0, 201);
|
|
56
|
+
} catch (error) {
|
|
57
|
+
console.error("[nextblogkit] POST /posts error:", error);
|
|
58
|
+
return chunkKDZER3PU_cjs.jsonError("INTERNAL_ERROR", "Failed to create post", 500);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async function PUT(request) {
|
|
62
|
+
try {
|
|
63
|
+
const authError = chunkKDZER3PU_cjs.requireAuth(request);
|
|
64
|
+
if (authError) return authError;
|
|
65
|
+
const params = chunkKDZER3PU_cjs.getSearchParams(request);
|
|
66
|
+
const id = params.id;
|
|
67
|
+
if (!id) return chunkKDZER3PU_cjs.jsonError("MISSING_ID", "Post ID is required");
|
|
68
|
+
const body = await request.json();
|
|
69
|
+
const parsed = chunkN5MKAD7J_cjs.UpdatePostSchema.safeParse(body);
|
|
70
|
+
if (!parsed.success) {
|
|
71
|
+
const errors = parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`);
|
|
72
|
+
return chunkKDZER3PU_cjs.jsonError("VALIDATION_ERROR", errors.join("; "));
|
|
73
|
+
}
|
|
74
|
+
const post = await chunkU2ROR6AY_cjs.updatePost(id, parsed.data);
|
|
75
|
+
if (!post) return chunkKDZER3PU_cjs.jsonError("NOT_FOUND", "Post not found", 404);
|
|
76
|
+
return chunkKDZER3PU_cjs.jsonSuccess(post);
|
|
77
|
+
} catch (error) {
|
|
78
|
+
console.error("[nextblogkit] PUT /posts error:", error);
|
|
79
|
+
return chunkKDZER3PU_cjs.jsonError("INTERNAL_ERROR", "Failed to update post", 500);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async function DELETE(request) {
|
|
83
|
+
try {
|
|
84
|
+
const authError = chunkKDZER3PU_cjs.requireAuth(request);
|
|
85
|
+
if (authError) return authError;
|
|
86
|
+
const params = chunkKDZER3PU_cjs.getSearchParams(request);
|
|
87
|
+
const id = params.id;
|
|
88
|
+
if (!id) return chunkKDZER3PU_cjs.jsonError("MISSING_ID", "Post ID is required");
|
|
89
|
+
const deleted = await chunkU2ROR6AY_cjs.deletePost(id);
|
|
90
|
+
if (!deleted) return chunkKDZER3PU_cjs.jsonError("NOT_FOUND", "Post not found", 404);
|
|
91
|
+
return chunkKDZER3PU_cjs.jsonSuccess({ deleted: true });
|
|
92
|
+
} catch (error) {
|
|
93
|
+
console.error("[nextblogkit] DELETE /posts error:", error);
|
|
94
|
+
return chunkKDZER3PU_cjs.jsonError("INTERNAL_ERROR", "Failed to delete post", 500);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
exports.DELETE = DELETE;
|
|
99
|
+
exports.GET = GET;
|
|
100
|
+
exports.POST = POST;
|
|
101
|
+
exports.PUT = PUT;
|
|
102
|
+
//# sourceMappingURL=posts.cjs.map
|
|
103
|
+
//# sourceMappingURL=posts.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/api/posts.ts"],"names":["getSearchParams","getPostBySlug","jsonError","jsonSuccess","getPostById","listPosts","parseIntParam","requireAuth","CreatePostSchema","createPost","UpdatePostSchema","updatePost","deletePost"],"mappings":"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","file":"posts.cjs","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"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { A as ApiErrorResponse } from '../types-CBEEBR4A.cjs';
|
|
2
|
+
import { NextResponse } from 'next/server';
|
|
3
|
+
import 'zod';
|
|
4
|
+
import 'mongodb';
|
|
5
|
+
|
|
6
|
+
declare function GET(request: Request): Promise<NextResponse<ApiErrorResponse> | NextResponse<{
|
|
7
|
+
success: boolean;
|
|
8
|
+
data: unknown;
|
|
9
|
+
meta: Record<string, unknown> | undefined;
|
|
10
|
+
}>>;
|
|
11
|
+
declare function POST(request: Request): Promise<NextResponse<ApiErrorResponse> | NextResponse<{
|
|
12
|
+
success: boolean;
|
|
13
|
+
data: unknown;
|
|
14
|
+
meta: Record<string, unknown> | undefined;
|
|
15
|
+
}>>;
|
|
16
|
+
declare function PUT(request: Request): Promise<NextResponse<ApiErrorResponse> | NextResponse<{
|
|
17
|
+
success: boolean;
|
|
18
|
+
data: unknown;
|
|
19
|
+
meta: Record<string, unknown> | undefined;
|
|
20
|
+
}>>;
|
|
21
|
+
declare function DELETE(request: Request): Promise<NextResponse<ApiErrorResponse> | NextResponse<{
|
|
22
|
+
success: boolean;
|
|
23
|
+
data: unknown;
|
|
24
|
+
meta: Record<string, unknown> | undefined;
|
|
25
|
+
}>>;
|
|
26
|
+
|
|
27
|
+
export { DELETE, GET, POST, PUT };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { A as ApiErrorResponse } from '../types-CBEEBR4A.js';
|
|
2
|
+
import { NextResponse } from 'next/server';
|
|
3
|
+
import 'zod';
|
|
4
|
+
import 'mongodb';
|
|
5
|
+
|
|
6
|
+
declare function GET(request: Request): Promise<NextResponse<ApiErrorResponse> | NextResponse<{
|
|
7
|
+
success: boolean;
|
|
8
|
+
data: unknown;
|
|
9
|
+
meta: Record<string, unknown> | undefined;
|
|
10
|
+
}>>;
|
|
11
|
+
declare function POST(request: Request): Promise<NextResponse<ApiErrorResponse> | NextResponse<{
|
|
12
|
+
success: boolean;
|
|
13
|
+
data: unknown;
|
|
14
|
+
meta: Record<string, unknown> | undefined;
|
|
15
|
+
}>>;
|
|
16
|
+
declare function PUT(request: Request): Promise<NextResponse<ApiErrorResponse> | NextResponse<{
|
|
17
|
+
success: boolean;
|
|
18
|
+
data: unknown;
|
|
19
|
+
meta: Record<string, unknown> | undefined;
|
|
20
|
+
}>>;
|
|
21
|
+
declare function DELETE(request: Request): Promise<NextResponse<ApiErrorResponse> | NextResponse<{
|
|
22
|
+
success: boolean;
|
|
23
|
+
data: unknown;
|
|
24
|
+
meta: Record<string, unknown> | undefined;
|
|
25
|
+
}>>;
|
|
26
|
+
|
|
27
|
+
export { DELETE, GET, POST, PUT };
|