payload-nested-docs-page-tree 1.4.0 → 1.4.2

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/endpoints/createReorderPageEndpoint.ts"],"sourcesContent":["import type { Endpoint, PayloadRequest, Where } from 'payload'\n\nimport { combineWhereConstraints, generateNKeysBetween } from 'payload/shared'\n\nimport { pageTreeMoveContextKey, type PageTreeSourceDoc } from '../types.js'\nimport {\n createFlowID,\n type Diagnostics,\n DIAGNOSTICS_FLOW_CONTEXT_KEY,\n readMainRowSnapshot,\n} from '../utilities/diagnostics.js'\nimport { getDocParentID, stringifyDocID } from '../utilities/pageTree.js'\nimport {\n assertUpdateAccess,\n collectionHasDrafts,\n getRequestedLocale,\n normalizeID,\n respond,\n toCollectionID,\n} from './shared.js'\n\ntype ReorderDocumentRequestBody = {\n docsToMove: string[]\n frontendOrder?: ReorderFrontendOrderDiagnostic\n newKeyWillBe: 'greater' | 'less'\n orderableFieldName: string\n target: {\n id: string\n key: null | string\n }\n}\n\ntype ReorderFrontendOrderDiagnostic = {\n activeSlug: null | string\n after: ReorderFrontendOrderEntry[]\n before: ReorderFrontendOrderEntry[]\n moveFromIndex: number\n moveToIndex: number\n newAfterRowSlug: null | string\n newBeforeRowSlug: null | string\n sort: null | string\n targetSlug: null | string\n}\n\ntype ReorderFrontendOrderEntry = {\n index: number\n orderKey: null | string\n slug: null | string\n}\n\ntype ReorderBackendOrderEntry = {\n index: number\n orderKey: null | string\n slug: null | string\n status: null | string\n}\n\ntype RawBodyAttempt = {\n raw: unknown\n source: 'req.data' | 'req.json' | 'req.text'\n}\n\ntype VersionRecord = {\n createdAt?: string\n id?: number | string\n latest?: boolean\n parent?: number | string\n publishedLocale?: string\n updatedAt?: string\n version?: Record<string, unknown>\n} & Record<string, unknown>\n\nconst SNAPSHOT_FIELDS = ['_status'] as const\n\nfunction hasOwnProperty(value: object, key: PropertyKey): boolean {\n return Object.prototype.hasOwnProperty.call(value, key)\n}\n\nfunction normalizeOptionalString(value: unknown): null | string {\n return typeof value === 'string' && value.length > 0 ? value : null\n}\n\nfunction normalizeFrontendOrderEntry(\n value: unknown,\n fallbackIndex: number,\n): null | ReorderFrontendOrderEntry {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return null\n }\n\n const data = value as Record<string, unknown>\n\n return {\n slug: normalizeOptionalString(data.slug),\n index: typeof data.index === 'number' && Number.isFinite(data.index) ? data.index : fallbackIndex,\n orderKey: normalizeOptionalString(data.orderKey),\n }\n}\n\nfunction normalizeFrontendOrder(value: unknown): ReorderFrontendOrderDiagnostic | undefined {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return undefined\n }\n\n const data = value as Record<string, unknown>\n\n if (!Array.isArray(data.before) || !Array.isArray(data.after)) {\n return undefined\n }\n\n const before = data.before\n .slice(0, 250)\n .map((entry, index) => normalizeFrontendOrderEntry(entry, index))\n .filter((entry): entry is ReorderFrontendOrderEntry => Boolean(entry))\n const after = data.after\n .slice(0, 250)\n .map((entry, index) => normalizeFrontendOrderEntry(entry, index))\n .filter((entry): entry is ReorderFrontendOrderEntry => Boolean(entry))\n\n return {\n activeSlug: normalizeOptionalString(data.activeSlug),\n after,\n before,\n moveFromIndex:\n typeof data.moveFromIndex === 'number' && Number.isFinite(data.moveFromIndex)\n ? data.moveFromIndex\n : -1,\n moveToIndex:\n typeof data.moveToIndex === 'number' && Number.isFinite(data.moveToIndex)\n ? data.moveToIndex\n : -1,\n newAfterRowSlug: normalizeOptionalString(data.newAfterRowSlug),\n newBeforeRowSlug: normalizeOptionalString(data.newBeforeRowSlug),\n sort: normalizeOptionalString(data.sort),\n targetSlug: normalizeOptionalString(data.targetSlug),\n }\n}\n\nfunction normalizeReorderDocumentBody(value: unknown): null | ReorderDocumentRequestBody {\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 const data = incomingData as Record<string, unknown>\n const target = data.target\n\n if (!Array.isArray(data.docsToMove) || data.docsToMove.length !== 1) {\n return null\n }\n\n if (data.newKeyWillBe !== 'greater' && data.newKeyWillBe !== 'less') {\n return null\n }\n\n if (typeof data.orderableFieldName !== 'string' || data.orderableFieldName.length === 0) {\n return null\n }\n\n if (!target || typeof target !== 'object' || Array.isArray(target)) {\n return null\n }\n\n const targetData = target as Record<string, unknown>\n const movedID = normalizeID(data.docsToMove[0])\n const targetID = normalizeID(targetData.id)\n\n if (!movedID || !targetID) {\n return null\n }\n\n const key = hasOwnProperty(targetData, 'key') ? targetData.key : null\n\n if (key !== null && key !== undefined && typeof key !== 'string') {\n return null\n }\n\n return {\n docsToMove: [movedID],\n frontendOrder: normalizeFrontendOrder(data.frontendOrder),\n newKeyWillBe: data.newKeyWillBe,\n orderableFieldName: data.orderableFieldName,\n target: {\n id: targetID,\n key: key || null,\n },\n }\n}\n\nasync function readBodyFromRequest(\n req: PayloadRequest,\n): Promise<{ body: null | ReorderDocumentRequestBody; 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 = normalizeReorderDocumentBody(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 = normalizeReorderDocumentBody(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 = normalizeReorderDocumentBody(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\nfunction getParentScopeWhere(args: {\n parentFieldSlug: string\n parentID: null | number | string\n}): Where {\n const { parentFieldSlug, parentID } = args\n\n return {\n [parentFieldSlug]: {\n equals: parentID,\n },\n } as Where\n}\n\nfunction getOrderableKey(doc: PageTreeSourceDoc | undefined, orderableFieldName: string) {\n const value = doc?.[orderableFieldName]\n\n return typeof value === 'string' && value.length > 0 ? value : null\n}\n\nfunction getDiagnosticDocString(value: unknown, locale?: string): null | string {\n if (typeof value === 'string' && value.length > 0) {\n return value\n }\n\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return null\n }\n\n const localizedValue = value as Record<string, unknown>\n const localeValue = locale ? localizedValue[locale] : undefined\n\n if (typeof localeValue === 'string' && localeValue.length > 0) {\n return localeValue\n }\n\n const firstString = Object.values(localizedValue).find(\n (entry): entry is string => typeof entry === 'string' && entry.length > 0,\n )\n\n return firstString ?? null\n}\n\nfunction getBackendOrderEntry(args: {\n doc: PageTreeSourceDoc\n index: number\n locale?: string\n orderableFieldName: string\n}): ReorderBackendOrderEntry {\n const { doc, index, locale, orderableFieldName } = args\n\n return {\n slug: getDiagnosticDocString(doc.slug, locale),\n index,\n orderKey: getOrderableKey(doc, orderableFieldName),\n status: getDiagnosticDocString(doc._status, locale),\n }\n}\n\nfunction getMainRowOrderSnapshot(\n snapshot: null | Record<string, unknown>,\n orderableFieldName: string,\n): { orderKey: null | string; status: null | string } | null {\n if (!snapshot) {\n return null\n }\n\n return {\n orderKey: normalizeOptionalString(snapshot[orderableFieldName]),\n status: normalizeOptionalString(snapshot._status),\n }\n}\n\nasync function readBackendSiblingOrder(args: {\n collectionSlug: string\n draft?: boolean\n orderableFieldName: string\n parentScopeWhere: Where\n req: PayloadRequest\n}): Promise<ReorderBackendOrderEntry[]> {\n const { collectionSlug, draft, orderableFieldName, parentScopeWhere, req } = args\n const locale = getRequestedLocale(req)\n\n try {\n const result = await req.payload.find({\n collection: collectionSlug as never,\n depth: 0,\n draft: draft as never,\n limit: 250,\n locale: locale as never,\n overrideAccess: true,\n pagination: false,\n req,\n sort: orderableFieldName,\n where: parentScopeWhere as never,\n } as never)\n\n return (result.docs as unknown as PageTreeSourceDoc[]).map((doc, index) =>\n getBackendOrderEntry({\n doc,\n index,\n locale,\n orderableFieldName,\n }),\n )\n } catch {\n return []\n }\n}\n\nfunction getOrderValuesBetween(args: {\n adjacentDocKey: null | string\n docsToMoveLength: number\n movedBoundaryKey: null | string\n newKeyWillBe: ReorderDocumentRequestBody['newKeyWillBe']\n targetKey: string\n}): { orderValues: string[]; usedMovedKeyBoundary: boolean } {\n const { adjacentDocKey, docsToMoveLength, movedBoundaryKey, newKeyWillBe, targetKey } = args\n const orderValues =\n newKeyWillBe === 'greater'\n ? generateNKeysBetween(targetKey, adjacentDocKey, docsToMoveLength)\n : generateNKeysBetween(adjacentDocKey, targetKey, docsToMoveLength)\n\n if (orderValues[0] !== movedBoundaryKey) {\n return { orderValues, usedMovedKeyBoundary: false }\n }\n\n if (newKeyWillBe === 'greater' && movedBoundaryKey && movedBoundaryKey > targetKey) {\n return {\n orderValues: generateNKeysBetween(targetKey, movedBoundaryKey, docsToMoveLength),\n usedMovedKeyBoundary: true,\n }\n }\n\n if (newKeyWillBe === 'less' && movedBoundaryKey && movedBoundaryKey < targetKey) {\n return {\n orderValues: generateNKeysBetween(movedBoundaryKey, targetKey, docsToMoveLength),\n usedMovedKeyBoundary: true,\n }\n }\n\n return { orderValues, usedMovedKeyBoundary: false }\n}\n\nasync function readLatestVersion(args: {\n collectionSlug: string\n id: number | string\n req: PayloadRequest\n}): Promise<null | VersionRecord> {\n const { id, collectionSlug, req } = args\n const versions = await req.payload.db.findVersions({\n collection: collectionSlug as never,\n limit: 1,\n pagination: false,\n req,\n sort: '-updatedAt',\n where: {\n latest: {\n equals: true,\n },\n parent: {\n equals: id,\n },\n },\n } as never)\n const latestVersion = versions.docs[0] as undefined | VersionRecord\n\n if (!latestVersion?.version) {\n return null\n }\n\n return latestVersion\n}\n\nasync function updateLatestVersionOrder(args: {\n collectionSlug: string\n id: number | string\n orderableFieldName: string\n orderValue: string\n req: PayloadRequest\n}): Promise<boolean> {\n const { id, collectionSlug, orderableFieldName, orderValue, req } = args\n const latestVersion = await readLatestVersion({\n id,\n collectionSlug,\n req,\n })\n\n if (!latestVersion?.id || !latestVersion.version) {\n return false\n }\n\n await req.payload.db.updateVersion({\n id: latestVersion.id as never,\n collection: collectionSlug as never,\n locale: getRequestedLocale(req) as never,\n req,\n returning: false,\n versionData: {\n createdAt: latestVersion.createdAt,\n latest: latestVersion.latest,\n parent: id,\n publishedLocale: latestVersion.publishedLocale,\n updatedAt: latestVersion.updatedAt,\n version: {\n ...latestVersion.version,\n [orderableFieldName]: orderValue,\n },\n },\n } as never)\n\n return true\n}\n\nasync function updateOrderValueSilently(args: {\n collectionSlug: string\n hasDrafts: boolean\n id: number | string\n orderableFieldName: string\n orderValue: string\n req: PayloadRequest\n}): Promise<{ updatedDraftVersion: boolean }> {\n const { id, collectionSlug, hasDrafts, orderableFieldName, orderValue, req } = args\n\n await req.payload.db.updateOne({\n id: id as never,\n collection: collectionSlug as never,\n data: {\n [orderableFieldName]: orderValue,\n updatedAt: null,\n },\n locale: getRequestedLocale(req) as never,\n req,\n returning: false,\n } as never)\n\n const updatedDraftVersion = hasDrafts\n ? await updateLatestVersionOrder({\n id,\n collectionSlug,\n orderableFieldName,\n orderValue,\n req,\n })\n : false\n\n return {\n updatedDraftVersion,\n }\n}\n\nasync function initializeMissingOrderKeys(args: {\n collectionSlug: string\n diagnostics: Diagnostics\n flow: string\n hasDrafts: boolean\n orderableFieldName: string\n parentScopeWhere: Where\n req: PayloadRequest\n}): Promise<Response> {\n const { collectionSlug, diagnostics, flow, hasDrafts, orderableFieldName, parentScopeWhere, req } =\n args\n const existingOrderedDocs = await req.payload.find({\n collection: collectionSlug as never,\n depth: 0,\n draft: hasDrafts ? true : undefined,\n limit: 1,\n locale: getRequestedLocale(req) as never,\n overrideAccess: true,\n pagination: false,\n req,\n select: { [orderableFieldName]: true } as never,\n sort: `-${orderableFieldName}`,\n where: combineWhereConstraints([\n {\n [orderableFieldName]: {\n exists: true,\n },\n },\n parentScopeWhere,\n ]) as never,\n } as never)\n const missingOrderDocs = await req.payload.find({\n collection: collectionSlug as never,\n depth: 0,\n draft: hasDrafts ? true : undefined,\n limit: 0,\n locale: getRequestedLocale(req) as never,\n overrideAccess: true,\n pagination: false,\n req,\n select: { [orderableFieldName]: true } as never,\n where: combineWhereConstraints([\n {\n [orderableFieldName]: {\n exists: false,\n },\n },\n parentScopeWhere,\n ]) as never,\n } as never)\n const lastOrderValue = getOrderableKey(\n existingOrderedDocs.docs[0] as unknown as PageTreeSourceDoc | undefined,\n orderableFieldName,\n )\n const orderValues = generateNKeysBetween(lastOrderValue, null, missingOrderDocs.docs.length)\n\n for (const [index, doc] of (missingOrderDocs.docs as unknown as PageTreeSourceDoc[]).entries()) {\n const docID = doc.id\n const orderValue = orderValues[index]\n\n if (\n orderValue &&\n (typeof docID === 'number' || typeof docID === 'string')\n ) {\n await updateOrderValueSilently({\n id: docID,\n collectionSlug,\n hasDrafts,\n orderableFieldName,\n orderValue,\n req,\n })\n }\n }\n\n diagnostics.log({\n collection: collectionSlug,\n data: {\n initializedCount: missingOrderDocs.docs.length,\n orderableFieldName,\n },\n flow,\n level: 'info',\n message: 'reorder endpoint initialized missing order keys',\n source: 'reorder-endpoint:initial-migration',\n })\n\n return respond(200, {\n message: 'initial migration',\n success: true,\n })\n}\n\nexport function createReorderPageEndpoint(args: {\n collectionSlug: string\n diagnostics: Diagnostics\n orderableFieldName: string\n parentFieldSlug: string\n}): Endpoint {\n const { collectionSlug, diagnostics, orderableFieldName, parentFieldSlug } = args\n const snapshotFields = [...SNAPSHOT_FIELDS, parentFieldSlug, orderableFieldName]\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 (\n !body ||\n body.orderableFieldName !== orderableFieldName ||\n body.docsToMove[0] !== movedIDFromRoute\n ) {\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('reorder-endpoint'),\n level: 'warn',\n message: 'reorder endpoint rejected request body',\n source: 'reorder-endpoint:body-rejected',\n })\n }\n\n return respond(400, {\n message: 'A valid reorder request is required.',\n })\n }\n\n if (body.target.id === movedIDFromRoute) {\n return respond(400, {\n message: 'Document is already in that position.',\n })\n }\n\n const movedID = toCollectionID({\n id: movedIDFromRoute,\n collectionSlug,\n req,\n })\n const targetID = toCollectionID({\n id: body.target.id,\n collectionSlug,\n req,\n })\n const accessError = await assertUpdateAccess({\n id: movedID,\n collectionSlug,\n data: {},\n req,\n })\n\n if (accessError) {\n return accessError\n }\n\n const flow = createFlowID('reorder-endpoint')\n const reorderStart = Date.now()\n const hasDrafts = collectionHasDrafts({ collectionSlug, req })\n\n if (!req.context) {\n req.context = {}\n }\n\n ;(req.context as Record<string, unknown>)[pageTreeMoveContextKey] = true\n ;(req.context as Record<string, unknown>)[DIAGNOSTICS_FLOW_CONTEXT_KEY] = flow\n\n const relatedDocsResult = await req.payload.find({\n collection: collectionSlug as never,\n depth: 0,\n draft: hasDrafts ? true : undefined,\n limit: 2,\n locale: getRequestedLocale(req) as never,\n overrideAccess: true,\n req,\n where: {\n id: {\n in: [movedID, targetID],\n },\n },\n } as never)\n const docsByID = new Map(\n (relatedDocsResult.docs as unknown as PageTreeSourceDoc[]).map((doc) => [\n stringifyDocID(doc.id),\n doc,\n ]),\n )\n const movedDoc = docsByID.get(movedIDFromRoute)\n const targetDoc = docsByID.get(body.target.id)\n\n if (!movedDoc) {\n return respond(404, {\n message: 'Document not found.',\n })\n }\n\n if (!targetDoc) {\n return respond(400, {\n message: 'Target document not found.',\n })\n }\n\n const movedParentID = getDocParentID(movedDoc, parentFieldSlug)\n const targetParentID = getDocParentID(targetDoc, parentFieldSlug)\n\n if (movedParentID !== targetParentID) {\n return respond(400, {\n message: 'Documents can only be reordered within the same parent.',\n })\n }\n\n const parentScopeWhere = getParentScopeWhere({\n parentFieldSlug,\n parentID:\n movedParentID === null\n ? null\n : toCollectionID({\n id: movedParentID,\n collectionSlug,\n req,\n }),\n })\n\n if (!body.target.key) {\n return initializeMissingOrderKeys({\n collectionSlug,\n diagnostics,\n flow,\n hasDrafts,\n orderableFieldName,\n parentScopeWhere,\n req,\n })\n }\n\n const beforeSnapshot = await readMainRowSnapshot({\n id: movedID,\n collectionSlug,\n fields: snapshotFields,\n req,\n })\n const backendDraftOrderBefore = diagnostics.enabled\n ? await readBackendSiblingOrder({\n collectionSlug,\n draft: hasDrafts ? true : undefined,\n orderableFieldName,\n parentScopeWhere,\n req,\n })\n : null\n const backendMainOrderBefore = diagnostics.enabled\n ? await readBackendSiblingOrder({\n collectionSlug,\n draft: false,\n orderableFieldName,\n parentScopeWhere,\n req,\n })\n : null\n const adjacentDoc = await req.payload.find({\n collection: collectionSlug as never,\n depth: 0,\n draft: hasDrafts ? true : undefined,\n limit: 1,\n locale: getRequestedLocale(req) as never,\n overrideAccess: true,\n pagination: false,\n req,\n select: { [orderableFieldName]: true } as never,\n sort: body.newKeyWillBe === 'greater' ? orderableFieldName : `-${orderableFieldName}`,\n where: combineWhereConstraints([\n {\n [orderableFieldName]: {\n [body.newKeyWillBe === 'greater' ? 'greater_than' : 'less_than']: body.target.key,\n },\n },\n parentScopeWhere,\n ]) as never,\n } as never)\n const adjacentDocKey = getOrderableKey(\n adjacentDoc.docs[0] as unknown as PageTreeSourceDoc | undefined,\n orderableFieldName,\n )\n const movedDocKey = getOrderableKey(movedDoc, orderableFieldName)\n const movedSlug = getDiagnosticDocString(movedDoc.slug, getRequestedLocale(req))\n const targetSlug = getDiagnosticDocString(targetDoc.slug, getRequestedLocale(req))\n const movedMainRowKey =\n typeof beforeSnapshot?.[orderableFieldName] === 'string' &&\n beforeSnapshot[orderableFieldName].length > 0\n ? beforeSnapshot[orderableFieldName]\n : movedDocKey\n const { orderValues, usedMovedKeyBoundary } = getOrderValuesBetween({\n adjacentDocKey,\n docsToMoveLength: body.docsToMove.length,\n movedBoundaryKey: movedMainRowKey,\n newKeyWillBe: body.newKeyWillBe,\n targetKey: body.target.key,\n })\n const orderValue = orderValues[0]\n\n if (!orderValue) {\n return respond(500, {\n message: 'Could not generate a new order key.',\n })\n }\n\n if (diagnostics.enabled) {\n diagnostics.log({\n collection: collectionSlug,\n data: {\n adjacentDocKey,\n backendOrderBefore: {\n draft: backendDraftOrderBefore,\n main: backendMainOrderBefore,\n },\n frontendOrder: body.frontendOrder ?? null,\n mainRowBefore: getMainRowOrderSnapshot(beforeSnapshot, orderableFieldName),\n movedDocKey,\n movedMainRowKey,\n movedSlug,\n newKeyWillBe: body.newKeyWillBe,\n orderableFieldName,\n orderValue,\n target: {\n slug: targetSlug,\n key: body.target.key,\n },\n usedMovedKeyBoundary,\n },\n flow,\n level: 'info',\n message: 'reorder endpoint entering: order key update only',\n source: 'reorder-endpoint:enter',\n })\n }\n\n try {\n const updateResult = await updateOrderValueSilently({\n id: movedID,\n collectionSlug,\n hasDrafts,\n orderableFieldName,\n orderValue,\n req,\n })\n\n if (diagnostics.enabled) {\n const afterSnapshot = await readMainRowSnapshot({\n id: movedID,\n collectionSlug,\n fields: snapshotFields,\n req,\n })\n const backendDraftOrderAfter = await readBackendSiblingOrder({\n collectionSlug,\n draft: hasDrafts ? true : undefined,\n orderableFieldName,\n parentScopeWhere,\n req,\n })\n const backendMainOrderAfter = await readBackendSiblingOrder({\n collectionSlug,\n draft: false,\n orderableFieldName,\n parentScopeWhere,\n req,\n })\n\n diagnostics.log({\n collection: collectionSlug,\n data: {\n backendOrderAfter: {\n draft: backendDraftOrderAfter,\n main: backendMainOrderAfter,\n },\n durMs: Date.now() - reorderStart,\n mainRowAfter: getMainRowOrderSnapshot(afterSnapshot, orderableFieldName),\n movedSlug,\n orderValue,\n updatedDraftVersion: updateResult.updatedDraftVersion,\n },\n flow,\n level: 'info',\n message: 'reorder endpoint order key update succeeded',\n source: 'reorder-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 name: error?.name,\n data: error?.data ?? null,\n durMs: Date.now() - reorderStart,\n message: error?.message,\n movedSlug,\n },\n flow,\n level: 'error',\n message: `reorder endpoint order key update failed: ${error?.message ?? 'unknown error'}`,\n source: 'reorder-endpoint:error',\n })\n\n throw err\n }\n\n return respond(200, {\n movedID: movedIDFromRoute,\n orderValues,\n success: true,\n })\n },\n method: 'post',\n path: '/:id/reorder',\n }\n}\n"],"names":["combineWhereConstraints","generateNKeysBetween","pageTreeMoveContextKey","createFlowID","DIAGNOSTICS_FLOW_CONTEXT_KEY","readMainRowSnapshot","getDocParentID","stringifyDocID","assertUpdateAccess","collectionHasDrafts","getRequestedLocale","normalizeID","respond","toCollectionID","SNAPSHOT_FIELDS","hasOwnProperty","value","key","Object","prototype","call","normalizeOptionalString","length","normalizeFrontendOrderEntry","fallbackIndex","Array","isArray","data","slug","index","Number","isFinite","orderKey","normalizeFrontendOrder","undefined","before","after","slice","map","entry","filter","Boolean","activeSlug","moveFromIndex","moveToIndex","newAfterRowSlug","newBeforeRowSlug","sort","targetSlug","normalizeReorderDocumentBody","incomingData","JSON","parse","target","docsToMove","newKeyWillBe","orderableFieldName","targetData","movedID","targetID","id","frontendOrder","readBodyFromRequest","req","lastAttempt","raw","source","directBody","body","json","jsonBody","text","textBody","getParentScopeWhere","args","parentFieldSlug","parentID","equals","getOrderableKey","doc","getDiagnosticDocString","locale","localizedValue","localeValue","firstString","values","find","getBackendOrderEntry","status","_status","getMainRowOrderSnapshot","snapshot","readBackendSiblingOrder","collectionSlug","draft","parentScopeWhere","result","payload","collection","depth","limit","overrideAccess","pagination","where","docs","getOrderValuesBetween","adjacentDocKey","docsToMoveLength","movedBoundaryKey","targetKey","orderValues","usedMovedKeyBoundary","readLatestVersion","versions","db","findVersions","latest","parent","latestVersion","version","updateLatestVersionOrder","orderValue","updateVersion","returning","versionData","createdAt","publishedLocale","updatedAt","updateOrderValueSilently","hasDrafts","updateOne","updatedDraftVersion","initializeMissingOrderKeys","diagnostics","flow","existingOrderedDocs","select","exists","missingOrderDocs","lastOrderValue","entries","docID","log","initializedCount","level","message","success","createReorderPageEndpoint","snapshotFields","handler","movedIDFromRoute","routeParams","enabled","rawBody","rawBodySource","accessError","reorderStart","Date","now","context","relatedDocsResult","in","docsByID","Map","movedDoc","get","targetDoc","movedParentID","targetParentID","beforeSnapshot","fields","backendDraftOrderBefore","backendMainOrderBefore","adjacentDoc","movedDocKey","movedSlug","movedMainRowKey","backendOrderBefore","main","mainRowBefore","updateResult","afterSnapshot","backendDraftOrderAfter","backendMainOrderAfter","backendOrderAfter","durMs","mainRowAfter","err","error","name","method","path"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/endpoints/createReorderPageEndpoint.ts"],"sourcesContent":["import type { Endpoint, PayloadRequest, Where } from 'payload'\n\nimport { combineWhereConstraints, generateNKeysBetween } from 'payload/shared'\n\nimport {\n pageTreeMoveContextKey,\n type PageTreeSourceDoc,\n pageTreeWriteContextKey,\n} from '../types.js'\nimport {\n createFlowID,\n type Diagnostics,\n DIAGNOSTICS_FLOW_CONTEXT_KEY,\n readMainRowSnapshot,\n} from '../utilities/diagnostics.js'\nimport { getDocParentID, stringifyDocID } from '../utilities/pageTree.js'\nimport {\n assertUpdateAccess,\n collectionHasDrafts,\n getRequestedLocale,\n normalizeID,\n respond,\n toCollectionID,\n} from './shared.js'\n\ntype ReorderDocumentRequestBody = {\n docsToMove: string[]\n frontendOrder?: ReorderFrontendOrderDiagnostic\n newKeyWillBe: 'greater' | 'less'\n orderableFieldName: string\n target: {\n id: string\n key: null | string\n }\n}\n\ntype ReorderFrontendOrderDiagnostic = {\n activeSlug: null | string\n after: ReorderFrontendOrderEntry[]\n before: ReorderFrontendOrderEntry[]\n moveFromIndex: number\n moveToIndex: number\n newAfterRowSlug: null | string\n newBeforeRowSlug: null | string\n sort: null | string\n targetSlug: null | string\n}\n\ntype ReorderFrontendOrderEntry = {\n index: number\n orderKey: null | string\n slug: null | string\n}\n\ntype ReorderBackendOrderEntry = {\n index: number\n orderKey: null | string\n slug: null | string\n status: null | string\n}\n\ntype RawBodyAttempt = {\n raw: unknown\n source: 'req.data' | 'req.json' | 'req.text'\n}\n\ntype VersionRecord = {\n createdAt?: string\n id?: number | string\n latest?: boolean\n parent?: number | string\n publishedLocale?: string\n updatedAt?: string\n version?: Record<string, unknown>\n} & Record<string, unknown>\n\nconst SNAPSHOT_FIELDS = ['_status'] as const\n\nfunction hasOwnProperty(value: object, key: PropertyKey): boolean {\n return Object.prototype.hasOwnProperty.call(value, key)\n}\n\nfunction normalizeOptionalString(value: unknown): null | string {\n return typeof value === 'string' && value.length > 0 ? value : null\n}\n\nfunction normalizeFrontendOrderEntry(\n value: unknown,\n fallbackIndex: number,\n): null | ReorderFrontendOrderEntry {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return null\n }\n\n const data = value as Record<string, unknown>\n\n return {\n slug: normalizeOptionalString(data.slug),\n index: typeof data.index === 'number' && Number.isFinite(data.index) ? data.index : fallbackIndex,\n orderKey: normalizeOptionalString(data.orderKey),\n }\n}\n\nfunction normalizeFrontendOrder(value: unknown): ReorderFrontendOrderDiagnostic | undefined {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return undefined\n }\n\n const data = value as Record<string, unknown>\n\n if (!Array.isArray(data.before) || !Array.isArray(data.after)) {\n return undefined\n }\n\n const before = data.before\n .slice(0, 250)\n .map((entry, index) => normalizeFrontendOrderEntry(entry, index))\n .filter((entry): entry is ReorderFrontendOrderEntry => Boolean(entry))\n const after = data.after\n .slice(0, 250)\n .map((entry, index) => normalizeFrontendOrderEntry(entry, index))\n .filter((entry): entry is ReorderFrontendOrderEntry => Boolean(entry))\n\n return {\n activeSlug: normalizeOptionalString(data.activeSlug),\n after,\n before,\n moveFromIndex:\n typeof data.moveFromIndex === 'number' && Number.isFinite(data.moveFromIndex)\n ? data.moveFromIndex\n : -1,\n moveToIndex:\n typeof data.moveToIndex === 'number' && Number.isFinite(data.moveToIndex)\n ? data.moveToIndex\n : -1,\n newAfterRowSlug: normalizeOptionalString(data.newAfterRowSlug),\n newBeforeRowSlug: normalizeOptionalString(data.newBeforeRowSlug),\n sort: normalizeOptionalString(data.sort),\n targetSlug: normalizeOptionalString(data.targetSlug),\n }\n}\n\nfunction normalizeReorderDocumentBody(value: unknown): null | ReorderDocumentRequestBody {\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 const data = incomingData as Record<string, unknown>\n const target = data.target\n\n if (!Array.isArray(data.docsToMove) || data.docsToMove.length !== 1) {\n return null\n }\n\n if (data.newKeyWillBe !== 'greater' && data.newKeyWillBe !== 'less') {\n return null\n }\n\n if (typeof data.orderableFieldName !== 'string' || data.orderableFieldName.length === 0) {\n return null\n }\n\n if (!target || typeof target !== 'object' || Array.isArray(target)) {\n return null\n }\n\n const targetData = target as Record<string, unknown>\n const movedID = normalizeID(data.docsToMove[0])\n const targetID = normalizeID(targetData.id)\n\n if (!movedID || !targetID) {\n return null\n }\n\n const key = hasOwnProperty(targetData, 'key') ? targetData.key : null\n\n if (key !== null && key !== undefined && typeof key !== 'string') {\n return null\n }\n\n return {\n docsToMove: [movedID],\n frontendOrder: normalizeFrontendOrder(data.frontendOrder),\n newKeyWillBe: data.newKeyWillBe,\n orderableFieldName: data.orderableFieldName,\n target: {\n id: targetID,\n key: key || null,\n },\n }\n}\n\nasync function readBodyFromRequest(\n req: PayloadRequest,\n): Promise<{ body: null | ReorderDocumentRequestBody; 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 = normalizeReorderDocumentBody(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 = normalizeReorderDocumentBody(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 = normalizeReorderDocumentBody(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\nfunction getParentScopeWhere(args: {\n parentFieldSlug: string\n parentID: null | number | string\n}): Where {\n const { parentFieldSlug, parentID } = args\n\n return {\n [parentFieldSlug]: {\n equals: parentID,\n },\n } as Where\n}\n\nfunction getOrderableKey(doc: PageTreeSourceDoc | undefined, orderableFieldName: string) {\n const value = doc?.[orderableFieldName]\n\n return typeof value === 'string' && value.length > 0 ? value : null\n}\n\nfunction getDiagnosticDocString(value: unknown, locale?: string): null | string {\n if (typeof value === 'string' && value.length > 0) {\n return value\n }\n\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return null\n }\n\n const localizedValue = value as Record<string, unknown>\n const localeValue = locale ? localizedValue[locale] : undefined\n\n if (typeof localeValue === 'string' && localeValue.length > 0) {\n return localeValue\n }\n\n const firstString = Object.values(localizedValue).find(\n (entry): entry is string => typeof entry === 'string' && entry.length > 0,\n )\n\n return firstString ?? null\n}\n\nfunction getBackendOrderEntry(args: {\n doc: PageTreeSourceDoc\n index: number\n locale?: string\n orderableFieldName: string\n}): ReorderBackendOrderEntry {\n const { doc, index, locale, orderableFieldName } = args\n\n return {\n slug: getDiagnosticDocString(doc.slug, locale),\n index,\n orderKey: getOrderableKey(doc, orderableFieldName),\n status: getDiagnosticDocString(doc._status, locale),\n }\n}\n\nfunction getMainRowOrderSnapshot(\n snapshot: null | Record<string, unknown>,\n orderableFieldName: string,\n): { orderKey: null | string; status: null | string } | null {\n if (!snapshot) {\n return null\n }\n\n return {\n orderKey: normalizeOptionalString(snapshot[orderableFieldName]),\n status: normalizeOptionalString(snapshot._status),\n }\n}\n\nasync function readBackendSiblingOrder(args: {\n collectionSlug: string\n draft?: boolean\n orderableFieldName: string\n parentScopeWhere: Where\n req: PayloadRequest\n}): Promise<ReorderBackendOrderEntry[]> {\n const { collectionSlug, draft, orderableFieldName, parentScopeWhere, req } = args\n const locale = getRequestedLocale(req)\n\n try {\n const result = await req.payload.find({\n collection: collectionSlug as never,\n depth: 0,\n draft: draft as never,\n limit: 250,\n locale: locale as never,\n overrideAccess: true,\n pagination: false,\n req,\n sort: orderableFieldName,\n where: parentScopeWhere as never,\n } as never)\n\n return (result.docs as unknown as PageTreeSourceDoc[]).map((doc, index) =>\n getBackendOrderEntry({\n doc,\n index,\n locale,\n orderableFieldName,\n }),\n )\n } catch {\n return []\n }\n}\n\nfunction getOrderValuesBetween(args: {\n adjacentDocKey: null | string\n docsToMoveLength: number\n movedBoundaryKey: null | string\n newKeyWillBe: ReorderDocumentRequestBody['newKeyWillBe']\n targetKey: string\n}): { orderValues: string[]; usedMovedKeyBoundary: boolean } {\n const { adjacentDocKey, docsToMoveLength, movedBoundaryKey, newKeyWillBe, targetKey } = args\n const orderValues =\n newKeyWillBe === 'greater'\n ? generateNKeysBetween(targetKey, adjacentDocKey, docsToMoveLength)\n : generateNKeysBetween(adjacentDocKey, targetKey, docsToMoveLength)\n\n if (orderValues[0] !== movedBoundaryKey) {\n return { orderValues, usedMovedKeyBoundary: false }\n }\n\n if (newKeyWillBe === 'greater' && movedBoundaryKey && movedBoundaryKey > targetKey) {\n return {\n orderValues: generateNKeysBetween(targetKey, movedBoundaryKey, docsToMoveLength),\n usedMovedKeyBoundary: true,\n }\n }\n\n if (newKeyWillBe === 'less' && movedBoundaryKey && movedBoundaryKey < targetKey) {\n return {\n orderValues: generateNKeysBetween(movedBoundaryKey, targetKey, docsToMoveLength),\n usedMovedKeyBoundary: true,\n }\n }\n\n return { orderValues, usedMovedKeyBoundary: false }\n}\n\nasync function readLatestVersion(args: {\n collectionSlug: string\n id: number | string\n req: PayloadRequest\n}): Promise<null | VersionRecord> {\n const { id, collectionSlug, req } = args\n const versions = await req.payload.db.findVersions({\n collection: collectionSlug as never,\n limit: 1,\n pagination: false,\n req,\n sort: '-updatedAt',\n where: {\n latest: {\n equals: true,\n },\n parent: {\n equals: id,\n },\n },\n } as never)\n const latestVersion = versions.docs[0] as undefined | VersionRecord\n\n if (!latestVersion?.version) {\n return null\n }\n\n return latestVersion\n}\n\nasync function updateLatestVersionOrder(args: {\n collectionSlug: string\n id: number | string\n orderableFieldName: string\n orderValue: string\n req: PayloadRequest\n}): Promise<boolean> {\n const { id, collectionSlug, orderableFieldName, orderValue, req } = args\n const latestVersion = await readLatestVersion({\n id,\n collectionSlug,\n req,\n })\n\n if (!latestVersion?.id || !latestVersion.version) {\n return false\n }\n\n await req.payload.db.updateVersion({\n id: latestVersion.id as never,\n collection: collectionSlug as never,\n locale: getRequestedLocale(req) as never,\n req,\n returning: false,\n versionData: {\n createdAt: latestVersion.createdAt,\n latest: latestVersion.latest,\n parent: id,\n publishedLocale: latestVersion.publishedLocale,\n updatedAt: latestVersion.updatedAt,\n version: {\n ...latestVersion.version,\n [orderableFieldName]: orderValue,\n },\n },\n } as never)\n\n return true\n}\n\nasync function updateOrderValueSilently(args: {\n collectionSlug: string\n hasDrafts: boolean\n id: number | string\n orderableFieldName: string\n orderValue: string\n req: PayloadRequest\n}): Promise<{ updatedDraftVersion: boolean }> {\n const { id, collectionSlug, hasDrafts, orderableFieldName, orderValue, req } = args\n\n await req.payload.db.updateOne({\n id: id as never,\n collection: collectionSlug as never,\n data: {\n [orderableFieldName]: orderValue,\n updatedAt: null,\n },\n locale: getRequestedLocale(req) as never,\n req,\n returning: false,\n } as never)\n\n const updatedDraftVersion = hasDrafts\n ? await updateLatestVersionOrder({\n id,\n collectionSlug,\n orderableFieldName,\n orderValue,\n req,\n })\n : false\n\n return {\n updatedDraftVersion,\n }\n}\n\nasync function initializeMissingOrderKeys(args: {\n collectionSlug: string\n diagnostics: Diagnostics\n flow: string\n hasDrafts: boolean\n orderableFieldName: string\n parentScopeWhere: Where\n req: PayloadRequest\n}): Promise<Response> {\n const { collectionSlug, diagnostics, flow, hasDrafts, orderableFieldName, parentScopeWhere, req } =\n args\n const existingOrderedDocs = await req.payload.find({\n collection: collectionSlug as never,\n depth: 0,\n draft: hasDrafts ? true : undefined,\n limit: 1,\n locale: getRequestedLocale(req) as never,\n overrideAccess: true,\n pagination: false,\n req,\n select: { [orderableFieldName]: true } as never,\n sort: `-${orderableFieldName}`,\n where: combineWhereConstraints([\n {\n [orderableFieldName]: {\n exists: true,\n },\n },\n parentScopeWhere,\n ]) as never,\n } as never)\n const missingOrderDocs = await req.payload.find({\n collection: collectionSlug as never,\n depth: 0,\n draft: hasDrafts ? true : undefined,\n limit: 0,\n locale: getRequestedLocale(req) as never,\n overrideAccess: true,\n pagination: false,\n req,\n select: { [orderableFieldName]: true } as never,\n where: combineWhereConstraints([\n {\n [orderableFieldName]: {\n exists: false,\n },\n },\n parentScopeWhere,\n ]) as never,\n } as never)\n const lastOrderValue = getOrderableKey(\n existingOrderedDocs.docs[0] as unknown as PageTreeSourceDoc | undefined,\n orderableFieldName,\n )\n const orderValues = generateNKeysBetween(lastOrderValue, null, missingOrderDocs.docs.length)\n\n for (const [index, doc] of (missingOrderDocs.docs as unknown as PageTreeSourceDoc[]).entries()) {\n const docID = doc.id\n const orderValue = orderValues[index]\n\n if (\n orderValue &&\n (typeof docID === 'number' || typeof docID === 'string')\n ) {\n await updateOrderValueSilently({\n id: docID,\n collectionSlug,\n hasDrafts,\n orderableFieldName,\n orderValue,\n req,\n })\n }\n }\n\n diagnostics.log({\n collection: collectionSlug,\n data: {\n initializedCount: missingOrderDocs.docs.length,\n orderableFieldName,\n },\n flow,\n level: 'info',\n message: 'reorder endpoint initialized missing order keys',\n source: 'reorder-endpoint:initial-migration',\n })\n\n return respond(200, {\n message: 'initial migration',\n success: true,\n })\n}\n\nexport function createReorderPageEndpoint(args: {\n collectionSlug: string\n diagnostics: Diagnostics\n orderableFieldName: string\n parentFieldSlug: string\n}): Endpoint {\n const { collectionSlug, diagnostics, orderableFieldName, parentFieldSlug } = args\n const snapshotFields = [...SNAPSHOT_FIELDS, parentFieldSlug, orderableFieldName]\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 (\n !body ||\n body.orderableFieldName !== orderableFieldName ||\n body.docsToMove[0] !== movedIDFromRoute\n ) {\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('reorder-endpoint'),\n level: 'warn',\n message: 'reorder endpoint rejected request body',\n source: 'reorder-endpoint:body-rejected',\n })\n }\n\n return respond(400, {\n message: 'A valid reorder request is required.',\n })\n }\n\n if (body.target.id === movedIDFromRoute) {\n return respond(400, {\n message: 'Document is already in that position.',\n })\n }\n\n const movedID = toCollectionID({\n id: movedIDFromRoute,\n collectionSlug,\n req,\n })\n const targetID = toCollectionID({\n id: body.target.id,\n collectionSlug,\n req,\n })\n const accessError = await assertUpdateAccess({\n id: movedID,\n collectionSlug,\n data: {},\n req,\n })\n\n if (accessError) {\n return accessError\n }\n\n const flow = createFlowID('reorder-endpoint')\n const reorderStart = Date.now()\n const hasDrafts = collectionHasDrafts({ collectionSlug, req })\n\n if (!req.context) {\n req.context = {}\n }\n\n // A reorder only writes the order key, never publishing state, so it\n // always carries the deploy opt-out flag.\n ;(req.context as Record<string, unknown>)[pageTreeMoveContextKey] = true\n ;(req.context as Record<string, unknown>)[pageTreeWriteContextKey] = true\n ;(req.context as Record<string, unknown>)[DIAGNOSTICS_FLOW_CONTEXT_KEY] = flow\n\n const relatedDocsResult = await req.payload.find({\n collection: collectionSlug as never,\n depth: 0,\n draft: hasDrafts ? true : undefined,\n limit: 2,\n locale: getRequestedLocale(req) as never,\n overrideAccess: true,\n req,\n where: {\n id: {\n in: [movedID, targetID],\n },\n },\n } as never)\n const docsByID = new Map(\n (relatedDocsResult.docs as unknown as PageTreeSourceDoc[]).map((doc) => [\n stringifyDocID(doc.id),\n doc,\n ]),\n )\n const movedDoc = docsByID.get(movedIDFromRoute)\n const targetDoc = docsByID.get(body.target.id)\n\n if (!movedDoc) {\n return respond(404, {\n message: 'Document not found.',\n })\n }\n\n if (!targetDoc) {\n return respond(400, {\n message: 'Target document not found.',\n })\n }\n\n const movedParentID = getDocParentID(movedDoc, parentFieldSlug)\n const targetParentID = getDocParentID(targetDoc, parentFieldSlug)\n\n if (movedParentID !== targetParentID) {\n return respond(400, {\n message: 'Documents can only be reordered within the same parent.',\n })\n }\n\n const parentScopeWhere = getParentScopeWhere({\n parentFieldSlug,\n parentID:\n movedParentID === null\n ? null\n : toCollectionID({\n id: movedParentID,\n collectionSlug,\n req,\n }),\n })\n\n if (!body.target.key) {\n return initializeMissingOrderKeys({\n collectionSlug,\n diagnostics,\n flow,\n hasDrafts,\n orderableFieldName,\n parentScopeWhere,\n req,\n })\n }\n\n const beforeSnapshot = await readMainRowSnapshot({\n id: movedID,\n collectionSlug,\n fields: snapshotFields,\n req,\n })\n const backendDraftOrderBefore = diagnostics.enabled\n ? await readBackendSiblingOrder({\n collectionSlug,\n draft: hasDrafts ? true : undefined,\n orderableFieldName,\n parentScopeWhere,\n req,\n })\n : null\n const backendMainOrderBefore = diagnostics.enabled\n ? await readBackendSiblingOrder({\n collectionSlug,\n draft: false,\n orderableFieldName,\n parentScopeWhere,\n req,\n })\n : null\n const adjacentDoc = await req.payload.find({\n collection: collectionSlug as never,\n depth: 0,\n draft: hasDrafts ? true : undefined,\n limit: 1,\n locale: getRequestedLocale(req) as never,\n overrideAccess: true,\n pagination: false,\n req,\n select: { [orderableFieldName]: true } as never,\n sort: body.newKeyWillBe === 'greater' ? orderableFieldName : `-${orderableFieldName}`,\n where: combineWhereConstraints([\n {\n [orderableFieldName]: {\n [body.newKeyWillBe === 'greater' ? 'greater_than' : 'less_than']: body.target.key,\n },\n },\n parentScopeWhere,\n ]) as never,\n } as never)\n const adjacentDocKey = getOrderableKey(\n adjacentDoc.docs[0] as unknown as PageTreeSourceDoc | undefined,\n orderableFieldName,\n )\n const movedDocKey = getOrderableKey(movedDoc, orderableFieldName)\n const movedSlug = getDiagnosticDocString(movedDoc.slug, getRequestedLocale(req))\n const targetSlug = getDiagnosticDocString(targetDoc.slug, getRequestedLocale(req))\n const movedMainRowKey =\n typeof beforeSnapshot?.[orderableFieldName] === 'string' &&\n beforeSnapshot[orderableFieldName].length > 0\n ? beforeSnapshot[orderableFieldName]\n : movedDocKey\n const { orderValues, usedMovedKeyBoundary } = getOrderValuesBetween({\n adjacentDocKey,\n docsToMoveLength: body.docsToMove.length,\n movedBoundaryKey: movedMainRowKey,\n newKeyWillBe: body.newKeyWillBe,\n targetKey: body.target.key,\n })\n const orderValue = orderValues[0]\n\n if (!orderValue) {\n return respond(500, {\n message: 'Could not generate a new order key.',\n })\n }\n\n if (diagnostics.enabled) {\n diagnostics.log({\n collection: collectionSlug,\n data: {\n adjacentDocKey,\n backendOrderBefore: {\n draft: backendDraftOrderBefore,\n main: backendMainOrderBefore,\n },\n frontendOrder: body.frontendOrder ?? null,\n mainRowBefore: getMainRowOrderSnapshot(beforeSnapshot, orderableFieldName),\n movedDocKey,\n movedMainRowKey,\n movedSlug,\n newKeyWillBe: body.newKeyWillBe,\n orderableFieldName,\n orderValue,\n target: {\n slug: targetSlug,\n key: body.target.key,\n },\n usedMovedKeyBoundary,\n },\n flow,\n level: 'info',\n message: 'reorder endpoint entering: order key update only',\n source: 'reorder-endpoint:enter',\n })\n }\n\n try {\n const updateResult = await updateOrderValueSilently({\n id: movedID,\n collectionSlug,\n hasDrafts,\n orderableFieldName,\n orderValue,\n req,\n })\n\n if (diagnostics.enabled) {\n const afterSnapshot = await readMainRowSnapshot({\n id: movedID,\n collectionSlug,\n fields: snapshotFields,\n req,\n })\n const backendDraftOrderAfter = await readBackendSiblingOrder({\n collectionSlug,\n draft: hasDrafts ? true : undefined,\n orderableFieldName,\n parentScopeWhere,\n req,\n })\n const backendMainOrderAfter = await readBackendSiblingOrder({\n collectionSlug,\n draft: false,\n orderableFieldName,\n parentScopeWhere,\n req,\n })\n\n diagnostics.log({\n collection: collectionSlug,\n data: {\n backendOrderAfter: {\n draft: backendDraftOrderAfter,\n main: backendMainOrderAfter,\n },\n durMs: Date.now() - reorderStart,\n mainRowAfter: getMainRowOrderSnapshot(afterSnapshot, orderableFieldName),\n movedSlug,\n orderValue,\n updatedDraftVersion: updateResult.updatedDraftVersion,\n },\n flow,\n level: 'info',\n message: 'reorder endpoint order key update succeeded',\n source: 'reorder-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 name: error?.name,\n data: error?.data ?? null,\n durMs: Date.now() - reorderStart,\n message: error?.message,\n movedSlug,\n },\n flow,\n level: 'error',\n message: `reorder endpoint order key update failed: ${error?.message ?? 'unknown error'}`,\n source: 'reorder-endpoint:error',\n })\n\n throw err\n }\n\n return respond(200, {\n movedID: movedIDFromRoute,\n orderValues,\n success: true,\n })\n },\n method: 'post',\n path: '/:id/reorder',\n }\n}\n"],"names":["combineWhereConstraints","generateNKeysBetween","pageTreeMoveContextKey","pageTreeWriteContextKey","createFlowID","DIAGNOSTICS_FLOW_CONTEXT_KEY","readMainRowSnapshot","getDocParentID","stringifyDocID","assertUpdateAccess","collectionHasDrafts","getRequestedLocale","normalizeID","respond","toCollectionID","SNAPSHOT_FIELDS","hasOwnProperty","value","key","Object","prototype","call","normalizeOptionalString","length","normalizeFrontendOrderEntry","fallbackIndex","Array","isArray","data","slug","index","Number","isFinite","orderKey","normalizeFrontendOrder","undefined","before","after","slice","map","entry","filter","Boolean","activeSlug","moveFromIndex","moveToIndex","newAfterRowSlug","newBeforeRowSlug","sort","targetSlug","normalizeReorderDocumentBody","incomingData","JSON","parse","target","docsToMove","newKeyWillBe","orderableFieldName","targetData","movedID","targetID","id","frontendOrder","readBodyFromRequest","req","lastAttempt","raw","source","directBody","body","json","jsonBody","text","textBody","getParentScopeWhere","args","parentFieldSlug","parentID","equals","getOrderableKey","doc","getDiagnosticDocString","locale","localizedValue","localeValue","firstString","values","find","getBackendOrderEntry","status","_status","getMainRowOrderSnapshot","snapshot","readBackendSiblingOrder","collectionSlug","draft","parentScopeWhere","result","payload","collection","depth","limit","overrideAccess","pagination","where","docs","getOrderValuesBetween","adjacentDocKey","docsToMoveLength","movedBoundaryKey","targetKey","orderValues","usedMovedKeyBoundary","readLatestVersion","versions","db","findVersions","latest","parent","latestVersion","version","updateLatestVersionOrder","orderValue","updateVersion","returning","versionData","createdAt","publishedLocale","updatedAt","updateOrderValueSilently","hasDrafts","updateOne","updatedDraftVersion","initializeMissingOrderKeys","diagnostics","flow","existingOrderedDocs","select","exists","missingOrderDocs","lastOrderValue","entries","docID","log","initializedCount","level","message","success","createReorderPageEndpoint","snapshotFields","handler","movedIDFromRoute","routeParams","enabled","rawBody","rawBodySource","accessError","reorderStart","Date","now","context","relatedDocsResult","in","docsByID","Map","movedDoc","get","targetDoc","movedParentID","targetParentID","beforeSnapshot","fields","backendDraftOrderBefore","backendMainOrderBefore","adjacentDoc","movedDocKey","movedSlug","movedMainRowKey","backendOrderBefore","main","mainRowBefore","updateResult","afterSnapshot","backendDraftOrderAfter","backendMainOrderAfter","backendOrderAfter","durMs","mainRowAfter","err","error","name","method","path"],"mappings":"AAEA,SAASA,uBAAuB,EAAEC,oBAAoB,QAAQ,iBAAgB;AAE9E,SACEC,sBAAsB,EAEtBC,uBAAuB,QAClB,cAAa;AACpB,SACEC,YAAY,EAEZC,4BAA4B,EAC5BC,mBAAmB,QACd,8BAA6B;AACpC,SAASC,cAAc,EAAEC,cAAc,QAAQ,2BAA0B;AACzE,SACEC,kBAAkB,EAClBC,mBAAmB,EACnBC,kBAAkB,EAClBC,WAAW,EACXC,OAAO,EACPC,cAAc,QACT,cAAa;AAqDpB,MAAMC,kBAAkB;IAAC;CAAU;AAEnC,SAASC,eAAeC,KAAa,EAAEC,GAAgB;IACrD,OAAOC,OAAOC,SAAS,CAACJ,cAAc,CAACK,IAAI,CAACJ,OAAOC;AACrD;AAEA,SAASI,wBAAwBL,KAAc;IAC7C,OAAO,OAAOA,UAAU,YAAYA,MAAMM,MAAM,GAAG,IAAIN,QAAQ;AACjE;AAEA,SAASO,4BACPP,KAAc,EACdQ,aAAqB;IAErB,IAAI,CAACR,SAAS,OAAOA,UAAU,YAAYS,MAAMC,OAAO,CAACV,QAAQ;QAC/D,OAAO;IACT;IAEA,MAAMW,OAAOX;IAEb,OAAO;QACLY,MAAMP,wBAAwBM,KAAKC,IAAI;QACvCC,OAAO,OAAOF,KAAKE,KAAK,KAAK,YAAYC,OAAOC,QAAQ,CAACJ,KAAKE,KAAK,IAAIF,KAAKE,KAAK,GAAGL;QACpFQ,UAAUX,wBAAwBM,KAAKK,QAAQ;IACjD;AACF;AAEA,SAASC,uBAAuBjB,KAAc;IAC5C,IAAI,CAACA,SAAS,OAAOA,UAAU,YAAYS,MAAMC,OAAO,CAACV,QAAQ;QAC/D,OAAOkB;IACT;IAEA,MAAMP,OAAOX;IAEb,IAAI,CAACS,MAAMC,OAAO,CAACC,KAAKQ,MAAM,KAAK,CAACV,MAAMC,OAAO,CAACC,KAAKS,KAAK,GAAG;QAC7D,OAAOF;IACT;IAEA,MAAMC,SAASR,KAAKQ,MAAM,CACvBE,KAAK,CAAC,GAAG,KACTC,GAAG,CAAC,CAACC,OAAOV,QAAUN,4BAA4BgB,OAAOV,QACzDW,MAAM,CAAC,CAACD,QAA8CE,QAAQF;IACjE,MAAMH,QAAQT,KAAKS,KAAK,CACrBC,KAAK,CAAC,GAAG,KACTC,GAAG,CAAC,CAACC,OAAOV,QAAUN,4BAA4BgB,OAAOV,QACzDW,MAAM,CAAC,CAACD,QAA8CE,QAAQF;IAEjE,OAAO;QACLG,YAAYrB,wBAAwBM,KAAKe,UAAU;QACnDN;QACAD;QACAQ,eACE,OAAOhB,KAAKgB,aAAa,KAAK,YAAYb,OAAOC,QAAQ,CAACJ,KAAKgB,aAAa,IACxEhB,KAAKgB,aAAa,GAClB,CAAC;QACPC,aACE,OAAOjB,KAAKiB,WAAW,KAAK,YAAYd,OAAOC,QAAQ,CAACJ,KAAKiB,WAAW,IACpEjB,KAAKiB,WAAW,GAChB,CAAC;QACPC,iBAAiBxB,wBAAwBM,KAAKkB,eAAe;QAC7DC,kBAAkBzB,wBAAwBM,KAAKmB,gBAAgB;QAC/DC,MAAM1B,wBAAwBM,KAAKoB,IAAI;QACvCC,YAAY3B,wBAAwBM,KAAKqB,UAAU;IACrD;AACF;AAEA,SAASC,6BAA6BjC,KAAc;IAClD,MAAMkC,eACJ,OAAOlC,UAAU,WACb,AAAC,CAAA;QACC,IAAI;YACF,OAAOmC,KAAKC,KAAK,CAACpC;QACpB,EAAE,OAAM;YACN,OAAO;QACT;IACF,CAAA,MACAA;IAEN,IAAI,CAACkC,gBAAgB,OAAOA,iBAAiB,YAAYzB,MAAMC,OAAO,CAACwB,eAAe;QACpF,OAAO;IACT;IAEA,MAAMvB,OAAOuB;IACb,MAAMG,SAAS1B,KAAK0B,MAAM;IAE1B,IAAI,CAAC5B,MAAMC,OAAO,CAACC,KAAK2B,UAAU,KAAK3B,KAAK2B,UAAU,CAAChC,MAAM,KAAK,GAAG;QACnE,OAAO;IACT;IAEA,IAAIK,KAAK4B,YAAY,KAAK,aAAa5B,KAAK4B,YAAY,KAAK,QAAQ;QACnE,OAAO;IACT;IAEA,IAAI,OAAO5B,KAAK6B,kBAAkB,KAAK,YAAY7B,KAAK6B,kBAAkB,CAAClC,MAAM,KAAK,GAAG;QACvF,OAAO;IACT;IAEA,IAAI,CAAC+B,UAAU,OAAOA,WAAW,YAAY5B,MAAMC,OAAO,CAAC2B,SAAS;QAClE,OAAO;IACT;IAEA,MAAMI,aAAaJ;IACnB,MAAMK,UAAU/C,YAAYgB,KAAK2B,UAAU,CAAC,EAAE;IAC9C,MAAMK,WAAWhD,YAAY8C,WAAWG,EAAE;IAE1C,IAAI,CAACF,WAAW,CAACC,UAAU;QACzB,OAAO;IACT;IAEA,MAAM1C,MAAMF,eAAe0C,YAAY,SAASA,WAAWxC,GAAG,GAAG;IAEjE,IAAIA,QAAQ,QAAQA,QAAQiB,aAAa,OAAOjB,QAAQ,UAAU;QAChE,OAAO;IACT;IAEA,OAAO;QACLqC,YAAY;YAACI;SAAQ;QACrBG,eAAe5B,uBAAuBN,KAAKkC,aAAa;QACxDN,cAAc5B,KAAK4B,YAAY;QAC/BC,oBAAoB7B,KAAK6B,kBAAkB;QAC3CH,QAAQ;YACNO,IAAID;YACJ1C,KAAKA,OAAO;QACd;IACF;AACF;AAEA,eAAe6C,oBACbC,GAAmB;IAEnB,IAAIC,cAAqC;IAEzC,IAAID,IAAIpC,IAAI,KAAKO,aAAa6B,IAAIpC,IAAI,KAAK,MAAM;QAC/CqC,cAAc;YAAEC,KAAKF,IAAIpC,IAAI;YAAEuC,QAAQ;QAAW;QAClD,MAAMC,aAAalB,6BAA6Bc,IAAIpC,IAAI;QAExD,IAAIwC,YAAY;YACd,OAAO;gBAAEC,MAAMD;gBAAYH;YAAY;QACzC;IACF;IAEA,IAAI,OAAOD,IAAIM,IAAI,KAAK,YAAY;QAClC,IAAI;YACF,MAAMJ,MAAM,MAAMF,IAAIM,IAAI;YAC1BL,cAAc;gBAAEC;gBAAKC,QAAQ;YAAW;YACxC,MAAMI,WAAWrB,6BAA6BgB;YAE9C,IAAIK,UAAU;gBACZ,OAAO;oBAAEF,MAAME;oBAAUN;gBAAY;YACvC;QACF,EAAE,OAAM;QACN,sFAAsF;QACxF;IACF;IAEA,IAAI,OAAOD,IAAIQ,IAAI,KAAK,YAAY;QAClC,IAAI;YACF,MAAMN,MAAM,MAAMF,IAAIQ,IAAI;YAC1BP,cAAc;gBAAEC;gBAAKC,QAAQ;YAAW;YACxC,MAAMM,WAAWvB,6BAA6BgB;YAE9C,IAAIO,UAAU;gBACZ,OAAO;oBAAEJ,MAAMI;oBAAUR;gBAAY;YACvC;QACF,EAAE,OAAM;YACN,OAAO;gBAAEI,MAAM;gBAAMJ;YAAY;QACnC;IACF;IAEA,OAAO;QAAEI,MAAM;QAAMJ;IAAY;AACnC;AAEA,SAASS,oBAAoBC,IAG5B;IACC,MAAM,EAAEC,eAAe,EAAEC,QAAQ,EAAE,GAAGF;IAEtC,OAAO;QACL,CAACC,gBAAgB,EAAE;YACjBE,QAAQD;QACV;IACF;AACF;AAEA,SAASE,gBAAgBC,GAAkC,EAAEvB,kBAA0B;IACrF,MAAMxC,QAAQ+D,KAAK,CAACvB,mBAAmB;IAEvC,OAAO,OAAOxC,UAAU,YAAYA,MAAMM,MAAM,GAAG,IAAIN,QAAQ;AACjE;AAEA,SAASgE,uBAAuBhE,KAAc,EAAEiE,MAAe;IAC7D,IAAI,OAAOjE,UAAU,YAAYA,MAAMM,MAAM,GAAG,GAAG;QACjD,OAAON;IACT;IAEA,IAAI,CAACA,SAAS,OAAOA,UAAU,YAAYS,MAAMC,OAAO,CAACV,QAAQ;QAC/D,OAAO;IACT;IAEA,MAAMkE,iBAAiBlE;IACvB,MAAMmE,cAAcF,SAASC,cAAc,CAACD,OAAO,GAAG/C;IAEtD,IAAI,OAAOiD,gBAAgB,YAAYA,YAAY7D,MAAM,GAAG,GAAG;QAC7D,OAAO6D;IACT;IAEA,MAAMC,cAAclE,OAAOmE,MAAM,CAACH,gBAAgBI,IAAI,CACpD,CAAC/C,QAA2B,OAAOA,UAAU,YAAYA,MAAMjB,MAAM,GAAG;IAG1E,OAAO8D,eAAe;AACxB;AAEA,SAASG,qBAAqBb,IAK7B;IACC,MAAM,EAAEK,GAAG,EAAElD,KAAK,EAAEoD,MAAM,EAAEzB,kBAAkB,EAAE,GAAGkB;IAEnD,OAAO;QACL9C,MAAMoD,uBAAuBD,IAAInD,IAAI,EAAEqD;QACvCpD;QACAG,UAAU8C,gBAAgBC,KAAKvB;QAC/BgC,QAAQR,uBAAuBD,IAAIU,OAAO,EAAER;IAC9C;AACF;AAEA,SAASS,wBACPC,QAAwC,EACxCnC,kBAA0B;IAE1B,IAAI,CAACmC,UAAU;QACb,OAAO;IACT;IAEA,OAAO;QACL3D,UAAUX,wBAAwBsE,QAAQ,CAACnC,mBAAmB;QAC9DgC,QAAQnE,wBAAwBsE,SAASF,OAAO;IAClD;AACF;AAEA,eAAeG,wBAAwBlB,IAMtC;IACC,MAAM,EAAEmB,cAAc,EAAEC,KAAK,EAAEtC,kBAAkB,EAAEuC,gBAAgB,EAAEhC,GAAG,EAAE,GAAGW;IAC7E,MAAMO,SAASvE,mBAAmBqD;IAElC,IAAI;QACF,MAAMiC,SAAS,MAAMjC,IAAIkC,OAAO,CAACX,IAAI,CAAC;YACpCY,YAAYL;YACZM,OAAO;YACPL,OAAOA;YACPM,OAAO;YACPnB,QAAQA;YACRoB,gBAAgB;YAChBC,YAAY;YACZvC;YACAhB,MAAMS;YACN+C,OAAOR;QACT;QAEA,OAAO,AAACC,OAAOQ,IAAI,CAAoClE,GAAG,CAAC,CAACyC,KAAKlD,QAC/D0D,qBAAqB;gBACnBR;gBACAlD;gBACAoD;gBACAzB;YACF;IAEJ,EAAE,OAAM;QACN,OAAO,EAAE;IACX;AACF;AAEA,SAASiD,sBAAsB/B,IAM9B;IACC,MAAM,EAAEgC,cAAc,EAAEC,gBAAgB,EAAEC,gBAAgB,EAAErD,YAAY,EAAEsD,SAAS,EAAE,GAAGnC;IACxF,MAAMoC,cACJvD,iBAAiB,YACbvD,qBAAqB6G,WAAWH,gBAAgBC,oBAChD3G,qBAAqB0G,gBAAgBG,WAAWF;IAEtD,IAAIG,WAAW,CAAC,EAAE,KAAKF,kBAAkB;QACvC,OAAO;YAAEE;YAAaC,sBAAsB;QAAM;IACpD;IAEA,IAAIxD,iBAAiB,aAAaqD,oBAAoBA,mBAAmBC,WAAW;QAClF,OAAO;YACLC,aAAa9G,qBAAqB6G,WAAWD,kBAAkBD;YAC/DI,sBAAsB;QACxB;IACF;IAEA,IAAIxD,iBAAiB,UAAUqD,oBAAoBA,mBAAmBC,WAAW;QAC/E,OAAO;YACLC,aAAa9G,qBAAqB4G,kBAAkBC,WAAWF;YAC/DI,sBAAsB;QACxB;IACF;IAEA,OAAO;QAAED;QAAaC,sBAAsB;IAAM;AACpD;AAEA,eAAeC,kBAAkBtC,IAIhC;IACC,MAAM,EAAEd,EAAE,EAAEiC,cAAc,EAAE9B,GAAG,EAAE,GAAGW;IACpC,MAAMuC,WAAW,MAAMlD,IAAIkC,OAAO,CAACiB,EAAE,CAACC,YAAY,CAAC;QACjDjB,YAAYL;QACZO,OAAO;QACPE,YAAY;QACZvC;QACAhB,MAAM;QACNwD,OAAO;YACLa,QAAQ;gBACNvC,QAAQ;YACV;YACAwC,QAAQ;gBACNxC,QAAQjB;YACV;QACF;IACF;IACA,MAAM0D,gBAAgBL,SAAST,IAAI,CAAC,EAAE;IAEtC,IAAI,CAACc,eAAeC,SAAS;QAC3B,OAAO;IACT;IAEA,OAAOD;AACT;AAEA,eAAeE,yBAAyB9C,IAMvC;IACC,MAAM,EAAEd,EAAE,EAAEiC,cAAc,EAAErC,kBAAkB,EAAEiE,UAAU,EAAE1D,GAAG,EAAE,GAAGW;IACpE,MAAM4C,gBAAgB,MAAMN,kBAAkB;QAC5CpD;QACAiC;QACA9B;IACF;IAEA,IAAI,CAACuD,eAAe1D,MAAM,CAAC0D,cAAcC,OAAO,EAAE;QAChD,OAAO;IACT;IAEA,MAAMxD,IAAIkC,OAAO,CAACiB,EAAE,CAACQ,aAAa,CAAC;QACjC9D,IAAI0D,cAAc1D,EAAE;QACpBsC,YAAYL;QACZZ,QAAQvE,mBAAmBqD;QAC3BA;QACA4D,WAAW;QACXC,aAAa;YACXC,WAAWP,cAAcO,SAAS;YAClCT,QAAQE,cAAcF,MAAM;YAC5BC,QAAQzD;YACRkE,iBAAiBR,cAAcQ,eAAe;YAC9CC,WAAWT,cAAcS,SAAS;YAClCR,SAAS;gBACP,GAAGD,cAAcC,OAAO;gBACxB,CAAC/D,mBAAmB,EAAEiE;YACxB;QACF;IACF;IAEA,OAAO;AACT;AAEA,eAAeO,yBAAyBtD,IAOvC;IACC,MAAM,EAAEd,EAAE,EAAEiC,cAAc,EAAEoC,SAAS,EAAEzE,kBAAkB,EAAEiE,UAAU,EAAE1D,GAAG,EAAE,GAAGW;IAE/E,MAAMX,IAAIkC,OAAO,CAACiB,EAAE,CAACgB,SAAS,CAAC;QAC7BtE,IAAIA;QACJsC,YAAYL;QACZlE,MAAM;YACJ,CAAC6B,mBAAmB,EAAEiE;YACtBM,WAAW;QACb;QACA9C,QAAQvE,mBAAmBqD;QAC3BA;QACA4D,WAAW;IACb;IAEA,MAAMQ,sBAAsBF,YACxB,MAAMT,yBAAyB;QAC7B5D;QACAiC;QACArC;QACAiE;QACA1D;IACF,KACA;IAEJ,OAAO;QACLoE;IACF;AACF;AAEA,eAAeC,2BAA2B1D,IAQzC;IACC,MAAM,EAAEmB,cAAc,EAAEwC,WAAW,EAAEC,IAAI,EAAEL,SAAS,EAAEzE,kBAAkB,EAAEuC,gBAAgB,EAAEhC,GAAG,EAAE,GAC/FW;IACF,MAAM6D,sBAAsB,MAAMxE,IAAIkC,OAAO,CAACX,IAAI,CAAC;QACjDY,YAAYL;QACZM,OAAO;QACPL,OAAOmC,YAAY,OAAO/F;QAC1BkE,OAAO;QACPnB,QAAQvE,mBAAmBqD;QAC3BsC,gBAAgB;QAChBC,YAAY;QACZvC;QACAyE,QAAQ;YAAE,CAAChF,mBAAmB,EAAE;QAAK;QACrCT,MAAM,CAAC,CAAC,EAAES,oBAAoB;QAC9B+C,OAAOxG,wBAAwB;YAC7B;gBACE,CAACyD,mBAAmB,EAAE;oBACpBiF,QAAQ;gBACV;YACF;YACA1C;SACD;IACH;IACA,MAAM2C,mBAAmB,MAAM3E,IAAIkC,OAAO,CAACX,IAAI,CAAC;QAC9CY,YAAYL;QACZM,OAAO;QACPL,OAAOmC,YAAY,OAAO/F;QAC1BkE,OAAO;QACPnB,QAAQvE,mBAAmBqD;QAC3BsC,gBAAgB;QAChBC,YAAY;QACZvC;QACAyE,QAAQ;YAAE,CAAChF,mBAAmB,EAAE;QAAK;QACrC+C,OAAOxG,wBAAwB;YAC7B;gBACE,CAACyD,mBAAmB,EAAE;oBACpBiF,QAAQ;gBACV;YACF;YACA1C;SACD;IACH;IACA,MAAM4C,iBAAiB7D,gBACrByD,oBAAoB/B,IAAI,CAAC,EAAE,EAC3BhD;IAEF,MAAMsD,cAAc9G,qBAAqB2I,gBAAgB,MAAMD,iBAAiBlC,IAAI,CAAClF,MAAM;IAE3F,KAAK,MAAM,CAACO,OAAOkD,IAAI,IAAI,AAAC2D,iBAAiBlC,IAAI,CAAoCoC,OAAO,GAAI;QAC9F,MAAMC,QAAQ9D,IAAInB,EAAE;QACpB,MAAM6D,aAAaX,WAAW,CAACjF,MAAM;QAErC,IACE4F,cACC,CAAA,OAAOoB,UAAU,YAAY,OAAOA,UAAU,QAAO,GACtD;YACA,MAAMb,yBAAyB;gBAC7BpE,IAAIiF;gBACJhD;gBACAoC;gBACAzE;gBACAiE;gBACA1D;YACF;QACF;IACF;IAEAsE,YAAYS,GAAG,CAAC;QACd5C,YAAYL;QACZlE,MAAM;YACJoH,kBAAkBL,iBAAiBlC,IAAI,CAAClF,MAAM;YAC9CkC;QACF;QACA8E;QACAU,OAAO;QACPC,SAAS;QACT/E,QAAQ;IACV;IAEA,OAAOtD,QAAQ,KAAK;QAClBqI,SAAS;QACTC,SAAS;IACX;AACF;AAEA,OAAO,SAASC,0BAA0BzE,IAKzC;IACC,MAAM,EAAEmB,cAAc,EAAEwC,WAAW,EAAE7E,kBAAkB,EAAEmB,eAAe,EAAE,GAAGD;IAC7E,MAAM0E,iBAAiB;WAAItI;QAAiB6D;QAAiBnB;KAAmB;IAEhF,OAAO;QACL6F,SAAS,OAAOtF;YACd,MAAMuF,mBAAmB3I,YAAYoD,IAAIwF,WAAW,EAAE3F;YAEtD,IAAI,CAAC0F,kBAAkB;gBACrB,OAAO1I,QAAQ,KAAK;oBAClBqI,SAAS;gBACX;YACF;YAEA,MAAM,EAAE7E,IAAI,EAAEJ,WAAW,EAAE,GAAG,MAAMF,oBAAoBC;YAExD,IACE,CAACK,QACDA,KAAKZ,kBAAkB,KAAKA,sBAC5BY,KAAKd,UAAU,CAAC,EAAE,KAAKgG,kBACvB;gBACA,IAAIjB,YAAYmB,OAAO,EAAE;oBACvBnB,YAAYS,GAAG,CAAC;wBACd5C,YAAYL;wBACZlE,MAAM;4BACJ+B,SAAS4F;4BACTG,SAASzF,aAAaC,OAAO;4BAC7ByF,eAAe1F,aAAaE,UAAU;wBACxC;wBACAoE,MAAMnI,aAAa;wBACnB6I,OAAO;wBACPC,SAAS;wBACT/E,QAAQ;oBACV;gBACF;gBAEA,OAAOtD,QAAQ,KAAK;oBAClBqI,SAAS;gBACX;YACF;YAEA,IAAI7E,KAAKf,MAAM,CAACO,EAAE,KAAK0F,kBAAkB;gBACvC,OAAO1I,QAAQ,KAAK;oBAClBqI,SAAS;gBACX;YACF;YAEA,MAAMvF,UAAU7C,eAAe;gBAC7B+C,IAAI0F;gBACJzD;gBACA9B;YACF;YACA,MAAMJ,WAAW9C,eAAe;gBAC9B+C,IAAIQ,KAAKf,MAAM,CAACO,EAAE;gBAClBiC;gBACA9B;YACF;YACA,MAAM4F,cAAc,MAAMnJ,mBAAmB;gBAC3CoD,IAAIF;gBACJmC;gBACAlE,MAAM,CAAC;gBACPoC;YACF;YAEA,IAAI4F,aAAa;gBACf,OAAOA;YACT;YAEA,MAAMrB,OAAOnI,aAAa;YAC1B,MAAMyJ,eAAeC,KAAKC,GAAG;YAC7B,MAAM7B,YAAYxH,oBAAoB;gBAAEoF;gBAAgB9B;YAAI;YAE5D,IAAI,CAACA,IAAIgG,OAAO,EAAE;gBAChBhG,IAAIgG,OAAO,GAAG,CAAC;YACjB;YAEA,qEAAqE;YACrE,0CAA0C;;YACxChG,IAAIgG,OAAO,AAA4B,CAAC9J,uBAAuB,GAAG;YAClE8D,IAAIgG,OAAO,AAA4B,CAAC7J,wBAAwB,GAAG;YACnE6D,IAAIgG,OAAO,AAA4B,CAAC3J,6BAA6B,GAAGkI;YAE1E,MAAM0B,oBAAoB,MAAMjG,IAAIkC,OAAO,CAACX,IAAI,CAAC;gBAC/CY,YAAYL;gBACZM,OAAO;gBACPL,OAAOmC,YAAY,OAAO/F;gBAC1BkE,OAAO;gBACPnB,QAAQvE,mBAAmBqD;gBAC3BsC,gBAAgB;gBAChBtC;gBACAwC,OAAO;oBACL3C,IAAI;wBACFqG,IAAI;4BAACvG;4BAASC;yBAAS;oBACzB;gBACF;YACF;YACA,MAAMuG,WAAW,IAAIC,IACnB,AAACH,kBAAkBxD,IAAI,CAAoClE,GAAG,CAAC,CAACyC,MAAQ;oBACtExE,eAAewE,IAAInB,EAAE;oBACrBmB;iBACD;YAEH,MAAMqF,WAAWF,SAASG,GAAG,CAACf;YAC9B,MAAMgB,YAAYJ,SAASG,GAAG,CAACjG,KAAKf,MAAM,CAACO,EAAE;YAE7C,IAAI,CAACwG,UAAU;gBACb,OAAOxJ,QAAQ,KAAK;oBAClBqI,SAAS;gBACX;YACF;YAEA,IAAI,CAACqB,WAAW;gBACd,OAAO1J,QAAQ,KAAK;oBAClBqI,SAAS;gBACX;YACF;YAEA,MAAMsB,gBAAgBjK,eAAe8J,UAAUzF;YAC/C,MAAM6F,iBAAiBlK,eAAegK,WAAW3F;YAEjD,IAAI4F,kBAAkBC,gBAAgB;gBACpC,OAAO5J,QAAQ,KAAK;oBAClBqI,SAAS;gBACX;YACF;YAEA,MAAMlD,mBAAmBtB,oBAAoB;gBAC3CE;gBACAC,UACE2F,kBAAkB,OACd,OACA1J,eAAe;oBACb+C,IAAI2G;oBACJ1E;oBACA9B;gBACF;YACR;YAEA,IAAI,CAACK,KAAKf,MAAM,CAACpC,GAAG,EAAE;gBACpB,OAAOmH,2BAA2B;oBAChCvC;oBACAwC;oBACAC;oBACAL;oBACAzE;oBACAuC;oBACAhC;gBACF;YACF;YAEA,MAAM0G,iBAAiB,MAAMpK,oBAAoB;gBAC/CuD,IAAIF;gBACJmC;gBACA6E,QAAQtB;gBACRrF;YACF;YACA,MAAM4G,0BAA0BtC,YAAYmB,OAAO,GAC/C,MAAM5D,wBAAwB;gBAC5BC;gBACAC,OAAOmC,YAAY,OAAO/F;gBAC1BsB;gBACAuC;gBACAhC;YACF,KACA;YACJ,MAAM6G,yBAAyBvC,YAAYmB,OAAO,GAC9C,MAAM5D,wBAAwB;gBAC5BC;gBACAC,OAAO;gBACPtC;gBACAuC;gBACAhC;YACF,KACA;YACJ,MAAM8G,cAAc,MAAM9G,IAAIkC,OAAO,CAACX,IAAI,CAAC;gBACzCY,YAAYL;gBACZM,OAAO;gBACPL,OAAOmC,YAAY,OAAO/F;gBAC1BkE,OAAO;gBACPnB,QAAQvE,mBAAmBqD;gBAC3BsC,gBAAgB;gBAChBC,YAAY;gBACZvC;gBACAyE,QAAQ;oBAAE,CAAChF,mBAAmB,EAAE;gBAAK;gBACrCT,MAAMqB,KAAKb,YAAY,KAAK,YAAYC,qBAAqB,CAAC,CAAC,EAAEA,oBAAoB;gBACrF+C,OAAOxG,wBAAwB;oBAC7B;wBACE,CAACyD,mBAAmB,EAAE;4BACpB,CAACY,KAAKb,YAAY,KAAK,YAAY,iBAAiB,YAAY,EAAEa,KAAKf,MAAM,CAACpC,GAAG;wBACnF;oBACF;oBACA8E;iBACD;YACH;YACA,MAAMW,iBAAiB5B,gBACrB+F,YAAYrE,IAAI,CAAC,EAAE,EACnBhD;YAEF,MAAMsH,cAAchG,gBAAgBsF,UAAU5G;YAC9C,MAAMuH,YAAY/F,uBAAuBoF,SAASxI,IAAI,EAAElB,mBAAmBqD;YAC3E,MAAMf,aAAagC,uBAAuBsF,UAAU1I,IAAI,EAAElB,mBAAmBqD;YAC7E,MAAMiH,kBACJ,OAAOP,gBAAgB,CAACjH,mBAAmB,KAAK,YAChDiH,cAAc,CAACjH,mBAAmB,CAAClC,MAAM,GAAG,IACxCmJ,cAAc,CAACjH,mBAAmB,GAClCsH;YACN,MAAM,EAAEhE,WAAW,EAAEC,oBAAoB,EAAE,GAAGN,sBAAsB;gBAClEC;gBACAC,kBAAkBvC,KAAKd,UAAU,CAAChC,MAAM;gBACxCsF,kBAAkBoE;gBAClBzH,cAAca,KAAKb,YAAY;gBAC/BsD,WAAWzC,KAAKf,MAAM,CAACpC,GAAG;YAC5B;YACA,MAAMwG,aAAaX,WAAW,CAAC,EAAE;YAEjC,IAAI,CAACW,YAAY;gBACf,OAAO7G,QAAQ,KAAK;oBAClBqI,SAAS;gBACX;YACF;YAEA,IAAIZ,YAAYmB,OAAO,EAAE;gBACvBnB,YAAYS,GAAG,CAAC;oBACd5C,YAAYL;oBACZlE,MAAM;wBACJ+E;wBACAuE,oBAAoB;4BAClBnF,OAAO6E;4BACPO,MAAMN;wBACR;wBACA/G,eAAeO,KAAKP,aAAa,IAAI;wBACrCsH,eAAezF,wBAAwB+E,gBAAgBjH;wBACvDsH;wBACAE;wBACAD;wBACAxH,cAAca,KAAKb,YAAY;wBAC/BC;wBACAiE;wBACApE,QAAQ;4BACNzB,MAAMoB;4BACN/B,KAAKmD,KAAKf,MAAM,CAACpC,GAAG;wBACtB;wBACA8F;oBACF;oBACAuB;oBACAU,OAAO;oBACPC,SAAS;oBACT/E,QAAQ;gBACV;YACF;YAEA,IAAI;gBACF,MAAMkH,eAAe,MAAMpD,yBAAyB;oBAClDpE,IAAIF;oBACJmC;oBACAoC;oBACAzE;oBACAiE;oBACA1D;gBACF;gBAEA,IAAIsE,YAAYmB,OAAO,EAAE;oBACvB,MAAM6B,gBAAgB,MAAMhL,oBAAoB;wBAC9CuD,IAAIF;wBACJmC;wBACA6E,QAAQtB;wBACRrF;oBACF;oBACA,MAAMuH,yBAAyB,MAAM1F,wBAAwB;wBAC3DC;wBACAC,OAAOmC,YAAY,OAAO/F;wBAC1BsB;wBACAuC;wBACAhC;oBACF;oBACA,MAAMwH,wBAAwB,MAAM3F,wBAAwB;wBAC1DC;wBACAC,OAAO;wBACPtC;wBACAuC;wBACAhC;oBACF;oBAEAsE,YAAYS,GAAG,CAAC;wBACd5C,YAAYL;wBACZlE,MAAM;4BACJ6J,mBAAmB;gCACjB1F,OAAOwF;gCACPJ,MAAMK;4BACR;4BACAE,OAAO5B,KAAKC,GAAG,KAAKF;4BACpB8B,cAAchG,wBAAwB2F,eAAe7H;4BACrDuH;4BACAtD;4BACAU,qBAAqBiD,aAAajD,mBAAmB;wBACvD;wBACAG;wBACAU,OAAO;wBACPC,SAAS;wBACT/E,QAAQ;oBACV;gBACF;YACF,EAAE,OAAOyH,KAAK;gBACZ,MAAMC,QAAQD;gBAEdtD,YAAYS,GAAG,CAAC;oBACd5C,YAAYL;oBACVlE,MAAM;wBACJkK,MAAMD,OAAOC;wBACblK,MAAMiK,OAAOjK,QAAQ;wBACrB8J,OAAO5B,KAAKC,GAAG,KAAKF;wBACpBX,SAAS2C,OAAO3C;wBAChB8B;oBACF;oBACFzC;oBACAU,OAAO;oBACPC,SAAS,CAAC,0CAA0C,EAAE2C,OAAO3C,WAAW,iBAAiB;oBACzF/E,QAAQ;gBACV;gBAEA,MAAMyH;YACR;YAEA,OAAO/K,QAAQ,KAAK;gBAClB8C,SAAS4F;gBACTxC;gBACAoC,SAAS;YACX;QACF;QACA4C,QAAQ;QACRC,MAAM;IACR;AACF"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/exports/client.ts"],"sourcesContent":["export { default as PageTreeListViewClient } from '../components/PageTreeListView.client.js'\r\n"],"names":["default","PageTreeListViewClient"],"mappings":"AAAA,SAASA,WAAWC,sBAAsB,QAAQ,2CAA0C"}
1
+ {"version":3,"sources":["../../src/exports/client.ts"],"sourcesContent":["export { default as PageTreeListViewClient } from '../components/PageTreeListView.client.js'\n"],"names":["default","PageTreeListViewClient"],"mappings":"AAAA,SAASA,WAAWC,sBAAsB,QAAQ,2CAA0C"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/exports/rsc.ts"],"sourcesContent":["export { NestedDocsPageTreeListView } from '../components/PageTreeListView.server.js'\r\n"],"names":["NestedDocsPageTreeListView"],"mappings":"AAAA,SAASA,0BAA0B,QAAQ,2CAA0C"}
1
+ {"version":3,"sources":["../../src/exports/rsc.ts"],"sourcesContent":["export { NestedDocsPageTreeListView } from '../components/PageTreeListView.server.js'\n"],"names":["NestedDocsPageTreeListView"],"mappings":"AAAA,SAASA,0BAA0B,QAAQ,2CAA0C"}
package/dist/index.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import { createMovePageEndpoint } from './endpoints/createMovePageEndpoint.js';
2
2
  import { createReorderPageEndpoint } from './endpoints/createReorderPageEndpoint.js';
3
- import { nestedDocsPageTreePluginCustomKey, pageTreeMoveContextKey } from './types.js';
3
+ import { nestedDocsPageTreePluginCustomKey, pageTreeWriteContextKey } from './types.js';
4
4
  import { normalizeNestedDocsPageTreePluginBadgeConfig } from './utilities/badgeConfig.js';
5
5
  import { DIAGNOSTICS_FLOW_CONTEXT_KEY, createFlowID, projectField, resolveDiagnostics } from './utilities/diagnostics.js';
6
+ import { findTopLevelField, mapTopLevelFields } from './utilities/fields.js';
6
7
  const DEFAULT_BREADCRUMBS_FIELD_SLUG = 'breadcrumbs';
7
8
  const DEFAULT_HOME_INDICATOR_COLLECTIONS = [
8
9
  'pages'
@@ -10,10 +11,10 @@ const DEFAULT_HOME_INDICATOR_COLLECTIONS = [
10
11
  const DEFAULT_LIMIT = 100;
11
12
  const DEFAULT_PARENT_FIELD_SLUG = 'parent';
12
13
  const PAGE_TREE_LIST_VIEW_PATH = 'payload-nested-docs-page-tree/rsc#NestedDocsPageTreeListView';
13
- /**
14
- * When diagnostics are enabled this hook emits a structured event for each
15
- * page-tree-tagged create/update, including a small before/after diff of the
16
- * fields most relevant to tree publish/draft regressions.
14
+ /**
15
+ * When diagnostics are enabled this hook emits a structured event for each
16
+ * page-tree-tagged create/update, including a small before/after diff of the
17
+ * fields most relevant to tree publish/draft regressions.
17
18
  */ function createDiagnosticsAfterChangeHook(args) {
18
19
  const { collectionSlug, diagnostics, orderableFieldName, parentFieldSlug } = args;
19
20
  const snapshotFields = [
@@ -30,7 +31,9 @@ const PAGE_TREE_LIST_VIEW_PATH = 'payload-nested-docs-page-tree/rsc#NestedDocsPa
30
31
  if (operation !== 'update' && operation !== 'create') {
31
32
  return doc;
32
33
  }
33
- if (!req.context?.[pageTreeMoveContextKey]) {
34
+ // Gated on the write flag, not the deploy opt-out flag: a published move
35
+ // withholds the latter, and that is the case most worth tracing.
36
+ if (!req.context?.[pageTreeWriteContextKey]) {
34
37
  return doc;
35
38
  }
36
39
  const docID = doc?.id;
@@ -83,9 +86,6 @@ const PAGE_TREE_LIST_VIEW_PATH = 'payload-nested-docs-page-tree/rsc#NestedDocsPa
83
86
  return doc;
84
87
  };
85
88
  }
86
- function getTopLevelField(collection, fieldName) {
87
- return collection.fields.find((field)=>'name' in field && field.name === fieldName);
88
- }
89
89
  function getCollectionEndpoints(collection) {
90
90
  return Array.isArray(collection.endpoints) ? [
91
91
  ...collection.endpoints
@@ -109,13 +109,13 @@ function validateTargetCollection(args) {
109
109
  if (typeof collection.admin?.useAsTitle !== 'string' || collection.admin.useAsTitle.includes('.')) {
110
110
  throw new Error(`payload-nested-docs-page-tree requires "${collection.slug}" to define a top-level admin.useAsTitle field.`);
111
111
  }
112
- if (!getTopLevelField(collection, collection.admin.useAsTitle)) {
113
- throw new Error(`payload-nested-docs-page-tree could not find the useAsTitle field "${collection.admin.useAsTitle}" on "${collection.slug}".`);
112
+ if (!findTopLevelField(collection.fields, collection.admin.useAsTitle)) {
113
+ throw new Error(`payload-nested-docs-page-tree could not find the useAsTitle field "${collection.admin.useAsTitle}" on "${collection.slug}". Fields inside tabs, rows, collapsibles, and unnamed groups are supported; fields inside a named tab or named group are not top-level.`);
114
114
  }
115
- if (!getTopLevelField(collection, parentFieldSlug)) {
115
+ if (!findTopLevelField(collection.fields, parentFieldSlug)) {
116
116
  throw new Error(`payload-nested-docs-page-tree requires "${collection.slug}" to already define the nested docs parent field "${parentFieldSlug}". Register @payloadcms/plugin-nested-docs before payload-nested-docs-page-tree.`);
117
117
  }
118
- if (!getTopLevelField(collection, breadcrumbsFieldSlug)) {
118
+ if (!findTopLevelField(collection.fields, breadcrumbsFieldSlug)) {
119
119
  throw new Error(`payload-nested-docs-page-tree requires "${collection.slug}" to already define the nested docs breadcrumbs field "${breadcrumbsFieldSlug}". Register @payloadcms/plugin-nested-docs before payload-nested-docs-page-tree.`);
120
120
  }
121
121
  const existingListView = collection.admin?.components?.views?.list?.Component;
@@ -160,6 +160,7 @@ export const nestedDocsPageTreePlugin = (pluginOptions)=>(config)=>{
160
160
  const defaultLimit = pluginOptions.defaultLimit ?? DEFAULT_LIMIT;
161
161
  const hideBreadcrumbs = pluginOptions.hideBreadcrumbs ?? true;
162
162
  const parentFieldSlug = pluginOptions.parentFieldSlug ?? DEFAULT_PARENT_FIELD_SLUG;
163
+ const publishOnMove = pluginOptions.publishOnMove ?? false;
163
164
  const badges = normalizeNestedDocsPageTreePluginBadgeConfig(pluginOptions.badges);
164
165
  const diagnostics = resolveDiagnostics(pluginOptions.diagnostics);
165
166
  const homeIndicatorCollectionSlugs = getHomeIndicatorCollectionSlugs(pluginOptions.homeIndicator);
@@ -222,7 +223,8 @@ export const nestedDocsPageTreePlugin = (pluginOptions)=>(config)=>{
222
223
  createMovePageEndpoint({
223
224
  collectionSlug: collection.slug,
224
225
  diagnostics,
225
- parentFieldSlug
226
+ parentFieldSlug,
227
+ publishOnMove
226
228
  }),
227
229
  ...orderableFieldName ? [
228
230
  createReorderPageEndpoint({
@@ -233,7 +235,7 @@ export const nestedDocsPageTreePlugin = (pluginOptions)=>(config)=>{
233
235
  })
234
236
  ] : []
235
237
  ],
236
- fields: collection.fields.map((field)=>patchBreadcrumbField({
238
+ fields: mapTopLevelFields(collection.fields, (field)=>patchBreadcrumbField({
237
239
  breadcrumbsFieldSlug,
238
240
  field,
239
241
  hideBreadcrumbs
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type {\r\n CollectionAfterChangeHook,\r\n CollectionConfig,\r\n Config,\r\n} from 'payload'\r\n\r\nimport { createMovePageEndpoint } from './endpoints/createMovePageEndpoint.js'\r\nimport { createReorderPageEndpoint } from './endpoints/createReorderPageEndpoint.js'\r\nimport type {\r\n NestedDocsPageTreePluginCollectionCustom,\r\n NestedDocsPageTreePluginConfig,\r\n} from './types.js'\r\nimport { nestedDocsPageTreePluginCustomKey, pageTreeMoveContextKey } from './types.js'\r\nimport { normalizeNestedDocsPageTreePluginBadgeConfig } from './utilities/badgeConfig.js'\r\nimport {\r\n DIAGNOSTICS_FLOW_CONTEXT_KEY,\r\n type Diagnostics,\r\n createFlowID,\r\n projectField,\r\n resolveDiagnostics,\r\n} from './utilities/diagnostics.js'\r\n\r\nconst DEFAULT_BREADCRUMBS_FIELD_SLUG = 'breadcrumbs'\r\nconst DEFAULT_HOME_INDICATOR_COLLECTIONS = ['pages']\r\nconst DEFAULT_LIMIT = 100\r\nconst DEFAULT_PARENT_FIELD_SLUG = 'parent'\r\nconst PAGE_TREE_LIST_VIEW_PATH =\r\n 'payload-nested-docs-page-tree/rsc#NestedDocsPageTreeListView'\r\ntype CollectionEndpoint = NonNullable<Exclude<CollectionConfig['endpoints'], false>>[number]\r\n\r\n/**\r\n * When diagnostics are enabled this hook emits a structured event for each\r\n * page-tree-tagged create/update, including a small before/after diff of the\r\n * fields most relevant to tree publish/draft regressions.\r\n */\r\nfunction createDiagnosticsAfterChangeHook(args: {\r\n collectionSlug: string\r\n diagnostics: Diagnostics\r\n orderableFieldName: null | string\r\n parentFieldSlug: string\r\n}): CollectionAfterChangeHook {\r\n const { collectionSlug, diagnostics, orderableFieldName, parentFieldSlug } = args\r\n const snapshotFields: string[] = ['_status', parentFieldSlug]\r\n\r\n if (orderableFieldName) {\r\n snapshotFields.push(orderableFieldName)\r\n }\r\n\r\n return async ({ doc, operation, previousDoc, req }) => {\r\n if (!diagnostics.enabled) {\r\n return doc\r\n }\r\n\r\n if (operation !== 'update' && operation !== 'create') {\r\n return doc\r\n }\r\n\r\n if (!req.context?.[pageTreeMoveContextKey]) {\r\n return doc\r\n }\r\n\r\n const docID = (doc as Record<string, unknown>)?.id\r\n\r\n if (typeof docID !== 'string' && typeof docID !== 'number') {\r\n return doc\r\n }\r\n\r\n const flow =\r\n (req.context?.[DIAGNOSTICS_FLOW_CONTEXT_KEY] as string | undefined) ??\r\n createFlowID('page-tree-change')\r\n const before: Record<string, unknown> = {}\r\n const after: Record<string, unknown> = {}\r\n const changed: string[] = []\r\n\r\n for (const field of snapshotFields) {\r\n const beforeValue = projectField((previousDoc as Record<string, unknown> | undefined)?.[field])\r\n const afterValue = projectField((doc as Record<string, unknown>)?.[field])\r\n\r\n before[field] = beforeValue\r\n after[field] = afterValue\r\n\r\n if (JSON.stringify(beforeValue) !== JSON.stringify(afterValue)) {\r\n changed.push(field)\r\n }\r\n }\r\n\r\n diagnostics.log({\r\n collection: collectionSlug,\r\n data: {\r\n after,\r\n before,\r\n changed,\r\n docID: String(docID),\r\n operation,\r\n },\r\n flow,\r\n level: 'info',\r\n message: `${operation} on ${collectionSlug}#${String(docID)}`,\r\n source: 'page-tree-change:after',\r\n })\r\n\r\n const beforeStatus = (previousDoc as Record<string, unknown> | undefined)?._status\r\n const afterStatus = (doc as Record<string, unknown>)?._status\r\n\r\n if (beforeStatus === 'published' && afterStatus !== 'published') {\r\n diagnostics.log({\r\n collection: collectionSlug,\r\n data: {\r\n afterStatus,\r\n beforeStatus,\r\n docID: String(docID),\r\n },\r\n flow,\r\n level: 'warn',\r\n message: `Published doc was demoted to \"${String(afterStatus ?? 'missing')}\" by a page-tree operation. Inspect the move-endpoint:enter/ok snapshots in flow ${flow} to confirm whether the main row was touched.`,\r\n source: 'page-tree-change:status-flip',\r\n })\r\n }\r\n\r\n return doc\r\n }\r\n}\r\n\r\nfunction getTopLevelField(\r\n collection: Pick<CollectionConfig, 'fields'>,\r\n fieldName: string,\r\n) {\r\n return collection.fields.find((field) => 'name' in field && field.name === fieldName)\r\n}\r\n\r\nfunction getCollectionEndpoints(collection: CollectionConfig): CollectionEndpoint[] {\r\n return Array.isArray(collection.endpoints) ? [...collection.endpoints] : []\r\n}\r\n\r\nfunction patchBreadcrumbField<TField extends CollectionConfig['fields'][number]>(args: {\r\n breadcrumbsFieldSlug: string\r\n field: TField\r\n hideBreadcrumbs: boolean\r\n}): TField {\r\n const { breadcrumbsFieldSlug, field, hideBreadcrumbs } = args\r\n\r\n if (!('name' in field) || field.name !== breadcrumbsFieldSlug) {\r\n return field\r\n }\r\n\r\n return {\r\n ...field,\r\n admin: {\r\n ...(field.admin ?? {}),\r\n hidden: hideBreadcrumbs,\r\n },\r\n } as TField\r\n}\r\n\r\nfunction validateTargetCollection(args: {\r\n breadcrumbsFieldSlug: string\r\n collection: CollectionConfig\r\n parentFieldSlug: string\r\n}) {\r\n const { breadcrumbsFieldSlug, collection, parentFieldSlug } = args\r\n\r\n if (typeof collection.admin?.useAsTitle !== 'string' || collection.admin.useAsTitle.includes('.')) {\r\n throw new Error(\r\n `payload-nested-docs-page-tree requires \"${collection.slug}\" to define a top-level admin.useAsTitle field.`,\r\n )\r\n }\r\n\r\n if (!getTopLevelField(collection, collection.admin.useAsTitle)) {\r\n throw new Error(\r\n `payload-nested-docs-page-tree could not find the useAsTitle field \"${collection.admin.useAsTitle}\" on \"${collection.slug}\".`,\r\n )\r\n }\r\n\r\n if (!getTopLevelField(collection, parentFieldSlug)) {\r\n throw new Error(\r\n `payload-nested-docs-page-tree requires \"${collection.slug}\" to already define the nested docs parent field \"${parentFieldSlug}\". Register @payloadcms/plugin-nested-docs before payload-nested-docs-page-tree.`,\r\n )\r\n }\r\n\r\n if (!getTopLevelField(collection, breadcrumbsFieldSlug)) {\r\n throw new Error(\r\n `payload-nested-docs-page-tree requires \"${collection.slug}\" to already define the nested docs breadcrumbs field \"${breadcrumbsFieldSlug}\". Register @payloadcms/plugin-nested-docs before payload-nested-docs-page-tree.`,\r\n )\r\n }\r\n\r\n const existingListView = collection.admin?.components?.views?.list?.Component\r\n\r\n if (existingListView && existingListView !== PAGE_TREE_LIST_VIEW_PATH) {\r\n throw new Error(\r\n `payload-nested-docs-page-tree cannot own the \"${collection.slug}\" list view because the collection already defines a custom admin.components.views.list.Component.`,\r\n )\r\n }\r\n\r\n const existingMoveEndpoint = getCollectionEndpoints(collection).find(\r\n (endpoint) => endpoint.path === '/:id/move',\r\n )\r\n const existingReorderEndpoint = getCollectionEndpoints(collection).find(\r\n (endpoint) => endpoint.path === '/:id/reorder',\r\n )\r\n\r\n if (existingMoveEndpoint) {\r\n throw new Error(\r\n `payload-nested-docs-page-tree cannot add the move endpoint to \"${collection.slug}\" because the collection already defines POST /:id/move.`,\r\n )\r\n }\r\n\r\n if (existingReorderEndpoint) {\r\n throw new Error(\r\n `payload-nested-docs-page-tree cannot add the reorder endpoint to \"${collection.slug}\" because the collection already defines POST /:id/reorder.`,\r\n )\r\n }\r\n}\r\n\r\nfunction buildCollectionCustom(args: {\r\n badges: NestedDocsPageTreePluginCollectionCustom['badges']\r\n breadcrumbsFieldSlug: string\r\n defaultLimit: number\r\n hideBreadcrumbs: boolean\r\n homeIndicator: NestedDocsPageTreePluginCollectionCustom['homeIndicator']\r\n parentFieldSlug: string\r\n}): NestedDocsPageTreePluginCollectionCustom {\r\n const {\r\n badges,\r\n breadcrumbsFieldSlug,\r\n defaultLimit,\r\n hideBreadcrumbs,\r\n homeIndicator,\r\n parentFieldSlug,\r\n } = args\r\n\r\n return {\r\n badges,\r\n breadcrumbsFieldSlug,\r\n defaultLimit,\r\n hideBreadcrumbs,\r\n homeIndicator,\r\n parentFieldSlug,\r\n }\r\n}\r\n\r\nfunction getHomeIndicatorCollectionSlugs(\r\n homeIndicator: NestedDocsPageTreePluginConfig['homeIndicator'],\r\n): Set<string> {\r\n if (homeIndicator === false) {\r\n return new Set()\r\n }\r\n\r\n return new Set(homeIndicator?.collections ?? DEFAULT_HOME_INDICATOR_COLLECTIONS)\r\n}\r\n\r\nexport type {\r\n NestedDocsPageTreePluginBadgeConfig,\r\n NestedDocsPageTreePluginBadgeMap,\r\n NestedDocsPageTreePluginBadgeStatus,\r\n NestedDocsPageTreePluginConfig,\r\n NestedDocsPageTreePluginHomeIndicatorConfig,\r\n PageTreeMoveContext,\r\n} from './types.js'\r\n\r\nexport { pageTreeMoveContextKey } from './types.js'\r\n\r\nexport const nestedDocsPageTreePlugin =\r\n (pluginOptions: NestedDocsPageTreePluginConfig) =>\r\n (config: Config): Config => {\r\n if (!pluginOptions.collections?.length) {\r\n throw new Error('payload-nested-docs-page-tree requires at least one collection slug.')\r\n }\r\n\r\n if (pluginOptions.disabled) {\r\n return config\r\n }\r\n\r\n const breadcrumbsFieldSlug =\r\n pluginOptions.breadcrumbsFieldSlug ?? DEFAULT_BREADCRUMBS_FIELD_SLUG\r\n const defaultLimit = pluginOptions.defaultLimit ?? DEFAULT_LIMIT\r\n const hideBreadcrumbs = pluginOptions.hideBreadcrumbs ?? true\r\n const parentFieldSlug = pluginOptions.parentFieldSlug ?? DEFAULT_PARENT_FIELD_SLUG\r\n const badges = normalizeNestedDocsPageTreePluginBadgeConfig(pluginOptions.badges)\r\n const diagnostics = resolveDiagnostics(pluginOptions.diagnostics)\r\n const homeIndicatorCollectionSlugs = getHomeIndicatorCollectionSlugs(\r\n pluginOptions.homeIndicator,\r\n )\r\n const targetedCollectionSlugs = new Set<string>(pluginOptions.collections)\r\n\r\n if (!config.collections?.length) {\r\n throw new Error('payload-nested-docs-page-tree could not find any collections to patch.')\r\n }\r\n\r\n const foundCollectionSlugs = new Set<string>()\r\n const nextCollections = config.collections.map((collection) => {\r\n if (!targetedCollectionSlugs.has(collection.slug)) {\r\n return collection\r\n }\r\n\r\n foundCollectionSlugs.add(collection.slug)\r\n validateTargetCollection({\r\n breadcrumbsFieldSlug,\r\n collection,\r\n parentFieldSlug,\r\n })\r\n const orderableFieldName =\r\n typeof collection.orderable === 'string'\r\n ? collection.orderable\r\n : collection.orderable\r\n ? '_order'\r\n : null\r\n const diagnosticsAfterChangeHook = diagnostics.enabled\r\n ? createDiagnosticsAfterChangeHook({\r\n collectionSlug: collection.slug,\r\n diagnostics,\r\n orderableFieldName,\r\n parentFieldSlug,\r\n })\r\n : null\r\n\r\n return {\r\n ...collection,\r\n admin: {\r\n ...(collection.admin ?? {}),\r\n components: {\r\n ...(collection.admin?.components ?? {}),\r\n views: {\r\n ...(collection.admin?.components?.views ?? {}),\r\n list: {\r\n ...(collection.admin?.components?.views?.list ?? {}),\r\n Component: PAGE_TREE_LIST_VIEW_PATH,\r\n },\r\n },\r\n },\r\n pagination: {\r\n ...(collection.admin?.pagination ?? {}),\r\n defaultLimit:\r\n collection.admin?.pagination?.defaultLimit === undefined\r\n ? defaultLimit\r\n : collection.admin.pagination.defaultLimit,\r\n },\r\n },\r\n custom: {\r\n ...(collection.custom ?? {}),\r\n [nestedDocsPageTreePluginCustomKey]: buildCollectionCustom({\r\n badges,\r\n breadcrumbsFieldSlug,\r\n defaultLimit,\r\n hideBreadcrumbs,\r\n homeIndicator: {\r\n enabled: homeIndicatorCollectionSlugs.has(collection.slug),\r\n },\r\n parentFieldSlug,\r\n }),\r\n },\r\n endpoints: [\r\n ...getCollectionEndpoints(collection),\r\n createMovePageEndpoint({\r\n collectionSlug: collection.slug,\r\n diagnostics,\r\n parentFieldSlug,\r\n }),\r\n ...(orderableFieldName\r\n ? [\r\n createReorderPageEndpoint({\r\n collectionSlug: collection.slug,\r\n diagnostics,\r\n orderableFieldName,\r\n parentFieldSlug,\r\n }),\r\n ]\r\n : []),\r\n ],\r\n fields: collection.fields.map((field) =>\r\n patchBreadcrumbField({\r\n breadcrumbsFieldSlug,\r\n field,\r\n hideBreadcrumbs,\r\n }),\r\n ),\r\n hooks: {\r\n ...(collection.hooks ?? {}),\r\n ...(diagnosticsAfterChangeHook\r\n ? {\r\n afterChange: [\r\n ...(collection.hooks?.afterChange ?? []),\r\n diagnosticsAfterChangeHook,\r\n ],\r\n }\r\n : {}),\r\n },\r\n }\r\n })\r\n\r\n const missingCollections = pluginOptions.collections.filter(\r\n (collectionSlug) => !foundCollectionSlugs.has(collectionSlug),\r\n )\r\n\r\n if (missingCollections.length > 0) {\r\n throw new Error(\r\n `payload-nested-docs-page-tree could not find the following collections: ${missingCollections.join(', ')}`,\r\n )\r\n }\r\n\r\n return {\r\n ...config,\r\n collections: nextCollections as CollectionConfig[],\r\n }\r\n }\r\n"],"names":["createMovePageEndpoint","createReorderPageEndpoint","nestedDocsPageTreePluginCustomKey","pageTreeMoveContextKey","normalizeNestedDocsPageTreePluginBadgeConfig","DIAGNOSTICS_FLOW_CONTEXT_KEY","createFlowID","projectField","resolveDiagnostics","DEFAULT_BREADCRUMBS_FIELD_SLUG","DEFAULT_HOME_INDICATOR_COLLECTIONS","DEFAULT_LIMIT","DEFAULT_PARENT_FIELD_SLUG","PAGE_TREE_LIST_VIEW_PATH","createDiagnosticsAfterChangeHook","args","collectionSlug","diagnostics","orderableFieldName","parentFieldSlug","snapshotFields","push","doc","operation","previousDoc","req","enabled","context","docID","id","flow","before","after","changed","field","beforeValue","afterValue","JSON","stringify","log","collection","data","String","level","message","source","beforeStatus","_status","afterStatus","getTopLevelField","fieldName","fields","find","name","getCollectionEndpoints","Array","isArray","endpoints","patchBreadcrumbField","breadcrumbsFieldSlug","hideBreadcrumbs","admin","hidden","validateTargetCollection","useAsTitle","includes","Error","slug","existingListView","components","views","list","Component","existingMoveEndpoint","endpoint","path","existingReorderEndpoint","buildCollectionCustom","badges","defaultLimit","homeIndicator","getHomeIndicatorCollectionSlugs","Set","collections","nestedDocsPageTreePlugin","pluginOptions","config","length","disabled","homeIndicatorCollectionSlugs","targetedCollectionSlugs","foundCollectionSlugs","nextCollections","map","has","add","orderable","diagnosticsAfterChangeHook","pagination","undefined","custom","hooks","afterChange","missingCollections","filter","join"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type {\n CollectionAfterChangeHook,\n CollectionConfig,\n Config,\n} from 'payload'\n\nimport { createMovePageEndpoint } from './endpoints/createMovePageEndpoint.js'\nimport { createReorderPageEndpoint } from './endpoints/createReorderPageEndpoint.js'\nimport type {\n NestedDocsPageTreePluginCollectionCustom,\n NestedDocsPageTreePluginConfig,\n} from './types.js'\nimport { nestedDocsPageTreePluginCustomKey, pageTreeWriteContextKey } from './types.js'\nimport { normalizeNestedDocsPageTreePluginBadgeConfig } from './utilities/badgeConfig.js'\nimport {\n DIAGNOSTICS_FLOW_CONTEXT_KEY,\n type Diagnostics,\n createFlowID,\n projectField,\n resolveDiagnostics,\n} from './utilities/diagnostics.js'\nimport { findTopLevelField, mapTopLevelFields } from './utilities/fields.js'\n\nconst DEFAULT_BREADCRUMBS_FIELD_SLUG = 'breadcrumbs'\nconst DEFAULT_HOME_INDICATOR_COLLECTIONS = ['pages']\nconst DEFAULT_LIMIT = 100\nconst DEFAULT_PARENT_FIELD_SLUG = 'parent'\nconst PAGE_TREE_LIST_VIEW_PATH =\n 'payload-nested-docs-page-tree/rsc#NestedDocsPageTreeListView'\ntype CollectionEndpoint = NonNullable<Exclude<CollectionConfig['endpoints'], false>>[number]\n\n/**\n * When diagnostics are enabled this hook emits a structured event for each\n * page-tree-tagged create/update, including a small before/after diff of the\n * fields most relevant to tree publish/draft regressions.\n */\nfunction createDiagnosticsAfterChangeHook(args: {\n collectionSlug: string\n diagnostics: Diagnostics\n orderableFieldName: null | string\n parentFieldSlug: string\n}): CollectionAfterChangeHook {\n const { collectionSlug, diagnostics, orderableFieldName, parentFieldSlug } = args\n const snapshotFields: string[] = ['_status', parentFieldSlug]\n\n if (orderableFieldName) {\n snapshotFields.push(orderableFieldName)\n }\n\n return async ({ doc, operation, previousDoc, req }) => {\n if (!diagnostics.enabled) {\n return doc\n }\n\n if (operation !== 'update' && operation !== 'create') {\n return doc\n }\n\n // Gated on the write flag, not the deploy opt-out flag: a published move\n // withholds the latter, and that is the case most worth tracing.\n if (!req.context?.[pageTreeWriteContextKey]) {\n return doc\n }\n\n const docID = (doc as Record<string, unknown>)?.id\n\n if (typeof docID !== 'string' && typeof docID !== 'number') {\n return doc\n }\n\n const flow =\n (req.context?.[DIAGNOSTICS_FLOW_CONTEXT_KEY] as string | undefined) ??\n createFlowID('page-tree-change')\n const before: Record<string, unknown> = {}\n const after: Record<string, unknown> = {}\n const changed: string[] = []\n\n for (const field of snapshotFields) {\n const beforeValue = projectField((previousDoc as Record<string, unknown> | undefined)?.[field])\n const afterValue = projectField((doc as Record<string, unknown>)?.[field])\n\n before[field] = beforeValue\n after[field] = afterValue\n\n if (JSON.stringify(beforeValue) !== JSON.stringify(afterValue)) {\n changed.push(field)\n }\n }\n\n diagnostics.log({\n collection: collectionSlug,\n data: {\n after,\n before,\n changed,\n docID: String(docID),\n operation,\n },\n flow,\n level: 'info',\n message: `${operation} on ${collectionSlug}#${String(docID)}`,\n source: 'page-tree-change:after',\n })\n\n const beforeStatus = (previousDoc as Record<string, unknown> | undefined)?._status\n const afterStatus = (doc as Record<string, unknown>)?._status\n\n if (beforeStatus === 'published' && afterStatus !== 'published') {\n diagnostics.log({\n collection: collectionSlug,\n data: {\n afterStatus,\n beforeStatus,\n docID: String(docID),\n },\n flow,\n level: 'warn',\n message: `Published doc was demoted to \"${String(afterStatus ?? 'missing')}\" by a page-tree operation. Inspect the move-endpoint:enter/ok snapshots in flow ${flow} to confirm whether the main row was touched.`,\n source: 'page-tree-change:status-flip',\n })\n }\n\n return doc\n }\n}\n\nfunction getCollectionEndpoints(collection: CollectionConfig): CollectionEndpoint[] {\n return Array.isArray(collection.endpoints) ? [...collection.endpoints] : []\n}\n\nfunction patchBreadcrumbField<TField extends CollectionConfig['fields'][number]>(args: {\n breadcrumbsFieldSlug: string\n field: TField\n hideBreadcrumbs: boolean\n}): TField {\n const { breadcrumbsFieldSlug, field, hideBreadcrumbs } = args\n\n if (!('name' in field) || field.name !== breadcrumbsFieldSlug) {\n return field\n }\n\n return {\n ...field,\n admin: {\n ...(field.admin ?? {}),\n hidden: hideBreadcrumbs,\n },\n } as TField\n}\n\nfunction validateTargetCollection(args: {\n breadcrumbsFieldSlug: string\n collection: CollectionConfig\n parentFieldSlug: string\n}) {\n const { breadcrumbsFieldSlug, collection, parentFieldSlug } = args\n\n if (typeof collection.admin?.useAsTitle !== 'string' || collection.admin.useAsTitle.includes('.')) {\n throw new Error(\n `payload-nested-docs-page-tree requires \"${collection.slug}\" to define a top-level admin.useAsTitle field.`,\n )\n }\n\n if (!findTopLevelField(collection.fields, collection.admin.useAsTitle)) {\n throw new Error(\n `payload-nested-docs-page-tree could not find the useAsTitle field \"${collection.admin.useAsTitle}\" on \"${collection.slug}\". Fields inside tabs, rows, collapsibles, and unnamed groups are supported; fields inside a named tab or named group are not top-level.`,\n )\n }\n\n if (!findTopLevelField(collection.fields, parentFieldSlug)) {\n throw new Error(\n `payload-nested-docs-page-tree requires \"${collection.slug}\" to already define the nested docs parent field \"${parentFieldSlug}\". Register @payloadcms/plugin-nested-docs before payload-nested-docs-page-tree.`,\n )\n }\n\n if (!findTopLevelField(collection.fields, breadcrumbsFieldSlug)) {\n throw new Error(\n `payload-nested-docs-page-tree requires \"${collection.slug}\" to already define the nested docs breadcrumbs field \"${breadcrumbsFieldSlug}\". Register @payloadcms/plugin-nested-docs before payload-nested-docs-page-tree.`,\n )\n }\n\n const existingListView = collection.admin?.components?.views?.list?.Component\n\n if (existingListView && existingListView !== PAGE_TREE_LIST_VIEW_PATH) {\n throw new Error(\n `payload-nested-docs-page-tree cannot own the \"${collection.slug}\" list view because the collection already defines a custom admin.components.views.list.Component.`,\n )\n }\n\n const existingMoveEndpoint = getCollectionEndpoints(collection).find(\n (endpoint) => endpoint.path === '/:id/move',\n )\n const existingReorderEndpoint = getCollectionEndpoints(collection).find(\n (endpoint) => endpoint.path === '/:id/reorder',\n )\n\n if (existingMoveEndpoint) {\n throw new Error(\n `payload-nested-docs-page-tree cannot add the move endpoint to \"${collection.slug}\" because the collection already defines POST /:id/move.`,\n )\n }\n\n if (existingReorderEndpoint) {\n throw new Error(\n `payload-nested-docs-page-tree cannot add the reorder endpoint to \"${collection.slug}\" because the collection already defines POST /:id/reorder.`,\n )\n }\n}\n\nfunction buildCollectionCustom(args: {\n badges: NestedDocsPageTreePluginCollectionCustom['badges']\n breadcrumbsFieldSlug: string\n defaultLimit: number\n hideBreadcrumbs: boolean\n homeIndicator: NestedDocsPageTreePluginCollectionCustom['homeIndicator']\n parentFieldSlug: string\n}): NestedDocsPageTreePluginCollectionCustom {\n const {\n badges,\n breadcrumbsFieldSlug,\n defaultLimit,\n hideBreadcrumbs,\n homeIndicator,\n parentFieldSlug,\n } = args\n\n return {\n badges,\n breadcrumbsFieldSlug,\n defaultLimit,\n hideBreadcrumbs,\n homeIndicator,\n parentFieldSlug,\n }\n}\n\nfunction getHomeIndicatorCollectionSlugs(\n homeIndicator: NestedDocsPageTreePluginConfig['homeIndicator'],\n): Set<string> {\n if (homeIndicator === false) {\n return new Set()\n }\n\n return new Set(homeIndicator?.collections ?? DEFAULT_HOME_INDICATOR_COLLECTIONS)\n}\n\nexport type {\n NestedDocsPageTreePluginBadgeConfig,\n NestedDocsPageTreePluginBadgeMap,\n NestedDocsPageTreePluginBadgeStatus,\n NestedDocsPageTreePluginConfig,\n NestedDocsPageTreePluginHomeIndicatorConfig,\n PageTreeMoveContext,\n} from './types.js'\n\nexport { pageTreeMoveContextKey } from './types.js'\n\nexport const nestedDocsPageTreePlugin =\n (pluginOptions: NestedDocsPageTreePluginConfig) =>\n (config: Config): Config => {\n if (!pluginOptions.collections?.length) {\n throw new Error('payload-nested-docs-page-tree requires at least one collection slug.')\n }\n\n if (pluginOptions.disabled) {\n return config\n }\n\n const breadcrumbsFieldSlug =\n pluginOptions.breadcrumbsFieldSlug ?? DEFAULT_BREADCRUMBS_FIELD_SLUG\n const defaultLimit = pluginOptions.defaultLimit ?? DEFAULT_LIMIT\n const hideBreadcrumbs = pluginOptions.hideBreadcrumbs ?? true\n const parentFieldSlug = pluginOptions.parentFieldSlug ?? DEFAULT_PARENT_FIELD_SLUG\n const publishOnMove = pluginOptions.publishOnMove ?? false\n const badges = normalizeNestedDocsPageTreePluginBadgeConfig(pluginOptions.badges)\n const diagnostics = resolveDiagnostics(pluginOptions.diagnostics)\n const homeIndicatorCollectionSlugs = getHomeIndicatorCollectionSlugs(\n pluginOptions.homeIndicator,\n )\n const targetedCollectionSlugs = new Set<string>(pluginOptions.collections)\n\n if (!config.collections?.length) {\n throw new Error('payload-nested-docs-page-tree could not find any collections to patch.')\n }\n\n const foundCollectionSlugs = new Set<string>()\n const nextCollections = config.collections.map((collection) => {\n if (!targetedCollectionSlugs.has(collection.slug)) {\n return collection\n }\n\n foundCollectionSlugs.add(collection.slug)\n validateTargetCollection({\n breadcrumbsFieldSlug,\n collection,\n parentFieldSlug,\n })\n const orderableFieldName =\n typeof collection.orderable === 'string'\n ? collection.orderable\n : collection.orderable\n ? '_order'\n : null\n const diagnosticsAfterChangeHook = diagnostics.enabled\n ? createDiagnosticsAfterChangeHook({\n collectionSlug: collection.slug,\n diagnostics,\n orderableFieldName,\n parentFieldSlug,\n })\n : null\n\n return {\n ...collection,\n admin: {\n ...(collection.admin ?? {}),\n components: {\n ...(collection.admin?.components ?? {}),\n views: {\n ...(collection.admin?.components?.views ?? {}),\n list: {\n ...(collection.admin?.components?.views?.list ?? {}),\n Component: PAGE_TREE_LIST_VIEW_PATH,\n },\n },\n },\n pagination: {\n ...(collection.admin?.pagination ?? {}),\n defaultLimit:\n collection.admin?.pagination?.defaultLimit === undefined\n ? defaultLimit\n : collection.admin.pagination.defaultLimit,\n },\n },\n custom: {\n ...(collection.custom ?? {}),\n [nestedDocsPageTreePluginCustomKey]: buildCollectionCustom({\n badges,\n breadcrumbsFieldSlug,\n defaultLimit,\n hideBreadcrumbs,\n homeIndicator: {\n enabled: homeIndicatorCollectionSlugs.has(collection.slug),\n },\n parentFieldSlug,\n }),\n },\n endpoints: [\n ...getCollectionEndpoints(collection),\n createMovePageEndpoint({\n collectionSlug: collection.slug,\n diagnostics,\n parentFieldSlug,\n publishOnMove,\n }),\n ...(orderableFieldName\n ? [\n createReorderPageEndpoint({\n collectionSlug: collection.slug,\n diagnostics,\n orderableFieldName,\n parentFieldSlug,\n }),\n ]\n : []),\n ],\n fields: mapTopLevelFields(collection.fields, (field) =>\n patchBreadcrumbField({\n breadcrumbsFieldSlug,\n field,\n hideBreadcrumbs,\n }),\n ),\n hooks: {\n ...(collection.hooks ?? {}),\n ...(diagnosticsAfterChangeHook\n ? {\n afterChange: [\n ...(collection.hooks?.afterChange ?? []),\n diagnosticsAfterChangeHook,\n ],\n }\n : {}),\n },\n }\n })\n\n const missingCollections = pluginOptions.collections.filter(\n (collectionSlug) => !foundCollectionSlugs.has(collectionSlug),\n )\n\n if (missingCollections.length > 0) {\n throw new Error(\n `payload-nested-docs-page-tree could not find the following collections: ${missingCollections.join(', ')}`,\n )\n }\n\n return {\n ...config,\n collections: nextCollections as CollectionConfig[],\n }\n }\n"],"names":["createMovePageEndpoint","createReorderPageEndpoint","nestedDocsPageTreePluginCustomKey","pageTreeWriteContextKey","normalizeNestedDocsPageTreePluginBadgeConfig","DIAGNOSTICS_FLOW_CONTEXT_KEY","createFlowID","projectField","resolveDiagnostics","findTopLevelField","mapTopLevelFields","DEFAULT_BREADCRUMBS_FIELD_SLUG","DEFAULT_HOME_INDICATOR_COLLECTIONS","DEFAULT_LIMIT","DEFAULT_PARENT_FIELD_SLUG","PAGE_TREE_LIST_VIEW_PATH","createDiagnosticsAfterChangeHook","args","collectionSlug","diagnostics","orderableFieldName","parentFieldSlug","snapshotFields","push","doc","operation","previousDoc","req","enabled","context","docID","id","flow","before","after","changed","field","beforeValue","afterValue","JSON","stringify","log","collection","data","String","level","message","source","beforeStatus","_status","afterStatus","getCollectionEndpoints","Array","isArray","endpoints","patchBreadcrumbField","breadcrumbsFieldSlug","hideBreadcrumbs","name","admin","hidden","validateTargetCollection","useAsTitle","includes","Error","slug","fields","existingListView","components","views","list","Component","existingMoveEndpoint","find","endpoint","path","existingReorderEndpoint","buildCollectionCustom","badges","defaultLimit","homeIndicator","getHomeIndicatorCollectionSlugs","Set","collections","pageTreeMoveContextKey","nestedDocsPageTreePlugin","pluginOptions","config","length","disabled","publishOnMove","homeIndicatorCollectionSlugs","targetedCollectionSlugs","foundCollectionSlugs","nextCollections","map","has","add","orderable","diagnosticsAfterChangeHook","pagination","undefined","custom","hooks","afterChange","missingCollections","filter","join"],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -34,6 +34,20 @@ export type NestedDocsPageTreePluginConfig = {
34
34
  hideBreadcrumbs?: boolean;
35
35
  homeIndicator?: NestedDocsPageTreePluginHomeIndicatorConfig;
36
36
  parentFieldSlug?: string;
37
+ /**
38
+ * Publish a hierarchy move immediately instead of staging it as a draft — but
39
+ * ONLY when the moved document had no unpublished changes before the move (its
40
+ * latest version is already published). A document with pending draft edits (a
41
+ * "changed" or draft-only doc) always stays staged, so in-progress edits are
42
+ * never published as a side effect of a move. Only affects collections with
43
+ * drafts enabled; collections without drafts move live regardless.
44
+ *
45
+ * Disabled by default: every move is staged as a draft and the live URL/path
46
+ * changes only when the document is next published.
47
+ *
48
+ * @default false
49
+ */
50
+ publishOnMove?: boolean;
37
51
  };
38
52
  export type NestedDocsPageTreePluginCollectionCustom = {
39
53
  badges: NestedDocsPageTreePluginResolvedBadgeConfig;
@@ -50,7 +64,31 @@ export type PageTreeSourceDoc = Record<string, unknown> & {
50
64
  slug?: null | string;
51
65
  };
52
66
  export declare const nestedDocsPageTreePluginCustomKey = "nestedDocsPageTreePlugin";
67
+ /**
68
+ * Set on Payload's hook context for every page-tree write that leaves the
69
+ * published site unchanged: sibling reorders, and parent moves staged as
70
+ * drafts. Deploy/revalidate hooks read it to skip rebuilds they do not need.
71
+ *
72
+ * It is deliberately NOT set when `publishOnMove` publishes a move, because
73
+ * that move changed the live URL of the page and its descendants and the site
74
+ * does need rebuilding. That way one guard covers every configuration:
75
+ *
76
+ * ```ts
77
+ * if (req.context?.[pageTreeMoveContextKey]) return
78
+ * ```
79
+ *
80
+ * Note the flag describes the *effect* of the write, not its kind - it is
81
+ * absent on published moves even though those are still page-tree moves. Use
82
+ * `pageTreeWriteContextKey` when you need "was this a page-tree write at all".
83
+ */
53
84
  export declare const pageTreeMoveContextKey = "pageTreeMove";
85
+ /**
86
+ * Internal: set on every page-tree write regardless of whether it published.
87
+ * Diagnostics uses it so that published moves are still traced, which is the
88
+ * case most worth observing. Not part of the public API.
89
+ */
90
+ export declare const pageTreeWriteContextKey = "pageTreeWrite";
54
91
  export type PageTreeMoveContext = {
55
92
  [pageTreeMoveContextKey]?: boolean;
93
+ [pageTreeWriteContextKey]?: boolean;
56
94
  };
package/dist/types.js CHANGED
@@ -4,6 +4,27 @@ export const nestedDocsPageTreePluginBadgeStatuses = [
4
4
  'draft'
5
5
  ];
6
6
  export const nestedDocsPageTreePluginCustomKey = 'nestedDocsPageTreePlugin';
7
- export const pageTreeMoveContextKey = 'pageTreeMove';
7
+ /**
8
+ * Set on Payload's hook context for every page-tree write that leaves the
9
+ * published site unchanged: sibling reorders, and parent moves staged as
10
+ * drafts. Deploy/revalidate hooks read it to skip rebuilds they do not need.
11
+ *
12
+ * It is deliberately NOT set when `publishOnMove` publishes a move, because
13
+ * that move changed the live URL of the page and its descendants and the site
14
+ * does need rebuilding. That way one guard covers every configuration:
15
+ *
16
+ * ```ts
17
+ * if (req.context?.[pageTreeMoveContextKey]) return
18
+ * ```
19
+ *
20
+ * Note the flag describes the *effect* of the write, not its kind - it is
21
+ * absent on published moves even though those are still page-tree moves. Use
22
+ * `pageTreeWriteContextKey` when you need "was this a page-tree write at all".
23
+ */ export const pageTreeMoveContextKey = 'pageTreeMove';
24
+ /**
25
+ * Internal: set on every page-tree write regardless of whether it published.
26
+ * Diagnostics uses it so that published moves are still traced, which is the
27
+ * case most worth observing. Not part of the public API.
28
+ */ export const pageTreeWriteContextKey = 'pageTreeWrite';
8
29
 
9
30
  //# sourceMappingURL=types.js.map
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { CollectionSlug } from 'payload'\r\n\r\nimport type { NestedDocsPageTreePluginDiagnosticsConfig } from './utilities/diagnostics.js'\r\n\r\nexport type {\r\n NestedDocsPageTreePluginDiagnosticEvent,\r\n NestedDocsPageTreePluginDiagnosticsConfig,\r\n} from './utilities/diagnostics.js'\r\n\r\nexport const nestedDocsPageTreePluginBadgeStatuses = ['published', 'changed', 'draft'] as const\r\n\r\nexport type NestedDocsPageTreePluginBadgeStatus =\r\n (typeof nestedDocsPageTreePluginBadgeStatuses)[number]\r\n\r\nexport type NestedDocsPageTreePluginBadgeMap = Partial<\r\n Record<NestedDocsPageTreePluginBadgeStatus, string>\r\n>\r\n\r\nexport type NestedDocsPageTreePluginBadgeConfig = {\r\n colors?: NestedDocsPageTreePluginBadgeMap\r\n labels?: NestedDocsPageTreePluginBadgeMap\r\n}\r\n\r\nexport type NestedDocsPageTreePluginResolvedBadgeConfig = {\r\n colors: NestedDocsPageTreePluginBadgeMap\r\n labels: NestedDocsPageTreePluginBadgeMap\r\n}\r\n\r\nexport type NestedDocsPageTreePluginHomeIndicatorConfig =\r\n | false\r\n | {\r\n collections?: CollectionSlug[]\r\n }\r\n\r\nexport type NestedDocsPageTreePluginResolvedHomeIndicatorConfig = {\r\n enabled: boolean\r\n}\r\n\r\nexport type NestedDocsPageTreePluginConfig = {\r\n badges?: NestedDocsPageTreePluginBadgeConfig\r\n breadcrumbsFieldSlug?: string\r\n collections: CollectionSlug[]\r\n defaultLimit?: number\r\n /**\r\n * When set, the plugin emits structured diagnostic events for page-tree\r\n * triggered moves, including before/after snapshots of the published main row.\r\n * Disabled by default. Pass `true` to log to `console`, or pass an object\r\n * with a custom `logger` to route events elsewhere.\r\n */\r\n diagnostics?: NestedDocsPageTreePluginDiagnosticsConfig\r\n disabled?: boolean\r\n hideBreadcrumbs?: boolean\r\n homeIndicator?: NestedDocsPageTreePluginHomeIndicatorConfig\r\n parentFieldSlug?: string\r\n}\r\n\r\nexport type NestedDocsPageTreePluginCollectionCustom = {\r\n badges: NestedDocsPageTreePluginResolvedBadgeConfig\r\n breadcrumbsFieldSlug: string\r\n defaultLimit: number\r\n hideBreadcrumbs: boolean\r\n homeIndicator: NestedDocsPageTreePluginResolvedHomeIndicatorConfig\r\n parentFieldSlug: string\r\n}\r\n\r\nexport type PageTreeSourceDoc = Record<string, unknown> & {\r\n _displayStatus?: null | string\r\n _status?: null | string\r\n id?: number | string\r\n slug?: null | string\r\n}\r\n\r\nexport const nestedDocsPageTreePluginCustomKey = 'nestedDocsPageTreePlugin'\r\n\r\nexport const pageTreeMoveContextKey = 'pageTreeMove'\r\n\r\nexport type PageTreeMoveContext = {\r\n [pageTreeMoveContextKey]?: boolean\r\n}\r\n"],"names":["nestedDocsPageTreePluginBadgeStatuses","nestedDocsPageTreePluginCustomKey","pageTreeMoveContextKey"],"mappings":"AASA,OAAO,MAAMA,wCAAwC;IAAC;IAAa;IAAW;CAAQ,CAAS;AA+D/F,OAAO,MAAMC,oCAAoC,2BAA0B;AAE3E,OAAO,MAAMC,yBAAyB,eAAc"}
1
+ {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { CollectionSlug } from 'payload'\n\nimport type { NestedDocsPageTreePluginDiagnosticsConfig } from './utilities/diagnostics.js'\n\nexport type {\n NestedDocsPageTreePluginDiagnosticEvent,\n NestedDocsPageTreePluginDiagnosticsConfig,\n} from './utilities/diagnostics.js'\n\nexport const nestedDocsPageTreePluginBadgeStatuses = ['published', 'changed', 'draft'] as const\n\nexport type NestedDocsPageTreePluginBadgeStatus =\n (typeof nestedDocsPageTreePluginBadgeStatuses)[number]\n\nexport type NestedDocsPageTreePluginBadgeMap = Partial<\n Record<NestedDocsPageTreePluginBadgeStatus, string>\n>\n\nexport type NestedDocsPageTreePluginBadgeConfig = {\n colors?: NestedDocsPageTreePluginBadgeMap\n labels?: NestedDocsPageTreePluginBadgeMap\n}\n\nexport type NestedDocsPageTreePluginResolvedBadgeConfig = {\n colors: NestedDocsPageTreePluginBadgeMap\n labels: NestedDocsPageTreePluginBadgeMap\n}\n\nexport type NestedDocsPageTreePluginHomeIndicatorConfig =\n | false\n | {\n collections?: CollectionSlug[]\n }\n\nexport type NestedDocsPageTreePluginResolvedHomeIndicatorConfig = {\n enabled: boolean\n}\n\nexport type NestedDocsPageTreePluginConfig = {\n badges?: NestedDocsPageTreePluginBadgeConfig\n breadcrumbsFieldSlug?: string\n collections: CollectionSlug[]\n defaultLimit?: number\n /**\n * When set, the plugin emits structured diagnostic events for page-tree\n * triggered moves, including before/after snapshots of the published main row.\n * Disabled by default. Pass `true` to log to `console`, or pass an object\n * with a custom `logger` to route events elsewhere.\n */\n diagnostics?: NestedDocsPageTreePluginDiagnosticsConfig\n disabled?: boolean\n hideBreadcrumbs?: boolean\n homeIndicator?: NestedDocsPageTreePluginHomeIndicatorConfig\n parentFieldSlug?: string\n /**\n * Publish a hierarchy move immediately instead of staging it as a draft — but\n * ONLY when the moved document had no unpublished changes before the move (its\n * latest version is already published). A document with pending draft edits (a\n * \"changed\" or draft-only doc) always stays staged, so in-progress edits are\n * never published as a side effect of a move. Only affects collections with\n * drafts enabled; collections without drafts move live regardless.\n *\n * Disabled by default: every move is staged as a draft and the live URL/path\n * changes only when the document is next published.\n *\n * @default false\n */\n publishOnMove?: boolean\n}\n\nexport type NestedDocsPageTreePluginCollectionCustom = {\n badges: NestedDocsPageTreePluginResolvedBadgeConfig\n breadcrumbsFieldSlug: string\n defaultLimit: number\n hideBreadcrumbs: boolean\n homeIndicator: NestedDocsPageTreePluginResolvedHomeIndicatorConfig\n parentFieldSlug: string\n}\n\nexport type PageTreeSourceDoc = Record<string, unknown> & {\n _displayStatus?: null | string\n _status?: null | string\n id?: number | string\n slug?: null | string\n}\n\nexport const nestedDocsPageTreePluginCustomKey = 'nestedDocsPageTreePlugin'\n\n/**\n * Set on Payload's hook context for every page-tree write that leaves the\n * published site unchanged: sibling reorders, and parent moves staged as\n * drafts. Deploy/revalidate hooks read it to skip rebuilds they do not need.\n *\n * It is deliberately NOT set when `publishOnMove` publishes a move, because\n * that move changed the live URL of the page and its descendants and the site\n * does need rebuilding. That way one guard covers every configuration:\n *\n * ```ts\n * if (req.context?.[pageTreeMoveContextKey]) return\n * ```\n *\n * Note the flag describes the *effect* of the write, not its kind - it is\n * absent on published moves even though those are still page-tree moves. Use\n * `pageTreeWriteContextKey` when you need \"was this a page-tree write at all\".\n */\nexport const pageTreeMoveContextKey = 'pageTreeMove'\n\n/**\n * Internal: set on every page-tree write regardless of whether it published.\n * Diagnostics uses it so that published moves are still traced, which is the\n * case most worth observing. Not part of the public API.\n */\nexport const pageTreeWriteContextKey = 'pageTreeWrite'\n\nexport type PageTreeMoveContext = {\n [pageTreeMoveContextKey]?: boolean\n [pageTreeWriteContextKey]?: boolean\n}\n"],"names":["nestedDocsPageTreePluginBadgeStatuses","nestedDocsPageTreePluginCustomKey","pageTreeMoveContextKey","pageTreeWriteContextKey"],"mappings":"AASA,OAAO,MAAMA,wCAAwC;IAAC;IAAa;IAAW;CAAQ,CAAS;AA6E/F,OAAO,MAAMC,oCAAoC,2BAA0B;AAE3E;;;;;;;;;;;;;;;;CAgBC,GACD,OAAO,MAAMC,yBAAyB,eAAc;AAEpD;;;;CAIC,GACD,OAAO,MAAMC,0BAA0B,gBAAe"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utilities/badgeConfig.ts"],"sourcesContent":["import type {\r\n NestedDocsPageTreePluginBadgeConfig,\r\n NestedDocsPageTreePluginBadgeMap,\r\n NestedDocsPageTreePluginResolvedBadgeConfig,\r\n} from '../types.js'\r\nimport { nestedDocsPageTreePluginBadgeStatuses } from '../types.js'\r\n\r\nfunction normalizeBadgeMap(value: unknown): NestedDocsPageTreePluginBadgeMap {\r\n const normalized: NestedDocsPageTreePluginBadgeMap = {}\r\n\r\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\r\n return normalized\r\n }\r\n\r\n const badgeMap = value as Record<string, unknown>\r\n\r\n for (const status of nestedDocsPageTreePluginBadgeStatuses) {\r\n const statusValue = badgeMap[status]\r\n\r\n if (typeof statusValue === 'string' && statusValue.trim().length > 0) {\r\n normalized[status] = statusValue.trim()\r\n }\r\n }\r\n\r\n return normalized\r\n}\r\n\r\nexport function normalizeNestedDocsPageTreePluginBadgeConfig(\r\n value: NestedDocsPageTreePluginBadgeConfig | unknown,\r\n): NestedDocsPageTreePluginResolvedBadgeConfig {\r\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\r\n return {\r\n colors: {},\r\n labels: {},\r\n }\r\n }\r\n\r\n const badgeConfig = value as NestedDocsPageTreePluginBadgeConfig\r\n\r\n return {\r\n colors: normalizeBadgeMap(badgeConfig.colors),\r\n labels: normalizeBadgeMap(badgeConfig.labels),\r\n }\r\n}\r\n"],"names":["nestedDocsPageTreePluginBadgeStatuses","normalizeBadgeMap","value","normalized","Array","isArray","badgeMap","status","statusValue","trim","length","normalizeNestedDocsPageTreePluginBadgeConfig","colors","labels","badgeConfig"],"mappings":"AAKA,SAASA,qCAAqC,QAAQ,cAAa;AAEnE,SAASC,kBAAkBC,KAAc;IACvC,MAAMC,aAA+C,CAAC;IAEtD,IAAI,CAACD,SAAS,OAAOA,UAAU,YAAYE,MAAMC,OAAO,CAACH,QAAQ;QAC/D,OAAOC;IACT;IAEA,MAAMG,WAAWJ;IAEjB,KAAK,MAAMK,UAAUP,sCAAuC;QAC1D,MAAMQ,cAAcF,QAAQ,CAACC,OAAO;QAEpC,IAAI,OAAOC,gBAAgB,YAAYA,YAAYC,IAAI,GAAGC,MAAM,GAAG,GAAG;YACpEP,UAAU,CAACI,OAAO,GAAGC,YAAYC,IAAI;QACvC;IACF;IAEA,OAAON;AACT;AAEA,OAAO,SAASQ,6CACdT,KAAoD;IAEpD,IAAI,CAACA,SAAS,OAAOA,UAAU,YAAYE,MAAMC,OAAO,CAACH,QAAQ;QAC/D,OAAO;YACLU,QAAQ,CAAC;YACTC,QAAQ,CAAC;QACX;IACF;IAEA,MAAMC,cAAcZ;IAEpB,OAAO;QACLU,QAAQX,kBAAkBa,YAAYF,MAAM;QAC5CC,QAAQZ,kBAAkBa,YAAYD,MAAM;IAC9C;AACF"}
1
+ {"version":3,"sources":["../../src/utilities/badgeConfig.ts"],"sourcesContent":["import type {\n NestedDocsPageTreePluginBadgeConfig,\n NestedDocsPageTreePluginBadgeMap,\n NestedDocsPageTreePluginResolvedBadgeConfig,\n} from '../types.js'\nimport { nestedDocsPageTreePluginBadgeStatuses } from '../types.js'\n\nfunction normalizeBadgeMap(value: unknown): NestedDocsPageTreePluginBadgeMap {\n const normalized: NestedDocsPageTreePluginBadgeMap = {}\n\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return normalized\n }\n\n const badgeMap = value as Record<string, unknown>\n\n for (const status of nestedDocsPageTreePluginBadgeStatuses) {\n const statusValue = badgeMap[status]\n\n if (typeof statusValue === 'string' && statusValue.trim().length > 0) {\n normalized[status] = statusValue.trim()\n }\n }\n\n return normalized\n}\n\nexport function normalizeNestedDocsPageTreePluginBadgeConfig(\n value: NestedDocsPageTreePluginBadgeConfig | unknown,\n): NestedDocsPageTreePluginResolvedBadgeConfig {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return {\n colors: {},\n labels: {},\n }\n }\n\n const badgeConfig = value as NestedDocsPageTreePluginBadgeConfig\n\n return {\n colors: normalizeBadgeMap(badgeConfig.colors),\n labels: normalizeBadgeMap(badgeConfig.labels),\n }\n}\n"],"names":["nestedDocsPageTreePluginBadgeStatuses","normalizeBadgeMap","value","normalized","Array","isArray","badgeMap","status","statusValue","trim","length","normalizeNestedDocsPageTreePluginBadgeConfig","colors","labels","badgeConfig"],"mappings":"AAKA,SAASA,qCAAqC,QAAQ,cAAa;AAEnE,SAASC,kBAAkBC,KAAc;IACvC,MAAMC,aAA+C,CAAC;IAEtD,IAAI,CAACD,SAAS,OAAOA,UAAU,YAAYE,MAAMC,OAAO,CAACH,QAAQ;QAC/D,OAAOC;IACT;IAEA,MAAMG,WAAWJ;IAEjB,KAAK,MAAMK,UAAUP,sCAAuC;QAC1D,MAAMQ,cAAcF,QAAQ,CAACC,OAAO;QAEpC,IAAI,OAAOC,gBAAgB,YAAYA,YAAYC,IAAI,GAAGC,MAAM,GAAG,GAAG;YACpEP,UAAU,CAACI,OAAO,GAAGC,YAAYC,IAAI;QACvC;IACF;IAEA,OAAON;AACT;AAEA,OAAO,SAASQ,6CACdT,KAAoD;IAEpD,IAAI,CAACA,SAAS,OAAOA,UAAU,YAAYE,MAAMC,OAAO,CAACH,QAAQ;QAC/D,OAAO;YACLU,QAAQ,CAAC;YACTC,QAAQ,CAAC;QACX;IACF;IAEA,MAAMC,cAAcZ;IAEpB,OAAO;QACLU,QAAQX,kBAAkBa,YAAYF,MAAM;QAC5CC,QAAQZ,kBAAkBa,YAAYD,MAAM;IAC9C;AACF"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utilities/dropTargets.ts"],"sourcesContent":["import type { PageTreeDoc } from './pageTree.js'\r\n\r\nexport type PageTreeInsertDropTarget = {\r\n depth: number\r\n dropID: string\r\n dropType: 'insert'\r\n parentID: null | string\r\n referenceRowID: string\r\n}\r\n\r\nexport type PageTreeRowDropTarget = {\r\n dropType: 'row'\r\n insertAfterDropID: null | string\r\n insertBeforeDropID: null | string\r\n rowID: string\r\n}\r\n\r\nexport type PageTreeDropTarget = PageTreeInsertDropTarget | PageTreeRowDropTarget\r\n\r\nexport type PageTreeOrderPlacement = {\r\n nextSiblingID: null | string\r\n parentID: null | string\r\n previousSiblingID: null | string\r\n}\r\n\r\nfunction getInsertIndex(dropID: string): null | number {\r\n const insertIndex = Number.parseInt(dropID.split(':')[1] ?? '', 10)\r\n\r\n return Number.isNaN(insertIndex) ? null : insertIndex\r\n}\r\n\r\nfunction getMovingSubtreeIDs(docs: PageTreeDoc[], activeDoc: PageTreeDoc): Set<string> {\r\n return new Set(\r\n docs\r\n .filter(\r\n (doc) =>\r\n doc.__pageTreeID === activeDoc.__pageTreeID ||\r\n doc.__pageTreeAncestorIDs.includes(activeDoc.__pageTreeID),\r\n )\r\n .map((doc) => doc.__pageTreeID),\r\n )\r\n}\r\n\r\nfunction getSiblingID(doc: PageTreeDoc | undefined): null | string {\r\n return doc?.__pageTreeID ?? null\r\n}\r\n\r\nexport function buildInsertDropTargets(docs: PageTreeDoc[]): PageTreeInsertDropTarget[] {\r\n const rootDocs = docs.filter((doc) => doc.__pageTreeParentID === null)\r\n\r\n if (rootDocs.length === 0) {\r\n return []\r\n }\r\n\r\n return Array.from({ length: rootDocs.length + 1 }, (_, index) => {\r\n const referenceDoc = rootDocs[index] ?? rootDocs[rootDocs.length - 1]\r\n\r\n return {\r\n depth: 0,\r\n dropID: `page-insert:${index}`,\r\n dropType: 'insert',\r\n parentID: null,\r\n referenceRowID: referenceDoc.__pageTreeID,\r\n }\r\n })\r\n}\r\n\r\nexport function getDropTargetParentDoc(args: {\r\n docsByID: ReadonlyMap<string, PageTreeDoc>\r\n dropTarget: null | PageTreeDropTarget\r\n}): null | PageTreeDoc {\r\n const { docsByID, dropTarget } = args\r\n\r\n if (!dropTarget) {\r\n return null\r\n }\r\n\r\n if (dropTarget.dropType === 'row') {\r\n return docsByID.get(dropTarget.rowID) ?? null\r\n }\r\n\r\n if (dropTarget.parentID === null) {\r\n return null\r\n }\r\n\r\n return docsByID.get(dropTarget.parentID) ?? null\r\n}\r\n\r\nexport function getOrderPlacementFromDropTarget(args: {\r\n activeDoc: PageTreeDoc\r\n docs: PageTreeDoc[]\r\n docsByID: ReadonlyMap<string, PageTreeDoc>\r\n dropTarget: null | PageTreeDropTarget\r\n}): null | PageTreeOrderPlacement {\r\n const { activeDoc, docs, docsByID, dropTarget } = args\r\n\r\n if (!dropTarget) {\r\n return null\r\n }\r\n\r\n const movingSubtreeIDs = getMovingSubtreeIDs(docs, activeDoc)\r\n\r\n if (dropTarget.dropType === 'row') {\r\n const targetDoc = docsByID.get(dropTarget.rowID)\r\n\r\n if (!targetDoc) {\r\n return null\r\n }\r\n\r\n const childSiblings = docs.filter(\r\n (doc) =>\r\n doc.__pageTreeParentID === targetDoc.__pageTreeID &&\r\n !movingSubtreeIDs.has(doc.__pageTreeID),\r\n )\r\n\r\n return {\r\n nextSiblingID: null,\r\n parentID: targetDoc.__pageTreeID,\r\n previousSiblingID: getSiblingID(childSiblings.at(-1)),\r\n }\r\n }\r\n\r\n const insertIndex = getInsertIndex(dropTarget.dropID)\r\n\r\n if (insertIndex === null) {\r\n return null\r\n }\r\n\r\n const parentID = dropTarget.parentID\r\n const siblingDocs = docs.filter(\r\n (doc) => doc.__pageTreeParentID === parentID && !movingSubtreeIDs.has(doc.__pageTreeID),\r\n )\r\n const beforeSiblings = siblingDocs.slice(0, insertIndex)\r\n const afterSiblings = siblingDocs.slice(insertIndex)\r\n\r\n return {\r\n nextSiblingID: getSiblingID(afterSiblings[0]),\r\n parentID,\r\n previousSiblingID: getSiblingID(beforeSiblings.at(-1)),\r\n }\r\n}\r\n"],"names":["getInsertIndex","dropID","insertIndex","Number","parseInt","split","isNaN","getMovingSubtreeIDs","docs","activeDoc","Set","filter","doc","__pageTreeID","__pageTreeAncestorIDs","includes","map","getSiblingID","buildInsertDropTargets","rootDocs","__pageTreeParentID","length","Array","from","_","index","referenceDoc","depth","dropType","parentID","referenceRowID","getDropTargetParentDoc","args","docsByID","dropTarget","get","rowID","getOrderPlacementFromDropTarget","movingSubtreeIDs","targetDoc","childSiblings","has","nextSiblingID","previousSiblingID","at","siblingDocs","beforeSiblings","slice","afterSiblings"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/utilities/dropTargets.ts"],"sourcesContent":["import type { PageTreeDoc } from './pageTree.js'\n\nexport type PageTreeInsertDropTarget = {\n depth: number\n dropID: string\n dropType: 'insert'\n parentID: null | string\n referenceRowID: string\n}\n\nexport type PageTreeRowDropTarget = {\n dropType: 'row'\n insertAfterDropID: null | string\n insertBeforeDropID: null | string\n rowID: string\n}\n\nexport type PageTreeDropTarget = PageTreeInsertDropTarget | PageTreeRowDropTarget\n\nexport type PageTreeOrderPlacement = {\n nextSiblingID: null | string\n parentID: null | string\n previousSiblingID: null | string\n}\n\nfunction getInsertIndex(dropID: string): null | number {\n const insertIndex = Number.parseInt(dropID.split(':')[1] ?? '', 10)\n\n return Number.isNaN(insertIndex) ? null : insertIndex\n}\n\nfunction getMovingSubtreeIDs(docs: PageTreeDoc[], activeDoc: PageTreeDoc): Set<string> {\n return new Set(\n docs\n .filter(\n (doc) =>\n doc.__pageTreeID === activeDoc.__pageTreeID ||\n doc.__pageTreeAncestorIDs.includes(activeDoc.__pageTreeID),\n )\n .map((doc) => doc.__pageTreeID),\n )\n}\n\nfunction getSiblingID(doc: PageTreeDoc | undefined): null | string {\n return doc?.__pageTreeID ?? null\n}\n\nexport function buildInsertDropTargets(docs: PageTreeDoc[]): PageTreeInsertDropTarget[] {\n const rootDocs = docs.filter((doc) => doc.__pageTreeParentID === null)\n\n if (rootDocs.length === 0) {\n return []\n }\n\n return Array.from({ length: rootDocs.length + 1 }, (_, index) => {\n const referenceDoc = rootDocs[index] ?? rootDocs[rootDocs.length - 1]\n\n return {\n depth: 0,\n dropID: `page-insert:${index}`,\n dropType: 'insert',\n parentID: null,\n referenceRowID: referenceDoc.__pageTreeID,\n }\n })\n}\n\nexport function getDropTargetParentDoc(args: {\n docsByID: ReadonlyMap<string, PageTreeDoc>\n dropTarget: null | PageTreeDropTarget\n}): null | PageTreeDoc {\n const { docsByID, dropTarget } = args\n\n if (!dropTarget) {\n return null\n }\n\n if (dropTarget.dropType === 'row') {\n return docsByID.get(dropTarget.rowID) ?? null\n }\n\n if (dropTarget.parentID === null) {\n return null\n }\n\n return docsByID.get(dropTarget.parentID) ?? null\n}\n\nexport function getOrderPlacementFromDropTarget(args: {\n activeDoc: PageTreeDoc\n docs: PageTreeDoc[]\n docsByID: ReadonlyMap<string, PageTreeDoc>\n dropTarget: null | PageTreeDropTarget\n}): null | PageTreeOrderPlacement {\n const { activeDoc, docs, docsByID, dropTarget } = args\n\n if (!dropTarget) {\n return null\n }\n\n const movingSubtreeIDs = getMovingSubtreeIDs(docs, activeDoc)\n\n if (dropTarget.dropType === 'row') {\n const targetDoc = docsByID.get(dropTarget.rowID)\n\n if (!targetDoc) {\n return null\n }\n\n const childSiblings = docs.filter(\n (doc) =>\n doc.__pageTreeParentID === targetDoc.__pageTreeID &&\n !movingSubtreeIDs.has(doc.__pageTreeID),\n )\n\n return {\n nextSiblingID: null,\n parentID: targetDoc.__pageTreeID,\n previousSiblingID: getSiblingID(childSiblings.at(-1)),\n }\n }\n\n const insertIndex = getInsertIndex(dropTarget.dropID)\n\n if (insertIndex === null) {\n return null\n }\n\n const parentID = dropTarget.parentID\n const siblingDocs = docs.filter(\n (doc) => doc.__pageTreeParentID === parentID && !movingSubtreeIDs.has(doc.__pageTreeID),\n )\n const beforeSiblings = siblingDocs.slice(0, insertIndex)\n const afterSiblings = siblingDocs.slice(insertIndex)\n\n return {\n nextSiblingID: getSiblingID(afterSiblings[0]),\n parentID,\n previousSiblingID: getSiblingID(beforeSiblings.at(-1)),\n }\n}\n"],"names":["getInsertIndex","dropID","insertIndex","Number","parseInt","split","isNaN","getMovingSubtreeIDs","docs","activeDoc","Set","filter","doc","__pageTreeID","__pageTreeAncestorIDs","includes","map","getSiblingID","buildInsertDropTargets","rootDocs","__pageTreeParentID","length","Array","from","_","index","referenceDoc","depth","dropType","parentID","referenceRowID","getDropTargetParentDoc","args","docsByID","dropTarget","get","rowID","getOrderPlacementFromDropTarget","movingSubtreeIDs","targetDoc","childSiblings","has","nextSiblingID","previousSiblingID","at","siblingDocs","beforeSiblings","slice","afterSiblings"],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { Field } from 'payload';
2
+ /**
3
+ * Finds the field stored under `fieldName` at the top level of the document,
4
+ * looking through presentational containers such as tabs and rows.
5
+ */
6
+ export declare function findTopLevelField(fields: Field[], fieldName: string): Field | undefined;
7
+ /**
8
+ * Maps `mapField` over every field stored at the top level of the document,
9
+ * rebuilding presentational containers so nested fields are patched in place.
10
+ */
11
+ export declare function mapTopLevelFields(fields: Field[], mapField: (field: Field) => Field): Field[];