payload-nested-docs-page-tree 1.2.4 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +356 -222
  2. package/dist/components/PageTreeContext.d.ts +13 -1
  3. package/dist/components/PageTreeContext.js +11 -1
  4. package/dist/components/PageTreeContext.js.map +1 -1
  5. package/dist/components/PageTreeListView.client.d.ts +4 -5
  6. package/dist/components/PageTreeListView.client.js +668 -128
  7. package/dist/components/PageTreeListView.client.js.map +1 -1
  8. package/dist/components/PageTreeListView.module.css +399 -376
  9. package/dist/components/PageTreeListView.server.js +18 -28
  10. package/dist/components/PageTreeListView.server.js.map +1 -1
  11. package/dist/components/PageTreeTitleCell.js +80 -18
  12. package/dist/components/PageTreeTitleCell.js.map +1 -1
  13. package/dist/endpoints/createMovePageEndpoint.d.ts +3 -0
  14. package/dist/endpoints/createMovePageEndpoint.js +186 -125
  15. package/dist/endpoints/createMovePageEndpoint.js.map +1 -1
  16. package/dist/endpoints/createReorderPageEndpoint.d.ts +8 -0
  17. package/dist/endpoints/createReorderPageEndpoint.js +706 -0
  18. package/dist/endpoints/createReorderPageEndpoint.js.map +1 -0
  19. package/dist/endpoints/shared.d.ts +40 -0
  20. package/dist/endpoints/shared.js +93 -0
  21. package/dist/endpoints/shared.js.map +1 -0
  22. package/dist/index.js +110 -27
  23. package/dist/index.js.map +1 -1
  24. package/dist/types.d.ts +47 -2
  25. package/dist/types.js +22 -3
  26. package/dist/types.js.map +1 -1
  27. package/dist/utilities/diagnostics.d.ts +42 -0
  28. package/dist/utilities/diagnostics.js +83 -0
  29. package/dist/utilities/diagnostics.js.map +1 -0
  30. package/dist/utilities/dropTargets.d.ts +2 -2
  31. package/dist/utilities/dropTargets.js +9 -7
  32. package/dist/utilities/dropTargets.js.map +1 -1
  33. package/dist/utilities/moveValidation.js.map +1 -1
  34. package/dist/utilities/pageTree.js +4 -6
  35. package/dist/utilities/pageTree.js.map +1 -1
  36. package/dist/utilities/pageTreeCollision.d.ts +6 -0
  37. package/dist/utilities/pageTreeCollision.js +39 -4
  38. package/dist/utilities/pageTreeCollision.js.map +1 -1
  39. package/dist/utilities/pageTreeConfig.js.map +1 -1
  40. package/dist/utilities/status.d.ts +1 -1
  41. package/dist/utilities/status.js +7 -3
  42. package/dist/utilities/status.js.map +1 -1
  43. package/package.json +54 -32
@@ -1,23 +1,14 @@
1
+ import { DIAGNOSTICS_FLOW_CONTEXT_KEY, createFlowID, readMainRowSnapshot } from '../utilities/diagnostics.js';
1
2
  import { CANCEL_DRAG_MESSAGE } from '../utilities/moveValidation.js';
2
3
  import { buildChildrenByParentID, collectDescendantIDs, getDocParentID, stringifyDocID } from '../utilities/pageTree.js';
3
- import { pageTreeMoveContextKey } from '../types.js';
4
- function respond(status, body) {
5
- return Response.json(body, {
6
- status
7
- });
8
- }
4
+ import { pageTreeMoveContextKey, pageTreeWriteContextKey } from '../types.js';
5
+ import { assertUpdateAccess, collectionHasAutosaveDrafts, collectionHasDrafts, getRequestedLocale, normalizeID, respond, toCollectionID } from './shared.js';
6
+ const SNAPSHOT_FIELDS = [
7
+ '_status'
8
+ ];
9
9
  function hasOwnProperty(value, key) {
10
10
  return Object.prototype.hasOwnProperty.call(value, key);
11
11
  }
12
- function normalizeID(value) {
13
- if (value === null || value === undefined || value === '') {
14
- return null;
15
- }
16
- if (typeof value === 'number' || typeof value === 'string') {
17
- return stringifyDocID(value);
18
- }
19
- return null;
20
- }
21
12
  function normalizeMoveDocumentBody(value) {
22
13
  const incomingData = typeof value === 'string' ? (()=>{
23
14
  try {
@@ -41,15 +32,33 @@ function normalizeMoveDocumentBody(value) {
41
32
  };
42
33
  }
43
34
  async function readBodyFromRequest(req) {
44
- const directBody = normalizeMoveDocumentBody(req.data);
45
- if (directBody) {
46
- return directBody;
35
+ let lastAttempt = null;
36
+ if (req.data !== undefined && req.data !== null) {
37
+ lastAttempt = {
38
+ raw: req.data,
39
+ source: 'req.data'
40
+ };
41
+ const directBody = normalizeMoveDocumentBody(req.data);
42
+ if (directBody) {
43
+ return {
44
+ body: directBody,
45
+ lastAttempt
46
+ };
47
+ }
47
48
  }
48
49
  if (typeof req.json === 'function') {
49
50
  try {
50
- const jsonBody = normalizeMoveDocumentBody(await req.json());
51
+ const raw = await req.json();
52
+ lastAttempt = {
53
+ raw,
54
+ source: 'req.json'
55
+ };
56
+ const jsonBody = normalizeMoveDocumentBody(raw);
51
57
  if (jsonBody) {
52
- return jsonBody;
58
+ return {
59
+ body: jsonBody,
60
+ lastAttempt
61
+ };
53
62
  }
54
63
  } catch {
55
64
  // Fall through to the text-based fallback when the runtime does not hydrate req.data.
@@ -57,98 +66,36 @@ async function readBodyFromRequest(req) {
57
66
  }
58
67
  if (typeof req.text === 'function') {
59
68
  try {
60
- return normalizeMoveDocumentBody(await req.text());
61
- } catch {
62
- return null;
63
- }
64
- }
65
- return null;
66
- }
67
- function getPayloadCollection({ collectionSlug, req }) {
68
- return req.payload.collections[collectionSlug];
69
- }
70
- function usesNumericID({ collectionSlug, req }) {
71
- const collection = getPayloadCollection({
72
- collectionSlug,
73
- req
74
- });
75
- if (!collection) {
76
- return false;
77
- }
78
- const idType = collection.customIDType ?? req.payload.db.defaultIDType;
79
- return idType === 'number';
80
- }
81
- function toCollectionID(args) {
82
- const { collectionSlug, id, req } = args;
83
- if (!usesNumericID({
84
- collectionSlug,
85
- req
86
- })) {
87
- return id;
88
- }
89
- return Number(id);
90
- }
91
- function getRequestedLocale(req) {
92
- return req.locale && req.locale !== 'all' ? req.locale : undefined;
93
- }
94
- function collectionHasDrafts(args) {
95
- return Boolean(getPayloadCollection(args)?.config?.versions?.drafts);
96
- }
97
- async function assertUpdateAccess(args) {
98
- const { collectionSlug, movedID, nextParentID, parentFieldSlug, req } = args;
99
- const collection = getPayloadCollection({
100
- collectionSlug,
101
- req
102
- });
103
- const updateAccess = collection?.config?.access?.update;
104
- if (!updateAccess) {
105
- return null;
106
- }
107
- const accessResult = await updateAccess({
108
- data: {
109
- [parentFieldSlug]: nextParentID
110
- },
111
- id: movedID,
112
- req
113
- });
114
- if (accessResult === false) {
115
- return respond(403, {
116
- message: req.i18n.t('error:unauthorized')
117
- });
118
- }
119
- if (accessResult && typeof accessResult === 'object') {
120
- const matchingDocs = await req.payload.find({
121
- collection: collectionSlug,
122
- depth: 0,
123
- draft: collectionHasDrafts({
124
- collectionSlug,
125
- req
126
- }) ? true : undefined,
127
- limit: 1,
128
- locale: getRequestedLocale(req),
129
- overrideAccess: true,
130
- req,
131
- where: {
132
- and: [
133
- {
134
- id: {
135
- equals: movedID
136
- }
137
- },
138
- accessResult
139
- ]
69
+ const raw = await req.text();
70
+ lastAttempt = {
71
+ raw,
72
+ source: 'req.text'
73
+ };
74
+ const textBody = normalizeMoveDocumentBody(raw);
75
+ if (textBody) {
76
+ return {
77
+ body: textBody,
78
+ lastAttempt
79
+ };
140
80
  }
141
- });
142
- if (matchingDocs.docs.length === 0) {
143
- return respond(403, {
144
- message: req.i18n.t('error:unauthorized')
145
- });
81
+ } catch {
82
+ return {
83
+ body: null,
84
+ lastAttempt
85
+ };
146
86
  }
147
87
  }
148
- return null;
88
+ return {
89
+ body: null,
90
+ lastAttempt
91
+ };
149
92
  }
150
93
  export function createMovePageEndpoint(args) {
151
- const { collectionSlug, parentFieldSlug } = args;
94
+ const { collectionSlug, diagnostics, parentFieldSlug, publishOnMove = false } = args;
95
+ const snapshotFields = [
96
+ ...SNAPSHOT_FIELDS,
97
+ parentFieldSlug
98
+ ];
152
99
  return {
153
100
  handler: async (req)=>{
154
101
  const movedIDFromRoute = normalizeID(req.routeParams?.id);
@@ -157,8 +104,22 @@ export function createMovePageEndpoint(args) {
157
104
  message: 'Document ID was not specified.'
158
105
  });
159
106
  }
160
- const body = await readBodyFromRequest(req);
107
+ const { body, lastAttempt } = await readBodyFromRequest(req);
161
108
  if (!body) {
109
+ if (diagnostics.enabled) {
110
+ diagnostics.log({
111
+ collection: collectionSlug,
112
+ data: {
113
+ movedID: movedIDFromRoute,
114
+ rawBody: lastAttempt?.raw ?? null,
115
+ rawBodySource: lastAttempt?.source ?? null
116
+ },
117
+ flow: createFlowID('move-endpoint'),
118
+ level: 'warn',
119
+ message: 'move endpoint rejected request body: parentID was missing or malformed',
120
+ source: 'move-endpoint:body-rejected'
121
+ });
122
+ }
162
123
  return respond(400, {
163
124
  message: 'A valid parentID is required.'
164
125
  });
@@ -175,9 +136,10 @@ export function createMovePageEndpoint(args) {
175
136
  });
176
137
  const accessError = await assertUpdateAccess({
177
138
  collectionSlug,
178
- movedID,
179
- nextParentID,
180
- parentFieldSlug,
139
+ data: {
140
+ [parentFieldSlug]: nextParentID
141
+ },
142
+ id: movedID,
181
143
  req
182
144
  });
183
145
  if (accessError) {
@@ -233,28 +195,127 @@ export function createMovePageEndpoint(args) {
233
195
  message: 'A document cannot be moved under one of its descendants.'
234
196
  });
235
197
  }
236
- await req.payload.update({
198
+ const flow = createFlowID('move-endpoint');
199
+ const moveStart = Date.now();
200
+ const hasDrafts = collectionHasDrafts({
201
+ collectionSlug,
202
+ req
203
+ });
204
+ const hasAutosave = hasDrafts && collectionHasAutosaveDrafts({
205
+ collectionSlug,
206
+ req
207
+ });
208
+ // With `publishOnMove`, publish the reparent right away instead of staging
209
+ // it — but ONLY when the moved doc had nothing staged before the move (its
210
+ // latest version, read above with `draft: true`, is already published). A
211
+ // doc with pending draft edits stays staged, so those in-progress edits are
212
+ // never published as a side effect of the move.
213
+ const publishMove = publishOnMove && hasDrafts && movedDoc._status === 'published';
214
+ const updateData = {
215
+ [parentFieldSlug]: body.parentID === null ? null : toCollectionID({
216
+ collectionSlug,
217
+ id: body.parentID,
218
+ req
219
+ }),
220
+ ...publishMove ? {
221
+ _status: 'published'
222
+ } : {}
223
+ };
224
+ const updateArgs = {
237
225
  collection: collectionSlug,
238
226
  context: {
239
- [pageTreeMoveContextKey]: true
240
- },
241
- data: {
242
- [parentFieldSlug]: body.parentID === null ? null : toCollectionID({
243
- collectionSlug,
244
- id: body.parentID,
245
- req
246
- })
227
+ // A published move changes the live URL of this page and of every
228
+ // descendant nested-docs resaves on this request, so the deploy
229
+ // opt-out flag is withheld and consumer rebuild hooks fire normally.
230
+ // A staged move changes nothing live and keeps the flag.
231
+ ...publishMove ? {} : {
232
+ [pageTreeMoveContextKey]: true
233
+ },
234
+ [pageTreeWriteContextKey]: true
247
235
  },
236
+ autosave: hasAutosave && !publishMove ? true : undefined,
237
+ data: updateData,
248
238
  depth: 0,
249
- draft: collectionHasDrafts({
250
- collectionSlug,
251
- req
252
- }) ? true : undefined,
239
+ draft: hasDrafts && !publishMove ? true : undefined,
253
240
  id: movedID,
254
241
  locale: getRequestedLocale(req),
255
242
  overrideAccess: true,
256
243
  req
257
- });
244
+ };
245
+ if (diagnostics.enabled) {
246
+ if (!req.context) {
247
+ req.context = {};
248
+ }
249
+ ;
250
+ req.context[DIAGNOSTICS_FLOW_CONTEXT_KEY] = flow;
251
+ const beforeSnapshot = await readMainRowSnapshot({
252
+ collectionSlug,
253
+ fields: snapshotFields,
254
+ id: movedID,
255
+ req
256
+ });
257
+ diagnostics.log({
258
+ collection: collectionSlug,
259
+ data: {
260
+ autosave: updateArgs.autosave ?? null,
261
+ currentParentID,
262
+ draft: updateArgs.draft,
263
+ hasTransaction: Boolean(req.transactionID),
264
+ locale: updateArgs.locale ?? null,
265
+ movedDocStatus: movedDoc._status ?? null,
266
+ movedID: String(movedID),
267
+ nextParentID: body.parentID,
268
+ publishedMainRowBefore: beforeSnapshot,
269
+ publishMove,
270
+ updateData
271
+ },
272
+ flow,
273
+ level: 'info',
274
+ message: 'move endpoint entering: parent move only',
275
+ source: 'move-endpoint:enter'
276
+ });
277
+ }
278
+ try {
279
+ const result = await req.payload.update(updateArgs);
280
+ if (diagnostics.enabled) {
281
+ const afterSnapshot = await readMainRowSnapshot({
282
+ collectionSlug,
283
+ fields: snapshotFields,
284
+ id: movedID,
285
+ req
286
+ });
287
+ diagnostics.log({
288
+ collection: collectionSlug,
289
+ data: {
290
+ durMs: Date.now() - moveStart,
291
+ movedID: String(movedID),
292
+ publishedMainRowAfter: afterSnapshot,
293
+ resultStatus: result?._status ?? null
294
+ },
295
+ flow,
296
+ level: 'info',
297
+ message: 'move endpoint payload.update succeeded',
298
+ source: 'move-endpoint:ok'
299
+ });
300
+ }
301
+ } catch (err) {
302
+ const error = err;
303
+ diagnostics.log({
304
+ collection: collectionSlug,
305
+ data: {
306
+ data: error?.data ?? null,
307
+ durMs: Date.now() - moveStart,
308
+ message: error?.message,
309
+ movedID: String(movedID),
310
+ name: error?.name
311
+ },
312
+ flow,
313
+ level: 'error',
314
+ message: `move endpoint payload.update failed: ${error?.message ?? 'unknown error'}`,
315
+ source: 'move-endpoint:error'
316
+ });
317
+ throw err;
318
+ }
258
319
  return respond(200, {
259
320
  movedID: movedIDFromRoute,
260
321
  ok: true,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/endpoints/createMovePageEndpoint.ts"],"sourcesContent":["import type { Endpoint, PayloadRequest, Where } from 'payload'\r\n\r\nimport { CANCEL_DRAG_MESSAGE } from '../utilities/moveValidation.js'\r\nimport {\r\n buildChildrenByParentID,\r\n collectDescendantIDs,\r\n getDocParentID,\r\n stringifyDocID,\r\n} from '../utilities/pageTree.js'\r\nimport { pageTreeMoveContextKey, type PageTreeSourceDoc } from '../types.js'\r\n\r\ntype MoveDocumentRequestBody = {\r\n parentID: null | string\r\n}\r\n\r\ntype PayloadCollectionLike = {\r\n config?: {\r\n access?: {\r\n update?: ((args: Record<string, unknown>) => Promise<Record<string, unknown> | boolean> | Record<string, unknown> | boolean) | undefined\r\n }\r\n versions?: {\r\n drafts?: unknown\r\n }\r\n }\r\n customIDType?: string\r\n}\r\n\r\nfunction respond(status: number, body: Record<string, unknown>) {\r\n return Response.json(body, { status })\r\n}\r\n\r\nfunction hasOwnProperty(value: object, key: PropertyKey): boolean {\r\n return Object.prototype.hasOwnProperty.call(value, key)\r\n}\r\n\r\nfunction normalizeID(value: unknown): null | string {\r\n if (value === null || value === undefined || value === '') {\r\n return null\r\n }\r\n\r\n if (typeof value === 'number' || typeof value === 'string') {\r\n return stringifyDocID(value)\r\n }\r\n\r\n return null\r\n}\r\n\r\nfunction normalizeMoveDocumentBody(value: unknown): MoveDocumentRequestBody | null {\r\n const incomingData =\r\n typeof value === 'string'\r\n ? (() => {\r\n try {\r\n return JSON.parse(value) as unknown\r\n } catch {\r\n return null\r\n }\r\n })()\r\n : value\r\n\r\n if (!incomingData || typeof incomingData !== 'object' || Array.isArray(incomingData)) {\r\n return null\r\n }\r\n\r\n if (!hasOwnProperty(incomingData, 'parentID')) {\r\n return null\r\n }\r\n\r\n const parentID = normalizeID((incomingData as { parentID?: unknown }).parentID)\r\n\r\n if (\r\n (incomingData as { parentID?: unknown }).parentID !== null &&\r\n (incomingData as { parentID?: unknown }).parentID !== undefined &&\r\n parentID === null\r\n ) {\r\n return null\r\n }\r\n\r\n return {\r\n parentID,\r\n }\r\n}\r\n\r\nasync function readBodyFromRequest(req: PayloadRequest): Promise<MoveDocumentRequestBody | null> {\r\n const directBody = normalizeMoveDocumentBody(req.data)\r\n\r\n if (directBody) {\r\n return directBody\r\n }\r\n\r\n if (typeof req.json === 'function') {\r\n try {\r\n const jsonBody = normalizeMoveDocumentBody(await req.json())\r\n\r\n if (jsonBody) {\r\n return jsonBody\r\n }\r\n } catch {\r\n // Fall through to the text-based fallback when the runtime does not hydrate req.data.\r\n }\r\n }\r\n\r\n if (typeof req.text === 'function') {\r\n try {\r\n return normalizeMoveDocumentBody(await req.text())\r\n } catch {\r\n return null\r\n }\r\n }\r\n\r\n return null\r\n}\r\n\r\nfunction getPayloadCollection({\r\n collectionSlug,\r\n req,\r\n}: {\r\n collectionSlug: string\r\n req: PayloadRequest\r\n}): PayloadCollectionLike | undefined {\r\n return (req.payload.collections as unknown as Record<string, PayloadCollectionLike | undefined>)[\r\n collectionSlug\r\n ]\r\n}\r\n\r\nfunction usesNumericID({\r\n collectionSlug,\r\n req,\r\n}: {\r\n collectionSlug: string\r\n req: PayloadRequest\r\n}): boolean {\r\n const collection = getPayloadCollection({ collectionSlug, req })\r\n\r\n if (!collection) {\r\n return false\r\n }\r\n\r\n const idType = collection.customIDType ?? req.payload.db.defaultIDType\r\n\r\n return idType === 'number'\r\n}\r\n\r\nfunction toCollectionID(args: {\r\n collectionSlug: string\r\n id: string\r\n req: PayloadRequest\r\n}): number | string {\r\n const { collectionSlug, id, req } = args\r\n\r\n if (!usesNumericID({ collectionSlug, req })) {\r\n return id\r\n }\r\n\r\n return Number(id)\r\n}\r\n\r\nfunction getRequestedLocale(req: PayloadRequest): string | undefined {\r\n return req.locale && req.locale !== 'all' ? req.locale : undefined\r\n}\r\n\r\nfunction collectionHasDrafts(args: {\r\n collectionSlug: string\r\n req: PayloadRequest\r\n}): boolean {\r\n return Boolean(getPayloadCollection(args)?.config?.versions?.drafts)\r\n}\r\n\r\nasync function assertUpdateAccess(args: {\r\n collectionSlug: string\r\n movedID: number | string\r\n nextParentID: null | number | string\r\n parentFieldSlug: string\r\n req: PayloadRequest\r\n}): Promise<Response | null> {\r\n const { collectionSlug, movedID, nextParentID, parentFieldSlug, req } = args\r\n const collection = getPayloadCollection({ collectionSlug, req })\r\n const updateAccess = collection?.config?.access?.update\r\n\r\n if (!updateAccess) {\r\n return null\r\n }\r\n\r\n const accessResult = await updateAccess({\r\n data: { [parentFieldSlug]: nextParentID } as never,\r\n id: movedID as never,\r\n req,\r\n })\r\n\r\n if (accessResult === false) {\r\n return respond(403, {\r\n message: req.i18n.t('error:unauthorized'),\r\n })\r\n }\r\n\r\n if (accessResult && typeof accessResult === 'object') {\r\n const matchingDocs = await req.payload.find({\r\n collection: collectionSlug as never,\r\n depth: 0,\r\n draft: collectionHasDrafts({ collectionSlug, req }) ? true : undefined,\r\n limit: 1,\r\n locale: getRequestedLocale(req) as never,\r\n overrideAccess: true,\r\n req,\r\n where: {\r\n and: [\r\n {\r\n id: {\r\n equals: movedID,\r\n },\r\n },\r\n accessResult as Where,\r\n ],\r\n },\r\n } as never)\r\n\r\n if (matchingDocs.docs.length === 0) {\r\n return respond(403, {\r\n message: req.i18n.t('error:unauthorized'),\r\n })\r\n }\r\n }\r\n\r\n return null\r\n}\r\n\r\nexport function createMovePageEndpoint(args: {\r\n collectionSlug: string\r\n parentFieldSlug: string\r\n}): Endpoint {\r\n const { collectionSlug, parentFieldSlug } = args\r\n\r\n return {\r\n handler: async (req) => {\r\n const movedIDFromRoute = normalizeID(req.routeParams?.id)\r\n\r\n if (!movedIDFromRoute) {\r\n return respond(400, {\r\n message: 'Document ID was not specified.',\r\n })\r\n }\r\n\r\n const body = await readBodyFromRequest(req)\r\n\r\n if (!body) {\r\n return respond(400, {\r\n message: 'A valid parentID is required.',\r\n })\r\n }\r\n\r\n const movedID = toCollectionID({\r\n collectionSlug,\r\n id: movedIDFromRoute,\r\n req,\r\n })\r\n const nextParentID =\r\n body.parentID === null\r\n ? null\r\n : toCollectionID({\r\n collectionSlug,\r\n id: body.parentID,\r\n req,\r\n })\r\n const accessError = await assertUpdateAccess({\r\n collectionSlug,\r\n movedID,\r\n nextParentID,\r\n parentFieldSlug,\r\n req,\r\n })\r\n\r\n if (accessError) {\r\n return accessError\r\n }\r\n\r\n const docsResult = await req.payload.find({\r\n collection: collectionSlug as never,\r\n depth: 0,\r\n draft: collectionHasDrafts({ collectionSlug, req }) ? true : undefined,\r\n fallbackLocale: false as never,\r\n limit: 0,\r\n locale: getRequestedLocale(req) as never,\r\n overrideAccess: true,\r\n req,\r\n } as never)\r\n const docs = docsResult.docs as unknown as PageTreeSourceDoc[]\r\n const docsByID = new Map(docs.map((doc) => [stringifyDocID(doc.id), doc]))\r\n const movedDoc = docsByID.get(movedIDFromRoute)\r\n\r\n if (!movedDoc) {\r\n return respond(404, {\r\n message: 'Document not found.',\r\n })\r\n }\r\n\r\n if (body.parentID !== null && !docsByID.has(body.parentID)) {\r\n return respond(400, {\r\n message: 'Parent document not found.',\r\n })\r\n }\r\n\r\n const currentParentID = getDocParentID(movedDoc, parentFieldSlug)\r\n\r\n if (currentParentID === body.parentID) {\r\n return respond(400, {\r\n message: 'Document already has that parent.',\r\n })\r\n }\r\n\r\n if (body.parentID === movedIDFromRoute) {\r\n return respond(400, {\r\n message: CANCEL_DRAG_MESSAGE,\r\n })\r\n }\r\n\r\n const childrenByParentID = buildChildrenByParentID({\r\n docs,\r\n parentFieldSlug,\r\n })\r\n const descendantIDs = collectDescendantIDs(movedIDFromRoute, childrenByParentID)\r\n\r\n if (body.parentID !== null && descendantIDs.includes(body.parentID)) {\r\n return respond(400, {\r\n message: 'A document cannot be moved under one of its descendants.',\r\n })\r\n }\r\n\r\n await req.payload.update({\r\n collection: collectionSlug as never,\r\n context: {\r\n [pageTreeMoveContextKey]: true,\r\n },\r\n data: {\r\n [parentFieldSlug]:\r\n body.parentID === null\r\n ? null\r\n : toCollectionID({\r\n collectionSlug,\r\n id: body.parentID,\r\n req,\r\n }),\r\n } as never,\r\n depth: 0,\r\n draft: collectionHasDrafts({ collectionSlug, req }) ? true : undefined,\r\n id: movedID as never,\r\n locale: getRequestedLocale(req) as never,\r\n overrideAccess: true,\r\n req,\r\n } as never)\r\n\r\n return respond(200, {\r\n movedID: movedIDFromRoute,\r\n ok: true,\r\n parentID: body.parentID,\r\n })\r\n },\r\n method: 'post',\r\n path: '/:id/move',\r\n }\r\n}\r\n"],"names":["CANCEL_DRAG_MESSAGE","buildChildrenByParentID","collectDescendantIDs","getDocParentID","stringifyDocID","pageTreeMoveContextKey","respond","status","body","Response","json","hasOwnProperty","value","key","Object","prototype","call","normalizeID","undefined","normalizeMoveDocumentBody","incomingData","JSON","parse","Array","isArray","parentID","readBodyFromRequest","req","directBody","data","jsonBody","text","getPayloadCollection","collectionSlug","payload","collections","usesNumericID","collection","idType","customIDType","db","defaultIDType","toCollectionID","args","id","Number","getRequestedLocale","locale","collectionHasDrafts","Boolean","config","versions","drafts","assertUpdateAccess","movedID","nextParentID","parentFieldSlug","updateAccess","access","update","accessResult","message","i18n","t","matchingDocs","find","depth","draft","limit","overrideAccess","where","and","equals","docs","length","createMovePageEndpoint","handler","movedIDFromRoute","routeParams","accessError","docsResult","fallbackLocale","docsByID","Map","map","doc","movedDoc","get","has","currentParentID","childrenByParentID","descendantIDs","includes","context","ok","method","path"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/endpoints/createMovePageEndpoint.ts"],"sourcesContent":["import type { Endpoint, PayloadRequest } from 'payload'\n\nimport {\n DIAGNOSTICS_FLOW_CONTEXT_KEY,\n type Diagnostics,\n createFlowID,\n readMainRowSnapshot,\n} from '../utilities/diagnostics.js'\nimport { CANCEL_DRAG_MESSAGE } from '../utilities/moveValidation.js'\nimport {\n buildChildrenByParentID,\n collectDescendantIDs,\n getDocParentID,\n stringifyDocID,\n} from '../utilities/pageTree.js'\nimport {\n pageTreeMoveContextKey,\n type PageTreeSourceDoc,\n pageTreeWriteContextKey,\n} from '../types.js'\nimport {\n assertUpdateAccess,\n collectionHasAutosaveDrafts,\n collectionHasDrafts,\n getRequestedLocale,\n normalizeID,\n respond,\n toCollectionID,\n} from './shared.js'\n\nconst SNAPSHOT_FIELDS = ['_status'] as const\n\ntype MoveDocumentRequestBody = {\n parentID: null | string\n}\n\nfunction hasOwnProperty(value: object, key: PropertyKey): boolean {\n return Object.prototype.hasOwnProperty.call(value, key)\n}\n\nfunction normalizeMoveDocumentBody(value: unknown): MoveDocumentRequestBody | null {\n const incomingData =\n typeof value === 'string'\n ? (() => {\n try {\n return JSON.parse(value) as unknown\n } catch {\n return null\n }\n })()\n : value\n\n if (!incomingData || typeof incomingData !== 'object' || Array.isArray(incomingData)) {\n return null\n }\n\n if (!hasOwnProperty(incomingData, 'parentID')) {\n return null\n }\n\n const parentID = normalizeID((incomingData as { parentID?: unknown }).parentID)\n\n if (\n (incomingData as { parentID?: unknown }).parentID !== null &&\n (incomingData as { parentID?: unknown }).parentID !== undefined &&\n parentID === null\n ) {\n return null\n }\n\n return {\n parentID,\n }\n}\n\ntype RawBodyAttempt = {\n raw: unknown\n source: 'req.data' | 'req.json' | 'req.text'\n}\n\nasync function readBodyFromRequest(\n req: PayloadRequest,\n): Promise<{ body: MoveDocumentRequestBody | null; lastAttempt: null | RawBodyAttempt }> {\n let lastAttempt: null | RawBodyAttempt = null\n\n if (req.data !== undefined && req.data !== null) {\n lastAttempt = { raw: req.data, source: 'req.data' }\n const directBody = normalizeMoveDocumentBody(req.data)\n\n if (directBody) {\n return { body: directBody, lastAttempt }\n }\n }\n\n if (typeof req.json === 'function') {\n try {\n const raw = await req.json()\n lastAttempt = { raw, source: 'req.json' }\n const jsonBody = normalizeMoveDocumentBody(raw)\n\n if (jsonBody) {\n return { body: jsonBody, lastAttempt }\n }\n } catch {\n // Fall through to the text-based fallback when the runtime does not hydrate req.data.\n }\n }\n\n if (typeof req.text === 'function') {\n try {\n const raw = await req.text()\n lastAttempt = { raw, source: 'req.text' }\n const textBody = normalizeMoveDocumentBody(raw)\n\n if (textBody) {\n return { body: textBody, lastAttempt }\n }\n } catch {\n return { body: null, lastAttempt }\n }\n }\n\n return { body: null, lastAttempt }\n}\n\nexport function createMovePageEndpoint(args: {\n collectionSlug: string\n diagnostics: Diagnostics\n parentFieldSlug: string\n publishOnMove?: boolean\n}): Endpoint {\n const { collectionSlug, diagnostics, parentFieldSlug, publishOnMove = false } = args\n const snapshotFields = [...SNAPSHOT_FIELDS, parentFieldSlug]\n\n return {\n handler: async (req) => {\n const movedIDFromRoute = normalizeID(req.routeParams?.id)\n\n if (!movedIDFromRoute) {\n return respond(400, {\n message: 'Document ID was not specified.',\n })\n }\n\n const { body, lastAttempt } = await readBodyFromRequest(req)\n\n if (!body) {\n if (diagnostics.enabled) {\n diagnostics.log({\n collection: collectionSlug,\n data: {\n movedID: movedIDFromRoute,\n rawBody: lastAttempt?.raw ?? null,\n rawBodySource: lastAttempt?.source ?? null,\n },\n flow: createFlowID('move-endpoint'),\n level: 'warn',\n message: 'move endpoint rejected request body: parentID was missing or malformed',\n source: 'move-endpoint:body-rejected',\n })\n }\n\n return respond(400, {\n message: 'A valid parentID is required.',\n })\n }\n\n const movedID = toCollectionID({\n collectionSlug,\n id: movedIDFromRoute,\n req,\n })\n const nextParentID =\n body.parentID === null\n ? null\n : toCollectionID({\n collectionSlug,\n id: body.parentID,\n req,\n })\n const accessError = await assertUpdateAccess({\n collectionSlug,\n data: { [parentFieldSlug]: nextParentID },\n id: movedID,\n req,\n })\n\n if (accessError) {\n return accessError\n }\n\n const docsResult = await req.payload.find({\n collection: collectionSlug as never,\n depth: 0,\n draft: collectionHasDrafts({ collectionSlug, req }) ? true : undefined,\n fallbackLocale: false as never,\n limit: 0,\n locale: getRequestedLocale(req) as never,\n overrideAccess: true,\n req,\n } as never)\n const docs = docsResult.docs as unknown as PageTreeSourceDoc[]\n const docsByID = new Map(docs.map((doc) => [stringifyDocID(doc.id), doc]))\n const movedDoc = docsByID.get(movedIDFromRoute)\n\n if (!movedDoc) {\n return respond(404, {\n message: 'Document not found.',\n })\n }\n\n if (body.parentID !== null && !docsByID.has(body.parentID)) {\n return respond(400, {\n message: 'Parent document not found.',\n })\n }\n\n const currentParentID = getDocParentID(movedDoc, parentFieldSlug)\n\n if (currentParentID === body.parentID) {\n return respond(400, {\n message: 'Document already has that parent.',\n })\n }\n\n if (body.parentID === movedIDFromRoute) {\n return respond(400, {\n message: CANCEL_DRAG_MESSAGE,\n })\n }\n\n const childrenByParentID = buildChildrenByParentID({\n docs,\n parentFieldSlug,\n })\n const descendantIDs = collectDescendantIDs(movedIDFromRoute, childrenByParentID)\n\n if (body.parentID !== null && descendantIDs.includes(body.parentID)) {\n return respond(400, {\n message: 'A document cannot be moved under one of its descendants.',\n })\n }\n\n const flow = createFlowID('move-endpoint')\n const moveStart = Date.now()\n const hasDrafts = collectionHasDrafts({ collectionSlug, req })\n const hasAutosave = hasDrafts && collectionHasAutosaveDrafts({ collectionSlug, req })\n // With `publishOnMove`, publish the reparent right away instead of staging\n // it — but ONLY when the moved doc had nothing staged before the move (its\n // latest version, read above with `draft: true`, is already published). A\n // doc with pending draft edits stays staged, so those in-progress edits are\n // never published as a side effect of the move.\n const publishMove = publishOnMove && hasDrafts && movedDoc._status === 'published'\n const updateData = {\n [parentFieldSlug]:\n body.parentID === null\n ? null\n : toCollectionID({\n collectionSlug,\n id: body.parentID,\n req,\n }),\n ...(publishMove ? { _status: 'published' } : {}),\n }\n const updateArgs = {\n collection: collectionSlug as never,\n context: {\n // A published move changes the live URL of this page and of every\n // descendant nested-docs resaves on this request, so the deploy\n // opt-out flag is withheld and consumer rebuild hooks fire normally.\n // A staged move changes nothing live and keeps the flag.\n ...(publishMove ? {} : { [pageTreeMoveContextKey]: true }),\n [pageTreeWriteContextKey]: true,\n } as Record<string, unknown>,\n autosave: hasAutosave && !publishMove ? true : undefined,\n data: updateData as never,\n depth: 0,\n draft: hasDrafts && !publishMove ? true : undefined,\n id: movedID as never,\n locale: getRequestedLocale(req) as never,\n overrideAccess: true,\n req,\n }\n\n if (diagnostics.enabled) {\n if (!req.context) {\n req.context = {}\n }\n\n ;(req.context as Record<string, unknown>)[DIAGNOSTICS_FLOW_CONTEXT_KEY] = flow\n\n const beforeSnapshot = await readMainRowSnapshot({\n collectionSlug,\n fields: snapshotFields,\n id: movedID,\n req,\n })\n\n diagnostics.log({\n collection: collectionSlug,\n data: {\n autosave: updateArgs.autosave ?? null,\n currentParentID,\n draft: updateArgs.draft,\n hasTransaction: Boolean((req as { transactionID?: unknown }).transactionID),\n locale: updateArgs.locale ?? null,\n movedDocStatus: movedDoc._status ?? null,\n movedID: String(movedID),\n nextParentID: body.parentID,\n publishedMainRowBefore: beforeSnapshot,\n publishMove,\n updateData,\n },\n flow,\n level: 'info',\n message: 'move endpoint entering: parent move only',\n source: 'move-endpoint:enter',\n })\n }\n\n try {\n const result = (await req.payload.update(updateArgs as never)) as\n | (Record<string, unknown> & { _status?: string })\n | undefined\n\n if (diagnostics.enabled) {\n const afterSnapshot = await readMainRowSnapshot({\n collectionSlug,\n fields: snapshotFields,\n id: movedID,\n req,\n })\n\n diagnostics.log({\n collection: collectionSlug,\n data: {\n durMs: Date.now() - moveStart,\n movedID: String(movedID),\n publishedMainRowAfter: afterSnapshot,\n resultStatus: result?._status ?? null,\n },\n flow,\n level: 'info',\n message: 'move endpoint payload.update succeeded',\n source: 'move-endpoint:ok',\n })\n }\n } catch (err) {\n const error = err as { data?: unknown; message?: string; name?: string } & Error\n\n diagnostics.log({\n collection: collectionSlug,\n data: {\n data: error?.data ?? null,\n durMs: Date.now() - moveStart,\n message: error?.message,\n movedID: String(movedID),\n name: error?.name,\n },\n flow,\n level: 'error',\n message: `move endpoint payload.update failed: ${error?.message ?? 'unknown error'}`,\n source: 'move-endpoint:error',\n })\n\n throw err\n }\n\n return respond(200, {\n movedID: movedIDFromRoute,\n ok: true,\n parentID: body.parentID,\n })\n },\n method: 'post',\n path: '/:id/move',\n }\n}\n"],"names":["DIAGNOSTICS_FLOW_CONTEXT_KEY","createFlowID","readMainRowSnapshot","CANCEL_DRAG_MESSAGE","buildChildrenByParentID","collectDescendantIDs","getDocParentID","stringifyDocID","pageTreeMoveContextKey","pageTreeWriteContextKey","assertUpdateAccess","collectionHasAutosaveDrafts","collectionHasDrafts","getRequestedLocale","normalizeID","respond","toCollectionID","SNAPSHOT_FIELDS","hasOwnProperty","value","key","Object","prototype","call","normalizeMoveDocumentBody","incomingData","JSON","parse","Array","isArray","parentID","undefined","readBodyFromRequest","req","lastAttempt","data","raw","source","directBody","body","json","jsonBody","text","textBody","createMovePageEndpoint","args","collectionSlug","diagnostics","parentFieldSlug","publishOnMove","snapshotFields","handler","movedIDFromRoute","routeParams","id","message","enabled","log","collection","movedID","rawBody","rawBodySource","flow","level","nextParentID","accessError","docsResult","payload","find","depth","draft","fallbackLocale","limit","locale","overrideAccess","docs","docsByID","Map","map","doc","movedDoc","get","has","currentParentID","childrenByParentID","descendantIDs","includes","moveStart","Date","now","hasDrafts","hasAutosave","publishMove","_status","updateData","updateArgs","context","autosave","beforeSnapshot","fields","hasTransaction","Boolean","transactionID","movedDocStatus","String","publishedMainRowBefore","result","update","afterSnapshot","durMs","publishedMainRowAfter","resultStatus","err","error","name","ok","method","path"],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { Endpoint } from 'payload';
2
+ import { type Diagnostics } from '../utilities/diagnostics.js';
3
+ export declare function createReorderPageEndpoint(args: {
4
+ collectionSlug: string;
5
+ diagnostics: Diagnostics;
6
+ orderableFieldName: string;
7
+ parentFieldSlug: string;
8
+ }): Endpoint;