@payloadcms/plugin-import-export 4.0.0-internal.c2b57ce → 4.0.0-internal.c6494b5

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 (194) hide show
  1. package/dist/components/CollectionField/index.d.ts +3 -2
  2. package/dist/components/CollectionField/index.d.ts.map +1 -1
  3. package/dist/components/CollectionField/index.js.map +1 -1
  4. package/dist/components/ExportListMenuItem/index.d.ts.map +1 -1
  5. package/dist/components/ExportListMenuItem/index.js +14 -12
  6. package/dist/components/ExportListMenuItem/index.js.map +1 -1
  7. package/dist/components/ExportPreview/index.css +52 -0
  8. package/dist/components/ExportPreview/index.d.ts +1 -1
  9. package/dist/components/ExportPreview/index.d.ts.map +1 -1
  10. package/dist/components/ExportPreview/index.js +12 -2
  11. package/dist/components/ExportPreview/index.js.map +1 -1
  12. package/dist/components/FieldsToExport/index.d.ts +3 -2
  13. package/dist/components/FieldsToExport/index.d.ts.map +1 -1
  14. package/dist/components/FieldsToExport/index.js +18 -15
  15. package/dist/components/FieldsToExport/index.js.map +1 -1
  16. package/dist/components/FieldsToExport/reduceFields.d.ts +6 -0
  17. package/dist/components/FieldsToExport/reduceFields.d.ts.map +1 -1
  18. package/dist/components/FieldsToExport/reduceFields.js +4 -0
  19. package/dist/components/FieldsToExport/reduceFields.js.map +1 -1
  20. package/dist/components/FormatField/index.d.ts +3 -2
  21. package/dist/components/FormatField/index.d.ts.map +1 -1
  22. package/dist/components/FormatField/index.js +6 -3
  23. package/dist/components/FormatField/index.js.map +1 -1
  24. package/dist/components/ImportListMenuItem/index.d.ts.map +1 -1
  25. package/dist/components/ImportListMenuItem/index.js +14 -12
  26. package/dist/components/ImportListMenuItem/index.js.map +1 -1
  27. package/dist/components/ImportPreview/index.css +45 -0
  28. package/dist/components/ImportPreview/index.d.ts +1 -1
  29. package/dist/components/ImportPreview/index.d.ts.map +1 -1
  30. package/dist/components/ImportPreview/index.js +44 -11
  31. package/dist/components/ImportPreview/index.js.map +1 -1
  32. package/dist/components/LimitField/index.d.ts +3 -2
  33. package/dist/components/LimitField/index.d.ts.map +1 -1
  34. package/dist/components/LimitField/index.js.map +1 -1
  35. package/dist/components/LocaleField/index.d.ts +3 -2
  36. package/dist/components/LocaleField/index.d.ts.map +1 -1
  37. package/dist/components/LocaleField/index.js.map +1 -1
  38. package/dist/components/Page/index.d.ts +4 -3
  39. package/dist/components/Page/index.d.ts.map +1 -1
  40. package/dist/components/Page/index.js +1 -1
  41. package/dist/components/Page/index.js.map +1 -1
  42. package/dist/components/RelationshipCell/getRelationshipGroupKey.d.ts +7 -0
  43. package/dist/components/RelationshipCell/getRelationshipGroupKey.d.ts.map +1 -0
  44. package/dist/components/RelationshipCell/getRelationshipGroupKey.js +3 -0
  45. package/dist/components/RelationshipCell/getRelationshipGroupKey.js.map +1 -0
  46. package/dist/components/RelationshipCell/getRelationshipGroups.d.ts +43 -0
  47. package/dist/components/RelationshipCell/getRelationshipGroups.d.ts.map +1 -0
  48. package/dist/components/RelationshipCell/getRelationshipGroups.js +109 -0
  49. package/dist/components/RelationshipCell/getRelationshipGroups.js.map +1 -0
  50. package/dist/components/RelationshipCell/index.css +30 -0
  51. package/dist/components/RelationshipCell/index.d.ts +15 -0
  52. package/dist/components/RelationshipCell/index.d.ts.map +1 -0
  53. package/dist/components/RelationshipCell/index.js +57 -0
  54. package/dist/components/RelationshipCell/index.js.map +1 -0
  55. package/dist/components/SortBy/index.css +9 -0
  56. package/dist/components/SortBy/index.d.ts +4 -3
  57. package/dist/components/SortBy/index.d.ts.map +1 -1
  58. package/dist/components/SortBy/index.js +1 -2
  59. package/dist/components/SortBy/index.js.map +1 -1
  60. package/dist/components/SortOrder/index.css +9 -0
  61. package/dist/components/SortOrder/index.d.ts +4 -3
  62. package/dist/components/SortOrder/index.d.ts.map +1 -1
  63. package/dist/components/SortOrder/index.js +1 -2
  64. package/dist/components/SortOrder/index.js.map +1 -1
  65. package/dist/export/batchProcessor.d.ts +4 -3
  66. package/dist/export/batchProcessor.d.ts.map +1 -1
  67. package/dist/export/batchProcessor.js +6 -2
  68. package/dist/export/batchProcessor.js.map +1 -1
  69. package/dist/export/createExport.d.ts +4 -2
  70. package/dist/export/createExport.d.ts.map +1 -1
  71. package/dist/export/createExport.js +7 -2
  72. package/dist/export/createExport.js.map +1 -1
  73. package/dist/export/getCreateExportCollectionTask.d.ts.map +1 -1
  74. package/dist/export/getCreateExportCollectionTask.js +11 -0
  75. package/dist/export/getCreateExportCollectionTask.js.map +1 -1
  76. package/dist/export/getExportCollection.d.ts.map +1 -1
  77. package/dist/export/getExportCollection.js +9 -4
  78. package/dist/export/getExportCollection.js.map +1 -1
  79. package/dist/export/getFields.d.ts.map +1 -1
  80. package/dist/export/handleDownload.d.ts.map +1 -1
  81. package/dist/export/handleDownload.js +7 -3
  82. package/dist/export/handleDownload.js.map +1 -1
  83. package/dist/export/handlePreview.d.ts.map +1 -1
  84. package/dist/export/handlePreview.js +24 -5
  85. package/dist/export/handlePreview.js.map +1 -1
  86. package/dist/exports/types.d.ts +1 -1
  87. package/dist/exports/types.d.ts.map +1 -1
  88. package/dist/exports/types.js.map +1 -1
  89. package/dist/import/batchProcessor.d.ts +4 -3
  90. package/dist/import/batchProcessor.d.ts.map +1 -1
  91. package/dist/import/batchProcessor.js +15 -8
  92. package/dist/import/batchProcessor.js.map +1 -1
  93. package/dist/import/createImport.d.ts +3 -2
  94. package/dist/import/createImport.d.ts.map +1 -1
  95. package/dist/import/createImport.js +8 -1
  96. package/dist/import/createImport.js.map +1 -1
  97. package/dist/import/getCreateImportCollectionTask.d.ts.map +1 -1
  98. package/dist/import/getCreateImportCollectionTask.js +5 -2
  99. package/dist/import/getCreateImportCollectionTask.js.map +1 -1
  100. package/dist/import/getFields.d.ts.map +1 -1
  101. package/dist/import/getImportCollection.d.ts.map +1 -1
  102. package/dist/import/getImportCollection.js +6 -4
  103. package/dist/import/getImportCollection.js.map +1 -1
  104. package/dist/import/handlePreview.d.ts.map +1 -1
  105. package/dist/import/handlePreview.js +5 -1
  106. package/dist/import/handlePreview.js.map +1 -1
  107. package/dist/index.d.ts +1 -2
  108. package/dist/index.d.ts.map +1 -1
  109. package/dist/index.js +6 -3
  110. package/dist/index.js.map +1 -1
  111. package/dist/translations/languages/en.d.ts.map +1 -1
  112. package/dist/types.d.ts +17 -1
  113. package/dist/types.d.ts.map +1 -1
  114. package/dist/types.js.map +1 -1
  115. package/dist/utilities/applyFieldHooks.d.ts.map +1 -1
  116. package/dist/utilities/applyFieldHooks.js +1 -1
  117. package/dist/utilities/applyFieldHooks.js.map +1 -1
  118. package/dist/utilities/buildDisabledFieldRegex.d.ts.map +1 -1
  119. package/dist/utilities/collectDisabledFieldPaths.d.ts.map +1 -1
  120. package/dist/utilities/fieldToRegex.d.ts.map +1 -1
  121. package/dist/utilities/flattenObject.d.ts.map +1 -1
  122. package/dist/utilities/flattenedFields.d.ts.map +1 -1
  123. package/dist/utilities/flattenedFields.js +3 -0
  124. package/dist/utilities/flattenedFields.js.map +1 -1
  125. package/dist/utilities/getExportFieldFunctions.d.ts.map +1 -1
  126. package/dist/utilities/getExportFieldFunctions.js +64 -27
  127. package/dist/utilities/getExportFieldFunctions.js.map +1 -1
  128. package/dist/utilities/getFileFromDoc.d.ts.map +1 -1
  129. package/dist/utilities/getFileFromDoc.js +3 -3
  130. package/dist/utilities/getFileFromDoc.js.map +1 -1
  131. package/dist/utilities/getFlattenedFieldKeys.d.ts.map +1 -1
  132. package/dist/utilities/getImportFieldFunctions.d.ts.map +1 -1
  133. package/dist/utilities/getPluginCollections.d.ts.map +1 -1
  134. package/dist/utilities/getSchemaColumns.d.ts.map +1 -1
  135. package/dist/utilities/getSelect.d.ts.map +1 -1
  136. package/dist/utilities/getSelect.js +11 -3
  137. package/dist/utilities/getSelect.js.map +1 -1
  138. package/dist/utilities/getSubmittedFormValues.d.ts +12 -0
  139. package/dist/utilities/getSubmittedFormValues.d.ts.map +1 -0
  140. package/dist/utilities/getSubmittedFormValues.js +24 -0
  141. package/dist/utilities/getSubmittedFormValues.js.map +1 -0
  142. package/dist/utilities/isPlainObject.d.ts.map +1 -1
  143. package/dist/utilities/parseCSV.d.ts.map +1 -1
  144. package/dist/utilities/parseJSON.d.ts.map +1 -1
  145. package/dist/utilities/polymorphicRel.d.ts.map +1 -1
  146. package/dist/utilities/processRichTextField.d.ts.map +1 -1
  147. package/dist/utilities/processRichTextField.js +7 -0
  148. package/dist/utilities/processRichTextField.js.map +1 -1
  149. package/dist/utilities/removeDisabledFields.d.ts.map +1 -1
  150. package/dist/utilities/setNestedValue.d.ts +2 -1
  151. package/dist/utilities/setNestedValue.d.ts.map +1 -1
  152. package/dist/utilities/setNestedValue.js +65 -34
  153. package/dist/utilities/setNestedValue.js.map +1 -1
  154. package/dist/utilities/sortHelpers.d.ts +1 -1
  155. package/dist/utilities/sortHelpers.d.ts.map +1 -1
  156. package/dist/utilities/unflattenObject.d.ts.map +1 -1
  157. package/dist/utilities/unflattenObject.js +21 -2
  158. package/dist/utilities/unflattenObject.js.map +1 -1
  159. package/dist/utilities/unflattenPostProcess.d.ts.map +1 -1
  160. package/dist/utilities/unflattenPostProcess.js +39 -13
  161. package/dist/utilities/unflattenPostProcess.js.map +1 -1
  162. package/dist/utilities/validateLimitValue.d.ts.map +1 -1
  163. package/license.md +1 -1
  164. package/package.json +9 -9
  165. package/dist/components/ExportPreview/index.scss +0 -48
  166. package/dist/components/FieldsToExport/index.scss +0 -0
  167. package/dist/components/FieldsToExport/reduceFields.spec.js +0 -239
  168. package/dist/components/FieldsToExport/reduceFields.spec.js.map +0 -1
  169. package/dist/components/ImportPreview/index.scss +0 -41
  170. package/dist/components/SortBy/index.scss +0 -3
  171. package/dist/components/SortOrder/index.scss +0 -3
  172. package/dist/utilities/applyFieldHooks.spec.js +0 -205
  173. package/dist/utilities/applyFieldHooks.spec.js.map +0 -1
  174. package/dist/utilities/buildDisabledFieldRegex.spec.js +0 -64
  175. package/dist/utilities/buildDisabledFieldRegex.spec.js.map +0 -1
  176. package/dist/utilities/fieldToRegex.spec.js +0 -151
  177. package/dist/utilities/fieldToRegex.spec.js.map +0 -1
  178. package/dist/utilities/filterToSelectedFields.spec.js +0 -204
  179. package/dist/utilities/filterToSelectedFields.spec.js.map +0 -1
  180. package/dist/utilities/flattenObject.spec.js +0 -158
  181. package/dist/utilities/flattenObject.spec.js.map +0 -1
  182. package/dist/utilities/getExportFieldFunctions.spec.js +0 -50
  183. package/dist/utilities/getExportFieldFunctions.spec.js.map +0 -1
  184. package/dist/utilities/getImportFieldFunctions.spec.js +0 -167
  185. package/dist/utilities/getImportFieldFunctions.spec.js.map +0 -1
  186. package/dist/utilities/getSchemaColumns.spec.js +0 -157
  187. package/dist/utilities/getSchemaColumns.spec.js.map +0 -1
  188. package/dist/utilities/parseCSV.spec.js +0 -195
  189. package/dist/utilities/parseCSV.spec.js.map +0 -1
  190. package/dist/utilities/siblingDoc.spec.js +0 -278
  191. package/dist/utilities/siblingDoc.spec.js.map +0 -1
  192. package/dist/utilities/unflattenObject.spec.js +0 -713
  193. package/dist/utilities/unflattenObject.spec.js.map +0 -1
  194. /package/dist/components/Page/{index.scss → index.css} +0 -0
@@ -0,0 +1,109 @@
1
+ import { getTranslation } from '@payloadcms/translations';
2
+ import { formatDocTitle } from '@payloadcms/ui/shared';
3
+ /**
4
+ * Labels rendered per collection before the rest collapse into `and N more`,
5
+ * matching `totalToShow` in the list view's relationship cell.
6
+ */ export const TOTAL_TO_SHOW = 3;
7
+ /**
8
+ * Groups a relationship or upload value by target collection — one group per
9
+ * collection, labeled with its plural label, holding one label per document.
10
+ *
11
+ * Import files carry relationships in whichever shape produced them, so every
12
+ * entry is one of: a bare ID, a populated document, or the polymorphic
13
+ * `{ relationTo, value }` pair — whose `value` is itself an ID or a document.
14
+ *
15
+ * Each group caps at `TOTAL_TO_SHOW` options and counts the rest into `remaining`,
16
+ * so a polymorphic field shows the same depth per collection rather than spending
17
+ * one cell's worth of rows on whichever collection happens to come first. Groups are
18
+ * returned in the order their collection first appears, and entries whose collection
19
+ * cannot be determined collect into a single unlabeled group. Options keep their order
20
+ * in the file rather than being sorted, so the preview reflects what will be imported.
21
+ */ export const getRelationshipGroups = ({ collections, dateFormat, i18n, relationTo, value })=>{
22
+ const entries = Array.isArray(value) ? value : [
23
+ value
24
+ ];
25
+ const configsBySlug = new Map(collections.map((collection)=>[
26
+ collection.slug,
27
+ collection
28
+ ]));
29
+ // Insertion order is the order each collection first appears, which is the order to render.
30
+ const groupsBySlug = new Map();
31
+ entries.forEach((entry)=>{
32
+ const { slug, target } = resolveEntry({
33
+ entry,
34
+ relationTo
35
+ });
36
+ const key = slug ?? '';
37
+ let group = groupsBySlug.get(key);
38
+ if (!group) {
39
+ group = {
40
+ slug,
41
+ label: slug ? getTranslation(configsBySlug.get(slug)?.labels?.plural || slug, i18n) : '',
42
+ options: [],
43
+ remaining: 0
44
+ };
45
+ groupsBySlug.set(key, group);
46
+ }
47
+ // Past the cap only the count matters, so skip the cost of titling the document.
48
+ if (group.options.length < TOTAL_TO_SHOW) {
49
+ group.options.push(getOptionLabel({
50
+ collectionConfig: slug ? configsBySlug.get(slug) : undefined,
51
+ dateFormat,
52
+ entry,
53
+ i18n,
54
+ target
55
+ }));
56
+ } else {
57
+ group.remaining++;
58
+ }
59
+ });
60
+ return [
61
+ ...groupsBySlug.values()
62
+ ];
63
+ };
64
+ /**
65
+ * Splits an entry into the collection it targets — `undefined` when that cannot be
66
+ * determined — and the ID or document it points at.
67
+ */ const resolveEntry = ({ entry, relationTo })=>{
68
+ const entryArgs = {
69
+ value: entry
70
+ };
71
+ if (isPolymorphicRelationship(entryArgs)) {
72
+ return {
73
+ slug: entryArgs.value.relationTo,
74
+ target: entryArgs.value.value
75
+ };
76
+ }
77
+ return {
78
+ slug: Array.isArray(relationTo) ? undefined : relationTo,
79
+ target: entry
80
+ };
81
+ };
82
+ const getOptionLabel = ({ collectionConfig, dateFormat, entry, i18n, target })=>{
83
+ const targetArgs = {
84
+ value: target
85
+ };
86
+ const doc = isRecord(targetArgs) ? targetArgs.value : undefined;
87
+ const id = doc ? doc.id : target;
88
+ // Fall back to JSON for anything that did not resolve to a usable ID. Interpolating an
89
+ // object into a template is the `[object Object]` this function exists to avoid.
90
+ if (typeof id !== 'string' && typeof id !== 'number') {
91
+ return JSON.stringify(entry) ?? '';
92
+ }
93
+ if (!doc) {
94
+ // A bare ID carries no document to title. Showing the ID alone is more honest than
95
+ // the field's `Untitled` fallback, which would assert the document has no title.
96
+ return `${id}`;
97
+ }
98
+ return formatDocTitle({
99
+ collectionConfig,
100
+ data: doc,
101
+ dateFormat,
102
+ fallback: `${i18n.t('general:untitled')} - ID: ${id}`,
103
+ i18n
104
+ });
105
+ };
106
+ const isRecord = (args)=>typeof args.value === 'object' && args.value !== null && !Array.isArray(args.value);
107
+ const isPolymorphicRelationship = (args)=>isRecord(args) && typeof args.value.relationTo === 'string' && 'value' in args.value;
108
+
109
+ //# sourceMappingURL=getRelationshipGroups.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/RelationshipCell/getRelationshipGroups.ts"],"sourcesContent":["import type { I18n } from '@payloadcms/translations'\nimport type { ClientCollectionConfig, SanitizedConfig } from 'payload'\n\nimport { getTranslation } from '@payloadcms/translations'\nimport { formatDocTitle } from '@payloadcms/ui/shared'\n\n/**\n * Labels rendered per collection before the rest collapse into `and N more`,\n * matching `totalToShow` in the list view's relationship cell.\n */\nexport const TOTAL_TO_SHOW = 3\n\ntype Args = {\n collections: ClientCollectionConfig[]\n dateFormat: SanitizedConfig['admin']['dateFormat']\n i18n: I18n<any, any>\n /** `field.relationTo` — an array when the field is polymorphic. */\n relationTo: string | string[]\n value: unknown\n}\n\nexport type RelationshipGroup = {\n /** Plural label of the target collection, empty when it cannot be determined. */\n label: string\n /** One rendered label per document, capped at `TOTAL_TO_SHOW`. */\n options: string[]\n /** Options past `TOTAL_TO_SHOW` dropped from this group, to render as `and N more`. */\n remaining: number\n /** Slug of the target collection, undefined when it cannot be determined. */\n slug?: string\n}\n\n/**\n * Groups a relationship or upload value by target collection — one group per\n * collection, labeled with its plural label, holding one label per document.\n *\n * Import files carry relationships in whichever shape produced them, so every\n * entry is one of: a bare ID, a populated document, or the polymorphic\n * `{ relationTo, value }` pair — whose `value` is itself an ID or a document.\n *\n * Each group caps at `TOTAL_TO_SHOW` options and counts the rest into `remaining`,\n * so a polymorphic field shows the same depth per collection rather than spending\n * one cell's worth of rows on whichever collection happens to come first. Groups are\n * returned in the order their collection first appears, and entries whose collection\n * cannot be determined collect into a single unlabeled group. Options keep their order\n * in the file rather than being sorted, so the preview reflects what will be imported.\n */\nexport const getRelationshipGroups = ({\n collections,\n dateFormat,\n i18n,\n relationTo,\n value,\n}: Args): RelationshipGroup[] => {\n const entries = Array.isArray(value) ? value : [value]\n const configsBySlug = new Map(collections.map((collection) => [collection.slug, collection]))\n\n // Insertion order is the order each collection first appears, which is the order to render.\n const groupsBySlug = new Map<string, RelationshipGroup>()\n\n entries.forEach((entry) => {\n const { slug, target } = resolveEntry({ entry, relationTo })\n\n const key = slug ?? ''\n let group = groupsBySlug.get(key)\n\n if (!group) {\n group = {\n slug,\n label: slug ? getTranslation(configsBySlug.get(slug)?.labels?.plural || slug, i18n) : '',\n options: [],\n remaining: 0,\n }\n\n groupsBySlug.set(key, group)\n }\n\n // Past the cap only the count matters, so skip the cost of titling the document.\n if (group.options.length < TOTAL_TO_SHOW) {\n group.options.push(\n getOptionLabel({\n collectionConfig: slug ? configsBySlug.get(slug) : undefined,\n dateFormat,\n entry,\n i18n,\n target,\n }),\n )\n } else {\n group.remaining++\n }\n })\n\n return [...groupsBySlug.values()]\n}\n\n/**\n * Splits an entry into the collection it targets — `undefined` when that cannot be\n * determined — and the ID or document it points at.\n */\nconst resolveEntry = ({\n entry,\n relationTo,\n}: { entry: unknown } & Pick<Args, 'relationTo'>): { slug?: string; target: unknown } => {\n const entryArgs = { value: entry }\n\n if (isPolymorphicRelationship(entryArgs)) {\n return { slug: entryArgs.value.relationTo, target: entryArgs.value.value }\n }\n\n return { slug: Array.isArray(relationTo) ? undefined : relationTo, target: entry }\n}\n\ntype GetOptionLabelArgs = {\n collectionConfig?: ClientCollectionConfig\n /** The original entry, kept for the JSON fallback when `target` holds no usable ID. */\n entry: unknown\n target: unknown\n} & Pick<Args, 'dateFormat' | 'i18n'>\n\nconst getOptionLabel = ({\n collectionConfig,\n dateFormat,\n entry,\n i18n,\n target,\n}: GetOptionLabelArgs): string => {\n const targetArgs = { value: target }\n const doc = isRecord(targetArgs) ? targetArgs.value : undefined\n const id = doc ? doc.id : target\n\n // Fall back to JSON for anything that did not resolve to a usable ID. Interpolating an\n // object into a template is the `[object Object]` this function exists to avoid.\n if (typeof id !== 'string' && typeof id !== 'number') {\n return JSON.stringify(entry) ?? ''\n }\n\n if (!doc) {\n // A bare ID carries no document to title. Showing the ID alone is more honest than\n // the field's `Untitled` fallback, which would assert the document has no title.\n return `${id}`\n }\n\n return formatDocTitle({\n collectionConfig,\n data: doc as Parameters<typeof formatDocTitle>[0]['data'],\n dateFormat,\n fallback: `${i18n.t('general:untitled')} - ID: ${id}`,\n i18n,\n })\n}\n\ntype ValueArgs = { value: unknown }\n\nconst isRecord = (args: ValueArgs): args is { value: Record<string, unknown> } =>\n typeof args.value === 'object' && args.value !== null && !Array.isArray(args.value)\n\nconst isPolymorphicRelationship = (\n args: ValueArgs,\n): args is { value: { relationTo: string; value: unknown } } =>\n isRecord(args) && typeof args.value.relationTo === 'string' && 'value' in args.value\n"],"names":["getTranslation","formatDocTitle","TOTAL_TO_SHOW","getRelationshipGroups","collections","dateFormat","i18n","relationTo","value","entries","Array","isArray","configsBySlug","Map","map","collection","slug","groupsBySlug","forEach","entry","target","resolveEntry","key","group","get","label","labels","plural","options","remaining","set","length","push","getOptionLabel","collectionConfig","undefined","values","entryArgs","isPolymorphicRelationship","targetArgs","doc","isRecord","id","JSON","stringify","data","fallback","t","args"],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ @layer payload-default {
2
+ .import-preview-relationship {
3
+ display: flex;
4
+ flex-direction: column;
5
+ gap: var(--spacer-2);
6
+ }
7
+
8
+ .import-preview-relationship__group {
9
+ display: flex;
10
+ flex-direction: column;
11
+ align-items: flex-start;
12
+ }
13
+
14
+ .import-preview-relationship__collection {
15
+ color: var(--color-text-secondary);
16
+ font-size: var(--text-body-medium-bold-font-size);
17
+ font-weight: var(--text-body-large-font-weight);
18
+ letter-spacing: var(--text-body-small-bold-letter-spacing);
19
+ line-height: var(--text-body-small-bold-line-height);
20
+ white-space: nowrap;
21
+ }
22
+
23
+ .import-preview-relationship__more {
24
+ display: block;
25
+ color: var(--color-text-secondary);
26
+ font-size: var(--text-body-small-font-size);
27
+ font-weight: var(--text-body-small-font-weight);
28
+ line-height: var(--text-body-small-line-height);
29
+ }
30
+ }
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import './index.css';
3
+ type Props = {
4
+ fieldPath: string;
5
+ /** `field.relationTo` — an array when the field is polymorphic. */
6
+ relationTo: string | string[];
7
+ value: unknown;
8
+ };
9
+ /**
10
+ * Renders a relationship or upload value for the import preview table, stacking
11
+ * one row per target collection.
12
+ */
13
+ export declare const RelationshipCell: React.FC<Props>;
14
+ export {};
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/RelationshipCell/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB,OAAO,aAAa,CAAA;AAIpB,KAAK,KAAK,GAAG;IACX,SAAS,EAAE,MAAM,CAAA;IACjB,mEAAmE;IACnE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC7B,KAAK,EAAE,OAAO,CAAA;CACf,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAuC5C,CAAA"}
@@ -0,0 +1,57 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useConfig, useTranslation } from '@payloadcms/ui';
4
+ import React from 'react';
5
+ import { getRelationshipGroupKey } from './getRelationshipGroupKey.js';
6
+ import { getRelationshipGroups } from './getRelationshipGroups.js';
7
+ import './index.css';
8
+ const baseClass = 'import-preview-relationship';
9
+ /**
10
+ * Renders a relationship or upload value for the import preview table, stacking
11
+ * one row per target collection.
12
+ */ export const RelationshipCell = ({ fieldPath, relationTo, value })=>{
13
+ const { config } = useConfig();
14
+ const { i18n } = useTranslation();
15
+ const groups = getRelationshipGroups({
16
+ collections: config.collections,
17
+ dateFormat: config.admin.dateFormat,
18
+ i18n,
19
+ relationTo,
20
+ value
21
+ });
22
+ // The column heading already names a monomorphic field, whose collection never varies.
23
+ const shouldShowCollectionLabels = Array.isArray(relationTo);
24
+ if (!groups.length) {
25
+ return null;
26
+ }
27
+ return /*#__PURE__*/ _jsx("div", {
28
+ className: baseClass,
29
+ children: groups.map(({ slug, label, options, remaining })=>/*#__PURE__*/ _jsxs("div", {
30
+ className: `${baseClass}__group`,
31
+ children: [
32
+ shouldShowCollectionLabels && label && /*#__PURE__*/ _jsx("span", {
33
+ className: `${baseClass}__collection`,
34
+ children: label
35
+ }),
36
+ /*#__PURE__*/ _jsxs("div", {
37
+ className: `${baseClass}__values`,
38
+ children: [
39
+ options.join(', '),
40
+ remaining > 0 && /*#__PURE__*/ _jsx("span", {
41
+ className: `${baseClass}__more`,
42
+ children: i18n.t('fields:itemsAndMore', {
43
+ count: remaining,
44
+ items: ''
45
+ }).trim()
46
+ })
47
+ ]
48
+ })
49
+ ]
50
+ }, getRelationshipGroupKey({
51
+ slug,
52
+ fieldPath
53
+ })))
54
+ });
55
+ };
56
+
57
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/RelationshipCell/index.tsx"],"sourcesContent":["'use client'\nimport { useConfig, useTranslation } from '@payloadcms/ui'\nimport React from 'react'\n\nimport { getRelationshipGroupKey } from './getRelationshipGroupKey.js'\nimport { getRelationshipGroups } from './getRelationshipGroups.js'\nimport './index.css'\n\nconst baseClass = 'import-preview-relationship'\n\ntype Props = {\n fieldPath: string\n /** `field.relationTo` — an array when the field is polymorphic. */\n relationTo: string | string[]\n value: unknown\n}\n\n/**\n * Renders a relationship or upload value for the import preview table, stacking\n * one row per target collection.\n */\nexport const RelationshipCell: React.FC<Props> = ({ fieldPath, relationTo, value }) => {\n const { config } = useConfig()\n const { i18n } = useTranslation()\n\n const groups = getRelationshipGroups({\n collections: config.collections,\n dateFormat: config.admin.dateFormat,\n i18n,\n relationTo,\n value,\n })\n\n // The column heading already names a monomorphic field, whose collection never varies.\n const shouldShowCollectionLabels = Array.isArray(relationTo)\n\n if (!groups.length) {\n return null\n }\n\n return (\n <div className={baseClass}>\n {groups.map(({ slug, label, options, remaining }) => (\n <div className={`${baseClass}__group`} key={getRelationshipGroupKey({ slug, fieldPath })}>\n {/* A `label` element would be unassociated here — the cell holds no control */}\n {shouldShowCollectionLabels && label && (\n <span className={`${baseClass}__collection`}>{label}</span>\n )}\n <div className={`${baseClass}__values`}>\n {options.join(', ')}\n {remaining > 0 && (\n <span className={`${baseClass}__more`}>\n {i18n.t('fields:itemsAndMore', { count: remaining, items: '' }).trim()}\n </span>\n )}\n </div>\n </div>\n ))}\n </div>\n )\n}\n"],"names":["useConfig","useTranslation","React","getRelationshipGroupKey","getRelationshipGroups","baseClass","RelationshipCell","fieldPath","relationTo","value","config","i18n","groups","collections","dateFormat","admin","shouldShowCollectionLabels","Array","isArray","length","div","className","map","slug","label","options","remaining","span","join","t","count","items","trim"],"mappings":"AAAA;;AACA,SAASA,SAAS,EAAEC,cAAc,QAAQ,iBAAgB;AAC1D,OAAOC,WAAW,QAAO;AAEzB,SAASC,uBAAuB,QAAQ,+BAA8B;AACtE,SAASC,qBAAqB,QAAQ,6BAA4B;AAClE,OAAO,cAAa;AAEpB,MAAMC,YAAY;AASlB;;;CAGC,GACD,OAAO,MAAMC,mBAAoC,CAAC,EAAEC,SAAS,EAAEC,UAAU,EAAEC,KAAK,EAAE;IAChF,MAAM,EAAEC,MAAM,EAAE,GAAGV;IACnB,MAAM,EAAEW,IAAI,EAAE,GAAGV;IAEjB,MAAMW,SAASR,sBAAsB;QACnCS,aAAaH,OAAOG,WAAW;QAC/BC,YAAYJ,OAAOK,KAAK,CAACD,UAAU;QACnCH;QACAH;QACAC;IACF;IAEA,uFAAuF;IACvF,MAAMO,6BAA6BC,MAAMC,OAAO,CAACV;IAEjD,IAAI,CAACI,OAAOO,MAAM,EAAE;QAClB,OAAO;IACT;IAEA,qBACE,KAACC;QAAIC,WAAWhB;kBACbO,OAAOU,GAAG,CAAC,CAAC,EAAEC,IAAI,EAAEC,KAAK,EAAEC,OAAO,EAAEC,SAAS,EAAE,iBAC9C,MAACN;gBAAIC,WAAW,GAAGhB,UAAU,OAAO,CAAC;;oBAElCW,8BAA8BQ,uBAC7B,KAACG;wBAAKN,WAAW,GAAGhB,UAAU,YAAY,CAAC;kCAAGmB;;kCAEhD,MAACJ;wBAAIC,WAAW,GAAGhB,UAAU,QAAQ,CAAC;;4BACnCoB,QAAQG,IAAI,CAAC;4BACbF,YAAY,mBACX,KAACC;gCAAKN,WAAW,GAAGhB,UAAU,MAAM,CAAC;0CAClCM,KAAKkB,CAAC,CAAC,uBAAuB;oCAAEC,OAAOJ;oCAAWK,OAAO;gCAAG,GAAGC,IAAI;;;;;eAThC7B,wBAAwB;gBAAEoB;gBAAMhB;YAAU;;AAiB9F,EAAC"}
@@ -0,0 +1,9 @@
1
+ @layer payload-default {
2
+ .sort-by-fields {
3
+ --field-width: 25%;
4
+
5
+ display: flex;
6
+ flex-direction: column;
7
+ gap: var(--spacer-2);
8
+ }
9
+ }
@@ -1,4 +1,5 @@
1
- import type { SelectFieldClientComponent } from 'payload';
2
- import './index.scss';
3
- export declare const SortBy: SelectFieldClientComponent;
1
+ import type { SelectFieldClientProps } from 'payload';
2
+ import React from 'react';
3
+ import './index.css';
4
+ export declare const SortBy: React.FC<SelectFieldClientProps>;
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/SortBy/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAA;AAgBzD,OAAO,cAAc,CAAA;AAIrB,eAAO,MAAM,MAAM,EAAE,0BAqHpB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/SortBy/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAA;AAWrD,OAAO,KAA+C,MAAM,OAAO,CAAA;AAKnE,OAAO,aAAa,CAAA;AAIpB,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAoHnD,CAAA"}
@@ -5,7 +5,7 @@ import React, { useEffect, useMemo, useRef, useState } from 'react';
5
5
  import { applySortOrder, normalizeQueryParam, stripSortDash } from '../../utilities/sortHelpers.js';
6
6
  import { reduceFields } from '../FieldsToExport/reduceFields.js';
7
7
  import { useImportExport } from '../ImportExportProvider/index.js';
8
- import './index.scss';
8
+ import './index.css';
9
9
  const baseClass = 'sort-by-fields';
10
10
  export const SortBy = (props)=>{
11
11
  const { id } = useDocumentInfo();
@@ -115,7 +115,6 @@ export const SortBy = (props)=>{
115
115
  path: props.path
116
116
  }),
117
117
  /*#__PURE__*/ _jsx(ReactSelect, {
118
- className: baseClass,
119
118
  disabled: props.readOnly,
120
119
  getOptionValue: (option)=>String(option.value),
121
120
  inputId: `field-${props.path.replace(/\./g, '__')}`,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/SortBy/index.tsx"],"sourcesContent":["'use client'\n\nimport type { SelectFieldClientComponent } from 'payload'\nimport type { ReactNode } from 'react'\n\nimport {\n FieldLabel,\n ReactSelect,\n useConfig,\n useDocumentInfo,\n useField,\n useListQuery,\n} from '@payloadcms/ui'\nimport React, { useEffect, useMemo, useRef, useState } from 'react'\n\nimport { applySortOrder, normalizeQueryParam, stripSortDash } from '../../utilities/sortHelpers.js'\nimport { reduceFields } from '../FieldsToExport/reduceFields.js'\nimport { useImportExport } from '../ImportExportProvider/index.js'\nimport './index.scss'\n\nconst baseClass = 'sort-by-fields'\n\nexport const SortBy: SelectFieldClientComponent = (props) => {\n const { id } = useDocumentInfo()\n\n // The \"sort\" text field that stores 'title' or '-title'\n const { setValue: setSort, value: sortRaw } = useField<string>()\n\n // Sibling order field ('asc' | 'desc') used when writing sort on change\n const { value: sortOrder = 'asc' } = useField<string>({ path: 'sortOrder' })\n // Needed so we can initialize sortOrder when SortOrder component is hidden\n const { setValue: setSortOrder } = useField<'asc' | 'desc'>({ path: 'sortOrder' })\n\n const { value: collectionSlug } = useField<string>({ path: 'collectionSlug' })\n const { query } = useListQuery()\n const { getEntityConfig } = useConfig()\n const { collection } = useImportExport()\n\n // ReactSelect's displayed option\n const [displayedValue, setDisplayedValue] = useState<{\n id: string\n label: ReactNode\n value: string\n } | null>(null)\n\n const collectionConfig = getEntityConfig({ collectionSlug: collectionSlug ?? collection })\n const fieldOptions = useMemo(\n () => reduceFields({ excludeUnsortable: true, fields: collectionConfig?.fields }),\n [collectionConfig?.fields],\n )\n\n // Normalize the stored value for display (strip the '-') and pick the option\n useEffect(() => {\n const clean = stripSortDash(sortRaw)\n if (!clean) {\n setDisplayedValue(null)\n return\n }\n\n const option = fieldOptions.find((f) => f.value === clean)\n if (option && (!displayedValue || displayedValue.value !== clean)) {\n setDisplayedValue(option)\n }\n }, [sortRaw, fieldOptions, displayedValue])\n\n // One-time init guard so clearing `sort` doesn't rehydrate from query again\n const didInitRef = useRef(false)\n\n // Sync the visible select from list-view query sort (preferred) or groupBy (fallback)\n // and initialize both `sort` and `sortOrder` here as SortOrder may be hidden by admin.condition.\n useEffect(() => {\n if (didInitRef.current) {\n return\n }\n if (id) {\n didInitRef.current = true\n return\n }\n if (typeof sortRaw === 'string' && sortRaw.length > 0) {\n // Already initialized elsewhere\n didInitRef.current = true\n return\n }\n\n const qsSort = normalizeQueryParam(query?.sort)\n const qsGroupBy = normalizeQueryParam(query?.groupBy)\n\n const source = qsSort ?? qsGroupBy\n if (!source) {\n didInitRef.current = true\n return\n }\n\n const isDesc = !!qsSort && qsSort.startsWith('-')\n const base = stripSortDash(source)\n const order: 'asc' | 'desc' = isDesc ? 'desc' : 'asc'\n\n // Write BOTH fields so preview/export have the right values even if SortOrder is hidden\n setSort(applySortOrder(base, order))\n setSortOrder(order)\n\n const option = fieldOptions.find((f) => f.value === base)\n if (option) {\n setDisplayedValue(option)\n }\n\n didInitRef.current = true\n }, [id, query?.groupBy, query?.sort, sortRaw, fieldOptions, setSort, setSortOrder])\n\n // When user selects a different field, store it with the current order applied\n const onChange = (option: { id: string; label: ReactNode; value: string } | null) => {\n if (!option) {\n setSort('')\n setDisplayedValue(null)\n } else {\n setDisplayedValue(option)\n const next = applySortOrder(option.value, String(sortOrder) as 'asc' | 'desc')\n setSort(next)\n }\n }\n\n return (\n <div className={baseClass}>\n <FieldLabel label={props.field.label} path={props.path} />\n <ReactSelect\n className={baseClass}\n disabled={props.readOnly}\n getOptionValue={(option) => String(option.value)}\n inputId={`field-${props.path.replace(/\\./g, '__')}`}\n isClearable={true}\n isSortable={true}\n // @ts-expect-error react select option\n onChange={onChange}\n options={fieldOptions}\n // @ts-expect-error react select\n value={displayedValue}\n />\n </div>\n )\n}\n"],"names":["FieldLabel","ReactSelect","useConfig","useDocumentInfo","useField","useListQuery","React","useEffect","useMemo","useRef","useState","applySortOrder","normalizeQueryParam","stripSortDash","reduceFields","useImportExport","baseClass","SortBy","props","id","setValue","setSort","value","sortRaw","sortOrder","path","setSortOrder","collectionSlug","query","getEntityConfig","collection","displayedValue","setDisplayedValue","collectionConfig","fieldOptions","excludeUnsortable","fields","clean","option","find","f","didInitRef","current","length","qsSort","sort","qsGroupBy","groupBy","source","isDesc","startsWith","base","order","onChange","next","String","div","className","label","field","disabled","readOnly","getOptionValue","inputId","replace","isClearable","isSortable","options"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/SortBy/index.tsx"],"sourcesContent":["'use client'\n\nimport type { SelectFieldClientProps } from 'payload'\nimport type { ReactNode } from 'react'\n\nimport {\n FieldLabel,\n ReactSelect,\n useConfig,\n useDocumentInfo,\n useField,\n useListQuery,\n} from '@payloadcms/ui'\nimport React, { useEffect, useMemo, useRef, useState } from 'react'\n\nimport { applySortOrder, normalizeQueryParam, stripSortDash } from '../../utilities/sortHelpers.js'\nimport { reduceFields } from '../FieldsToExport/reduceFields.js'\nimport { useImportExport } from '../ImportExportProvider/index.js'\nimport './index.css'\n\nconst baseClass = 'sort-by-fields'\n\nexport const SortBy: React.FC<SelectFieldClientProps> = (props) => {\n const { id } = useDocumentInfo()\n\n // The \"sort\" text field that stores 'title' or '-title'\n const { setValue: setSort, value: sortRaw } = useField<string>()\n\n // Sibling order field ('asc' | 'desc') used when writing sort on change\n const { value: sortOrder = 'asc' } = useField<string>({ path: 'sortOrder' })\n // Needed so we can initialize sortOrder when SortOrder component is hidden\n const { setValue: setSortOrder } = useField<'asc' | 'desc'>({ path: 'sortOrder' })\n\n const { value: collectionSlug } = useField<string>({ path: 'collectionSlug' })\n const { query } = useListQuery()\n const { getEntityConfig } = useConfig()\n const { collection } = useImportExport()\n\n // ReactSelect's displayed option\n const [displayedValue, setDisplayedValue] = useState<{\n id: string\n label: ReactNode\n value: string\n } | null>(null)\n\n const collectionConfig = getEntityConfig({ collectionSlug: collectionSlug ?? collection })\n const fieldOptions = useMemo(\n () => reduceFields({ excludeUnsortable: true, fields: collectionConfig?.fields }),\n [collectionConfig?.fields],\n )\n\n // Normalize the stored value for display (strip the '-') and pick the option\n useEffect(() => {\n const clean = stripSortDash(sortRaw)\n if (!clean) {\n setDisplayedValue(null)\n return\n }\n\n const option = fieldOptions.find((f) => f.value === clean)\n if (option && (!displayedValue || displayedValue.value !== clean)) {\n setDisplayedValue(option)\n }\n }, [sortRaw, fieldOptions, displayedValue])\n\n // One-time init guard so clearing `sort` doesn't rehydrate from query again\n const didInitRef = useRef(false)\n\n // Sync the visible select from list-view query sort (preferred) or groupBy (fallback)\n // and initialize both `sort` and `sortOrder` here as SortOrder may be hidden by admin.condition.\n useEffect(() => {\n if (didInitRef.current) {\n return\n }\n if (id) {\n didInitRef.current = true\n return\n }\n if (typeof sortRaw === 'string' && sortRaw.length > 0) {\n // Already initialized elsewhere\n didInitRef.current = true\n return\n }\n\n const qsSort = normalizeQueryParam(query?.sort)\n const qsGroupBy = normalizeQueryParam(query?.groupBy)\n\n const source = qsSort ?? qsGroupBy\n if (!source) {\n didInitRef.current = true\n return\n }\n\n const isDesc = !!qsSort && qsSort.startsWith('-')\n const base = stripSortDash(source)\n const order: 'asc' | 'desc' = isDesc ? 'desc' : 'asc'\n\n // Write BOTH fields so preview/export have the right values even if SortOrder is hidden\n setSort(applySortOrder(base, order))\n setSortOrder(order)\n\n const option = fieldOptions.find((f) => f.value === base)\n if (option) {\n setDisplayedValue(option)\n }\n\n didInitRef.current = true\n }, [id, query?.groupBy, query?.sort, sortRaw, fieldOptions, setSort, setSortOrder])\n\n // When user selects a different field, store it with the current order applied\n const onChange = (option: { id: string; label: ReactNode; value: string } | null) => {\n if (!option) {\n setSort('')\n setDisplayedValue(null)\n } else {\n setDisplayedValue(option)\n const next = applySortOrder(option.value, String(sortOrder) as 'asc' | 'desc')\n setSort(next)\n }\n }\n\n return (\n <div className={baseClass}>\n <FieldLabel label={props.field.label} path={props.path} />\n <ReactSelect\n disabled={props.readOnly}\n getOptionValue={(option) => String(option.value)}\n inputId={`field-${props.path.replace(/\\./g, '__')}`}\n isClearable={true}\n isSortable={true}\n // @ts-expect-error react select option\n onChange={onChange}\n options={fieldOptions}\n // @ts-expect-error react select\n value={displayedValue}\n />\n </div>\n )\n}\n"],"names":["FieldLabel","ReactSelect","useConfig","useDocumentInfo","useField","useListQuery","React","useEffect","useMemo","useRef","useState","applySortOrder","normalizeQueryParam","stripSortDash","reduceFields","useImportExport","baseClass","SortBy","props","id","setValue","setSort","value","sortRaw","sortOrder","path","setSortOrder","collectionSlug","query","getEntityConfig","collection","displayedValue","setDisplayedValue","collectionConfig","fieldOptions","excludeUnsortable","fields","clean","option","find","f","didInitRef","current","length","qsSort","sort","qsGroupBy","groupBy","source","isDesc","startsWith","base","order","onChange","next","String","div","className","label","field","disabled","readOnly","getOptionValue","inputId","replace","isClearable","isSortable","options"],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ @layer payload-default {
2
+ .sort-order-field {
3
+ --field-width: 25%;
4
+
5
+ display: flex;
6
+ flex-direction: column;
7
+ gap: var(--spacer-2);
8
+ }
9
+ }
@@ -1,4 +1,5 @@
1
- import type { SelectFieldClientComponent } from 'payload';
2
- import './index.scss';
3
- export declare const SortOrder: SelectFieldClientComponent;
1
+ import type { SelectFieldClientProps } from 'payload';
2
+ import React from 'react';
3
+ import './index.css';
4
+ export declare const SortOrder: React.FC<SelectFieldClientProps>;
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/SortOrder/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAA;AAMzD,OAAO,cAAc,CAAA;AAcrB,eAAO,MAAM,SAAS,EAAE,0BAuGvB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/SortOrder/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAA;AAGrD,OAAO,KAA+C,MAAM,OAAO,CAAA;AAGnE,OAAO,aAAa,CAAA;AAcpB,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAsGtD,CAAA"}
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { FieldLabel, ReactSelect, useDocumentInfo, useField, useListQuery } from '@payloadcms/ui';
4
4
  import React, { useEffect, useMemo, useRef, useState } from 'react';
5
5
  import { applySortOrder, normalizeQueryParam, stripSortDash } from '../../utilities/sortHelpers.js';
6
- import './index.scss';
6
+ import './index.css';
7
7
  const baseClass = 'sort-order-field';
8
8
  const options = [
9
9
  {
@@ -103,7 +103,6 @@ export const SortOrder = (props)=>{
103
103
  path: props.path
104
104
  }),
105
105
  /*#__PURE__*/ _jsx(ReactSelect, {
106
- className: baseClass,
107
106
  disabled: props.readOnly,
108
107
  inputId: `field-${props.path.replace(/\./g, '__')}`,
109
108
  isClearable: false,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/SortOrder/index.tsx"],"sourcesContent":["'use client'\n\nimport type { SelectFieldClientComponent } from 'payload'\n\nimport { FieldLabel, ReactSelect, useDocumentInfo, useField, useListQuery } from '@payloadcms/ui'\nimport React, { useEffect, useMemo, useRef, useState } from 'react'\n\nimport { applySortOrder, normalizeQueryParam, stripSortDash } from '../../utilities/sortHelpers.js'\nimport './index.scss'\n\nconst baseClass = 'sort-order-field'\n\ntype Order = 'asc' | 'desc'\ntype OrderOption = { label: string; value: Order }\n\nconst options = [\n { label: 'Ascending', value: 'asc' as const },\n { label: 'Descending', value: 'desc' as const },\n] as const\n\nconst defaultOption: OrderOption = options[0]\n\nexport const SortOrder: SelectFieldClientComponent = (props) => {\n const { id } = useDocumentInfo()\n const { query } = useListQuery()\n\n // 'sortOrder' select field: 'asc' | 'desc'\n const { setValue: setOrder, value: orderValueRaw } = useField<Order>()\n\n // 'sort' text field: 'title' | '-title'\n const { setValue: setSort, value: sortRaw } = useField<string>({ path: 'sort' })\n\n // The current order value, defaulting to 'asc' for UI\n const orderValue: Order = orderValueRaw || 'asc'\n\n // Map 'asc' | 'desc' to the option object for ReactSelect\n const currentOption = useMemo<OrderOption>(\n () => options.find((o) => o.value === orderValue) ?? defaultOption,\n [orderValue],\n )\n const [displayed, setDisplayed] = useState<null | OrderOption>(currentOption)\n\n // One-time init guard so clearing `sort` doesn't rehydrate from query again\n const didInitRef = useRef(false)\n\n // Derive from list-view query.sort if present; otherwise fall back to groupBy\n useEffect(() => {\n if (didInitRef.current) {\n return\n }\n\n // Existing export -> don't initialize here\n if (id) {\n didInitRef.current = true\n return\n }\n\n // If sort already has a value, treat as initialized\n if (typeof sortRaw === 'string' && sortRaw.length > 0) {\n didInitRef.current = true\n return\n }\n\n const qsSort = normalizeQueryParam(query?.sort)\n const qsGroupBy = normalizeQueryParam(query?.groupBy)\n\n if (qsSort) {\n const isDesc = qsSort.startsWith('-')\n const base = stripSortDash(qsSort)\n const order: Order = isDesc ? 'desc' : 'asc'\n setOrder(order)\n setSort(applySortOrder(base, order)) // combined: 'title' or '-title'\n didInitRef.current = true\n return\n }\n\n // Fallback: groupBy (always ascending)\n if (qsGroupBy) {\n setOrder('asc')\n setSort(applySortOrder(qsGroupBy, 'asc')) // write 'groupByField' (no dash)\n didInitRef.current = true\n return\n }\n\n // Nothing to initialize\n didInitRef.current = true\n }, [id, query?.sort, query?.groupBy, sortRaw, setOrder, setSort])\n\n // Keep the select's displayed option in sync with the stored order\n useEffect(() => {\n setDisplayed(currentOption ?? defaultOption)\n }, [currentOption])\n\n // Handle manual order changes via ReactSelect:\n // - update the order field\n // - rewrite the combined \"sort\" string to add/remove the leading '-'\n const onChange = (option: null | OrderOption) => {\n const next = option?.value ?? 'asc'\n setOrder(next)\n\n const base = stripSortDash(sortRaw)\n if (base) {\n setSort(applySortOrder(base, next))\n }\n\n setDisplayed(option ?? defaultOption)\n }\n\n return (\n <div className={baseClass}>\n <FieldLabel label={props.field.label} path={props.path} />\n <ReactSelect\n className={baseClass}\n disabled={props.readOnly}\n inputId={`field-${props.path.replace(/\\./g, '__')}`}\n isClearable={false}\n isSearchable={false}\n // @ts-expect-error react-select option typing differs from our local type\n onChange={onChange}\n options={options as unknown as OrderOption[]}\n // @ts-expect-error react-select option typing differs from our local type\n value={displayed}\n />\n </div>\n )\n}\n"],"names":["FieldLabel","ReactSelect","useDocumentInfo","useField","useListQuery","React","useEffect","useMemo","useRef","useState","applySortOrder","normalizeQueryParam","stripSortDash","baseClass","options","label","value","defaultOption","SortOrder","props","id","query","setValue","setOrder","orderValueRaw","setSort","sortRaw","path","orderValue","currentOption","find","o","displayed","setDisplayed","didInitRef","current","length","qsSort","sort","qsGroupBy","groupBy","isDesc","startsWith","base","order","onChange","option","next","div","className","field","disabled","readOnly","inputId","replace","isClearable","isSearchable"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/SortOrder/index.tsx"],"sourcesContent":["'use client'\n\nimport type { SelectFieldClientProps } from 'payload'\n\nimport { FieldLabel, ReactSelect, useDocumentInfo, useField, useListQuery } from '@payloadcms/ui'\nimport React, { useEffect, useMemo, useRef, useState } from 'react'\n\nimport { applySortOrder, normalizeQueryParam, stripSortDash } from '../../utilities/sortHelpers.js'\nimport './index.css'\n\nconst baseClass = 'sort-order-field'\n\ntype Order = 'asc' | 'desc'\ntype OrderOption = { label: string; value: Order }\n\nconst options = [\n { label: 'Ascending', value: 'asc' as const },\n { label: 'Descending', value: 'desc' as const },\n] as const\n\nconst defaultOption: OrderOption = options[0]\n\nexport const SortOrder: React.FC<SelectFieldClientProps> = (props) => {\n const { id } = useDocumentInfo()\n const { query } = useListQuery()\n\n // 'sortOrder' select field: 'asc' | 'desc'\n const { setValue: setOrder, value: orderValueRaw } = useField<Order>()\n\n // 'sort' text field: 'title' | '-title'\n const { setValue: setSort, value: sortRaw } = useField<string>({ path: 'sort' })\n\n // The current order value, defaulting to 'asc' for UI\n const orderValue: Order = orderValueRaw || 'asc'\n\n // Map 'asc' | 'desc' to the option object for ReactSelect\n const currentOption = useMemo<OrderOption>(\n () => options.find((o) => o.value === orderValue) ?? defaultOption,\n [orderValue],\n )\n const [displayed, setDisplayed] = useState<null | OrderOption>(currentOption)\n\n // One-time init guard so clearing `sort` doesn't rehydrate from query again\n const didInitRef = useRef(false)\n\n // Derive from list-view query.sort if present; otherwise fall back to groupBy\n useEffect(() => {\n if (didInitRef.current) {\n return\n }\n\n // Existing export -> don't initialize here\n if (id) {\n didInitRef.current = true\n return\n }\n\n // If sort already has a value, treat as initialized\n if (typeof sortRaw === 'string' && sortRaw.length > 0) {\n didInitRef.current = true\n return\n }\n\n const qsSort = normalizeQueryParam(query?.sort)\n const qsGroupBy = normalizeQueryParam(query?.groupBy)\n\n if (qsSort) {\n const isDesc = qsSort.startsWith('-')\n const base = stripSortDash(qsSort)\n const order: Order = isDesc ? 'desc' : 'asc'\n setOrder(order)\n setSort(applySortOrder(base, order)) // combined: 'title' or '-title'\n didInitRef.current = true\n return\n }\n\n // Fallback: groupBy (always ascending)\n if (qsGroupBy) {\n setOrder('asc')\n setSort(applySortOrder(qsGroupBy, 'asc')) // write 'groupByField' (no dash)\n didInitRef.current = true\n return\n }\n\n // Nothing to initialize\n didInitRef.current = true\n }, [id, query?.sort, query?.groupBy, sortRaw, setOrder, setSort])\n\n // Keep the select's displayed option in sync with the stored order\n useEffect(() => {\n setDisplayed(currentOption ?? defaultOption)\n }, [currentOption])\n\n // Handle manual order changes via ReactSelect:\n // - update the order field\n // - rewrite the combined \"sort\" string to add/remove the leading '-'\n const onChange = (option: null | OrderOption) => {\n const next = option?.value ?? 'asc'\n setOrder(next)\n\n const base = stripSortDash(sortRaw)\n if (base) {\n setSort(applySortOrder(base, next))\n }\n\n setDisplayed(option ?? defaultOption)\n }\n\n return (\n <div className={baseClass}>\n <FieldLabel label={props.field.label} path={props.path} />\n <ReactSelect\n disabled={props.readOnly}\n inputId={`field-${props.path.replace(/\\./g, '__')}`}\n isClearable={false}\n isSearchable={false}\n // @ts-expect-error react-select option typing differs from our local type\n onChange={onChange}\n options={options as unknown as OrderOption[]}\n // @ts-expect-error react-select option typing differs from our local type\n value={displayed}\n />\n </div>\n )\n}\n"],"names":["FieldLabel","ReactSelect","useDocumentInfo","useField","useListQuery","React","useEffect","useMemo","useRef","useState","applySortOrder","normalizeQueryParam","stripSortDash","baseClass","options","label","value","defaultOption","SortOrder","props","id","query","setValue","setOrder","orderValueRaw","setSort","sortRaw","path","orderValue","currentOption","find","o","displayed","setDisplayed","didInitRef","current","length","qsSort","sort","qsGroupBy","groupBy","isDesc","startsWith","base","order","onChange","option","next","div","className","field","disabled","readOnly","inputId","replace","isClearable","isSearchable"],"mappings":"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"}
@@ -2,8 +2,8 @@
2
2
  * Export-specific batch processor for processing documents in batches during export.
3
3
  * Uses the generic batch processing utilities from useBatchProcessor.
4
4
  */
5
- import type { PayloadRequest, SelectType, Sort, TypedUser, Where } from 'payload';
6
- import type { ExportAfterHook, ExportBeforeHook } from '../types.js';
5
+ import type { PayloadRequest, SelectType, Sort, User, Where } from 'payload';
6
+ import type { ExportAfterHook, ExportBeforeHook, ExportDoc } from '../types.js';
7
7
  import { type BatchProcessorOptions } from '../utilities/useBatchProcessor.js';
8
8
  /**
9
9
  * Export-specific batch processor options
@@ -24,7 +24,7 @@ export interface ExportFindArgs {
24
24
  page?: number;
25
25
  select?: SelectType;
26
26
  sort?: Sort;
27
- user?: TypedUser;
27
+ user?: User;
28
28
  where?: Where;
29
29
  }
30
30
  /**
@@ -35,6 +35,7 @@ export interface ExportProcessOptions<TDoc = unknown> {
35
35
  * The slug of the collection to export
36
36
  */
37
37
  collectionSlug: string;
38
+ exportDoc: ExportDoc;
38
39
  /**
39
40
  * Arguments to pass to payload.find()
40
41
  */
@@ -1 +1 @@
1
- {"version":3,"file":"batchProcessor.d.ts","sourceRoot":"","sources":["../../src/export/batchProcessor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAEjF,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAEpE,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,mCAAmC,CAAA;AAE9E;;GAEG;AACH,MAAM,WAAW,2BAA4B,SAAQ,qBAAqB;IACxE,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,OAAO,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,cAAc,EAAE,OAAO,CAAA;IACvB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,KAAK,CAAC,EAAE,KAAK,CAAA;CACd;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB,CAAC,IAAI,GAAG,OAAO;IAClD;;OAEG;IACH,cAAc,EAAE,MAAM,CAAA;IACtB;;OAEG;IACH,QAAQ,EAAE,cAAc,CAAA;IACxB;;OAEG;IACH,MAAM,EAAE,KAAK,GAAG,MAAM,CAAA;IACtB,gDAAgD;IAChD,KAAK,CAAC,EAAE;QACN,KAAK,CAAC,EAAE,eAAe,CAAA;QACvB,MAAM,CAAC,EAAE,gBAAgB,CAAA;KAC1B,CAAA;IACD;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;IACf;;OAEG;IACH,GAAG,EAAE,cAAc,CAAA;IACnB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,YAAY,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACrD;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;IAC/B;;OAEG;IACH,YAAY,EAAE,MAAM,CAAA;CACrB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,2BAAgC;sBA6NnD,IAAI,kBACjB,oBAAoB,CAAC,IAAI,CAAC,KACzC,OAAO,CAAC,MAAM,EAAE,CAAC;oBA7MS,IAAI,kBACf,oBAAoB,CAAC,IAAI,CAAC,KACzC,OAAO,CAAC,YAAY,CAAC;mBA0GK,IAAI,kBACf,oBAAoB,CAAC,IAAI,CAAC,KACzC,cAAc,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;KAAE,CAAC;EAwJ1E"}
1
+ {"version":3,"file":"batchProcessor.d.ts","sourceRoot":"","sources":["../../src/export/batchProcessor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAE5E,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE/E,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,mCAAmC,CAAA;AAE9E;;GAEG;AACH,MAAM,WAAW,2BAA4B,SAAQ,qBAAqB;IACxE,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,OAAO,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,cAAc,EAAE,OAAO,CAAA;IACvB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,KAAK,CAAC,EAAE,KAAK,CAAA;CACd;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB,CAAC,IAAI,GAAG,OAAO;IAClD;;OAEG;IACH,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,SAAS,CAAA;IACpB;;OAEG;IACH,QAAQ,EAAE,cAAc,CAAA;IACxB;;OAEG;IACH,MAAM,EAAE,KAAK,GAAG,MAAM,CAAA;IACtB,gDAAgD;IAChD,KAAK,CAAC,EAAE;QACN,KAAK,CAAC,EAAE,eAAe,CAAA;QACvB,MAAM,CAAC,EAAE,gBAAgB,CAAA;KAC1B,CAAA;IACD;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;IACf;;OAEG;IACH,GAAG,EAAE,cAAc,CAAA;IACnB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,YAAY,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACrD;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;IAC/B;;OAEG;IACH,YAAY,EAAE,MAAM,CAAA;CACrB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,2BAAgC;sBAmOnD,IAAI,kBACjB,oBAAoB,CAAC,IAAI,CAAC,KACzC,OAAO,CAAC,MAAM,EAAE,CAAC;oBAnNS,IAAI,kBACf,oBAAoB,CAAC,IAAI,CAAC,KACzC,OAAO,CAAC,YAAY,CAAC;mBA6GK,IAAI,kBACf,oBAAoB,CAAC,IAAI,CAAC,KACzC,cAAc,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;KAAE,CAAC;EA2J1E"}
@@ -33,7 +33,7 @@
33
33
  * @param processOptions - Options for the export operation
34
34
  * @returns The export result containing transformed documents and column info
35
35
  */ const processExport = async (processOptions)=>{
36
- const { findArgs, format, hooks, maxDocs, req, startPage = 1, totalDocs, transformDoc } = processOptions;
36
+ const { exportDoc, findArgs, format, hooks, maxDocs, req, startPage = 1, totalDocs, transformDoc } = processOptions;
37
37
  const totalBatches = computeTotalBatches(totalDocs, maxDocs);
38
38
  const docs = [];
39
39
  const columnsSet = new Set();
@@ -60,6 +60,7 @@
60
60
  const dataToWrite = hooks?.before && batchData.length > 0 ? await hooks.before({
61
61
  batchNumber,
62
62
  data: batchData,
63
+ exportDoc,
63
64
  format,
64
65
  originalData: originalDocs,
65
66
  req,
@@ -80,6 +81,7 @@
80
81
  await hooks.after({
81
82
  batchNumber,
82
83
  data: dataToWrite,
84
+ exportDoc,
83
85
  format,
84
86
  originalData: originalDocs,
85
87
  req,
@@ -113,7 +115,7 @@
113
115
  * }
114
116
  * ```
115
117
  */ async function* streamExport(processOptions) {
116
- const { findArgs, format, hooks, maxDocs, req, startPage = 1, totalDocs, transformDoc } = processOptions;
118
+ const { exportDoc, findArgs, format, hooks, maxDocs, req, startPage = 1, totalDocs, transformDoc } = processOptions;
117
119
  const totalBatches = computeTotalBatches(totalDocs, maxDocs);
118
120
  const columnsSet = new Set();
119
121
  const columns = [];
@@ -139,6 +141,7 @@
139
141
  const dataToWrite = hooks?.before && batchData.length > 0 ? await hooks.before({
140
142
  batchNumber,
141
143
  data: batchData,
144
+ exportDoc,
142
145
  format,
143
146
  originalData: originalDocs,
144
147
  req,
@@ -164,6 +167,7 @@
164
167
  await hooks.after({
165
168
  batchNumber,
166
169
  data: dataToWrite,
170
+ exportDoc,
167
171
  format,
168
172
  originalData: originalDocs,
169
173
  req,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/export/batchProcessor.ts"],"sourcesContent":["/**\n * Export-specific batch processor for processing documents in batches during export.\n * Uses the generic batch processing utilities from useBatchProcessor.\n */\nimport type { PayloadRequest, SelectType, Sort, TypedUser, Where } from 'payload'\n\nimport type { ExportAfterHook, ExportBeforeHook } from '../types.js'\n\nimport { type BatchProcessorOptions } from '../utilities/useBatchProcessor.js'\n\n/**\n * Export-specific batch processor options\n */\nexport interface ExportBatchProcessorOptions extends BatchProcessorOptions {\n debug?: boolean\n}\n\n/**\n * Find arguments for querying documents during export\n */\nexport interface ExportFindArgs {\n collection: string\n depth: number\n draft: boolean\n limit: number\n locale?: string\n overrideAccess: boolean\n page?: number\n select?: SelectType\n sort?: Sort\n user?: TypedUser\n where?: Where\n}\n\n/**\n * Options for processing an export operation\n */\nexport interface ExportProcessOptions<TDoc = unknown> {\n /**\n * The slug of the collection to export\n */\n collectionSlug: string\n /**\n * Arguments to pass to payload.find()\n */\n findArgs: ExportFindArgs\n /**\n * The export format - affects column tracking for CSV\n */\n format: 'csv' | 'json'\n /** Lifecycle hooks for this export operation */\n hooks?: {\n after?: ExportAfterHook\n before?: ExportBeforeHook\n }\n /**\n * Maximum number of documents to export\n */\n maxDocs: number\n /**\n * The Payload request object\n */\n req: PayloadRequest\n /**\n * Starting page for pagination (default: 1)\n */\n startPage?: number\n /** Total number of docs available (used to compute totalBatches for hooks) */\n totalDocs?: number\n /**\n * Transform function to apply to each document\n */\n transformDoc: (doc: TDoc) => Record<string, unknown>\n}\n\n/**\n * Result from processing an export operation\n */\nexport interface ExportResult {\n /**\n * Discovered column names (for CSV exports)\n */\n columns: string[]\n /**\n * Transformed documents ready for output\n */\n docs: Record<string, unknown>[]\n /**\n * Total number of documents fetched\n */\n fetchedCount: number\n}\n\n/**\n * Creates an export batch processor with the specified options.\n *\n * @param options - Configuration options for the batch processor\n * @returns An object containing the processExport method\n *\n * @example\n * ```ts\n * const processor = createExportBatchProcessor({ batchSize: 100, debug: true })\n *\n * const result = await processor.processExport({\n * collectionSlug: 'posts',\n * findArgs: { collection: 'posts', depth: 1, draft: false, limit: 100, overrideAccess: false },\n * format: 'csv',\n * maxDocs: 1000,\n * req,\n * transformDoc: (doc) => flattenObject({ data: doc }),\n * })\n * ```\n */\nexport function createExportBatchProcessor(options: ExportBatchProcessorOptions = {}) {\n const batchSize = options.batchSize ?? 100\n const debug = options.debug ?? false\n\n const computeTotalBatches = (totalDocs: number | undefined, maxDocs: number): number => {\n const effectiveDocs =\n totalDocs !== undefined\n ? Math.min(totalDocs, maxDocs === Number.POSITIVE_INFINITY ? totalDocs : maxDocs)\n : 0\n return effectiveDocs > 0 ? Math.ceil(effectiveDocs / batchSize) : 1\n }\n\n /**\n * Process an export operation by fetching and transforming documents in batches.\n *\n * @param processOptions - Options for the export operation\n * @returns The export result containing transformed documents and column info\n */\n const processExport = async <TDoc>(\n processOptions: ExportProcessOptions<TDoc>,\n ): Promise<ExportResult> => {\n const {\n findArgs,\n format,\n hooks,\n maxDocs,\n req,\n startPage = 1,\n totalDocs,\n transformDoc,\n } = processOptions\n\n const totalBatches = computeTotalBatches(totalDocs, maxDocs)\n\n const docs: Record<string, unknown>[] = []\n const columnsSet = new Set<string>()\n const columns: string[] = []\n\n let currentPage = startPage\n let fetched = 0\n let hasNextPage = true\n\n while (hasNextPage) {\n const remaining = Math.max(0, maxDocs - fetched)\n\n if (remaining === 0) {\n break\n }\n\n const result = await req.payload.find({\n ...findArgs,\n limit: Math.min(batchSize, remaining),\n page: currentPage,\n })\n\n if (debug) {\n req.payload.logger.debug(\n `Processing export batch ${currentPage} with ${result.docs.length} documents`,\n )\n }\n\n const batchNumber = currentPage - startPage + 1\n const originalDocs = result.docs as Record<string, unknown>[]\n const batchData = result.docs.map((doc) => transformDoc(doc as TDoc))\n\n const dataToWrite =\n hooks?.before && batchData.length > 0\n ? await hooks.before({\n batchNumber,\n data: batchData,\n format,\n originalData: originalDocs,\n req,\n totalBatches,\n })\n : batchData\n\n for (const row of dataToWrite) {\n docs.push(row)\n\n if (format === 'csv') {\n for (const key of Object.keys(row)) {\n if (!columnsSet.has(key)) {\n columnsSet.add(key)\n columns.push(key)\n }\n }\n }\n }\n\n if (hooks?.after && dataToWrite.length > 0) {\n await hooks.after({\n batchNumber,\n data: dataToWrite,\n format,\n originalData: originalDocs,\n req,\n totalBatches,\n })\n }\n\n fetched += result.docs.length\n hasNextPage = result.hasNextPage && fetched < maxDocs\n currentPage++\n }\n\n return { columns, docs, fetchedCount: fetched }\n }\n\n /**\n * Async generator for streaming export - yields batches instead of collecting all.\n * Useful for streaming exports where you want to process batches as they're fetched.\n *\n * @param processOptions - Options for the export operation\n * @yields Batch results containing transformed documents and discovered columns\n *\n * @example\n * ```ts\n * const processor = createExportBatchProcessor({ batchSize: 100 })\n *\n * for await (const batch of processor.streamExport({ ... })) {\n * // Process each batch as it's yielded\n * console.log(`Got ${batch.docs.length} documents`)\n * }\n * ```\n */\n async function* streamExport<TDoc>(\n processOptions: ExportProcessOptions<TDoc>,\n ): AsyncGenerator<{ columns: string[]; docs: Record<string, unknown>[] }> {\n const {\n findArgs,\n format,\n hooks,\n maxDocs,\n req,\n startPage = 1,\n totalDocs,\n transformDoc,\n } = processOptions\n\n const totalBatches = computeTotalBatches(totalDocs, maxDocs)\n\n const columnsSet = new Set<string>()\n const columns: string[] = []\n\n let currentPage = startPage\n let fetched = 0\n let hasNextPage = true\n\n while (hasNextPage) {\n const remaining = Math.max(0, maxDocs - fetched)\n\n if (remaining === 0) {\n break\n }\n\n const result = await req.payload.find({\n ...findArgs,\n limit: Math.min(batchSize, remaining),\n page: currentPage,\n })\n\n if (debug) {\n req.payload.logger.debug(\n `Streaming export batch ${currentPage} with ${result.docs.length} documents`,\n )\n }\n\n const batchNumber = currentPage - startPage + 1\n const originalDocs = result.docs as Record<string, unknown>[]\n const batchData = result.docs.map((doc) => transformDoc(doc as TDoc))\n\n const dataToWrite =\n hooks?.before && batchData.length > 0\n ? await hooks.before({\n batchNumber,\n data: batchData,\n format,\n originalData: originalDocs,\n req,\n totalBatches,\n })\n : batchData\n\n for (const row of dataToWrite) {\n if (format === 'csv') {\n for (const key of Object.keys(row)) {\n if (!columnsSet.has(key)) {\n columnsSet.add(key)\n columns.push(key)\n }\n }\n }\n }\n\n yield { columns: [...columns], docs: dataToWrite }\n\n if (hooks?.after && dataToWrite.length > 0) {\n await hooks.after({\n batchNumber,\n data: dataToWrite,\n format,\n originalData: originalDocs,\n req,\n totalBatches,\n })\n }\n\n fetched += result.docs.length\n hasNextPage = result.hasNextPage && fetched < maxDocs\n currentPage++\n }\n }\n\n /**\n * Discover all columns from the dataset by scanning through all batches.\n * Useful for CSV exports where you need to know all columns before streaming.\n *\n * @param processOptions - Options for the export operation\n * @returns Array of discovered column names\n */\n const discoverColumns = async <TDoc>(\n processOptions: ExportProcessOptions<TDoc>,\n ): Promise<string[]> => {\n const { findArgs, maxDocs, req, startPage = 1, transformDoc } = processOptions\n\n const columnsSet = new Set<string>()\n const columns: string[] = []\n\n let currentPage = startPage\n let fetched = 0\n let hasNextPage = true\n\n while (hasNextPage) {\n const remaining = Math.max(0, maxDocs - fetched)\n\n if (remaining === 0) {\n break\n }\n\n const result = await req.payload.find({\n ...findArgs,\n limit: Math.min(batchSize, remaining),\n page: currentPage,\n })\n\n if (debug) {\n req.payload.logger.debug(\n `Scanning columns from batch ${currentPage} with ${result.docs.length} documents`,\n )\n }\n\n for (const doc of result.docs) {\n const transformedDoc = transformDoc(doc as TDoc)\n\n for (const key of Object.keys(transformedDoc)) {\n if (!columnsSet.has(key)) {\n columnsSet.add(key)\n columns.push(key)\n }\n }\n }\n\n fetched += result.docs.length\n hasNextPage = result.hasNextPage && fetched < maxDocs\n currentPage++\n }\n\n if (debug) {\n req.payload.logger.debug(`Discovered ${columns.length} columns`)\n }\n\n return columns\n }\n\n return {\n discoverColumns,\n processExport,\n streamExport,\n }\n}\n"],"names":["createExportBatchProcessor","options","batchSize","debug","computeTotalBatches","totalDocs","maxDocs","effectiveDocs","undefined","Math","min","Number","POSITIVE_INFINITY","ceil","processExport","processOptions","findArgs","format","hooks","req","startPage","transformDoc","totalBatches","docs","columnsSet","Set","columns","currentPage","fetched","hasNextPage","remaining","max","result","payload","find","limit","page","logger","length","batchNumber","originalDocs","batchData","map","doc","dataToWrite","before","data","originalData","row","push","key","Object","keys","has","add","after","fetchedCount","streamExport","discoverColumns","transformedDoc"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/export/batchProcessor.ts"],"sourcesContent":["/**\n * Export-specific batch processor for processing documents in batches during export.\n * Uses the generic batch processing utilities from useBatchProcessor.\n */\nimport type { PayloadRequest, SelectType, Sort, User, Where } from 'payload'\n\nimport type { ExportAfterHook, ExportBeforeHook, ExportDoc } from '../types.js'\n\nimport { type BatchProcessorOptions } from '../utilities/useBatchProcessor.js'\n\n/**\n * Export-specific batch processor options\n */\nexport interface ExportBatchProcessorOptions extends BatchProcessorOptions {\n debug?: boolean\n}\n\n/**\n * Find arguments for querying documents during export\n */\nexport interface ExportFindArgs {\n collection: string\n depth: number\n draft: boolean\n limit: number\n locale?: string\n overrideAccess: boolean\n page?: number\n select?: SelectType\n sort?: Sort\n user?: User\n where?: Where\n}\n\n/**\n * Options for processing an export operation\n */\nexport interface ExportProcessOptions<TDoc = unknown> {\n /**\n * The slug of the collection to export\n */\n collectionSlug: string\n exportDoc: ExportDoc\n /**\n * Arguments to pass to payload.find()\n */\n findArgs: ExportFindArgs\n /**\n * The export format - affects column tracking for CSV\n */\n format: 'csv' | 'json'\n /** Lifecycle hooks for this export operation */\n hooks?: {\n after?: ExportAfterHook\n before?: ExportBeforeHook\n }\n /**\n * Maximum number of documents to export\n */\n maxDocs: number\n /**\n * The Payload request object\n */\n req: PayloadRequest\n /**\n * Starting page for pagination (default: 1)\n */\n startPage?: number\n /** Total number of docs available (used to compute totalBatches for hooks) */\n totalDocs?: number\n /**\n * Transform function to apply to each document\n */\n transformDoc: (doc: TDoc) => Record<string, unknown>\n}\n\n/**\n * Result from processing an export operation\n */\nexport interface ExportResult {\n /**\n * Discovered column names (for CSV exports)\n */\n columns: string[]\n /**\n * Transformed documents ready for output\n */\n docs: Record<string, unknown>[]\n /**\n * Total number of documents fetched\n */\n fetchedCount: number\n}\n\n/**\n * Creates an export batch processor with the specified options.\n *\n * @param options - Configuration options for the batch processor\n * @returns An object containing the processExport method\n *\n * @example\n * ```ts\n * const processor = createExportBatchProcessor({ batchSize: 100, debug: true })\n *\n * const result = await processor.processExport({\n * collectionSlug: 'posts',\n * findArgs: { collection: 'posts', depth: 1, draft: false, limit: 100, overrideAccess: false },\n * format: 'csv',\n * maxDocs: 1000,\n * req,\n * transformDoc: (doc) => flattenObject({ data: doc }),\n * })\n * ```\n */\nexport function createExportBatchProcessor(options: ExportBatchProcessorOptions = {}) {\n const batchSize = options.batchSize ?? 100\n const debug = options.debug ?? false\n\n const computeTotalBatches = (totalDocs: number | undefined, maxDocs: number): number => {\n const effectiveDocs =\n totalDocs !== undefined\n ? Math.min(totalDocs, maxDocs === Number.POSITIVE_INFINITY ? totalDocs : maxDocs)\n : 0\n return effectiveDocs > 0 ? Math.ceil(effectiveDocs / batchSize) : 1\n }\n\n /**\n * Process an export operation by fetching and transforming documents in batches.\n *\n * @param processOptions - Options for the export operation\n * @returns The export result containing transformed documents and column info\n */\n const processExport = async <TDoc>(\n processOptions: ExportProcessOptions<TDoc>,\n ): Promise<ExportResult> => {\n const {\n exportDoc,\n findArgs,\n format,\n hooks,\n maxDocs,\n req,\n startPage = 1,\n totalDocs,\n transformDoc,\n } = processOptions\n\n const totalBatches = computeTotalBatches(totalDocs, maxDocs)\n\n const docs: Record<string, unknown>[] = []\n const columnsSet = new Set<string>()\n const columns: string[] = []\n\n let currentPage = startPage\n let fetched = 0\n let hasNextPage = true\n\n while (hasNextPage) {\n const remaining = Math.max(0, maxDocs - fetched)\n\n if (remaining === 0) {\n break\n }\n\n const result = await req.payload.find({\n ...findArgs,\n limit: Math.min(batchSize, remaining),\n page: currentPage,\n })\n\n if (debug) {\n req.payload.logger.debug(\n `Processing export batch ${currentPage} with ${result.docs.length} documents`,\n )\n }\n\n const batchNumber = currentPage - startPage + 1\n const originalDocs = result.docs as Record<string, unknown>[]\n const batchData = result.docs.map((doc) => transformDoc(doc as TDoc))\n\n const dataToWrite =\n hooks?.before && batchData.length > 0\n ? await hooks.before({\n batchNumber,\n data: batchData,\n exportDoc,\n format,\n originalData: originalDocs,\n req,\n totalBatches,\n })\n : batchData\n\n for (const row of dataToWrite) {\n docs.push(row)\n\n if (format === 'csv') {\n for (const key of Object.keys(row)) {\n if (!columnsSet.has(key)) {\n columnsSet.add(key)\n columns.push(key)\n }\n }\n }\n }\n\n if (hooks?.after && dataToWrite.length > 0) {\n await hooks.after({\n batchNumber,\n data: dataToWrite,\n exportDoc,\n format,\n originalData: originalDocs,\n req,\n totalBatches,\n })\n }\n\n fetched += result.docs.length\n hasNextPage = result.hasNextPage && fetched < maxDocs\n currentPage++\n }\n\n return { columns, docs, fetchedCount: fetched }\n }\n\n /**\n * Async generator for streaming export - yields batches instead of collecting all.\n * Useful for streaming exports where you want to process batches as they're fetched.\n *\n * @param processOptions - Options for the export operation\n * @yields Batch results containing transformed documents and discovered columns\n *\n * @example\n * ```ts\n * const processor = createExportBatchProcessor({ batchSize: 100 })\n *\n * for await (const batch of processor.streamExport({ ... })) {\n * // Process each batch as it's yielded\n * console.log(`Got ${batch.docs.length} documents`)\n * }\n * ```\n */\n async function* streamExport<TDoc>(\n processOptions: ExportProcessOptions<TDoc>,\n ): AsyncGenerator<{ columns: string[]; docs: Record<string, unknown>[] }> {\n const {\n exportDoc,\n findArgs,\n format,\n hooks,\n maxDocs,\n req,\n startPage = 1,\n totalDocs,\n transformDoc,\n } = processOptions\n\n const totalBatches = computeTotalBatches(totalDocs, maxDocs)\n\n const columnsSet = new Set<string>()\n const columns: string[] = []\n\n let currentPage = startPage\n let fetched = 0\n let hasNextPage = true\n\n while (hasNextPage) {\n const remaining = Math.max(0, maxDocs - fetched)\n\n if (remaining === 0) {\n break\n }\n\n const result = await req.payload.find({\n ...findArgs,\n limit: Math.min(batchSize, remaining),\n page: currentPage,\n })\n\n if (debug) {\n req.payload.logger.debug(\n `Streaming export batch ${currentPage} with ${result.docs.length} documents`,\n )\n }\n\n const batchNumber = currentPage - startPage + 1\n const originalDocs = result.docs as Record<string, unknown>[]\n const batchData = result.docs.map((doc) => transformDoc(doc as TDoc))\n\n const dataToWrite =\n hooks?.before && batchData.length > 0\n ? await hooks.before({\n batchNumber,\n data: batchData,\n exportDoc,\n format,\n originalData: originalDocs,\n req,\n totalBatches,\n })\n : batchData\n\n for (const row of dataToWrite) {\n if (format === 'csv') {\n for (const key of Object.keys(row)) {\n if (!columnsSet.has(key)) {\n columnsSet.add(key)\n columns.push(key)\n }\n }\n }\n }\n\n yield { columns: [...columns], docs: dataToWrite }\n\n if (hooks?.after && dataToWrite.length > 0) {\n await hooks.after({\n batchNumber,\n data: dataToWrite,\n exportDoc,\n format,\n originalData: originalDocs,\n req,\n totalBatches,\n })\n }\n\n fetched += result.docs.length\n hasNextPage = result.hasNextPage && fetched < maxDocs\n currentPage++\n }\n }\n\n /**\n * Discover all columns from the dataset by scanning through all batches.\n * Useful for CSV exports where you need to know all columns before streaming.\n *\n * @param processOptions - Options for the export operation\n * @returns Array of discovered column names\n */\n const discoverColumns = async <TDoc>(\n processOptions: ExportProcessOptions<TDoc>,\n ): Promise<string[]> => {\n const { findArgs, maxDocs, req, startPage = 1, transformDoc } = processOptions\n\n const columnsSet = new Set<string>()\n const columns: string[] = []\n\n let currentPage = startPage\n let fetched = 0\n let hasNextPage = true\n\n while (hasNextPage) {\n const remaining = Math.max(0, maxDocs - fetched)\n\n if (remaining === 0) {\n break\n }\n\n const result = await req.payload.find({\n ...findArgs,\n limit: Math.min(batchSize, remaining),\n page: currentPage,\n })\n\n if (debug) {\n req.payload.logger.debug(\n `Scanning columns from batch ${currentPage} with ${result.docs.length} documents`,\n )\n }\n\n for (const doc of result.docs) {\n const transformedDoc = transformDoc(doc as TDoc)\n\n for (const key of Object.keys(transformedDoc)) {\n if (!columnsSet.has(key)) {\n columnsSet.add(key)\n columns.push(key)\n }\n }\n }\n\n fetched += result.docs.length\n hasNextPage = result.hasNextPage && fetched < maxDocs\n currentPage++\n }\n\n if (debug) {\n req.payload.logger.debug(`Discovered ${columns.length} columns`)\n }\n\n return columns\n }\n\n return {\n discoverColumns,\n processExport,\n streamExport,\n }\n}\n"],"names":["createExportBatchProcessor","options","batchSize","debug","computeTotalBatches","totalDocs","maxDocs","effectiveDocs","undefined","Math","min","Number","POSITIVE_INFINITY","ceil","processExport","processOptions","exportDoc","findArgs","format","hooks","req","startPage","transformDoc","totalBatches","docs","columnsSet","Set","columns","currentPage","fetched","hasNextPage","remaining","max","result","payload","find","limit","page","logger","length","batchNumber","originalDocs","batchData","map","doc","dataToWrite","before","data","originalData","row","push","key","Object","keys","has","add","after","fetchedCount","streamExport","discoverColumns","transformedDoc"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import type { PayloadRequest, Sort, Where } from 'payload';
2
+ import type { ExportDoc } from '../types.js';
2
3
  export type Export = {
3
4
  /**
4
5
  * Number of documents to process in each batch during export
@@ -26,8 +27,8 @@ export type Export = {
26
27
  name: string;
27
28
  page?: number;
28
29
  sort?: Sort;
29
- userCollection: string;
30
- userID: number | string;
30
+ userCollection?: string;
31
+ userID?: number | string;
31
32
  where?: Where;
32
33
  };
33
34
  export type CreateExportArgs = {
@@ -35,6 +36,7 @@ export type CreateExportArgs = {
35
36
  * If true, stream the file instead of saving it
36
37
  */
37
38
  download?: boolean;
39
+ exportDoc: ExportDoc;
38
40
  req: PayloadRequest;
39
41
  } & Export;
40
42
  export declare const createExport: (args: CreateExportArgs) => Promise<Response | undefined>;