@delmaredigital/payload-puck 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/LICENSE +73 -0
  2. package/README.md +1580 -0
  3. package/dist/AccordionClient.d.mts +24 -0
  4. package/dist/AccordionClient.d.ts +24 -0
  5. package/dist/AccordionClient.js +786 -0
  6. package/dist/AccordionClient.js.map +1 -0
  7. package/dist/AccordionClient.mjs +784 -0
  8. package/dist/AccordionClient.mjs.map +1 -0
  9. package/dist/AnimatedWrapper.d.mts +30 -0
  10. package/dist/AnimatedWrapper.d.ts +30 -0
  11. package/dist/AnimatedWrapper.js +379 -0
  12. package/dist/AnimatedWrapper.js.map +1 -0
  13. package/dist/AnimatedWrapper.mjs +377 -0
  14. package/dist/AnimatedWrapper.mjs.map +1 -0
  15. package/dist/admin/client.d.mts +108 -0
  16. package/dist/admin/client.d.ts +108 -0
  17. package/dist/admin/client.js +177 -0
  18. package/dist/admin/client.js.map +1 -0
  19. package/dist/admin/client.mjs +173 -0
  20. package/dist/admin/client.mjs.map +1 -0
  21. package/dist/admin/index.d.mts +157 -0
  22. package/dist/admin/index.d.ts +157 -0
  23. package/dist/admin/index.js +31 -0
  24. package/dist/admin/index.js.map +1 -0
  25. package/dist/admin/index.mjs +29 -0
  26. package/dist/admin/index.mjs.map +1 -0
  27. package/dist/api/index.d.mts +460 -0
  28. package/dist/api/index.d.ts +460 -0
  29. package/dist/api/index.js +588 -0
  30. package/dist/api/index.js.map +1 -0
  31. package/dist/api/index.mjs +578 -0
  32. package/dist/api/index.mjs.map +1 -0
  33. package/dist/components/index.css +339 -0
  34. package/dist/components/index.css.map +1 -0
  35. package/dist/components/index.d.mts +222 -0
  36. package/dist/components/index.d.ts +222 -0
  37. package/dist/components/index.js +9177 -0
  38. package/dist/components/index.js.map +1 -0
  39. package/dist/components/index.mjs +9130 -0
  40. package/dist/components/index.mjs.map +1 -0
  41. package/dist/config/config.editor.css +339 -0
  42. package/dist/config/config.editor.css.map +1 -0
  43. package/dist/config/config.editor.d.mts +153 -0
  44. package/dist/config/config.editor.d.ts +153 -0
  45. package/dist/config/config.editor.js +9400 -0
  46. package/dist/config/config.editor.js.map +1 -0
  47. package/dist/config/config.editor.mjs +9368 -0
  48. package/dist/config/config.editor.mjs.map +1 -0
  49. package/dist/config/index.d.mts +68 -0
  50. package/dist/config/index.d.ts +68 -0
  51. package/dist/config/index.js +2017 -0
  52. package/dist/config/index.js.map +1 -0
  53. package/dist/config/index.mjs +1991 -0
  54. package/dist/config/index.mjs.map +1 -0
  55. package/dist/editor/index.d.mts +784 -0
  56. package/dist/editor/index.d.ts +784 -0
  57. package/dist/editor/index.js +4517 -0
  58. package/dist/editor/index.js.map +1 -0
  59. package/dist/editor/index.mjs +4483 -0
  60. package/dist/editor/index.mjs.map +1 -0
  61. package/dist/fields/index.css +339 -0
  62. package/dist/fields/index.css.map +1 -0
  63. package/dist/fields/index.d.mts +600 -0
  64. package/dist/fields/index.d.ts +600 -0
  65. package/dist/fields/index.js +7739 -0
  66. package/dist/fields/index.js.map +1 -0
  67. package/dist/fields/index.mjs +7590 -0
  68. package/dist/fields/index.mjs.map +1 -0
  69. package/dist/index-CQu6SzDg.d.mts +327 -0
  70. package/dist/index-CoUQnyC3.d.ts +327 -0
  71. package/dist/index.d.mts +6 -0
  72. package/dist/index.d.ts +6 -0
  73. package/dist/index.js +569 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/index.mjs +555 -0
  76. package/dist/index.mjs.map +1 -0
  77. package/dist/layouts/index.d.mts +96 -0
  78. package/dist/layouts/index.d.ts +96 -0
  79. package/dist/layouts/index.js +394 -0
  80. package/dist/layouts/index.js.map +1 -0
  81. package/dist/layouts/index.mjs +378 -0
  82. package/dist/layouts/index.mjs.map +1 -0
  83. package/dist/plugin/index.d.mts +289 -0
  84. package/dist/plugin/index.d.ts +289 -0
  85. package/dist/plugin/index.js +569 -0
  86. package/dist/plugin/index.js.map +1 -0
  87. package/dist/plugin/index.mjs +555 -0
  88. package/dist/plugin/index.mjs.map +1 -0
  89. package/dist/render/index.d.mts +109 -0
  90. package/dist/render/index.d.ts +109 -0
  91. package/dist/render/index.js +2146 -0
  92. package/dist/render/index.js.map +1 -0
  93. package/dist/render/index.mjs +2123 -0
  94. package/dist/render/index.mjs.map +1 -0
  95. package/dist/shared-DMAF1AcH.d.mts +545 -0
  96. package/dist/shared-DMAF1AcH.d.ts +545 -0
  97. package/dist/theme/index.d.mts +155 -0
  98. package/dist/theme/index.d.ts +155 -0
  99. package/dist/theme/index.js +201 -0
  100. package/dist/theme/index.js.map +1 -0
  101. package/dist/theme/index.mjs +186 -0
  102. package/dist/theme/index.mjs.map +1 -0
  103. package/dist/types-D7D3rZ1J.d.mts +116 -0
  104. package/dist/types-D7D3rZ1J.d.ts +116 -0
  105. package/dist/types-_6MvjyKv.d.mts +104 -0
  106. package/dist/types-_6MvjyKv.d.ts +104 -0
  107. package/dist/utils/index.d.mts +267 -0
  108. package/dist/utils/index.d.ts +267 -0
  109. package/dist/utils/index.js +426 -0
  110. package/dist/utils/index.js.map +1 -0
  111. package/dist/utils/index.mjs +412 -0
  112. package/dist/utils/index.mjs.map +1 -0
  113. package/dist/utils-DaRs9t0J.d.mts +85 -0
  114. package/dist/utils-gAvt0Vhw.d.ts +85 -0
  115. package/examples/README.md +240 -0
  116. package/examples/api/puck/pages/[id]/route.ts +64 -0
  117. package/examples/api/puck/pages/[id]/versions/route.ts +47 -0
  118. package/examples/api/puck/pages/route.ts +45 -0
  119. package/examples/app/(frontend)/page.tsx +94 -0
  120. package/examples/app/[...slug]/page.tsx +101 -0
  121. package/examples/app/pages/[id]/edit/page.tsx +148 -0
  122. package/examples/components/CustomBanner.tsx +368 -0
  123. package/examples/config/custom-config.ts +223 -0
  124. package/examples/config/payload.config.example.ts +64 -0
  125. package/examples/lib/puck-layouts.ts +258 -0
  126. package/examples/lib/puck-theme.ts +94 -0
  127. package/examples/styles/puck-theme.css +171 -0
  128. package/package.json +157 -0
@@ -0,0 +1,578 @@
1
+ import { NextResponse } from 'next/server';
2
+ import { getPayload } from 'payload';
3
+
4
+ // src/api/createPuckApiRoutes.ts
5
+ var DEFAULT_PUCK_DATA = {
6
+ root: {
7
+ props: {
8
+ title: ""
9
+ }
10
+ },
11
+ content: [],
12
+ zones: {}
13
+ };
14
+ function createPuckApiRoutes(routeConfig) {
15
+ const {
16
+ collection = "pages",
17
+ payloadConfig,
18
+ auth,
19
+ defaultPuckData = DEFAULT_PUCK_DATA,
20
+ enableDrafts = true,
21
+ onError
22
+ } = routeConfig;
23
+ async function GET(request, _context) {
24
+ try {
25
+ const authResult = await auth.authenticate(request);
26
+ if (!authResult.authenticated || !authResult.user) {
27
+ return NextResponse.json(
28
+ { error: authResult.error || "Unauthorized" },
29
+ { status: 401 }
30
+ );
31
+ }
32
+ if (auth.canList) {
33
+ const permission = await auth.canList(authResult.user);
34
+ if (!permission.allowed) {
35
+ return NextResponse.json(
36
+ { error: permission.error || "Forbidden" },
37
+ { status: 403 }
38
+ );
39
+ }
40
+ }
41
+ const { searchParams } = new URL(request.url);
42
+ const page = parseInt(searchParams.get("page") || "1", 10);
43
+ const limit = Math.min(parseInt(searchParams.get("limit") || "10", 10), 100);
44
+ const search = searchParams.get("search") || "";
45
+ const status = searchParams.get("status");
46
+ const editorVersion = searchParams.get("editorVersion");
47
+ const sort = searchParams.get("sort") || "-updatedAt";
48
+ const config = await payloadConfig;
49
+ const payload = await getPayload({ config });
50
+ const conditions = [];
51
+ if (search) {
52
+ conditions.push({ title: { contains: search } });
53
+ }
54
+ if (status && status !== "all") {
55
+ conditions.push({ _status: { equals: status } });
56
+ }
57
+ if (editorVersion && editorVersion !== "all") {
58
+ conditions.push({ editorVersion: { equals: editorVersion } });
59
+ }
60
+ const where = conditions.length > 0 ? conditions.length === 1 ? conditions[0] : { and: conditions } : void 0;
61
+ const result = await payload.find({
62
+ collection,
63
+ page,
64
+ limit,
65
+ sort,
66
+ where
67
+ });
68
+ return NextResponse.json(result);
69
+ } catch (error) {
70
+ if (onError) {
71
+ onError(error, { operation: "list", request });
72
+ }
73
+ console.error("Error listing pages:", error);
74
+ return NextResponse.json(
75
+ { error: "Failed to list pages" },
76
+ { status: 500 }
77
+ );
78
+ }
79
+ }
80
+ async function POST(request, _context) {
81
+ try {
82
+ const authResult = await auth.authenticate(request);
83
+ if (!authResult.authenticated || !authResult.user) {
84
+ return NextResponse.json(
85
+ { error: authResult.error || "Unauthorized" },
86
+ { status: 401 }
87
+ );
88
+ }
89
+ if (auth.canCreate) {
90
+ const permission = await auth.canCreate(authResult.user);
91
+ if (!permission.allowed) {
92
+ return NextResponse.json(
93
+ { error: permission.error || "Forbidden" },
94
+ { status: 403 }
95
+ );
96
+ }
97
+ }
98
+ const body = await request.json();
99
+ const { title, slug, puckData, status = "draft" } = body;
100
+ if (!title || !slug) {
101
+ return NextResponse.json(
102
+ { error: "Title and slug are required" },
103
+ { status: 400 }
104
+ );
105
+ }
106
+ const config = await payloadConfig;
107
+ const payload = await getPayload({ config });
108
+ const existing = await payload.find({
109
+ collection,
110
+ where: { slug: { equals: slug } },
111
+ limit: 1
112
+ });
113
+ if (existing.docs.length > 0) {
114
+ return NextResponse.json(
115
+ { error: "A page with this slug already exists" },
116
+ { status: 409 }
117
+ );
118
+ }
119
+ const initialPuckData = puckData || {
120
+ ...defaultPuckData,
121
+ root: {
122
+ ...defaultPuckData.root,
123
+ props: {
124
+ ...defaultPuckData.root?.props,
125
+ title
126
+ }
127
+ }
128
+ };
129
+ const newPage = await payload.create({
130
+ collection,
131
+ draft: enableDrafts,
132
+ data: {
133
+ title,
134
+ slug,
135
+ editorVersion: "puck",
136
+ puckData: initialPuckData,
137
+ _status: status
138
+ }
139
+ });
140
+ return NextResponse.json({ doc: newPage }, { status: 201 });
141
+ } catch (error) {
142
+ if (onError) {
143
+ onError(error, { operation: "create", request });
144
+ }
145
+ console.error("Error creating page:", error);
146
+ return NextResponse.json(
147
+ { error: "Failed to create page" },
148
+ { status: 500 }
149
+ );
150
+ }
151
+ }
152
+ return { GET, POST };
153
+ }
154
+
155
+ // src/api/utils/mapRootProps.ts
156
+ var DEFAULT_ROOT_PROPS_MAPPINGS = [
157
+ // Core page fields
158
+ { from: "title", to: "title" },
159
+ { from: "slug", to: "slug" },
160
+ { from: "pageLayout", to: "pageLayout" },
161
+ { from: "pageType", to: "pageType" },
162
+ { from: "isHomepage", to: "isHomepage" },
163
+ // SEO/Meta fields (uses official @payloadcms/plugin-seo convention)
164
+ { from: "metaTitle", to: "meta.title" },
165
+ { from: "metaDescription", to: "meta.description" },
166
+ { from: "noindex", to: "meta.noindex" },
167
+ { from: "nofollow", to: "meta.nofollow" },
168
+ { from: "excludeFromSitemap", to: "meta.excludeFromSitemap" },
169
+ // Conversion tracking fields
170
+ { from: "isConversionPage", to: "conversionTracking.isConversionPage" },
171
+ { from: "conversionType", to: "conversionTracking.conversionType" },
172
+ { from: "conversionValue", to: "conversionTracking.conversionValue" }
173
+ ];
174
+ function setNestedValue(obj, path, value) {
175
+ const keys = path.split(".");
176
+ let current = obj;
177
+ for (let i = 0; i < keys.length - 1; i++) {
178
+ const key = keys[i];
179
+ if (!(key in current) || typeof current[key] !== "object") {
180
+ current[key] = {};
181
+ }
182
+ current = current[key];
183
+ }
184
+ const finalKey = keys[keys.length - 1];
185
+ current[finalKey] = value;
186
+ }
187
+ function getNestedValue(obj, path) {
188
+ const keys = path.split(".");
189
+ let current = obj;
190
+ for (const key of keys) {
191
+ if (current === null || current === void 0) {
192
+ return void 0;
193
+ }
194
+ if (typeof current !== "object") {
195
+ return void 0;
196
+ }
197
+ current = current[key];
198
+ }
199
+ return current;
200
+ }
201
+ function mergeMappings(customMappings) {
202
+ if (!customMappings || customMappings.length === 0) {
203
+ return DEFAULT_ROOT_PROPS_MAPPINGS;
204
+ }
205
+ const mappingMap = /* @__PURE__ */ new Map();
206
+ for (const mapping of DEFAULT_ROOT_PROPS_MAPPINGS) {
207
+ mappingMap.set(mapping.from, mapping);
208
+ }
209
+ for (const mapping of customMappings) {
210
+ mappingMap.set(mapping.from, mapping);
211
+ }
212
+ return Array.from(mappingMap.values());
213
+ }
214
+ function mapRootPropsToPayloadFields(rootProps, customMappings) {
215
+ const mappings = mergeMappings(customMappings);
216
+ const result = {};
217
+ for (const mapping of mappings) {
218
+ const value = rootProps[mapping.from];
219
+ if (value === void 0) {
220
+ continue;
221
+ }
222
+ const transformedValue = mapping.transform ? mapping.transform(value) : value;
223
+ setNestedValue(result, mapping.to, transformedValue);
224
+ }
225
+ return result;
226
+ }
227
+ function deepMerge(target, source) {
228
+ for (const key of Object.keys(source)) {
229
+ const sourceValue = source[key];
230
+ const targetValue = target[key];
231
+ if (sourceValue !== null && typeof sourceValue === "object" && !Array.isArray(sourceValue) && targetValue !== null && typeof targetValue === "object" && !Array.isArray(targetValue)) {
232
+ target[key] = deepMerge(
233
+ targetValue,
234
+ sourceValue
235
+ );
236
+ } else {
237
+ target[key] = sourceValue;
238
+ }
239
+ }
240
+ return target;
241
+ }
242
+
243
+ // src/api/createPuckApiRoutesWithId.ts
244
+ function createPuckApiRoutesWithId(routeConfig) {
245
+ const {
246
+ collection = "pages",
247
+ payloadConfig,
248
+ auth,
249
+ rootPropsMapping,
250
+ onError
251
+ } = routeConfig;
252
+ async function GET(request, context) {
253
+ try {
254
+ const params = await context.params;
255
+ const id = params.id;
256
+ if (!id) {
257
+ return NextResponse.json(
258
+ { error: "Page ID is required" },
259
+ { status: 400 }
260
+ );
261
+ }
262
+ const authResult = await auth.authenticate(request);
263
+ if (!authResult.authenticated || !authResult.user) {
264
+ return NextResponse.json(
265
+ { error: authResult.error || "Unauthorized" },
266
+ { status: 401 }
267
+ );
268
+ }
269
+ if (auth.canView) {
270
+ const permission = await auth.canView(authResult.user, id);
271
+ if (!permission.allowed) {
272
+ return NextResponse.json(
273
+ { error: permission.error || "Forbidden" },
274
+ { status: 403 }
275
+ );
276
+ }
277
+ }
278
+ const config = await payloadConfig;
279
+ const payload = await getPayload({ config });
280
+ const url = new URL(request.url);
281
+ const wantsDraft = url.searchParams.get("draft") !== "false";
282
+ const page = await payload.findByID({
283
+ collection,
284
+ id,
285
+ draft: wantsDraft
286
+ // Load draft version by default for editing
287
+ });
288
+ if (!page) {
289
+ return NextResponse.json({ error: "Page not found" }, { status: 404 });
290
+ }
291
+ return NextResponse.json({ doc: page });
292
+ } catch (error) {
293
+ const params = await context.params;
294
+ if (onError) {
295
+ onError(error, { operation: "read", request, pageId: params.id });
296
+ }
297
+ console.error("Error fetching page:", error);
298
+ return NextResponse.json(
299
+ { error: "Failed to fetch page" },
300
+ { status: 500 }
301
+ );
302
+ }
303
+ }
304
+ async function PATCH(request, context) {
305
+ try {
306
+ const params = await context.params;
307
+ const id = params.id;
308
+ if (!id) {
309
+ return NextResponse.json(
310
+ { error: "Page ID is required" },
311
+ { status: 400 }
312
+ );
313
+ }
314
+ const authResult = await auth.authenticate(request);
315
+ if (!authResult.authenticated || !authResult.user) {
316
+ return NextResponse.json(
317
+ { error: authResult.error || "Unauthorized" },
318
+ { status: 401 }
319
+ );
320
+ }
321
+ if (auth.canEdit) {
322
+ const permission = await auth.canEdit(authResult.user, id);
323
+ if (!permission.allowed) {
324
+ return NextResponse.json(
325
+ { error: permission.error || "Forbidden" },
326
+ { status: 403 }
327
+ );
328
+ }
329
+ }
330
+ const body = await request.json();
331
+ const { puckData, title, slug, status, draft } = body;
332
+ if (status === "published") {
333
+ const canPublish = auth.canPublish || auth.canEdit;
334
+ if (canPublish) {
335
+ const permission = await canPublish(authResult.user, id);
336
+ if (!permission.allowed) {
337
+ return NextResponse.json(
338
+ { error: permission.error || "Not authorized to publish pages" },
339
+ { status: 403 }
340
+ );
341
+ }
342
+ }
343
+ }
344
+ const config = await payloadConfig;
345
+ const payload = await getPayload({ config });
346
+ const rootProps = puckData?.root?.props || {};
347
+ const updateData = {
348
+ editorVersion: "puck"
349
+ };
350
+ if (puckData) {
351
+ updateData.puckData = puckData;
352
+ }
353
+ const mappedFields = mapRootPropsToPayloadFields(rootProps, rootPropsMapping);
354
+ deepMerge(updateData, mappedFields);
355
+ if (title !== void 0) {
356
+ updateData.title = title;
357
+ }
358
+ if (slug !== void 0) {
359
+ updateData.slug = slug;
360
+ }
361
+ if (status) {
362
+ updateData._status = status;
363
+ }
364
+ const updatedPage = await payload.update({
365
+ collection,
366
+ id,
367
+ data: updateData,
368
+ draft: draft === true
369
+ });
370
+ return NextResponse.json({ doc: updatedPage });
371
+ } catch (error) {
372
+ const params = await context.params;
373
+ if (onError) {
374
+ onError(error, { operation: "update", request, pageId: params.id });
375
+ }
376
+ console.error("Error updating page:", error);
377
+ if (error instanceof Error && error.name === "ValidationError") {
378
+ const validationError = error;
379
+ const fieldErrors = validationError.data?.errors || [];
380
+ const slugError = fieldErrors.find((e) => e.field === "slug");
381
+ if (slugError) {
382
+ return NextResponse.json(
383
+ {
384
+ error: "A page with this slug already exists. Please choose a different slug.",
385
+ field: "slug",
386
+ details: fieldErrors
387
+ },
388
+ { status: 400 }
389
+ );
390
+ }
391
+ return NextResponse.json(
392
+ {
393
+ error: `Validation failed: ${fieldErrors.map((e) => e.message || e.field).join(", ")}`,
394
+ details: fieldErrors
395
+ },
396
+ { status: 400 }
397
+ );
398
+ }
399
+ return NextResponse.json(
400
+ { error: "Failed to update page" },
401
+ { status: 500 }
402
+ );
403
+ }
404
+ }
405
+ async function DELETE(request, context) {
406
+ try {
407
+ const params = await context.params;
408
+ const id = params.id;
409
+ if (!id) {
410
+ return NextResponse.json(
411
+ { error: "Page ID is required" },
412
+ { status: 400 }
413
+ );
414
+ }
415
+ const authResult = await auth.authenticate(request);
416
+ if (!authResult.authenticated || !authResult.user) {
417
+ return NextResponse.json(
418
+ { error: authResult.error || "Unauthorized" },
419
+ { status: 401 }
420
+ );
421
+ }
422
+ if (auth.canDelete) {
423
+ const permission = await auth.canDelete(authResult.user, id);
424
+ if (!permission.allowed) {
425
+ return NextResponse.json(
426
+ { error: permission.error || "Forbidden" },
427
+ { status: 403 }
428
+ );
429
+ }
430
+ }
431
+ const config = await payloadConfig;
432
+ const payload = await getPayload({ config });
433
+ await payload.delete({
434
+ collection,
435
+ id
436
+ });
437
+ return NextResponse.json({ success: true });
438
+ } catch (error) {
439
+ const params = await context.params;
440
+ if (onError) {
441
+ onError(error, { operation: "delete", request, pageId: params.id });
442
+ }
443
+ console.error("Error deleting page:", error);
444
+ return NextResponse.json(
445
+ { error: "Failed to delete page" },
446
+ { status: 500 }
447
+ );
448
+ }
449
+ }
450
+ return { GET, PATCH, DELETE };
451
+ }
452
+ function createPuckApiRoutesVersions(routeConfig) {
453
+ const {
454
+ collection = "pages",
455
+ payloadConfig,
456
+ auth,
457
+ onError
458
+ } = routeConfig;
459
+ async function GET(request, context) {
460
+ try {
461
+ const params = await context.params;
462
+ const id = params.id;
463
+ if (!id) {
464
+ return NextResponse.json(
465
+ { error: "Page ID is required" },
466
+ { status: 400 }
467
+ );
468
+ }
469
+ const authResult = await auth.authenticate(request);
470
+ if (!authResult.authenticated || !authResult.user) {
471
+ return NextResponse.json(
472
+ { error: authResult.error || "Unauthorized" },
473
+ { status: 401 }
474
+ );
475
+ }
476
+ if (auth.canView) {
477
+ const permission = await auth.canView(authResult.user, id);
478
+ if (!permission.allowed) {
479
+ return NextResponse.json(
480
+ { error: permission.error || "Forbidden" },
481
+ { status: 403 }
482
+ );
483
+ }
484
+ }
485
+ const config = await payloadConfig;
486
+ const payload = await getPayload({ config });
487
+ const url = new URL(request.url);
488
+ const limit = parseInt(url.searchParams.get("limit") || "20", 10);
489
+ const page = parseInt(url.searchParams.get("page") || "1", 10);
490
+ const versions = await payload.findVersions({
491
+ collection,
492
+ where: {
493
+ parent: { equals: id }
494
+ },
495
+ sort: "-updatedAt",
496
+ limit,
497
+ page
498
+ });
499
+ return NextResponse.json({
500
+ docs: versions.docs,
501
+ totalDocs: versions.totalDocs,
502
+ totalPages: versions.totalPages,
503
+ page: versions.page,
504
+ limit: versions.limit,
505
+ hasPrevPage: versions.hasPrevPage,
506
+ hasNextPage: versions.hasNextPage
507
+ });
508
+ } catch (error) {
509
+ const params = await context.params;
510
+ if (onError) {
511
+ onError(error, { operation: "listVersions", request, pageId: params.id });
512
+ }
513
+ console.error("Error fetching versions:", error);
514
+ return NextResponse.json(
515
+ { error: "Failed to fetch versions" },
516
+ { status: 500 }
517
+ );
518
+ }
519
+ }
520
+ async function POST(request, context) {
521
+ try {
522
+ const params = await context.params;
523
+ const id = params.id;
524
+ if (!id) {
525
+ return NextResponse.json(
526
+ { error: "Page ID is required" },
527
+ { status: 400 }
528
+ );
529
+ }
530
+ const authResult = await auth.authenticate(request);
531
+ if (!authResult.authenticated || !authResult.user) {
532
+ return NextResponse.json(
533
+ { error: authResult.error || "Unauthorized" },
534
+ { status: 401 }
535
+ );
536
+ }
537
+ if (auth.canEdit) {
538
+ const permission = await auth.canEdit(authResult.user, id);
539
+ if (!permission.allowed) {
540
+ return NextResponse.json(
541
+ { error: permission.error || "Forbidden" },
542
+ { status: 403 }
543
+ );
544
+ }
545
+ }
546
+ const body = await request.json();
547
+ const { versionId } = body;
548
+ if (!versionId) {
549
+ return NextResponse.json(
550
+ { error: "Version ID is required" },
551
+ { status: 400 }
552
+ );
553
+ }
554
+ const config = await payloadConfig;
555
+ const payload = await getPayload({ config });
556
+ const restoredDoc = await payload.restoreVersion({
557
+ collection,
558
+ id: versionId
559
+ });
560
+ return NextResponse.json({ doc: restoredDoc });
561
+ } catch (error) {
562
+ const params = await context.params;
563
+ if (onError) {
564
+ onError(error, { operation: "restoreVersion", request, pageId: params.id });
565
+ }
566
+ console.error("Error restoring version:", error);
567
+ return NextResponse.json(
568
+ { error: "Failed to restore version" },
569
+ { status: 500 }
570
+ );
571
+ }
572
+ }
573
+ return { GET, POST };
574
+ }
575
+
576
+ export { DEFAULT_ROOT_PROPS_MAPPINGS, createPuckApiRoutes, createPuckApiRoutesVersions, createPuckApiRoutesWithId, deepMerge, getNestedValue, mapRootPropsToPayloadFields, mergeMappings, setNestedValue };
577
+ //# sourceMappingURL=index.mjs.map
578
+ //# sourceMappingURL=index.mjs.map