@valkyrianlabs/payload-markdown-docs 0.1.0-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/README.md +195 -0
  2. package/dist/admin/DocsSetManager.d.ts +2 -0
  3. package/dist/admin/DocsSetManager.js +298 -0
  4. package/dist/admin/DocsSetManager.js.map +1 -0
  5. package/dist/admin/docsSetManagerData.d.ts +25 -0
  6. package/dist/admin/docsSetManagerData.js +266 -0
  7. package/dist/admin/docsSetManagerData.js.map +1 -0
  8. package/dist/admin/docsSetManagerTypes.d.ts +103 -0
  9. package/dist/admin/docsSetManagerTypes.js +3 -0
  10. package/dist/admin/docsSetManagerTypes.js.map +1 -0
  11. package/dist/admin/index.d.ts +3 -0
  12. package/dist/admin/index.js +4 -0
  13. package/dist/admin/index.js.map +1 -0
  14. package/dist/cli/commands/install.d.ts +2 -0
  15. package/dist/cli/commands/install.js +211 -0
  16. package/dist/cli/commands/install.js.map +1 -0
  17. package/dist/cli/commands/keygen.d.ts +2 -0
  18. package/dist/cli/commands/keygen.js +89 -0
  19. package/dist/cli/commands/keygen.js.map +1 -0
  20. package/dist/cli/commands/manifest.d.ts +2 -0
  21. package/dist/cli/commands/manifest.js +50 -0
  22. package/dist/cli/commands/manifest.js.map +1 -0
  23. package/dist/cli/commands/plan.d.ts +2 -0
  24. package/dist/cli/commands/plan.js +110 -0
  25. package/dist/cli/commands/plan.js.map +1 -0
  26. package/dist/cli/commands/push.d.ts +3 -0
  27. package/dist/cli/commands/push.js +308 -0
  28. package/dist/cli/commands/push.js.map +1 -0
  29. package/dist/cli/commands/validate.d.ts +3 -0
  30. package/dist/cli/commands/validate.js +109 -0
  31. package/dist/cli/commands/validate.js.map +1 -0
  32. package/dist/cli/filesystem.d.ts +20 -0
  33. package/dist/cli/filesystem.js +96 -0
  34. package/dist/cli/filesystem.js.map +1 -0
  35. package/dist/cli/format.d.ts +35 -0
  36. package/dist/cli/format.js +76 -0
  37. package/dist/cli/format.js.map +1 -0
  38. package/dist/cli/http.d.ts +19 -0
  39. package/dist/cli/http.js +39 -0
  40. package/dist/cli/http.js.map +1 -0
  41. package/dist/cli/index.d.ts +3 -0
  42. package/dist/cli/index.js +214 -0
  43. package/dist/cli/index.js.map +1 -0
  44. package/dist/cli/parseArgs.d.ts +5 -0
  45. package/dist/cli/parseArgs.js +219 -0
  46. package/dist/cli/parseArgs.js.map +1 -0
  47. package/dist/cli/types.d.ts +51 -0
  48. package/dist/cli/types.js +3 -0
  49. package/dist/cli/types.js.map +1 -0
  50. package/dist/collections/docs.d.ts +9 -0
  51. package/dist/collections/docs.js +168 -0
  52. package/dist/collections/docs.js.map +1 -0
  53. package/dist/collections/docsGroups.d.ts +5 -0
  54. package/dist/collections/docsGroups.js +57 -0
  55. package/dist/collections/docsGroups.js.map +1 -0
  56. package/dist/collections/docsSets.d.ts +8 -0
  57. package/dist/collections/docsSets.js +158 -0
  58. package/dist/collections/docsSets.js.map +1 -0
  59. package/dist/collections/index.d.ts +10 -0
  60. package/dist/collections/index.js +7 -0
  61. package/dist/collections/index.js.map +1 -0
  62. package/dist/collections/nonces.d.ts +6 -0
  63. package/dist/collections/nonces.js +57 -0
  64. package/dist/collections/nonces.js.map +1 -0
  65. package/dist/collections/syncRuns.d.ts +5 -0
  66. package/dist/collections/syncRuns.js +139 -0
  67. package/dist/collections/syncRuns.js.map +1 -0
  68. package/dist/constants.d.ts +21 -0
  69. package/dist/constants.js +23 -0
  70. package/dist/constants.js.map +1 -0
  71. package/dist/endpoints/index.d.ts +2 -0
  72. package/dist/endpoints/index.js +3 -0
  73. package/dist/endpoints/index.js.map +1 -0
  74. package/dist/endpoints/sync.d.ts +47 -0
  75. package/dist/endpoints/sync.js +616 -0
  76. package/dist/endpoints/sync.js.map +1 -0
  77. package/dist/index.d.ts +9 -0
  78. package/dist/index.js +7 -0
  79. package/dist/index.js.map +1 -0
  80. package/dist/next/PayloadMarkdownDocsPage.d.ts +7 -0
  81. package/dist/next/PayloadMarkdownDocsPage.js +142 -0
  82. package/dist/next/PayloadMarkdownDocsPage.js.map +1 -0
  83. package/dist/next/index.d.ts +9 -0
  84. package/dist/next/index.js +7 -0
  85. package/dist/next/index.js.map +1 -0
  86. package/dist/next/markdown.d.ts +14 -0
  87. package/dist/next/markdown.js +232 -0
  88. package/dist/next/markdown.js.map +1 -0
  89. package/dist/next/metadata.d.ts +3 -0
  90. package/dist/next/metadata.js +33 -0
  91. package/dist/next/metadata.js.map +1 -0
  92. package/dist/next/records.d.ts +14 -0
  93. package/dist/next/records.js +146 -0
  94. package/dist/next/records.js.map +1 -0
  95. package/dist/next/route.d.ts +6 -0
  96. package/dist/next/route.js +271 -0
  97. package/dist/next/route.js.map +1 -0
  98. package/dist/next/sidebar.d.ts +15 -0
  99. package/dist/next/sidebar.js +137 -0
  100. package/dist/next/sidebar.js.map +1 -0
  101. package/dist/next/types.d.ts +117 -0
  102. package/dist/next/types.js +3 -0
  103. package/dist/next/types.js.map +1 -0
  104. package/dist/payload/applyDocsSync.d.ts +54 -0
  105. package/dist/payload/applyDocsSync.js +176 -0
  106. package/dist/payload/applyDocsSync.js.map +1 -0
  107. package/dist/payload/docsConflicts.d.ts +12 -0
  108. package/dist/payload/docsConflicts.js +34 -0
  109. package/dist/payload/docsConflicts.js.map +1 -0
  110. package/dist/payload/docsData.d.ts +23 -0
  111. package/dist/payload/docsData.js +59 -0
  112. package/dist/payload/docsData.js.map +1 -0
  113. package/dist/payload/docsSets.d.ts +38 -0
  114. package/dist/payload/docsSets.js +57 -0
  115. package/dist/payload/docsSets.js.map +1 -0
  116. package/dist/payload/existingDocs.d.ts +43 -0
  117. package/dist/payload/existingDocs.js +97 -0
  118. package/dist/payload/existingDocs.js.map +1 -0
  119. package/dist/payload/index.d.ts +15 -0
  120. package/dist/payload/index.js +10 -0
  121. package/dist/payload/index.js.map +1 -0
  122. package/dist/payload/routeCollisions.d.ts +31 -0
  123. package/dist/payload/routeCollisions.js +104 -0
  124. package/dist/payload/routeCollisions.js.map +1 -0
  125. package/dist/payload/syncRuns.d.ts +60 -0
  126. package/dist/payload/syncRuns.js +53 -0
  127. package/dist/payload/syncRuns.js.map +1 -0
  128. package/dist/plugin.d.ts +3 -0
  129. package/dist/plugin.js +165 -0
  130. package/dist/plugin.js.map +1 -0
  131. package/dist/routing/index.d.ts +3 -0
  132. package/dist/routing/index.js +4 -0
  133. package/dist/routing/index.js.map +1 -0
  134. package/dist/routing/paths.d.ts +7 -0
  135. package/dist/routing/paths.js +23 -0
  136. package/dist/routing/paths.js.map +1 -0
  137. package/dist/routing/reservations.d.ts +37 -0
  138. package/dist/routing/reservations.js +79 -0
  139. package/dist/routing/reservations.js.map +1 -0
  140. package/dist/security/canonical.d.ts +12 -0
  141. package/dist/security/canonical.js +24 -0
  142. package/dist/security/canonical.js.map +1 -0
  143. package/dist/security/githubOidc.d.ts +45 -0
  144. package/dist/security/githubOidc.js +177 -0
  145. package/dist/security/githubOidc.js.map +1 -0
  146. package/dist/security/headers.d.ts +22 -0
  147. package/dist/security/headers.js +44 -0
  148. package/dist/security/headers.js.map +1 -0
  149. package/dist/security/index.d.ts +15 -0
  150. package/dist/security/index.js +9 -0
  151. package/dist/security/index.js.map +1 -0
  152. package/dist/security/jwks.d.ts +20 -0
  153. package/dist/security/jwks.js +40 -0
  154. package/dist/security/jwks.js.map +1 -0
  155. package/dist/security/jwt.d.ts +10 -0
  156. package/dist/security/jwt.js +42 -0
  157. package/dist/security/jwt.js.map +1 -0
  158. package/dist/security/nonce.d.ts +34 -0
  159. package/dist/security/nonce.js +43 -0
  160. package/dist/security/nonce.js.map +1 -0
  161. package/dist/security/sign.d.ts +13 -0
  162. package/dist/security/sign.js +39 -0
  163. package/dist/security/sign.js.map +1 -0
  164. package/dist/security/verify.d.ts +28 -0
  165. package/dist/security/verify.js +54 -0
  166. package/dist/security/verify.js.map +1 -0
  167. package/dist/skills/codex/SKILL.md +173 -0
  168. package/dist/skills/codex/examples/docs-page.md +42 -0
  169. package/dist/skills/codex/examples/github-actions.md +64 -0
  170. package/dist/skills/codex/reference/admin.md +28 -0
  171. package/dist/skills/codex/reference/frontmatter.md +39 -0
  172. package/dist/skills/codex/reference/payload-markdown-directives.md +77 -0
  173. package/dist/skills/codex/reference/routing.md +35 -0
  174. package/dist/skills/codex/reference/sync.md +35 -0
  175. package/dist/skills/codex/reference/troubleshooting.md +53 -0
  176. package/dist/skills/codex/reference/workflow.md +39 -0
  177. package/dist/sync/aiExportManifest.d.ts +58 -0
  178. package/dist/sync/aiExportManifest.js +430 -0
  179. package/dist/sync/aiExportManifest.js.map +1 -0
  180. package/dist/sync/frontmatter.d.ts +28 -0
  181. package/dist/sync/frontmatter.js +210 -0
  182. package/dist/sync/frontmatter.js.map +1 -0
  183. package/dist/sync/hash.d.ts +1 -0
  184. package/dist/sync/hash.js +8 -0
  185. package/dist/sync/hash.js.map +1 -0
  186. package/dist/sync/index.d.ts +12 -0
  187. package/dist/sync/index.js +9 -0
  188. package/dist/sync/index.js.map +1 -0
  189. package/dist/sync/manifest.d.ts +58 -0
  190. package/dist/sync/manifest.js +21 -0
  191. package/dist/sync/manifest.js.map +1 -0
  192. package/dist/sync/paths.d.ts +16 -0
  193. package/dist/sync/paths.js +116 -0
  194. package/dist/sync/paths.js.map +1 -0
  195. package/dist/sync/plan.d.ts +29 -0
  196. package/dist/sync/plan.js +72 -0
  197. package/dist/sync/plan.js.map +1 -0
  198. package/dist/sync/validate.d.ts +26 -0
  199. package/dist/sync/validate.js +308 -0
  200. package/dist/sync/validate.js.map +1 -0
  201. package/dist/types.d.ts +84 -0
  202. package/dist/types.js +3 -0
  203. package/dist/types.js.map +1 -0
  204. package/package.json +143 -0
@@ -0,0 +1,137 @@
1
+ import { DEFAULT_DOCS_COLLECTION_SLUG, DEFAULT_MARKDOWN_FIELD_NAME } from '../constants.js';
2
+ import { joinRouteSegments } from '../routing/index.js';
3
+ import { isVisibleDocsRecord, toResolvedDocsRecord } from './records.js';
4
+ const titleCaseSegment = (segment)=>segment.split(/[-_]+/).filter(Boolean).map((part)=>`${part.charAt(0).toUpperCase()}${part.slice(1)}`).join(' ');
5
+ const getSidebarLabel = (record)=>record.overrides?.navTitle ?? record.navTitle ?? record.title ?? record.sourcePath;
6
+ const getSourcePathSegments = (sourcePath)=>{
7
+ const withoutExtension = sourcePath.replace(/\.md$/i, '');
8
+ const segments = withoutExtension.split('/').filter(Boolean);
9
+ if (segments.at(-1) === 'index') {
10
+ return segments.slice(0, -1);
11
+ }
12
+ return segments;
13
+ };
14
+ const compareSidebarItems = (first, second)=>{
15
+ if (first.order !== second.order) {
16
+ return first.order - second.order;
17
+ }
18
+ return first.sourcePath.localeCompare(second.sourcePath);
19
+ };
20
+ const sortSidebarTree = (items)=>{
21
+ items.sort(compareSidebarItems);
22
+ for (const item of items){
23
+ if (item.children) {
24
+ sortSidebarTree(item.children);
25
+ }
26
+ }
27
+ };
28
+ const getOrCreateFolderNode = ({ currentItems, depth, docsSet, order, segment, sourcePath })=>{
29
+ const existing = currentItems.find((item)=>item.sourcePath === sourcePath);
30
+ if (existing) {
31
+ existing.order = Math.min(existing.order, order);
32
+ return existing;
33
+ }
34
+ const node = {
35
+ children: [],
36
+ depth,
37
+ label: titleCaseSegment(segment),
38
+ order,
39
+ route: docsSet ? joinRouteSegments(docsSet.routeBase, sourcePath) : `/${sourcePath}`,
40
+ sourcePath
41
+ };
42
+ currentItems.push(node);
43
+ return node;
44
+ };
45
+ const mergeLeafIntoTree = ({ docsSet, record, rootItems })=>{
46
+ const segments = getSourcePathSegments(record.sourcePath);
47
+ if (segments.length === 0) {
48
+ rootItems.push({
49
+ depth: 0,
50
+ label: getSidebarLabel(record),
51
+ order: record.order,
52
+ route: record.route,
53
+ sourcePath: record.sourcePath
54
+ });
55
+ return;
56
+ }
57
+ let currentItems = rootItems;
58
+ for (const [index, segment] of segments.entries()){
59
+ const sourcePath = segments.slice(0, index + 1).join('/');
60
+ const isLeaf = index === segments.length - 1;
61
+ if (isLeaf) {
62
+ const existing = currentItems.find((item)=>item.sourcePath === sourcePath);
63
+ if (existing) {
64
+ existing.label = getSidebarLabel(record);
65
+ existing.order = record.order;
66
+ existing.route = record.route;
67
+ existing.sourcePath = record.sourcePath;
68
+ existing.children ??= [];
69
+ return;
70
+ }
71
+ currentItems.push({
72
+ depth: index,
73
+ label: getSidebarLabel(record),
74
+ order: record.order,
75
+ route: record.route,
76
+ sourcePath: record.sourcePath
77
+ });
78
+ return;
79
+ }
80
+ const folder = getOrCreateFolderNode({
81
+ currentItems,
82
+ depth: index,
83
+ docsSet,
84
+ order: record.order,
85
+ segment,
86
+ sourcePath
87
+ });
88
+ folder.children ??= [];
89
+ currentItems = folder.children;
90
+ }
91
+ };
92
+ export const buildPayloadMarkdownDocsSidebar = (records, options = {})=>{
93
+ const sidebar = [];
94
+ const visibleRecords = records.filter((record)=>isVisibleDocsRecord({
95
+ includeDrafts: options.includeDrafts,
96
+ record
97
+ })).filter((record)=>record.overrides?.hideFromNav !== true).sort((first, second)=>{
98
+ if (first.order !== second.order) {
99
+ return first.order - second.order;
100
+ }
101
+ return first.sourcePath.localeCompare(second.sourcePath);
102
+ });
103
+ for (const record of visibleRecords){
104
+ mergeLeafIntoTree({
105
+ docsSet: options.docsSet,
106
+ record,
107
+ rootItems: sidebar
108
+ });
109
+ }
110
+ sortSidebarTree(sidebar);
111
+ return sidebar;
112
+ };
113
+ export const getPayloadMarkdownDocsSidebar = async ({ collections, docsSet, includeDrafts = false, markdownField = DEFAULT_MARKDOWN_FIELD_NAME, // Sidebar data reads plugin-owned generated docs server-side.
114
+ // Access is overridden here, then nav visibility is enforced explicitly.
115
+ overrideAccess = true, payload })=>{
116
+ const result = await payload.find({
117
+ collection: collections?.docs ?? DEFAULT_DOCS_COLLECTION_SLUG,
118
+ depth: 0,
119
+ limit: 1000,
120
+ overrideAccess,
121
+ where: {
122
+ docsSet: {
123
+ equals: docsSet.id
124
+ }
125
+ }
126
+ });
127
+ const records = result.docs.map((doc)=>toResolvedDocsRecord({
128
+ doc,
129
+ markdownField
130
+ })).filter((record)=>record !== undefined);
131
+ return buildPayloadMarkdownDocsSidebar(records, {
132
+ docsSet,
133
+ includeDrafts
134
+ });
135
+ };
136
+
137
+ //# sourceMappingURL=sidebar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/next/sidebar.ts"],"sourcesContent":["import type {\n PayloadMarkdownDocsCollectionSlugs,\n PayloadMarkdownDocsReadPayload,\n PayloadMarkdownDocsSidebarItem,\n ResolvedPayloadMarkdownDocsRecord,\n ResolvedPayloadMarkdownDocsSet,\n} from './types.js'\n\nimport {\n DEFAULT_DOCS_COLLECTION_SLUG,\n DEFAULT_MARKDOWN_FIELD_NAME,\n} from '../constants.js'\nimport { joinRouteSegments } from '../routing/index.js'\nimport {\n isVisibleDocsRecord,\n toResolvedDocsRecord,\n} from './records.js'\n\nexport type BuildPayloadMarkdownDocsSidebarOptions = {\n docsSet?: ResolvedPayloadMarkdownDocsSet\n includeDrafts?: boolean\n}\n\nexport type GetPayloadMarkdownDocsSidebarOptions = {\n collections?: PayloadMarkdownDocsCollectionSlugs\n docsSet: ResolvedPayloadMarkdownDocsSet\n includeDrafts?: boolean\n markdownField?: string\n overrideAccess?: boolean\n payload: PayloadMarkdownDocsReadPayload\n}\n\nconst titleCaseSegment = (segment: string): string =>\n segment\n .split(/[-_]+/)\n .filter(Boolean)\n .map((part) => `${part.charAt(0).toUpperCase()}${part.slice(1)}`)\n .join(' ')\n\nconst getSidebarLabel = (record: ResolvedPayloadMarkdownDocsRecord): string =>\n record.overrides?.navTitle ?? record.navTitle ?? record.title ?? record.sourcePath\n\nconst getSourcePathSegments = (sourcePath: string): string[] => {\n const withoutExtension = sourcePath.replace(/\\.md$/i, '')\n const segments = withoutExtension.split('/').filter(Boolean)\n\n if (segments.at(-1) === 'index') {\n return segments.slice(0, -1)\n }\n\n return segments\n}\n\nconst compareSidebarItems = (\n first: PayloadMarkdownDocsSidebarItem,\n second: PayloadMarkdownDocsSidebarItem,\n): number => {\n if (first.order !== second.order) {\n return first.order - second.order\n }\n\n return first.sourcePath.localeCompare(second.sourcePath)\n}\n\nconst sortSidebarTree = (items: PayloadMarkdownDocsSidebarItem[]) => {\n items.sort(compareSidebarItems)\n\n for (const item of items) {\n if (item.children) {\n sortSidebarTree(item.children)\n }\n }\n}\n\nconst getOrCreateFolderNode = ({\n currentItems,\n depth,\n docsSet,\n order,\n segment,\n sourcePath,\n}: {\n currentItems: PayloadMarkdownDocsSidebarItem[]\n depth: number\n docsSet?: ResolvedPayloadMarkdownDocsSet\n order: number\n segment: string\n sourcePath: string\n}): PayloadMarkdownDocsSidebarItem => {\n const existing = currentItems.find((item) => item.sourcePath === sourcePath)\n\n if (existing) {\n existing.order = Math.min(existing.order, order)\n return existing\n }\n\n const node: PayloadMarkdownDocsSidebarItem = {\n children: [],\n depth,\n label: titleCaseSegment(segment),\n order,\n route: docsSet ? joinRouteSegments(docsSet.routeBase, sourcePath) : `/${sourcePath}`,\n sourcePath,\n }\n\n currentItems.push(node)\n\n return node\n}\n\nconst mergeLeafIntoTree = ({\n docsSet,\n record,\n rootItems,\n}: {\n docsSet?: ResolvedPayloadMarkdownDocsSet\n record: ResolvedPayloadMarkdownDocsRecord\n rootItems: PayloadMarkdownDocsSidebarItem[]\n}) => {\n const segments = getSourcePathSegments(record.sourcePath)\n\n if (segments.length === 0) {\n rootItems.push({\n depth: 0,\n label: getSidebarLabel(record),\n order: record.order,\n route: record.route,\n sourcePath: record.sourcePath,\n })\n return\n }\n\n let currentItems = rootItems\n\n for (const [index, segment] of segments.entries()) {\n const sourcePath = segments.slice(0, index + 1).join('/')\n const isLeaf = index === segments.length - 1\n\n if (isLeaf) {\n const existing = currentItems.find((item) => item.sourcePath === sourcePath)\n\n if (existing) {\n existing.label = getSidebarLabel(record)\n existing.order = record.order\n existing.route = record.route\n existing.sourcePath = record.sourcePath\n existing.children ??= []\n return\n }\n\n currentItems.push({\n depth: index,\n label: getSidebarLabel(record),\n order: record.order,\n route: record.route,\n sourcePath: record.sourcePath,\n })\n return\n }\n\n const folder = getOrCreateFolderNode({\n currentItems,\n depth: index,\n docsSet,\n order: record.order,\n segment,\n sourcePath,\n })\n\n folder.children ??= []\n currentItems = folder.children\n }\n}\n\nexport const buildPayloadMarkdownDocsSidebar = (\n records: ResolvedPayloadMarkdownDocsRecord[],\n options: BuildPayloadMarkdownDocsSidebarOptions = {},\n): PayloadMarkdownDocsSidebarItem[] => {\n const sidebar: PayloadMarkdownDocsSidebarItem[] = []\n const visibleRecords = records\n .filter((record) =>\n isVisibleDocsRecord({\n includeDrafts: options.includeDrafts,\n record,\n }),\n )\n .filter((record) => record.overrides?.hideFromNav !== true)\n .sort((first, second) => {\n if (first.order !== second.order) {\n return first.order - second.order\n }\n\n return first.sourcePath.localeCompare(second.sourcePath)\n })\n\n for (const record of visibleRecords) {\n mergeLeafIntoTree({\n docsSet: options.docsSet,\n record,\n rootItems: sidebar,\n })\n }\n\n sortSidebarTree(sidebar)\n\n return sidebar\n}\n\nexport const getPayloadMarkdownDocsSidebar = async ({\n collections,\n docsSet,\n includeDrafts = false,\n markdownField = DEFAULT_MARKDOWN_FIELD_NAME,\n // Sidebar data reads plugin-owned generated docs server-side.\n // Access is overridden here, then nav visibility is enforced explicitly.\n overrideAccess = true,\n payload,\n}: GetPayloadMarkdownDocsSidebarOptions): Promise<PayloadMarkdownDocsSidebarItem[]> => {\n const result = await payload.find({\n collection: collections?.docs ?? DEFAULT_DOCS_COLLECTION_SLUG,\n depth: 0,\n limit: 1000,\n overrideAccess,\n where: {\n docsSet: {\n equals: docsSet.id,\n },\n },\n })\n\n const records = result.docs\n .map((doc) =>\n toResolvedDocsRecord({\n doc,\n markdownField,\n }),\n )\n .filter(\n (record): record is ResolvedPayloadMarkdownDocsRecord => record !== undefined,\n )\n\n return buildPayloadMarkdownDocsSidebar(records, {\n docsSet,\n includeDrafts,\n })\n}\n"],"names":["DEFAULT_DOCS_COLLECTION_SLUG","DEFAULT_MARKDOWN_FIELD_NAME","joinRouteSegments","isVisibleDocsRecord","toResolvedDocsRecord","titleCaseSegment","segment","split","filter","Boolean","map","part","charAt","toUpperCase","slice","join","getSidebarLabel","record","overrides","navTitle","title","sourcePath","getSourcePathSegments","withoutExtension","replace","segments","at","compareSidebarItems","first","second","order","localeCompare","sortSidebarTree","items","sort","item","children","getOrCreateFolderNode","currentItems","depth","docsSet","existing","find","Math","min","node","label","route","routeBase","push","mergeLeafIntoTree","rootItems","length","index","entries","isLeaf","folder","buildPayloadMarkdownDocsSidebar","records","options","sidebar","visibleRecords","includeDrafts","hideFromNav","getPayloadMarkdownDocsSidebar","collections","markdownField","overrideAccess","payload","result","collection","docs","limit","where","equals","id","doc","undefined"],"mappings":"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"}
@@ -0,0 +1,117 @@
1
+ import type { DocsAiExportManifest } from '../sync/index.js';
2
+ export type PayloadMarkdownDocsFindArgs = {
3
+ collection: string;
4
+ depth?: number;
5
+ limit?: number;
6
+ overrideAccess?: boolean;
7
+ sort?: string;
8
+ where?: unknown;
9
+ };
10
+ export type PayloadMarkdownDocsReadPayload = {
11
+ find: (args: PayloadMarkdownDocsFindArgs) => Promise<{
12
+ docs: unknown[];
13
+ }>;
14
+ };
15
+ export type PayloadMarkdownDocsCollectionSlugs = {
16
+ docs?: string;
17
+ docsGroups?: string;
18
+ docsSets?: string;
19
+ };
20
+ export type ResolvePayloadMarkdownDocsRouteOptions = {
21
+ collections?: PayloadMarkdownDocsCollectionSlugs;
22
+ includeDrafts?: boolean;
23
+ markdownField?: string;
24
+ overrideAccess?: boolean;
25
+ path?: string;
26
+ payload: PayloadMarkdownDocsReadPayload;
27
+ slug?: string | string[];
28
+ };
29
+ export type PayloadMarkdownDocsDefaults = {
30
+ heroDescription?: string;
31
+ heroEyebrow?: string;
32
+ heroTitle?: string;
33
+ seoDescription?: string;
34
+ seoTitle?: string;
35
+ sidebarMode?: 'auto' | 'hidden' | 'manual';
36
+ theme?: string;
37
+ };
38
+ export type PayloadMarkdownDocsOverrides = {
39
+ heroDescription?: string;
40
+ heroEyebrow?: string;
41
+ heroTitle?: string;
42
+ hideFromNav?: boolean;
43
+ navTitle?: string;
44
+ seoDescription?: string;
45
+ seoTitle?: string;
46
+ theme?: string;
47
+ };
48
+ export type ResolvedPayloadMarkdownDocsSet = {
49
+ aiExport?: DocsAiExportManifest;
50
+ defaults?: PayloadMarkdownDocsDefaults;
51
+ description?: string;
52
+ id: string;
53
+ navTitle?: string;
54
+ order: number;
55
+ routeBase: string;
56
+ slug?: string;
57
+ sourceId?: string;
58
+ sourceRoot?: string;
59
+ title: string;
60
+ };
61
+ export type ResolvedPayloadMarkdownDocsGroup = {
62
+ description?: string;
63
+ id: string;
64
+ navTitle?: string;
65
+ order: number;
66
+ routePath: string;
67
+ serveIndex: boolean;
68
+ slug?: string;
69
+ title: string;
70
+ };
71
+ export type ResolvedPayloadMarkdownDocsRecord = {
72
+ archived: boolean;
73
+ content?: string;
74
+ depth: number;
75
+ description?: string;
76
+ docsSetId?: string;
77
+ id: string;
78
+ navTitle?: string;
79
+ order: number;
80
+ overrides?: PayloadMarkdownDocsOverrides;
81
+ route: string;
82
+ sourceHash?: string;
83
+ sourcePath: string;
84
+ status?: 'draft' | 'published';
85
+ title: string;
86
+ };
87
+ export type PayloadMarkdownDocsSidebarItem = {
88
+ children?: PayloadMarkdownDocsSidebarItem[];
89
+ depth: number;
90
+ hidden?: boolean;
91
+ label: string;
92
+ order: number;
93
+ route: string;
94
+ sourcePath: string;
95
+ };
96
+ export type ResolvedPayloadMarkdownDocsRoute = {
97
+ doc: ResolvedPayloadMarkdownDocsRecord;
98
+ docsSet: ResolvedPayloadMarkdownDocsSet;
99
+ route: string;
100
+ sidebar: PayloadMarkdownDocsSidebarItem[];
101
+ type: 'doc';
102
+ } | {
103
+ doc?: ResolvedPayloadMarkdownDocsRecord;
104
+ docsSet: ResolvedPayloadMarkdownDocsSet;
105
+ route: string;
106
+ sidebar: PayloadMarkdownDocsSidebarItem[];
107
+ type: 'docsSetIndex';
108
+ } | {
109
+ docsSets: ResolvedPayloadMarkdownDocsSet[];
110
+ group: ResolvedPayloadMarkdownDocsGroup;
111
+ route: string;
112
+ type: 'docsGroupIndex';
113
+ };
114
+ export type PayloadMarkdownDocsMetadata = {
115
+ description?: string;
116
+ title?: string;
117
+ };
@@ -0,0 +1,3 @@
1
+ export { };
2
+
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/next/types.ts"],"sourcesContent":["import type { DocsAiExportManifest } from '../sync/index.js'\n\nexport type PayloadMarkdownDocsFindArgs = {\n collection: string\n depth?: number\n limit?: number\n overrideAccess?: boolean\n sort?: string\n where?: unknown\n}\n\nexport type PayloadMarkdownDocsReadPayload = {\n find: (args: PayloadMarkdownDocsFindArgs) => Promise<{\n docs: unknown[]\n }>\n}\n\nexport type PayloadMarkdownDocsCollectionSlugs = {\n docs?: string\n docsGroups?: string\n docsSets?: string\n}\n\nexport type ResolvePayloadMarkdownDocsRouteOptions = {\n collections?: PayloadMarkdownDocsCollectionSlugs\n includeDrafts?: boolean\n markdownField?: string\n overrideAccess?: boolean\n path?: string\n payload: PayloadMarkdownDocsReadPayload\n slug?: string | string[]\n}\n\nexport type PayloadMarkdownDocsDefaults = {\n heroDescription?: string\n heroEyebrow?: string\n heroTitle?: string\n seoDescription?: string\n seoTitle?: string\n sidebarMode?: 'auto' | 'hidden' | 'manual'\n theme?: string\n}\n\nexport type PayloadMarkdownDocsOverrides = {\n heroDescription?: string\n heroEyebrow?: string\n heroTitle?: string\n hideFromNav?: boolean\n navTitle?: string\n seoDescription?: string\n seoTitle?: string\n theme?: string\n}\n\nexport type ResolvedPayloadMarkdownDocsSet = {\n aiExport?: DocsAiExportManifest\n defaults?: PayloadMarkdownDocsDefaults\n description?: string\n id: string\n navTitle?: string\n order: number\n routeBase: string\n slug?: string\n sourceId?: string\n sourceRoot?: string\n title: string\n}\n\nexport type ResolvedPayloadMarkdownDocsGroup = {\n description?: string\n id: string\n navTitle?: string\n order: number\n routePath: string\n serveIndex: boolean\n slug?: string\n title: string\n}\n\nexport type ResolvedPayloadMarkdownDocsRecord = {\n archived: boolean\n content?: string\n depth: number\n description?: string\n docsSetId?: string\n id: string\n navTitle?: string\n order: number\n overrides?: PayloadMarkdownDocsOverrides\n route: string\n sourceHash?: string\n sourcePath: string\n status?: 'draft' | 'published'\n title: string\n}\n\nexport type PayloadMarkdownDocsSidebarItem = {\n children?: PayloadMarkdownDocsSidebarItem[]\n depth: number\n hidden?: boolean\n label: string\n order: number\n route: string\n sourcePath: string\n}\n\nexport type ResolvedPayloadMarkdownDocsRoute =\n | {\n doc: ResolvedPayloadMarkdownDocsRecord\n docsSet: ResolvedPayloadMarkdownDocsSet\n route: string\n sidebar: PayloadMarkdownDocsSidebarItem[]\n type: 'doc'\n }\n | {\n doc?: ResolvedPayloadMarkdownDocsRecord\n docsSet: ResolvedPayloadMarkdownDocsSet\n route: string\n sidebar: PayloadMarkdownDocsSidebarItem[]\n type: 'docsSetIndex'\n }\n | {\n docsSets: ResolvedPayloadMarkdownDocsSet[]\n group: ResolvedPayloadMarkdownDocsGroup\n route: string\n type: 'docsGroupIndex'\n }\n\nexport type PayloadMarkdownDocsMetadata = {\n description?: string\n title?: string\n}\n"],"names":[],"mappings":"AAgIA,WAGC"}
@@ -0,0 +1,54 @@
1
+ import type { DocsDeleteBehavior, DocsSyncPlan, ValidatedDocsManifest } from '../sync/index.js';
2
+ import type { DocsSyncConflict } from './docsConflicts.js';
3
+ import type { DocsPublishMode } from './docsData.js';
4
+ import type { ExistingPayloadDocsRecord } from './existingDocs.js';
5
+ export type ApplyDocsSyncPayloadOperations = {
6
+ create: (args: {
7
+ collection: string;
8
+ data: Record<string, unknown>;
9
+ overrideAccess?: boolean;
10
+ }) => Promise<Record<string, unknown>>;
11
+ delete?: (args: {
12
+ collection: string;
13
+ id: string;
14
+ overrideAccess?: boolean;
15
+ }) => Promise<Record<string, unknown>>;
16
+ update: (args: {
17
+ collection: string;
18
+ data: Record<string, unknown>;
19
+ id: string;
20
+ overrideAccess?: boolean;
21
+ }) => Promise<Record<string, unknown>>;
22
+ };
23
+ export type ApplyDocsSyncResult = {
24
+ conflicts: DocsSyncConflict[];
25
+ ok: false;
26
+ } | {
27
+ ok: true;
28
+ writes: {
29
+ archive: number;
30
+ create: number;
31
+ delete: number;
32
+ draft: number;
33
+ reactivate: number;
34
+ update: number;
35
+ };
36
+ };
37
+ export declare const assertApplyDeleteBehaviorSupported: (deleteBehavior: DocsDeleteBehavior, { allowHardDelete, docsEnableDrafts, }?: {
38
+ allowHardDelete?: boolean;
39
+ docsEnableDrafts?: boolean;
40
+ }) => boolean;
41
+ export declare const applyDocsSync: ({ collectionSlug, deleteBehavior, docsEnableDrafts, docsSetId, existing, manifest, markdownFieldName, now, payload, plan, publishMode, syncRunId, }: {
42
+ collectionSlug: string;
43
+ deleteBehavior: DocsDeleteBehavior;
44
+ docsEnableDrafts: boolean;
45
+ docsSetId?: number | string;
46
+ existing: ExistingPayloadDocsRecord[];
47
+ manifest: ValidatedDocsManifest;
48
+ markdownFieldName: string;
49
+ now: Date;
50
+ payload: ApplyDocsSyncPayloadOperations;
51
+ plan: DocsSyncPlan;
52
+ publishMode: DocsPublishMode;
53
+ syncRunId?: number | string;
54
+ }) => Promise<ApplyDocsSyncResult>;
@@ -0,0 +1,176 @@
1
+ import { findDocsSyncConflicts } from './docsConflicts.js';
2
+ import { buildArchiveData, buildDocsData } from './docsData.js';
3
+ export const assertApplyDeleteBehaviorSupported = (deleteBehavior, { allowHardDelete = false, docsEnableDrafts = false } = {})=>{
4
+ if (deleteBehavior === 'archive' || deleteBehavior === 'ignore') {
5
+ return true;
6
+ }
7
+ if (deleteBehavior === 'draft') {
8
+ return docsEnableDrafts;
9
+ }
10
+ return allowHardDelete;
11
+ };
12
+ export const applyDocsSync = async ({ collectionSlug, deleteBehavior, docsEnableDrafts, docsSetId, existing, manifest, markdownFieldName, now, payload, plan, publishMode, syncRunId })=>{
13
+ const existingBySourcePath = new Map(existing.map((record)=>[
14
+ record.sourcePath,
15
+ record
16
+ ]));
17
+ const reactivations = plan.unchanged.filter((change)=>change.current?.archived);
18
+ const conflicts = findDocsSyncConflicts({
19
+ existingBySourcePath,
20
+ plannedChanges: [
21
+ ...plan.update,
22
+ ...plan.archive,
23
+ ...plan.draft,
24
+ ...plan.delete,
25
+ ...reactivations
26
+ ]
27
+ });
28
+ if (conflicts.length > 0) {
29
+ return {
30
+ conflicts,
31
+ ok: false
32
+ };
33
+ }
34
+ const writes = {
35
+ archive: 0,
36
+ create: 0,
37
+ delete: 0,
38
+ draft: 0,
39
+ reactivate: 0,
40
+ update: 0
41
+ };
42
+ for (const change of plan.create){
43
+ if (!change.desired) {
44
+ continue;
45
+ }
46
+ await payload.create({
47
+ collection: collectionSlug,
48
+ data: buildDocsData({
49
+ desired: change.desired,
50
+ docsEnableDrafts,
51
+ docsSetId,
52
+ manifest,
53
+ markdownFieldName,
54
+ now,
55
+ publishMode,
56
+ syncRunId
57
+ }),
58
+ overrideAccess: true
59
+ });
60
+ writes.create += 1;
61
+ }
62
+ for (const change of plan.update){
63
+ if (!change.desired) {
64
+ continue;
65
+ }
66
+ const current = existingBySourcePath.get(change.sourcePath);
67
+ if (!current) {
68
+ continue;
69
+ }
70
+ await payload.update({
71
+ id: current.id,
72
+ collection: collectionSlug,
73
+ data: buildDocsData({
74
+ current,
75
+ desired: change.desired,
76
+ docsEnableDrafts,
77
+ docsSetId,
78
+ manifest,
79
+ markdownFieldName,
80
+ now,
81
+ publishMode,
82
+ syncRunId
83
+ }),
84
+ overrideAccess: true
85
+ });
86
+ writes.update += 1;
87
+ }
88
+ for (const change of reactivations){
89
+ if (!change.desired) {
90
+ continue;
91
+ }
92
+ const current = existingBySourcePath.get(change.sourcePath);
93
+ if (!current) {
94
+ continue;
95
+ }
96
+ await payload.update({
97
+ id: current.id,
98
+ collection: collectionSlug,
99
+ data: buildDocsData({
100
+ current,
101
+ desired: change.desired,
102
+ docsEnableDrafts,
103
+ docsSetId,
104
+ manifest,
105
+ markdownFieldName,
106
+ now,
107
+ publishMode,
108
+ syncRunId
109
+ }),
110
+ overrideAccess: true
111
+ });
112
+ writes.reactivate += 1;
113
+ }
114
+ if (deleteBehavior === 'archive') {
115
+ for (const change of plan.archive){
116
+ const current = existingBySourcePath.get(change.sourcePath);
117
+ if (!current) {
118
+ continue;
119
+ }
120
+ await payload.update({
121
+ id: current.id,
122
+ collection: collectionSlug,
123
+ data: buildArchiveData({
124
+ docsEnableDrafts,
125
+ now,
126
+ syncRunId
127
+ }),
128
+ overrideAccess: true
129
+ });
130
+ writes.archive += 1;
131
+ }
132
+ }
133
+ if (deleteBehavior === 'draft') {
134
+ for (const change of plan.draft){
135
+ const current = existingBySourcePath.get(change.sourcePath);
136
+ if (!current) {
137
+ continue;
138
+ }
139
+ await payload.update({
140
+ id: current.id,
141
+ collection: collectionSlug,
142
+ data: buildArchiveData({
143
+ docsEnableDrafts,
144
+ draftMissing: true,
145
+ now,
146
+ syncRunId
147
+ }),
148
+ overrideAccess: true
149
+ });
150
+ writes.draft += 1;
151
+ }
152
+ }
153
+ if (deleteBehavior === 'delete') {
154
+ if (!payload.delete) {
155
+ throw new Error('Payload delete operation is required for hard delete.');
156
+ }
157
+ for (const change of plan.delete){
158
+ const current = existingBySourcePath.get(change.sourcePath);
159
+ if (!current) {
160
+ continue;
161
+ }
162
+ await payload.delete({
163
+ id: current.id,
164
+ collection: collectionSlug,
165
+ overrideAccess: true
166
+ });
167
+ writes.delete += 1;
168
+ }
169
+ }
170
+ return {
171
+ ok: true,
172
+ writes
173
+ };
174
+ };
175
+
176
+ //# sourceMappingURL=applyDocsSync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/payload/applyDocsSync.ts"],"sourcesContent":["import type {\n DocsDeleteBehavior,\n DocsSyncPlan,\n ValidatedDocsManifest,\n} from '../sync/index.js'\nimport type { DocsSyncConflict } from './docsConflicts.js'\nimport type { DocsPublishMode } from './docsData.js'\nimport type { ExistingPayloadDocsRecord } from './existingDocs.js'\n\nimport { findDocsSyncConflicts } from './docsConflicts.js'\nimport { buildArchiveData, buildDocsData } from './docsData.js'\n\nexport type ApplyDocsSyncPayloadOperations = {\n create: (args: {\n collection: string\n data: Record<string, unknown>\n overrideAccess?: boolean\n }) => Promise<Record<string, unknown>>\n delete?: (args: {\n collection: string\n id: string\n overrideAccess?: boolean\n }) => Promise<Record<string, unknown>>\n update: (args: {\n collection: string\n data: Record<string, unknown>\n id: string\n overrideAccess?: boolean\n }) => Promise<Record<string, unknown>>\n}\n\nexport type ApplyDocsSyncResult =\n | {\n conflicts: DocsSyncConflict[]\n ok: false\n }\n | {\n ok: true\n writes: {\n archive: number\n create: number\n delete: number\n draft: number\n reactivate: number\n update: number\n }\n }\n\nexport const assertApplyDeleteBehaviorSupported = (\n deleteBehavior: DocsDeleteBehavior,\n {\n allowHardDelete = false,\n docsEnableDrafts = false,\n }: {\n allowHardDelete?: boolean\n docsEnableDrafts?: boolean\n } = {},\n): boolean => {\n if (deleteBehavior === 'archive' || deleteBehavior === 'ignore') {\n return true\n }\n\n if (deleteBehavior === 'draft') {\n return docsEnableDrafts\n }\n\n return allowHardDelete\n}\n\nexport const applyDocsSync = async ({\n collectionSlug,\n deleteBehavior,\n docsEnableDrafts,\n docsSetId,\n existing,\n manifest,\n markdownFieldName,\n now,\n payload,\n plan,\n publishMode,\n syncRunId,\n}: {\n collectionSlug: string\n deleteBehavior: DocsDeleteBehavior\n docsEnableDrafts: boolean\n docsSetId?: number | string\n existing: ExistingPayloadDocsRecord[]\n manifest: ValidatedDocsManifest\n markdownFieldName: string\n now: Date\n payload: ApplyDocsSyncPayloadOperations\n plan: DocsSyncPlan\n publishMode: DocsPublishMode\n syncRunId?: number | string\n}): Promise<ApplyDocsSyncResult> => {\n const existingBySourcePath = new Map(\n existing.map((record) => [record.sourcePath, record]),\n )\n const reactivations = plan.unchanged.filter((change) => change.current?.archived)\n const conflicts = findDocsSyncConflicts({\n existingBySourcePath,\n plannedChanges: [\n ...plan.update,\n ...plan.archive,\n ...plan.draft,\n ...plan.delete,\n ...reactivations,\n ],\n })\n\n if (conflicts.length > 0) {\n return {\n conflicts,\n ok: false,\n }\n }\n\n const writes = {\n archive: 0,\n create: 0,\n delete: 0,\n draft: 0,\n reactivate: 0,\n update: 0,\n }\n\n for (const change of plan.create) {\n if (!change.desired) {\n continue\n }\n\n await payload.create({\n collection: collectionSlug,\n data: buildDocsData({\n desired: change.desired,\n docsEnableDrafts,\n docsSetId,\n manifest,\n markdownFieldName,\n now,\n publishMode,\n syncRunId,\n }),\n overrideAccess: true,\n })\n writes.create += 1\n }\n\n for (const change of plan.update) {\n if (!change.desired) {\n continue\n }\n\n const current = existingBySourcePath.get(change.sourcePath)\n\n if (!current) {\n continue\n }\n\n await payload.update({\n id: current.id,\n collection: collectionSlug,\n data: buildDocsData({\n current,\n desired: change.desired,\n docsEnableDrafts,\n docsSetId,\n manifest,\n markdownFieldName,\n now,\n publishMode,\n syncRunId,\n }),\n overrideAccess: true,\n })\n writes.update += 1\n }\n\n for (const change of reactivations) {\n if (!change.desired) {\n continue\n }\n\n const current = existingBySourcePath.get(change.sourcePath)\n\n if (!current) {\n continue\n }\n\n await payload.update({\n id: current.id,\n collection: collectionSlug,\n data: buildDocsData({\n current,\n desired: change.desired,\n docsEnableDrafts,\n docsSetId,\n manifest,\n markdownFieldName,\n now,\n publishMode,\n syncRunId,\n }),\n overrideAccess: true,\n })\n writes.reactivate += 1\n }\n\n if (deleteBehavior === 'archive') {\n for (const change of plan.archive) {\n const current = existingBySourcePath.get(change.sourcePath)\n\n if (!current) {\n continue\n }\n\n await payload.update({\n id: current.id,\n collection: collectionSlug,\n data: buildArchiveData({\n docsEnableDrafts,\n now,\n syncRunId,\n }),\n overrideAccess: true,\n })\n writes.archive += 1\n }\n }\n\n if (deleteBehavior === 'draft') {\n for (const change of plan.draft) {\n const current = existingBySourcePath.get(change.sourcePath)\n\n if (!current) {\n continue\n }\n\n await payload.update({\n id: current.id,\n collection: collectionSlug,\n data: buildArchiveData({\n docsEnableDrafts,\n draftMissing: true,\n now,\n syncRunId,\n }),\n overrideAccess: true,\n })\n writes.draft += 1\n }\n }\n\n if (deleteBehavior === 'delete') {\n if (!payload.delete) {\n throw new Error('Payload delete operation is required for hard delete.')\n }\n\n for (const change of plan.delete) {\n const current = existingBySourcePath.get(change.sourcePath)\n\n if (!current) {\n continue\n }\n\n await payload.delete({\n id: current.id,\n collection: collectionSlug,\n overrideAccess: true,\n })\n writes.delete += 1\n }\n }\n\n return {\n ok: true,\n writes,\n }\n}\n"],"names":["findDocsSyncConflicts","buildArchiveData","buildDocsData","assertApplyDeleteBehaviorSupported","deleteBehavior","allowHardDelete","docsEnableDrafts","applyDocsSync","collectionSlug","docsSetId","existing","manifest","markdownFieldName","now","payload","plan","publishMode","syncRunId","existingBySourcePath","Map","map","record","sourcePath","reactivations","unchanged","filter","change","current","archived","conflicts","plannedChanges","update","archive","draft","delete","length","ok","writes","create","reactivate","desired","collection","data","overrideAccess","get","id","draftMissing","Error"],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { PlannedDocChange } from '../sync/index.js';
2
+ import type { ExistingPayloadDocsRecord } from './existingDocs.js';
3
+ export type DocsSyncConflictReason = 'current_content_hash_mismatch' | 'missing_current_record' | 'unmanaged_record';
4
+ export type DocsSyncConflict = {
5
+ reason: DocsSyncConflictReason;
6
+ route?: string;
7
+ sourcePath: string;
8
+ };
9
+ export declare const findDocsSyncConflicts: ({ existingBySourcePath, plannedChanges, }: {
10
+ existingBySourcePath: Map<string, ExistingPayloadDocsRecord>;
11
+ plannedChanges: PlannedDocChange[];
12
+ }) => DocsSyncConflict[];
@@ -0,0 +1,34 @@
1
+ import { MANAGED_BY } from '../constants.js';
2
+ import { sha256Hex } from '../sync/index.js';
3
+ export const findDocsSyncConflicts = ({ existingBySourcePath, plannedChanges })=>{
4
+ const conflicts = [];
5
+ for (const change of plannedChanges){
6
+ const current = existingBySourcePath.get(change.sourcePath);
7
+ if (!current) {
8
+ conflicts.push({
9
+ reason: 'missing_current_record',
10
+ sourcePath: change.sourcePath
11
+ });
12
+ continue;
13
+ }
14
+ if (current.sync?.managedBy !== MANAGED_BY) {
15
+ conflicts.push({
16
+ reason: 'unmanaged_record',
17
+ route: current.route,
18
+ sourcePath: current.sourcePath
19
+ });
20
+ continue;
21
+ }
22
+ const currentContentHash = sha256Hex(current.content ?? '');
23
+ if (currentContentHash !== current.sync.sourceHashAtLastSync) {
24
+ conflicts.push({
25
+ reason: 'current_content_hash_mismatch',
26
+ route: current.route,
27
+ sourcePath: current.sourcePath
28
+ });
29
+ }
30
+ }
31
+ return conflicts;
32
+ };
33
+
34
+ //# sourceMappingURL=docsConflicts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/payload/docsConflicts.ts"],"sourcesContent":["import type { PlannedDocChange } from '../sync/index.js'\nimport type { ExistingPayloadDocsRecord } from './existingDocs.js'\n\nimport { MANAGED_BY } from '../constants.js'\nimport { sha256Hex } from '../sync/index.js'\n\nexport type DocsSyncConflictReason =\n | 'current_content_hash_mismatch'\n | 'missing_current_record'\n | 'unmanaged_record'\n\nexport type DocsSyncConflict = {\n reason: DocsSyncConflictReason\n route?: string\n sourcePath: string\n}\n\nexport const findDocsSyncConflicts = ({\n existingBySourcePath,\n plannedChanges,\n}: {\n existingBySourcePath: Map<string, ExistingPayloadDocsRecord>\n plannedChanges: PlannedDocChange[]\n}): DocsSyncConflict[] => {\n const conflicts: DocsSyncConflict[] = []\n\n for (const change of plannedChanges) {\n const current = existingBySourcePath.get(change.sourcePath)\n\n if (!current) {\n conflicts.push({\n reason: 'missing_current_record',\n sourcePath: change.sourcePath,\n })\n continue\n }\n\n if (current.sync?.managedBy !== MANAGED_BY) {\n conflicts.push({\n reason: 'unmanaged_record',\n route: current.route,\n sourcePath: current.sourcePath,\n })\n continue\n }\n\n const currentContentHash = sha256Hex(current.content ?? '')\n\n if (currentContentHash !== current.sync.sourceHashAtLastSync) {\n conflicts.push({\n reason: 'current_content_hash_mismatch',\n route: current.route,\n sourcePath: current.sourcePath,\n })\n }\n }\n\n return conflicts\n}\n\n"],"names":["MANAGED_BY","sha256Hex","findDocsSyncConflicts","existingBySourcePath","plannedChanges","conflicts","change","current","get","sourcePath","push","reason","sync","managedBy","route","currentContentHash","content","sourceHashAtLastSync"],"mappings":"AAGA,SAASA,UAAU,QAAQ,kBAAiB;AAC5C,SAASC,SAAS,QAAQ,mBAAkB;AAa5C,OAAO,MAAMC,wBAAwB,CAAC,EACpCC,oBAAoB,EACpBC,cAAc,EAIf;IACC,MAAMC,YAAgC,EAAE;IAExC,KAAK,MAAMC,UAAUF,eAAgB;QACnC,MAAMG,UAAUJ,qBAAqBK,GAAG,CAACF,OAAOG,UAAU;QAE1D,IAAI,CAACF,SAAS;YACZF,UAAUK,IAAI,CAAC;gBACbC,QAAQ;gBACRF,YAAYH,OAAOG,UAAU;YAC/B;YACA;QACF;QAEA,IAAIF,QAAQK,IAAI,EAAEC,cAAcb,YAAY;YAC1CK,UAAUK,IAAI,CAAC;gBACbC,QAAQ;gBACRG,OAAOP,QAAQO,KAAK;gBACpBL,YAAYF,QAAQE,UAAU;YAChC;YACA;QACF;QAEA,MAAMM,qBAAqBd,UAAUM,QAAQS,OAAO,IAAI;QAExD,IAAID,uBAAuBR,QAAQK,IAAI,CAACK,oBAAoB,EAAE;YAC5DZ,UAAUK,IAAI,CAAC;gBACbC,QAAQ;gBACRG,OAAOP,QAAQO,KAAK;gBACpBL,YAAYF,QAAQE,UAAU;YAChC;QACF;IACF;IAEA,OAAOJ;AACT,EAAC"}
@@ -0,0 +1,23 @@
1
+ import type { ValidatedDocsManifest, ValidatedDocsManifestFile } from '../sync/index.js';
2
+ import type { ExistingPayloadDocsRecord } from './existingDocs.js';
3
+ export type BuildDocsDataInput = {
4
+ current?: ExistingPayloadDocsRecord;
5
+ desired: ValidatedDocsManifestFile;
6
+ docsEnableDrafts: boolean;
7
+ docsSetId?: number | string;
8
+ manifest: ValidatedDocsManifest;
9
+ markdownFieldName: string;
10
+ now: Date;
11
+ publishMode: DocsPublishMode;
12
+ syncRunId?: number | string;
13
+ };
14
+ export type DocsDraftStatus = 'draft' | 'published';
15
+ export type DocsPublishMode = 'draft' | 'preserve' | 'published';
16
+ export declare const getDocsDepth: (sourcePath: string) => number;
17
+ export declare const buildDocsData: ({ current, desired, docsEnableDrafts, docsSetId, manifest, markdownFieldName, now, publishMode, syncRunId, }: BuildDocsDataInput) => Record<string, unknown>;
18
+ export declare const buildArchiveData: ({ docsEnableDrafts, draftMissing, now, syncRunId, }: {
19
+ docsEnableDrafts?: boolean;
20
+ draftMissing?: boolean;
21
+ now: Date;
22
+ syncRunId?: number | string;
23
+ }) => Record<string, unknown>;