@payloadcms/plugin-import-export 3.75.0 → 3.76.0-canary.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. package/dist/components/CollectionField/index.d.ts.map +1 -1
  2. package/dist/components/CollectionField/index.js +6 -2
  3. package/dist/components/CollectionField/index.js.map +1 -1
  4. package/dist/components/ExportPreview/index.d.ts.map +1 -1
  5. package/dist/components/ExportPreview/index.js +30 -12
  6. package/dist/components/ExportPreview/index.js.map +1 -1
  7. package/dist/components/ExportPreview/index.scss +12 -0
  8. package/dist/components/ImportPreview/index.js +3 -15
  9. package/dist/components/ImportPreview/index.js.map +1 -1
  10. package/dist/export/createExport.d.ts +6 -1
  11. package/dist/export/createExport.d.ts.map +1 -1
  12. package/dist/export/createExport.js +37 -13
  13. package/dist/export/createExport.js.map +1 -1
  14. package/dist/export/getCreateExportCollectionTask.d.ts.map +1 -1
  15. package/dist/export/getCreateExportCollectionTask.js +4 -1
  16. package/dist/export/getCreateExportCollectionTask.js.map +1 -1
  17. package/dist/export/getExportCollection.d.ts.map +1 -1
  18. package/dist/export/getExportCollection.js +23 -3
  19. package/dist/export/getExportCollection.js.map +1 -1
  20. package/dist/export/getFields.d.ts.map +1 -1
  21. package/dist/export/getFields.js +7 -3
  22. package/dist/export/getFields.js.map +1 -1
  23. package/dist/export/handleDownload.d.ts.map +1 -1
  24. package/dist/export/handleDownload.js +18 -1
  25. package/dist/export/handleDownload.js.map +1 -1
  26. package/dist/export/handlePreview.d.ts.map +1 -1
  27. package/dist/export/handlePreview.js +32 -10
  28. package/dist/export/handlePreview.js.map +1 -1
  29. package/dist/exports/types.d.ts +1 -1
  30. package/dist/exports/types.d.ts.map +1 -1
  31. package/dist/exports/types.js.map +1 -1
  32. package/dist/import/batchProcessor.d.ts.map +1 -1
  33. package/dist/import/batchProcessor.js +54 -55
  34. package/dist/import/batchProcessor.js.map +1 -1
  35. package/dist/import/createImport.d.ts +6 -1
  36. package/dist/import/createImport.d.ts.map +1 -1
  37. package/dist/import/createImport.js +5 -1
  38. package/dist/import/createImport.js.map +1 -1
  39. package/dist/import/getCreateImportCollectionTask.d.ts +9 -6
  40. package/dist/import/getCreateImportCollectionTask.d.ts.map +1 -1
  41. package/dist/import/getCreateImportCollectionTask.js +105 -65
  42. package/dist/import/getCreateImportCollectionTask.js.map +1 -1
  43. package/dist/import/getImportCollection.d.ts.map +1 -1
  44. package/dist/import/getImportCollection.js +39 -45
  45. package/dist/import/getImportCollection.js.map +1 -1
  46. package/dist/import/handlePreview.d.ts.map +1 -1
  47. package/dist/import/handlePreview.js +11 -0
  48. package/dist/import/handlePreview.js.map +1 -1
  49. package/dist/index.d.ts +22 -1
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +26 -2
  52. package/dist/index.js.map +1 -1
  53. package/dist/translations/languages/ar.d.ts.map +1 -1
  54. package/dist/translations/languages/ar.js +3 -0
  55. package/dist/translations/languages/ar.js.map +1 -1
  56. package/dist/translations/languages/az.d.ts.map +1 -1
  57. package/dist/translations/languages/az.js +3 -0
  58. package/dist/translations/languages/az.js.map +1 -1
  59. package/dist/translations/languages/bg.d.ts.map +1 -1
  60. package/dist/translations/languages/bg.js +3 -0
  61. package/dist/translations/languages/bg.js.map +1 -1
  62. package/dist/translations/languages/bnBd.d.ts.map +1 -1
  63. package/dist/translations/languages/bnBd.js +22 -19
  64. package/dist/translations/languages/bnBd.js.map +1 -1
  65. package/dist/translations/languages/bnIn.d.ts.map +1 -1
  66. package/dist/translations/languages/bnIn.js +22 -19
  67. package/dist/translations/languages/bnIn.js.map +1 -1
  68. package/dist/translations/languages/ca.d.ts.map +1 -1
  69. package/dist/translations/languages/ca.js +3 -0
  70. package/dist/translations/languages/ca.js.map +1 -1
  71. package/dist/translations/languages/cs.d.ts.map +1 -1
  72. package/dist/translations/languages/cs.js +3 -0
  73. package/dist/translations/languages/cs.js.map +1 -1
  74. package/dist/translations/languages/da.d.ts.map +1 -1
  75. package/dist/translations/languages/da.js +3 -0
  76. package/dist/translations/languages/da.js.map +1 -1
  77. package/dist/translations/languages/de.d.ts.map +1 -1
  78. package/dist/translations/languages/de.js +3 -0
  79. package/dist/translations/languages/de.js.map +1 -1
  80. package/dist/translations/languages/en.d.ts +3 -0
  81. package/dist/translations/languages/en.d.ts.map +1 -1
  82. package/dist/translations/languages/en.js +3 -0
  83. package/dist/translations/languages/en.js.map +1 -1
  84. package/dist/translations/languages/es.d.ts.map +1 -1
  85. package/dist/translations/languages/es.js +3 -0
  86. package/dist/translations/languages/es.js.map +1 -1
  87. package/dist/translations/languages/et.d.ts.map +1 -1
  88. package/dist/translations/languages/et.js +3 -0
  89. package/dist/translations/languages/et.js.map +1 -1
  90. package/dist/translations/languages/fa.d.ts.map +1 -1
  91. package/dist/translations/languages/fa.js +3 -0
  92. package/dist/translations/languages/fa.js.map +1 -1
  93. package/dist/translations/languages/fr.d.ts.map +1 -1
  94. package/dist/translations/languages/fr.js +3 -0
  95. package/dist/translations/languages/fr.js.map +1 -1
  96. package/dist/translations/languages/he.d.ts.map +1 -1
  97. package/dist/translations/languages/he.js +3 -0
  98. package/dist/translations/languages/he.js.map +1 -1
  99. package/dist/translations/languages/hr.d.ts.map +1 -1
  100. package/dist/translations/languages/hr.js +3 -0
  101. package/dist/translations/languages/hr.js.map +1 -1
  102. package/dist/translations/languages/hu.d.ts.map +1 -1
  103. package/dist/translations/languages/hu.js +3 -0
  104. package/dist/translations/languages/hu.js.map +1 -1
  105. package/dist/translations/languages/hy.d.ts.map +1 -1
  106. package/dist/translations/languages/hy.js +3 -0
  107. package/dist/translations/languages/hy.js.map +1 -1
  108. package/dist/translations/languages/id.d.ts.map +1 -1
  109. package/dist/translations/languages/id.js +13 -10
  110. package/dist/translations/languages/id.js.map +1 -1
  111. package/dist/translations/languages/is.d.ts.map +1 -1
  112. package/dist/translations/languages/is.js +3 -0
  113. package/dist/translations/languages/is.js.map +1 -1
  114. package/dist/translations/languages/it.d.ts.map +1 -1
  115. package/dist/translations/languages/it.js +3 -0
  116. package/dist/translations/languages/it.js.map +1 -1
  117. package/dist/translations/languages/ja.d.ts.map +1 -1
  118. package/dist/translations/languages/ja.js +3 -0
  119. package/dist/translations/languages/ja.js.map +1 -1
  120. package/dist/translations/languages/ko.d.ts.map +1 -1
  121. package/dist/translations/languages/ko.js +3 -0
  122. package/dist/translations/languages/ko.js.map +1 -1
  123. package/dist/translations/languages/lt.d.ts.map +1 -1
  124. package/dist/translations/languages/lt.js +3 -0
  125. package/dist/translations/languages/lt.js.map +1 -1
  126. package/dist/translations/languages/lv.d.ts.map +1 -1
  127. package/dist/translations/languages/lv.js +16 -13
  128. package/dist/translations/languages/lv.js.map +1 -1
  129. package/dist/translations/languages/my.d.ts.map +1 -1
  130. package/dist/translations/languages/my.js +3 -0
  131. package/dist/translations/languages/my.js.map +1 -1
  132. package/dist/translations/languages/nb.d.ts.map +1 -1
  133. package/dist/translations/languages/nb.js +3 -0
  134. package/dist/translations/languages/nb.js.map +1 -1
  135. package/dist/translations/languages/nl.d.ts.map +1 -1
  136. package/dist/translations/languages/nl.js +3 -0
  137. package/dist/translations/languages/nl.js.map +1 -1
  138. package/dist/translations/languages/pl.d.ts.map +1 -1
  139. package/dist/translations/languages/pl.js +3 -0
  140. package/dist/translations/languages/pl.js.map +1 -1
  141. package/dist/translations/languages/pt.d.ts.map +1 -1
  142. package/dist/translations/languages/pt.js +3 -0
  143. package/dist/translations/languages/pt.js.map +1 -1
  144. package/dist/translations/languages/ro.d.ts.map +1 -1
  145. package/dist/translations/languages/ro.js +3 -0
  146. package/dist/translations/languages/ro.js.map +1 -1
  147. package/dist/translations/languages/rs.d.ts.map +1 -1
  148. package/dist/translations/languages/rs.js +3 -0
  149. package/dist/translations/languages/rs.js.map +1 -1
  150. package/dist/translations/languages/rsLatin.d.ts.map +1 -1
  151. package/dist/translations/languages/rsLatin.js +3 -0
  152. package/dist/translations/languages/rsLatin.js.map +1 -1
  153. package/dist/translations/languages/ru.d.ts.map +1 -1
  154. package/dist/translations/languages/ru.js +3 -0
  155. package/dist/translations/languages/ru.js.map +1 -1
  156. package/dist/translations/languages/sk.d.ts.map +1 -1
  157. package/dist/translations/languages/sk.js +3 -0
  158. package/dist/translations/languages/sk.js.map +1 -1
  159. package/dist/translations/languages/sl.d.ts.map +1 -1
  160. package/dist/translations/languages/sl.js +3 -0
  161. package/dist/translations/languages/sl.js.map +1 -1
  162. package/dist/translations/languages/sv.d.ts.map +1 -1
  163. package/dist/translations/languages/sv.js +3 -0
  164. package/dist/translations/languages/sv.js.map +1 -1
  165. package/dist/translations/languages/ta.d.ts.map +1 -1
  166. package/dist/translations/languages/ta.js +3 -0
  167. package/dist/translations/languages/ta.js.map +1 -1
  168. package/dist/translations/languages/th.d.ts.map +1 -1
  169. package/dist/translations/languages/th.js +3 -0
  170. package/dist/translations/languages/th.js.map +1 -1
  171. package/dist/translations/languages/tr.d.ts.map +1 -1
  172. package/dist/translations/languages/tr.js +3 -0
  173. package/dist/translations/languages/tr.js.map +1 -1
  174. package/dist/translations/languages/uk.d.ts.map +1 -1
  175. package/dist/translations/languages/uk.js +3 -0
  176. package/dist/translations/languages/uk.js.map +1 -1
  177. package/dist/translations/languages/vi.d.ts.map +1 -1
  178. package/dist/translations/languages/vi.js +3 -0
  179. package/dist/translations/languages/vi.js.map +1 -1
  180. package/dist/translations/languages/zh.d.ts.map +1 -1
  181. package/dist/translations/languages/zh.js +3 -0
  182. package/dist/translations/languages/zh.js.map +1 -1
  183. package/dist/translations/languages/zhTw.d.ts.map +1 -1
  184. package/dist/translations/languages/zhTw.js +3 -0
  185. package/dist/translations/languages/zhTw.js.map +1 -1
  186. package/dist/types.d.ts +44 -1
  187. package/dist/types.d.ts.map +1 -1
  188. package/dist/types.js.map +1 -1
  189. package/dist/utilities/buildDisabledFieldRegex.d.ts +11 -2
  190. package/dist/utilities/buildDisabledFieldRegex.d.ts.map +1 -1
  191. package/dist/utilities/buildDisabledFieldRegex.js +33 -7
  192. package/dist/utilities/buildDisabledFieldRegex.js.map +1 -1
  193. package/dist/utilities/buildDisabledFieldRegex.spec.js +64 -0
  194. package/dist/utilities/buildDisabledFieldRegex.spec.js.map +1 -0
  195. package/dist/utilities/collectTimezoneCompanionFields.d.ts +24 -0
  196. package/dist/utilities/collectTimezoneCompanionFields.d.ts.map +1 -0
  197. package/dist/utilities/collectTimezoneCompanionFields.js +89 -0
  198. package/dist/utilities/collectTimezoneCompanionFields.js.map +1 -0
  199. package/dist/utilities/collectTimezoneCompanionFields.spec.js +319 -0
  200. package/dist/utilities/collectTimezoneCompanionFields.spec.js.map +1 -0
  201. package/dist/utilities/fieldToRegex.d.ts +14 -0
  202. package/dist/utilities/fieldToRegex.d.ts.map +1 -0
  203. package/dist/utilities/fieldToRegex.js +34 -0
  204. package/dist/utilities/fieldToRegex.js.map +1 -0
  205. package/dist/utilities/fieldToRegex.spec.js +151 -0
  206. package/dist/utilities/fieldToRegex.spec.js.map +1 -0
  207. package/dist/utilities/flattenObject.d.ts +7 -1
  208. package/dist/utilities/flattenObject.d.ts.map +1 -1
  209. package/dist/utilities/flattenObject.js +30 -18
  210. package/dist/utilities/flattenObject.js.map +1 -1
  211. package/dist/utilities/getExportFieldFunctions.d.ts.map +1 -1
  212. package/dist/utilities/getExportFieldFunctions.js +7 -0
  213. package/dist/utilities/getExportFieldFunctions.js.map +1 -1
  214. package/dist/utilities/getFileFromDoc.d.ts +26 -0
  215. package/dist/utilities/getFileFromDoc.d.ts.map +1 -0
  216. package/dist/utilities/getFileFromDoc.js +67 -0
  217. package/dist/utilities/getFileFromDoc.js.map +1 -0
  218. package/dist/utilities/getImportFieldFunctions.d.ts.map +1 -1
  219. package/dist/utilities/getImportFieldFunctions.js +2 -16
  220. package/dist/utilities/getImportFieldFunctions.js.map +1 -1
  221. package/dist/utilities/getPluginCollections.d.ts +1 -0
  222. package/dist/utilities/getPluginCollections.d.ts.map +1 -1
  223. package/dist/utilities/getPluginCollections.js +59 -10
  224. package/dist/utilities/getPluginCollections.js.map +1 -1
  225. package/dist/utilities/getSchemaColumns.d.ts +8 -2
  226. package/dist/utilities/getSchemaColumns.d.ts.map +1 -1
  227. package/dist/utilities/getSchemaColumns.js +61 -27
  228. package/dist/utilities/getSchemaColumns.js.map +1 -1
  229. package/dist/utilities/parseCSV.d.ts.map +1 -1
  230. package/dist/utilities/parseCSV.js +4 -10
  231. package/dist/utilities/parseCSV.js.map +1 -1
  232. package/dist/utilities/resolveLimit.d.ts +15 -0
  233. package/dist/utilities/resolveLimit.d.ts.map +1 -0
  234. package/dist/utilities/resolveLimit.js +21 -0
  235. package/dist/utilities/resolveLimit.js.map +1 -0
  236. package/dist/utilities/unflattenObject.d.ts +13 -0
  237. package/dist/utilities/unflattenObject.d.ts.map +1 -1
  238. package/dist/utilities/unflattenObject.js +64 -65
  239. package/dist/utilities/unflattenObject.js.map +1 -1
  240. package/package.json +8 -8
  241. package/dist/utilities/getvalueAtPath.d.ts +0 -15
  242. package/dist/utilities/getvalueAtPath.d.ts.map +0 -1
  243. package/dist/utilities/getvalueAtPath.js +0 -49
  244. package/dist/utilities/getvalueAtPath.js.map +0 -1
@@ -2,6 +2,7 @@
2
2
  import { APIError } from 'payload';
3
3
  import { Readable } from 'stream';
4
4
  import { buildDisabledFieldRegex } from '../utilities/buildDisabledFieldRegex.js';
5
+ import { collectTimezoneCompanionFields } from '../utilities/collectTimezoneCompanionFields.js';
5
6
  import { flattenObject } from '../utilities/flattenObject.js';
6
7
  import { getExportFieldFunctions } from '../utilities/getExportFieldFunctions.js';
7
8
  import { getFilename } from '../utilities/getFilename.js';
@@ -10,7 +11,7 @@ import { getSelect } from '../utilities/getSelect.js';
10
11
  import { validateLimitValue } from '../utilities/validateLimitValue.js';
11
12
  import { createExportBatchProcessor } from './batchProcessor.js';
12
13
  export const createExport = async (args)=>{
13
- const { id, name: nameArg, batchSize = 100, collectionSlug, debug = false, download, drafts: draftsFromInput, exportsCollection, fields, format, limit: incomingLimit, locale: localeFromInput, page, req, sort, userCollection, userID, where: whereFromInput = {} } = args;
14
+ const { id, name: nameArg, batchSize = 100, collectionSlug, debug = false, download, drafts: draftsFromInput, exportCollection, fields, format, limit: incomingLimit, maxLimit, locale: localeFromInput, page, req, sort, userCollection, userID, where: whereFromInput = {} } = args;
14
15
  const { locale: localeFromReq, payload } = req;
15
16
  if (debug) {
16
17
  req.payload.logger.debug({
@@ -65,7 +66,22 @@ export const createExport = async (args)=>{
65
66
  locale
66
67
  });
67
68
  }
68
- const hardLimit = typeof incomingLimit === 'number' && incomingLimit > 0 ? incomingLimit : undefined;
69
+ // Determine maximum export documents:
70
+ // 1. If maxLimit is defined, it sets the absolute ceiling
71
+ // 2. User's limit is applied but clamped to maxLimit if it exceeds it
72
+ let maxExportDocuments;
73
+ if (typeof maxLimit === 'number' && maxLimit > 0) {
74
+ if (typeof incomingLimit === 'number' && incomingLimit > 0) {
75
+ // User provided a limit - clamp it to maxLimit
76
+ maxExportDocuments = Math.min(incomingLimit, maxLimit);
77
+ } else {
78
+ // No user limit - use maxLimit as the ceiling
79
+ maxExportDocuments = maxLimit;
80
+ }
81
+ } else {
82
+ // No maxLimit - use user's limit if provided
83
+ maxExportDocuments = typeof incomingLimit === 'number' && incomingLimit > 0 ? incomingLimit : undefined;
84
+ }
69
85
  // Try to count documents - if access is denied, treat as 0 documents
70
86
  let totalDocs = 0;
71
87
  let accessDenied = false;
@@ -113,12 +129,14 @@ export const createExport = async (args)=>{
113
129
  const toCSVFunctions = getExportFieldFunctions({
114
130
  fields: collectionConfig.flattenedFields
115
131
  });
132
+ // Collect auto-generated timezone companion fields from schema
133
+ const timezoneCompanionFields = collectTimezoneCompanionFields(collectionConfig.flattenedFields);
116
134
  const disabledFields = collectionConfig.admin?.custom?.['plugin-import-export']?.disabledFields ?? [];
117
- const disabledRegexes = disabledFields.map(buildDisabledFieldRegex);
135
+ const disabledMatchers = disabledFields.map(buildDisabledFieldRegex);
118
136
  const filterDisabledCSV = (row)=>{
119
137
  const filtered = {};
120
138
  for (const [key, value] of Object.entries(row)){
121
- const isDisabled = disabledRegexes.some((regex)=>regex.test(key));
139
+ const isDisabled = disabledMatchers.some((matcher)=>matcher.test(key));
122
140
  if (!isDisabled) {
123
141
  filtered[key] = value;
124
142
  }
@@ -157,7 +175,8 @@ export const createExport = async (args)=>{
157
175
  disabledFields,
158
176
  fields,
159
177
  locale,
160
- localeCodes
178
+ localeCodes,
179
+ timezoneCompanionFields
161
180
  });
162
181
  if (debug) {
163
182
  req.payload.logger.debug({
@@ -171,9 +190,9 @@ export const createExport = async (args)=>{
171
190
  let columnsFinalized = false;
172
191
  const encoder = new TextEncoder();
173
192
  let isFirstBatch = true;
174
- let streamPage = adjustedPage;
193
+ let currentBatchPage = adjustedPage;
175
194
  let fetched = 0;
176
- const maxDocs = typeof hardLimit === 'number' ? hardLimit : Number.POSITIVE_INFINITY;
195
+ const maxDocs = typeof maxExportDocuments === 'number' ? maxExportDocuments : Number.POSITIVE_INFINITY;
177
196
  const stream = new Readable({
178
197
  async read () {
179
198
  const remaining = Math.max(0, maxDocs - fetched);
@@ -187,11 +206,11 @@ export const createExport = async (args)=>{
187
206
  }
188
207
  const result = await payload.find({
189
208
  ...findArgs,
190
- page: streamPage,
209
+ page: currentBatchPage,
191
210
  limit: Math.min(batchSize, remaining)
192
211
  });
193
212
  if (debug) {
194
- req.payload.logger.debug(`Streaming batch ${streamPage} with ${result.docs.length} docs`);
213
+ req.payload.logger.debug(`Streaming batch ${currentBatchPage} with ${result.docs.length} docs`);
195
214
  }
196
215
  if (result.docs.length === 0) {
197
216
  // Close JSON array properly if JSON
@@ -207,6 +226,7 @@ export const createExport = async (args)=>{
207
226
  const batchRows = result.docs.map((doc)=>filterDisabledCSV(flattenObject({
208
227
  doc,
209
228
  fields,
229
+ timezoneCompanionFields,
210
230
  toCSVFunctions
211
231
  })));
212
232
  // On first batch, discover additional columns from data and merge with schema
@@ -240,6 +260,7 @@ export const createExport = async (args)=>{
240
260
  return fullRow;
241
261
  });
242
262
  const csvString = stringify(paddedRows, {
263
+ bom: isFirstBatch,
243
264
  header: isFirstBatch,
244
265
  columns: allColumns
245
266
  });
@@ -257,7 +278,7 @@ export const createExport = async (args)=>{
257
278
  }
258
279
  fetched += result.docs.length;
259
280
  isFirstBatch = false;
260
- streamPage += 1; // Increment stream page for the next batch
281
+ currentBatchPage += 1;
261
282
  if (!result.hasNextPage || fetched >= maxDocs) {
262
283
  if (debug) {
263
284
  req.payload.logger.debug('Stream complete - no more pages');
@@ -289,6 +310,7 @@ export const createExport = async (args)=>{
289
310
  const transformDoc = (doc)=>isCSV ? filterDisabledCSV(flattenObject({
290
311
  doc,
291
312
  fields,
313
+ timezoneCompanionFields,
292
314
  toCSVFunctions
293
315
  })) : filterDisabledJSON(doc);
294
316
  // Skip fetching if access was denied - we'll create an empty export
@@ -302,7 +324,7 @@ export const createExport = async (args)=>{
302
324
  collectionSlug,
303
325
  findArgs: findArgs,
304
326
  format,
305
- maxDocs: typeof hardLimit === 'number' ? hardLimit : Number.POSITIVE_INFINITY,
327
+ maxDocs: typeof maxExportDocuments === 'number' ? maxExportDocuments : Number.POSITIVE_INFINITY,
306
328
  req,
307
329
  startPage: adjustedPage,
308
330
  transformDoc
@@ -319,7 +341,8 @@ export const createExport = async (args)=>{
319
341
  disabledFields,
320
342
  fields,
321
343
  locale,
322
- localeCodes
344
+ localeCodes,
345
+ timezoneCompanionFields
323
346
  });
324
347
  // Merge schema columns with data-discovered columns
325
348
  // Schema provides ordering, data provides additional columns (e.g., array indices > 0)
@@ -333,6 +356,7 @@ export const createExport = async (args)=>{
333
356
  });
334
357
  // Always output CSV with header, even if empty
335
358
  outputData.push(stringify(paddedRows, {
359
+ bom: true,
336
360
  header: true,
337
361
  columns: finalColumns
338
362
  }));
@@ -364,7 +388,7 @@ export const createExport = async (args)=>{
364
388
  }
365
389
  await req.payload.update({
366
390
  id,
367
- collection: exportsCollection,
391
+ collection: exportCollection,
368
392
  data: {},
369
393
  file: {
370
394
  name,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/export/createExport.ts"],"sourcesContent":["/* eslint-disable perfectionist/sort-objects */\nimport type { PayloadRequest, Sort, TypedUser, Where } from 'payload'\n\nimport { stringify } from 'csv-stringify/sync'\nimport { APIError } from 'payload'\nimport { Readable } from 'stream'\n\nimport { buildDisabledFieldRegex } from '../utilities/buildDisabledFieldRegex.js'\nimport { flattenObject } from '../utilities/flattenObject.js'\nimport { getExportFieldFunctions } from '../utilities/getExportFieldFunctions.js'\nimport { getFilename } from '../utilities/getFilename.js'\nimport { getSchemaColumns, mergeColumns } from '../utilities/getSchemaColumns.js'\nimport { getSelect } from '../utilities/getSelect.js'\nimport { validateLimitValue } from '../utilities/validateLimitValue.js'\nimport { createExportBatchProcessor, type ExportFindArgs } from './batchProcessor.js'\n\nexport type Export = {\n /**\n * Number of documents to process in each batch during export\n * @default 100\n */\n batchSize?: number\n collectionSlug: string\n /**\n * If true, enables debug logging\n */\n debug?: boolean\n drafts?: 'no' | 'yes'\n exportsCollection: string\n fields?: string[]\n format: 'csv' | 'json'\n globals?: string[]\n id: number | string\n limit?: number\n locale?: string\n name: string\n page?: number\n slug: string\n sort: Sort\n userCollection: string\n userID: number | string\n where?: Where\n}\n\nexport type CreateExportArgs = {\n /**\n * If true, stream the file instead of saving it\n */\n download?: boolean\n req: PayloadRequest\n} & Export\n\nexport const createExport = async (args: CreateExportArgs) => {\n const {\n id,\n name: nameArg,\n batchSize = 100,\n collectionSlug,\n debug = false,\n download,\n drafts: draftsFromInput,\n exportsCollection,\n fields,\n format,\n limit: incomingLimit,\n locale: localeFromInput,\n page,\n req,\n sort,\n userCollection,\n userID,\n where: whereFromInput = {},\n } = args\n const { locale: localeFromReq, payload } = req\n\n if (debug) {\n req.payload.logger.debug({\n message: 'Starting export process with args:',\n collectionSlug,\n draft: draftsFromInput,\n fields,\n format,\n })\n }\n\n const locale = localeFromInput ?? localeFromReq\n const collectionConfig = payload.config.collections.find(({ slug }) => slug === collectionSlug)\n\n if (!collectionConfig) {\n throw new APIError(`Collection with slug ${collectionSlug} not found.`)\n }\n\n let user: TypedUser | undefined\n\n if (userCollection && userID) {\n user = (await req.payload.findByID({\n id: userID,\n collection: userCollection,\n overrideAccess: true,\n })) as TypedUser\n }\n\n if (!user && req.user) {\n user = req?.user?.id ? req.user : req?.user?.user\n }\n\n if (!user) {\n throw new APIError('User authentication is required to create exports.')\n }\n\n const draft = draftsFromInput === 'yes'\n const hasVersions = Boolean(collectionConfig.versions)\n\n // Only filter by _status for versioned collections\n const publishedWhere: Where = hasVersions ? { _status: { equals: 'published' } } : {}\n\n const where: Where = {\n and: [whereFromInput, draft ? {} : publishedWhere],\n }\n\n const name = `${nameArg ?? `${getFilename()}-${collectionSlug}`}.${format}`\n const isCSV = format === 'csv'\n const select = Array.isArray(fields) && fields.length > 0 ? getSelect(fields) : undefined\n\n if (debug) {\n req.payload.logger.debug({ message: 'Export configuration:', name, isCSV, locale })\n }\n\n const hardLimit =\n typeof incomingLimit === 'number' && incomingLimit > 0 ? incomingLimit : undefined\n\n // Try to count documents - if access is denied, treat as 0 documents\n let totalDocs = 0\n let accessDenied = false\n try {\n const countResult = await payload.count({\n collection: collectionSlug,\n user,\n locale,\n overrideAccess: false,\n })\n totalDocs = countResult.totalDocs\n } catch (error) {\n // Access denied - user can't read from this collection\n // We'll create an empty export file\n accessDenied = true\n if (debug) {\n req.payload.logger.debug({\n message: 'Access denied for collection, creating empty export',\n collectionSlug,\n })\n }\n }\n\n const totalPages = Math.max(1, Math.ceil(totalDocs / batchSize))\n const requestedPage = page || 1\n const adjustedPage = requestedPage > totalPages ? 1 : requestedPage\n\n const findArgs = {\n collection: collectionSlug,\n depth: 1,\n draft,\n limit: batchSize,\n locale,\n overrideAccess: false,\n page: 0, // The page will be incremented manually in the loop\n select,\n sort,\n user,\n where,\n }\n\n if (debug) {\n req.payload.logger.debug({ message: 'Find arguments:', findArgs })\n }\n\n const toCSVFunctions = getExportFieldFunctions({\n fields: collectionConfig.flattenedFields,\n })\n\n const disabledFields =\n collectionConfig.admin?.custom?.['plugin-import-export']?.disabledFields ?? []\n\n const disabledRegexes: RegExp[] = disabledFields.map(buildDisabledFieldRegex)\n\n const filterDisabledCSV = (row: Record<string, unknown>): Record<string, unknown> => {\n const filtered: Record<string, unknown> = {}\n\n for (const [key, value] of Object.entries(row)) {\n const isDisabled = disabledRegexes.some((regex) => regex.test(key))\n if (!isDisabled) {\n filtered[key] = value\n }\n }\n\n return filtered\n }\n\n const filterDisabledJSON = (doc: any, parentPath = ''): any => {\n if (Array.isArray(doc)) {\n return doc.map((item) => filterDisabledJSON(item, parentPath))\n }\n\n if (typeof doc !== 'object' || doc === null) {\n return doc\n }\n\n const filtered: Record<string, any> = {}\n for (const [key, value] of Object.entries(doc)) {\n const currentPath = parentPath ? `${parentPath}.${key}` : key\n\n // Only remove if this exact path is disabled\n const isDisabled = disabledFields.includes(currentPath)\n\n if (!isDisabled) {\n filtered[key] = filterDisabledJSON(value, currentPath)\n }\n }\n\n return filtered\n }\n\n if (download) {\n const limitErrorMsg = validateLimitValue(incomingLimit, req.t)\n if (limitErrorMsg) {\n throw new APIError(limitErrorMsg)\n }\n\n // Get schema-based columns first (provides base ordering and handles empty exports)\n let schemaColumns: string[] = []\n if (isCSV) {\n const localeCodes =\n locale === 'all' && payload.config.localization\n ? payload.config.localization.localeCodes\n : undefined\n\n schemaColumns = getSchemaColumns({\n collectionConfig,\n disabledFields,\n fields,\n locale,\n localeCodes,\n })\n\n if (debug) {\n req.payload.logger.debug({\n columnCount: schemaColumns.length,\n msg: 'Schema-based column inference complete',\n })\n }\n }\n\n // allColumns will be finalized after first batch (schema + data columns merged)\n let allColumns: string[] = []\n let columnsFinalized = false\n\n const encoder = new TextEncoder()\n let isFirstBatch = true\n let streamPage = adjustedPage\n let fetched = 0\n const maxDocs = typeof hardLimit === 'number' ? hardLimit : Number.POSITIVE_INFINITY\n\n const stream = new Readable({\n async read() {\n const remaining = Math.max(0, maxDocs - fetched)\n\n if (remaining === 0) {\n if (!isCSV) {\n // If first batch with no remaining, output empty array; otherwise just close\n this.push(encoder.encode(isFirstBatch ? '[]' : ']'))\n }\n this.push(null)\n return\n }\n\n const result = await payload.find({\n ...findArgs,\n page: streamPage,\n limit: Math.min(batchSize, remaining),\n })\n\n if (debug) {\n req.payload.logger.debug(`Streaming batch ${streamPage} with ${result.docs.length} docs`)\n }\n\n if (result.docs.length === 0) {\n // Close JSON array properly if JSON\n if (!isCSV) {\n // If first batch with no docs, output empty array; otherwise just close\n this.push(encoder.encode(isFirstBatch ? '[]' : ']'))\n }\n this.push(null)\n return\n }\n\n if (isCSV) {\n // --- CSV Streaming ---\n const batchRows = result.docs.map((doc) =>\n filterDisabledCSV(flattenObject({ doc, fields, toCSVFunctions })),\n )\n\n // On first batch, discover additional columns from data and merge with schema\n if (!columnsFinalized) {\n const dataColumns: string[] = []\n const seenCols = new Set<string>()\n for (const row of batchRows) {\n for (const key of Object.keys(row)) {\n if (!seenCols.has(key)) {\n seenCols.add(key)\n dataColumns.push(key)\n }\n }\n }\n // Merge schema columns with data-discovered columns\n allColumns = mergeColumns(schemaColumns, dataColumns)\n columnsFinalized = true\n\n if (debug) {\n req.payload.logger.debug({\n dataColumnsCount: dataColumns.length,\n finalColumnsCount: allColumns.length,\n msg: 'Merged schema and data columns',\n })\n }\n }\n\n const paddedRows = batchRows.map((row) => {\n const fullRow: Record<string, unknown> = {}\n for (const col of allColumns) {\n fullRow[col] = row[col] ?? ''\n }\n return fullRow\n })\n\n const csvString = stringify(paddedRows, {\n header: isFirstBatch,\n columns: allColumns,\n })\n\n this.push(encoder.encode(csvString))\n } else {\n // --- JSON Streaming ---\n const batchRows = result.docs.map((doc) => filterDisabledJSON(doc))\n\n // Convert each filtered/flattened row into JSON string\n const batchJSON = batchRows.map((row) => JSON.stringify(row)).join(',')\n\n if (isFirstBatch) {\n this.push(encoder.encode('[' + batchJSON))\n } else {\n this.push(encoder.encode(',' + batchJSON))\n }\n }\n\n fetched += result.docs.length\n isFirstBatch = false\n streamPage += 1 // Increment stream page for the next batch\n\n if (!result.hasNextPage || fetched >= maxDocs) {\n if (debug) {\n req.payload.logger.debug('Stream complete - no more pages')\n }\n if (!isCSV) {\n this.push(encoder.encode(']'))\n }\n this.push(null) // End the stream\n }\n },\n })\n\n return new Response(Readable.toWeb(stream) as ReadableStream, {\n headers: {\n 'Content-Disposition': `attachment; filename=\"${name}\"`,\n 'Content-Type': isCSV ? 'text/csv' : 'application/json',\n },\n })\n }\n\n // Non-download path (buffered export)\n if (debug) {\n req.payload.logger.debug('Starting file generation')\n }\n\n // Create export batch processor\n const processor = createExportBatchProcessor({ batchSize, debug })\n\n // Transform function based on format\n const transformDoc = (doc: unknown) =>\n isCSV\n ? filterDisabledCSV(flattenObject({ doc, fields, toCSVFunctions }))\n : filterDisabledJSON(doc)\n\n // Skip fetching if access was denied - we'll create an empty export\n let exportResult = {\n columns: [] as string[],\n docs: [] as Record<string, unknown>[],\n fetchedCount: 0,\n }\n\n if (!accessDenied) {\n exportResult = await processor.processExport({\n collectionSlug,\n findArgs: findArgs as ExportFindArgs,\n format,\n maxDocs: typeof hardLimit === 'number' ? hardLimit : Number.POSITIVE_INFINITY,\n req,\n startPage: adjustedPage,\n transformDoc,\n })\n }\n\n const { columns: dataColumns, docs: rows } = exportResult\n const outputData: string[] = []\n\n // Prepare final output\n if (isCSV) {\n // Get schema-based columns for consistent ordering\n const localeCodes =\n locale === 'all' && payload.config.localization\n ? payload.config.localization.localeCodes\n : undefined\n\n const schemaColumns = getSchemaColumns({\n collectionConfig,\n disabledFields,\n fields,\n locale,\n localeCodes,\n })\n\n // Merge schema columns with data-discovered columns\n // Schema provides ordering, data provides additional columns (e.g., array indices > 0)\n const finalColumns = mergeColumns(schemaColumns, dataColumns)\n\n const paddedRows = rows.map((row) => {\n const fullRow: Record<string, unknown> = {}\n for (const col of finalColumns) {\n fullRow[col] = row[col] ?? ''\n }\n return fullRow\n })\n\n // Always output CSV with header, even if empty\n outputData.push(\n stringify(paddedRows, {\n header: true,\n columns: finalColumns,\n }),\n )\n } else {\n // JSON format\n outputData.push(rows.map((doc) => JSON.stringify(doc)).join(',\\n'))\n }\n\n // Ensure we always have valid content for the file\n // For JSON, empty exports produce \"[]\"\n // For CSV, if completely empty (no columns, no rows), produce at least a newline to ensure file creation\n const content = format === 'json' ? `[${outputData.join(',')}]` : outputData.join('')\n const buffer = Buffer.from(content.length > 0 ? content : '\\n')\n if (debug) {\n req.payload.logger.debug(`${format} file generation complete`)\n }\n\n if (!id) {\n if (debug) {\n req.payload.logger.debug('Creating new export file')\n }\n req.file = {\n name,\n data: buffer,\n mimetype: isCSV ? 'text/csv' : 'application/json',\n size: buffer.length,\n }\n } else {\n if (debug) {\n req.payload.logger.debug(`Updating existing export with id: ${id}`)\n }\n await req.payload.update({\n id,\n collection: exportsCollection,\n data: {},\n file: {\n name,\n data: buffer,\n mimetype: isCSV ? 'text/csv' : 'application/json',\n size: buffer.length,\n },\n // Override access only here so that we can be sure the export collection itself is updated as expected\n overrideAccess: true,\n req,\n })\n }\n if (debug) {\n req.payload.logger.debug('Export process completed successfully')\n }\n}\n"],"names":["stringify","APIError","Readable","buildDisabledFieldRegex","flattenObject","getExportFieldFunctions","getFilename","getSchemaColumns","mergeColumns","getSelect","validateLimitValue","createExportBatchProcessor","createExport","args","id","name","nameArg","batchSize","collectionSlug","debug","download","drafts","draftsFromInput","exportsCollection","fields","format","limit","incomingLimit","locale","localeFromInput","page","req","sort","userCollection","userID","where","whereFromInput","localeFromReq","payload","logger","message","draft","collectionConfig","config","collections","find","slug","user","findByID","collection","overrideAccess","hasVersions","Boolean","versions","publishedWhere","_status","equals","and","isCSV","select","Array","isArray","length","undefined","hardLimit","totalDocs","accessDenied","countResult","count","error","totalPages","Math","max","ceil","requestedPage","adjustedPage","findArgs","depth","toCSVFunctions","flattenedFields","disabledFields","admin","custom","disabledRegexes","map","filterDisabledCSV","row","filtered","key","value","Object","entries","isDisabled","some","regex","test","filterDisabledJSON","doc","parentPath","item","currentPath","includes","limitErrorMsg","t","schemaColumns","localeCodes","localization","columnCount","msg","allColumns","columnsFinalized","encoder","TextEncoder","isFirstBatch","streamPage","fetched","maxDocs","Number","POSITIVE_INFINITY","stream","read","remaining","push","encode","result","min","docs","batchRows","dataColumns","seenCols","Set","keys","has","add","dataColumnsCount","finalColumnsCount","paddedRows","fullRow","col","csvString","header","columns","batchJSON","JSON","join","hasNextPage","Response","toWeb","headers","processor","transformDoc","exportResult","fetchedCount","processExport","startPage","rows","outputData","finalColumns","content","buffer","Buffer","from","file","data","mimetype","size","update"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/export/createExport.ts"],"sourcesContent":["/* eslint-disable perfectionist/sort-objects */\nimport type { PayloadRequest, Sort, TypedUser, Where } from 'payload'\n\nimport { stringify } from 'csv-stringify/sync'\nimport { APIError } from 'payload'\nimport { Readable } from 'stream'\n\nimport { buildDisabledFieldRegex } from '../utilities/buildDisabledFieldRegex.js'\nimport { collectTimezoneCompanionFields } from '../utilities/collectTimezoneCompanionFields.js'\nimport { flattenObject } from '../utilities/flattenObject.js'\nimport { getExportFieldFunctions } from '../utilities/getExportFieldFunctions.js'\nimport { getFilename } from '../utilities/getFilename.js'\nimport { getSchemaColumns, mergeColumns } from '../utilities/getSchemaColumns.js'\nimport { getSelect } from '../utilities/getSelect.js'\nimport { validateLimitValue } from '../utilities/validateLimitValue.js'\nimport { createExportBatchProcessor, type ExportFindArgs } from './batchProcessor.js'\n\nexport type Export = {\n /**\n * Number of documents to process in each batch during export\n * @default 100\n */\n batchSize?: number\n collectionSlug: string\n /**\n * If true, enables debug logging\n */\n debug?: boolean\n drafts?: 'no' | 'yes'\n exportCollection: string\n fields?: string[]\n format: 'csv' | 'json'\n globals?: string[]\n id: number | string\n limit?: number\n locale?: string\n /**\n * Maximum number of documents that can be exported in a single operation.\n * This value has already been resolved from the plugin config.\n */\n maxLimit?: number\n name: string\n page?: number\n slug: string\n sort: Sort\n userCollection: string\n userID: number | string\n where?: Where\n}\n\nexport type CreateExportArgs = {\n /**\n * If true, stream the file instead of saving it\n */\n download?: boolean\n req: PayloadRequest\n} & Export\n\nexport const createExport = async (args: CreateExportArgs) => {\n const {\n id,\n name: nameArg,\n batchSize = 100,\n collectionSlug,\n debug = false,\n download,\n drafts: draftsFromInput,\n exportCollection,\n fields,\n format,\n limit: incomingLimit,\n maxLimit,\n locale: localeFromInput,\n page,\n req,\n sort,\n userCollection,\n userID,\n where: whereFromInput = {},\n } = args\n const { locale: localeFromReq, payload } = req\n\n if (debug) {\n req.payload.logger.debug({\n message: 'Starting export process with args:',\n collectionSlug,\n draft: draftsFromInput,\n fields,\n format,\n })\n }\n\n const locale = localeFromInput ?? localeFromReq\n const collectionConfig = payload.config.collections.find(({ slug }) => slug === collectionSlug)\n\n if (!collectionConfig) {\n throw new APIError(`Collection with slug ${collectionSlug} not found.`)\n }\n\n let user: TypedUser | undefined\n\n if (userCollection && userID) {\n user = (await req.payload.findByID({\n id: userID,\n collection: userCollection,\n overrideAccess: true,\n })) as TypedUser\n }\n\n if (!user && req.user) {\n user = req?.user?.id ? req.user : req?.user?.user\n }\n\n if (!user) {\n throw new APIError('User authentication is required to create exports.')\n }\n\n const draft = draftsFromInput === 'yes'\n const hasVersions = Boolean(collectionConfig.versions)\n\n // Only filter by _status for versioned collections\n const publishedWhere: Where = hasVersions ? { _status: { equals: 'published' } } : {}\n\n const where: Where = {\n and: [whereFromInput, draft ? {} : publishedWhere],\n }\n\n const name = `${nameArg ?? `${getFilename()}-${collectionSlug}`}.${format}`\n const isCSV = format === 'csv'\n const select = Array.isArray(fields) && fields.length > 0 ? getSelect(fields) : undefined\n\n if (debug) {\n req.payload.logger.debug({ message: 'Export configuration:', name, isCSV, locale })\n }\n\n // Determine maximum export documents:\n // 1. If maxLimit is defined, it sets the absolute ceiling\n // 2. User's limit is applied but clamped to maxLimit if it exceeds it\n let maxExportDocuments: number | undefined\n\n if (typeof maxLimit === 'number' && maxLimit > 0) {\n if (typeof incomingLimit === 'number' && incomingLimit > 0) {\n // User provided a limit - clamp it to maxLimit\n maxExportDocuments = Math.min(incomingLimit, maxLimit)\n } else {\n // No user limit - use maxLimit as the ceiling\n maxExportDocuments = maxLimit\n }\n } else {\n // No maxLimit - use user's limit if provided\n maxExportDocuments =\n typeof incomingLimit === 'number' && incomingLimit > 0 ? incomingLimit : undefined\n }\n\n // Try to count documents - if access is denied, treat as 0 documents\n let totalDocs = 0\n let accessDenied = false\n try {\n const countResult = await payload.count({\n collection: collectionSlug,\n user,\n locale,\n overrideAccess: false,\n })\n totalDocs = countResult.totalDocs\n } catch (error) {\n // Access denied - user can't read from this collection\n // We'll create an empty export file\n accessDenied = true\n if (debug) {\n req.payload.logger.debug({\n message: 'Access denied for collection, creating empty export',\n collectionSlug,\n })\n }\n }\n\n const totalPages = Math.max(1, Math.ceil(totalDocs / batchSize))\n const requestedPage = page || 1\n const adjustedPage = requestedPage > totalPages ? 1 : requestedPage\n\n const findArgs = {\n collection: collectionSlug,\n depth: 1,\n draft,\n limit: batchSize,\n locale,\n overrideAccess: false,\n page: 0,\n select,\n sort,\n user,\n where,\n }\n\n if (debug) {\n req.payload.logger.debug({ message: 'Find arguments:', findArgs })\n }\n\n const toCSVFunctions = getExportFieldFunctions({\n fields: collectionConfig.flattenedFields,\n })\n\n // Collect auto-generated timezone companion fields from schema\n const timezoneCompanionFields = collectTimezoneCompanionFields(collectionConfig.flattenedFields)\n\n const disabledFields =\n collectionConfig.admin?.custom?.['plugin-import-export']?.disabledFields ?? []\n\n const disabledMatchers = disabledFields.map(buildDisabledFieldRegex)\n\n const filterDisabledCSV = (row: Record<string, unknown>): Record<string, unknown> => {\n const filtered: Record<string, unknown> = {}\n\n for (const [key, value] of Object.entries(row)) {\n const isDisabled = disabledMatchers.some((matcher) => matcher.test(key))\n if (!isDisabled) {\n filtered[key] = value\n }\n }\n\n return filtered\n }\n\n const filterDisabledJSON = (doc: any, parentPath = ''): any => {\n if (Array.isArray(doc)) {\n return doc.map((item) => filterDisabledJSON(item, parentPath))\n }\n\n if (typeof doc !== 'object' || doc === null) {\n return doc\n }\n\n const filtered: Record<string, any> = {}\n for (const [key, value] of Object.entries(doc)) {\n const currentPath = parentPath ? `${parentPath}.${key}` : key\n\n // Only remove if this exact path is disabled\n const isDisabled = disabledFields.includes(currentPath)\n\n if (!isDisabled) {\n filtered[key] = filterDisabledJSON(value, currentPath)\n }\n }\n\n return filtered\n }\n\n if (download) {\n const limitErrorMsg = validateLimitValue(incomingLimit, req.t)\n if (limitErrorMsg) {\n throw new APIError(limitErrorMsg)\n }\n\n // Get schema-based columns first (provides base ordering and handles empty exports)\n let schemaColumns: string[] = []\n if (isCSV) {\n const localeCodes =\n locale === 'all' && payload.config.localization\n ? payload.config.localization.localeCodes\n : undefined\n\n schemaColumns = getSchemaColumns({\n collectionConfig,\n disabledFields,\n fields,\n locale,\n localeCodes,\n timezoneCompanionFields,\n })\n\n if (debug) {\n req.payload.logger.debug({\n columnCount: schemaColumns.length,\n msg: 'Schema-based column inference complete',\n })\n }\n }\n\n // allColumns will be finalized after first batch (schema + data columns merged)\n let allColumns: string[] = []\n let columnsFinalized = false\n\n const encoder = new TextEncoder()\n let isFirstBatch = true\n let currentBatchPage = adjustedPage\n let fetched = 0\n const maxDocs =\n typeof maxExportDocuments === 'number' ? maxExportDocuments : Number.POSITIVE_INFINITY\n\n const stream = new Readable({\n async read() {\n const remaining = Math.max(0, maxDocs - fetched)\n\n if (remaining === 0) {\n if (!isCSV) {\n // If first batch with no remaining, output empty array; otherwise just close\n this.push(encoder.encode(isFirstBatch ? '[]' : ']'))\n }\n this.push(null)\n return\n }\n\n const result = await payload.find({\n ...findArgs,\n page: currentBatchPage,\n limit: Math.min(batchSize, remaining),\n })\n\n if (debug) {\n req.payload.logger.debug(\n `Streaming batch ${currentBatchPage} with ${result.docs.length} docs`,\n )\n }\n\n if (result.docs.length === 0) {\n // Close JSON array properly if JSON\n if (!isCSV) {\n // If first batch with no docs, output empty array; otherwise just close\n this.push(encoder.encode(isFirstBatch ? '[]' : ']'))\n }\n this.push(null)\n return\n }\n\n if (isCSV) {\n // --- CSV Streaming ---\n const batchRows = result.docs.map((doc) =>\n filterDisabledCSV(\n flattenObject({ doc, fields, timezoneCompanionFields, toCSVFunctions }),\n ),\n )\n\n // On first batch, discover additional columns from data and merge with schema\n if (!columnsFinalized) {\n const dataColumns: string[] = []\n const seenCols = new Set<string>()\n for (const row of batchRows) {\n for (const key of Object.keys(row)) {\n if (!seenCols.has(key)) {\n seenCols.add(key)\n dataColumns.push(key)\n }\n }\n }\n // Merge schema columns with data-discovered columns\n allColumns = mergeColumns(schemaColumns, dataColumns)\n columnsFinalized = true\n\n if (debug) {\n req.payload.logger.debug({\n dataColumnsCount: dataColumns.length,\n finalColumnsCount: allColumns.length,\n msg: 'Merged schema and data columns',\n })\n }\n }\n\n const paddedRows = batchRows.map((row) => {\n const fullRow: Record<string, unknown> = {}\n for (const col of allColumns) {\n fullRow[col] = row[col] ?? ''\n }\n return fullRow\n })\n\n const csvString = stringify(paddedRows, {\n bom: isFirstBatch,\n header: isFirstBatch,\n columns: allColumns,\n })\n\n this.push(encoder.encode(csvString))\n } else {\n // --- JSON Streaming ---\n const batchRows = result.docs.map((doc) => filterDisabledJSON(doc))\n\n // Convert each filtered/flattened row into JSON string\n const batchJSON = batchRows.map((row) => JSON.stringify(row)).join(',')\n\n if (isFirstBatch) {\n this.push(encoder.encode('[' + batchJSON))\n } else {\n this.push(encoder.encode(',' + batchJSON))\n }\n }\n\n fetched += result.docs.length\n isFirstBatch = false\n currentBatchPage += 1\n\n if (!result.hasNextPage || fetched >= maxDocs) {\n if (debug) {\n req.payload.logger.debug('Stream complete - no more pages')\n }\n if (!isCSV) {\n this.push(encoder.encode(']'))\n }\n this.push(null) // End the stream\n }\n },\n })\n\n return new Response(Readable.toWeb(stream) as ReadableStream, {\n headers: {\n 'Content-Disposition': `attachment; filename=\"${name}\"`,\n 'Content-Type': isCSV ? 'text/csv' : 'application/json',\n },\n })\n }\n\n // Non-download path (buffered export)\n if (debug) {\n req.payload.logger.debug('Starting file generation')\n }\n\n // Create export batch processor\n const processor = createExportBatchProcessor({ batchSize, debug })\n\n // Transform function based on format\n const transformDoc = (doc: unknown) =>\n isCSV\n ? filterDisabledCSV(flattenObject({ doc, fields, timezoneCompanionFields, toCSVFunctions }))\n : filterDisabledJSON(doc)\n\n // Skip fetching if access was denied - we'll create an empty export\n let exportResult = {\n columns: [] as string[],\n docs: [] as Record<string, unknown>[],\n fetchedCount: 0,\n }\n\n if (!accessDenied) {\n exportResult = await processor.processExport({\n collectionSlug,\n findArgs: findArgs as ExportFindArgs,\n format,\n maxDocs:\n typeof maxExportDocuments === 'number' ? maxExportDocuments : Number.POSITIVE_INFINITY,\n req,\n startPage: adjustedPage,\n transformDoc,\n })\n }\n\n const { columns: dataColumns, docs: rows } = exportResult\n const outputData: string[] = []\n\n // Prepare final output\n if (isCSV) {\n // Get schema-based columns for consistent ordering\n const localeCodes =\n locale === 'all' && payload.config.localization\n ? payload.config.localization.localeCodes\n : undefined\n\n const schemaColumns = getSchemaColumns({\n collectionConfig,\n disabledFields,\n fields,\n locale,\n localeCodes,\n timezoneCompanionFields,\n })\n\n // Merge schema columns with data-discovered columns\n // Schema provides ordering, data provides additional columns (e.g., array indices > 0)\n const finalColumns = mergeColumns(schemaColumns, dataColumns)\n\n const paddedRows = rows.map((row) => {\n const fullRow: Record<string, unknown> = {}\n for (const col of finalColumns) {\n fullRow[col] = row[col] ?? ''\n }\n return fullRow\n })\n\n // Always output CSV with header, even if empty\n outputData.push(\n stringify(paddedRows, {\n bom: true,\n header: true,\n columns: finalColumns,\n }),\n )\n } else {\n // JSON format\n outputData.push(rows.map((doc) => JSON.stringify(doc)).join(',\\n'))\n }\n\n // Ensure we always have valid content for the file\n // For JSON, empty exports produce \"[]\"\n // For CSV, if completely empty (no columns, no rows), produce at least a newline to ensure file creation\n const content = format === 'json' ? `[${outputData.join(',')}]` : outputData.join('')\n const buffer = Buffer.from(content.length > 0 ? content : '\\n')\n if (debug) {\n req.payload.logger.debug(`${format} file generation complete`)\n }\n\n if (!id) {\n if (debug) {\n req.payload.logger.debug('Creating new export file')\n }\n req.file = {\n name,\n data: buffer,\n mimetype: isCSV ? 'text/csv' : 'application/json',\n size: buffer.length,\n }\n } else {\n if (debug) {\n req.payload.logger.debug(`Updating existing export with id: ${id}`)\n }\n await req.payload.update({\n id,\n collection: exportCollection,\n data: {},\n file: {\n name,\n data: buffer,\n mimetype: isCSV ? 'text/csv' : 'application/json',\n size: buffer.length,\n },\n // Override access only here so that we can be sure the export collection itself is updated as expected\n overrideAccess: true,\n req,\n })\n }\n if (debug) {\n req.payload.logger.debug('Export process completed successfully')\n }\n}\n"],"names":["stringify","APIError","Readable","buildDisabledFieldRegex","collectTimezoneCompanionFields","flattenObject","getExportFieldFunctions","getFilename","getSchemaColumns","mergeColumns","getSelect","validateLimitValue","createExportBatchProcessor","createExport","args","id","name","nameArg","batchSize","collectionSlug","debug","download","drafts","draftsFromInput","exportCollection","fields","format","limit","incomingLimit","maxLimit","locale","localeFromInput","page","req","sort","userCollection","userID","where","whereFromInput","localeFromReq","payload","logger","message","draft","collectionConfig","config","collections","find","slug","user","findByID","collection","overrideAccess","hasVersions","Boolean","versions","publishedWhere","_status","equals","and","isCSV","select","Array","isArray","length","undefined","maxExportDocuments","Math","min","totalDocs","accessDenied","countResult","count","error","totalPages","max","ceil","requestedPage","adjustedPage","findArgs","depth","toCSVFunctions","flattenedFields","timezoneCompanionFields","disabledFields","admin","custom","disabledMatchers","map","filterDisabledCSV","row","filtered","key","value","Object","entries","isDisabled","some","matcher","test","filterDisabledJSON","doc","parentPath","item","currentPath","includes","limitErrorMsg","t","schemaColumns","localeCodes","localization","columnCount","msg","allColumns","columnsFinalized","encoder","TextEncoder","isFirstBatch","currentBatchPage","fetched","maxDocs","Number","POSITIVE_INFINITY","stream","read","remaining","push","encode","result","docs","batchRows","dataColumns","seenCols","Set","keys","has","add","dataColumnsCount","finalColumnsCount","paddedRows","fullRow","col","csvString","bom","header","columns","batchJSON","JSON","join","hasNextPage","Response","toWeb","headers","processor","transformDoc","exportResult","fetchedCount","processExport","startPage","rows","outputData","finalColumns","content","buffer","Buffer","from","file","data","mimetype","size","update"],"mappings":"AAAA,6CAA6C,GAG7C,SAASA,SAAS,QAAQ,qBAAoB;AAC9C,SAASC,QAAQ,QAAQ,UAAS;AAClC,SAASC,QAAQ,QAAQ,SAAQ;AAEjC,SAASC,uBAAuB,QAAQ,0CAAyC;AACjF,SAASC,8BAA8B,QAAQ,iDAAgD;AAC/F,SAASC,aAAa,QAAQ,gCAA+B;AAC7D,SAASC,uBAAuB,QAAQ,0CAAyC;AACjF,SAASC,WAAW,QAAQ,8BAA6B;AACzD,SAASC,gBAAgB,EAAEC,YAAY,QAAQ,mCAAkC;AACjF,SAASC,SAAS,QAAQ,4BAA2B;AACrD,SAASC,kBAAkB,QAAQ,qCAAoC;AACvE,SAASC,0BAA0B,QAA6B,sBAAqB;AA2CrF,OAAO,MAAMC,eAAe,OAAOC;IACjC,MAAM,EACJC,EAAE,EACFC,MAAMC,OAAO,EACbC,YAAY,GAAG,EACfC,cAAc,EACdC,QAAQ,KAAK,EACbC,QAAQ,EACRC,QAAQC,eAAe,EACvBC,gBAAgB,EAChBC,MAAM,EACNC,MAAM,EACNC,OAAOC,aAAa,EACpBC,QAAQ,EACRC,QAAQC,eAAe,EACvBC,IAAI,EACJC,GAAG,EACHC,IAAI,EACJC,cAAc,EACdC,MAAM,EACNC,OAAOC,iBAAiB,CAAC,CAAC,EAC3B,GAAGxB;IACJ,MAAM,EAAEgB,QAAQS,aAAa,EAAEC,OAAO,EAAE,GAAGP;IAE3C,IAAIb,OAAO;QACTa,IAAIO,OAAO,CAACC,MAAM,CAACrB,KAAK,CAAC;YACvBsB,SAAS;YACTvB;YACAwB,OAAOpB;YACPE;YACAC;QACF;IACF;IAEA,MAAMI,SAASC,mBAAmBQ;IAClC,MAAMK,mBAAmBJ,QAAQK,MAAM,CAACC,WAAW,CAACC,IAAI,CAAC,CAAC,EAAEC,IAAI,EAAE,GAAKA,SAAS7B;IAEhF,IAAI,CAACyB,kBAAkB;QACrB,MAAM,IAAI3C,SAAS,CAAC,qBAAqB,EAAEkB,eAAe,WAAW,CAAC;IACxE;IAEA,IAAI8B;IAEJ,IAAId,kBAAkBC,QAAQ;QAC5Ba,OAAQ,MAAMhB,IAAIO,OAAO,CAACU,QAAQ,CAAC;YACjCnC,IAAIqB;YACJe,YAAYhB;YACZiB,gBAAgB;QAClB;IACF;IAEA,IAAI,CAACH,QAAQhB,IAAIgB,IAAI,EAAE;QACrBA,OAAOhB,KAAKgB,MAAMlC,KAAKkB,IAAIgB,IAAI,GAAGhB,KAAKgB,MAAMA;IAC/C;IAEA,IAAI,CAACA,MAAM;QACT,MAAM,IAAIhD,SAAS;IACrB;IAEA,MAAM0C,QAAQpB,oBAAoB;IAClC,MAAM8B,cAAcC,QAAQV,iBAAiBW,QAAQ;IAErD,mDAAmD;IACnD,MAAMC,iBAAwBH,cAAc;QAAEI,SAAS;YAAEC,QAAQ;QAAY;IAAE,IAAI,CAAC;IAEpF,MAAMrB,QAAe;QACnBsB,KAAK;YAACrB;YAAgBK,QAAQ,CAAC,IAAIa;SAAe;IACpD;IAEA,MAAMxC,OAAO,GAAGC,WAAW,GAAGV,cAAc,CAAC,EAAEY,gBAAgB,CAAC,CAAC,EAAEO,QAAQ;IAC3E,MAAMkC,QAAQlC,WAAW;IACzB,MAAMmC,SAASC,MAAMC,OAAO,CAACtC,WAAWA,OAAOuC,MAAM,GAAG,IAAItD,UAAUe,UAAUwC;IAEhF,IAAI7C,OAAO;QACTa,IAAIO,OAAO,CAACC,MAAM,CAACrB,KAAK,CAAC;YAAEsB,SAAS;YAAyB1B;YAAM4C;YAAO9B;QAAO;IACnF;IAEA,sCAAsC;IACtC,0DAA0D;IAC1D,sEAAsE;IACtE,IAAIoC;IAEJ,IAAI,OAAOrC,aAAa,YAAYA,WAAW,GAAG;QAChD,IAAI,OAAOD,kBAAkB,YAAYA,gBAAgB,GAAG;YAC1D,+CAA+C;YAC/CsC,qBAAqBC,KAAKC,GAAG,CAACxC,eAAeC;QAC/C,OAAO;YACL,8CAA8C;YAC9CqC,qBAAqBrC;QACvB;IACF,OAAO;QACL,6CAA6C;QAC7CqC,qBACE,OAAOtC,kBAAkB,YAAYA,gBAAgB,IAAIA,gBAAgBqC;IAC7E;IAEA,qEAAqE;IACrE,IAAII,YAAY;IAChB,IAAIC,eAAe;IACnB,IAAI;QACF,MAAMC,cAAc,MAAM/B,QAAQgC,KAAK,CAAC;YACtCrB,YAAYhC;YACZ8B;YACAnB;YACAsB,gBAAgB;QAClB;QACAiB,YAAYE,YAAYF,SAAS;IACnC,EAAE,OAAOI,OAAO;QACd,uDAAuD;QACvD,oCAAoC;QACpCH,eAAe;QACf,IAAIlD,OAAO;YACTa,IAAIO,OAAO,CAACC,MAAM,CAACrB,KAAK,CAAC;gBACvBsB,SAAS;gBACTvB;YACF;QACF;IACF;IAEA,MAAMuD,aAAaP,KAAKQ,GAAG,CAAC,GAAGR,KAAKS,IAAI,CAACP,YAAYnD;IACrD,MAAM2D,gBAAgB7C,QAAQ;IAC9B,MAAM8C,eAAeD,gBAAgBH,aAAa,IAAIG;IAEtD,MAAME,WAAW;QACf5B,YAAYhC;QACZ6D,OAAO;QACPrC;QACAhB,OAAOT;QACPY;QACAsB,gBAAgB;QAChBpB,MAAM;QACN6B;QACA3B;QACAe;QACAZ;IACF;IAEA,IAAIjB,OAAO;QACTa,IAAIO,OAAO,CAACC,MAAM,CAACrB,KAAK,CAAC;YAAEsB,SAAS;YAAmBqC;QAAS;IAClE;IAEA,MAAME,iBAAiB3E,wBAAwB;QAC7CmB,QAAQmB,iBAAiBsC,eAAe;IAC1C;IAEA,+DAA+D;IAC/D,MAAMC,0BAA0B/E,+BAA+BwC,iBAAiBsC,eAAe;IAE/F,MAAME,iBACJxC,iBAAiByC,KAAK,EAAEC,QAAQ,CAAC,uBAAuB,EAAEF,kBAAkB,EAAE;IAEhF,MAAMG,mBAAmBH,eAAeI,GAAG,CAACrF;IAE5C,MAAMsF,oBAAoB,CAACC;QACzB,MAAMC,WAAoC,CAAC;QAE3C,KAAK,MAAM,CAACC,KAAKC,MAAM,IAAIC,OAAOC,OAAO,CAACL,KAAM;YAC9C,MAAMM,aAAaT,iBAAiBU,IAAI,CAAC,CAACC,UAAYA,QAAQC,IAAI,CAACP;YACnE,IAAI,CAACI,YAAY;gBACfL,QAAQ,CAACC,IAAI,GAAGC;YAClB;QACF;QAEA,OAAOF;IACT;IAEA,MAAMS,qBAAqB,CAACC,KAAUC,aAAa,EAAE;QACnD,IAAIxC,MAAMC,OAAO,CAACsC,MAAM;YACtB,OAAOA,IAAIb,GAAG,CAAC,CAACe,OAASH,mBAAmBG,MAAMD;QACpD;QAEA,IAAI,OAAOD,QAAQ,YAAYA,QAAQ,MAAM;YAC3C,OAAOA;QACT;QAEA,MAAMV,WAAgC,CAAC;QACvC,KAAK,MAAM,CAACC,KAAKC,MAAM,IAAIC,OAAOC,OAAO,CAACM,KAAM;YAC9C,MAAMG,cAAcF,aAAa,GAAGA,WAAW,CAAC,EAAEV,KAAK,GAAGA;YAE1D,6CAA6C;YAC7C,MAAMI,aAAaZ,eAAeqB,QAAQ,CAACD;YAE3C,IAAI,CAACR,YAAY;gBACfL,QAAQ,CAACC,IAAI,GAAGQ,mBAAmBP,OAAOW;YAC5C;QACF;QAEA,OAAOb;IACT;IAEA,IAAItE,UAAU;QACZ,MAAMqF,gBAAgB/F,mBAAmBiB,eAAeK,IAAI0E,CAAC;QAC7D,IAAID,eAAe;YACjB,MAAM,IAAIzG,SAASyG;QACrB;QAEA,oFAAoF;QACpF,IAAIE,gBAA0B,EAAE;QAChC,IAAIhD,OAAO;YACT,MAAMiD,cACJ/E,WAAW,SAASU,QAAQK,MAAM,CAACiE,YAAY,GAC3CtE,QAAQK,MAAM,CAACiE,YAAY,CAACD,WAAW,GACvC5C;YAEN2C,gBAAgBpG,iBAAiB;gBAC/BoC;gBACAwC;gBACA3D;gBACAK;gBACA+E;gBACA1B;YACF;YAEA,IAAI/D,OAAO;gBACTa,IAAIO,OAAO,CAACC,MAAM,CAACrB,KAAK,CAAC;oBACvB2F,aAAaH,cAAc5C,MAAM;oBACjCgD,KAAK;gBACP;YACF;QACF;QAEA,gFAAgF;QAChF,IAAIC,aAAuB,EAAE;QAC7B,IAAIC,mBAAmB;QAEvB,MAAMC,UAAU,IAAIC;QACpB,IAAIC,eAAe;QACnB,IAAIC,mBAAmBxC;QACvB,IAAIyC,UAAU;QACd,MAAMC,UACJ,OAAOtD,uBAAuB,WAAWA,qBAAqBuD,OAAOC,iBAAiB;QAExF,MAAMC,SAAS,IAAIzH,SAAS;YAC1B,MAAM0H;gBACJ,MAAMC,YAAY1D,KAAKQ,GAAG,CAAC,GAAG6C,UAAUD;gBAExC,IAAIM,cAAc,GAAG;oBACnB,IAAI,CAACjE,OAAO;wBACV,6EAA6E;wBAC7E,IAAI,CAACkE,IAAI,CAACX,QAAQY,MAAM,CAACV,eAAe,OAAO;oBACjD;oBACA,IAAI,CAACS,IAAI,CAAC;oBACV;gBACF;gBAEA,MAAME,SAAS,MAAMxF,QAAQO,IAAI,CAAC;oBAChC,GAAGgC,QAAQ;oBACX/C,MAAMsF;oBACN3F,OAAOwC,KAAKC,GAAG,CAAClD,WAAW2G;gBAC7B;gBAEA,IAAIzG,OAAO;oBACTa,IAAIO,OAAO,CAACC,MAAM,CAACrB,KAAK,CACtB,CAAC,gBAAgB,EAAEkG,iBAAiB,MAAM,EAAEU,OAAOC,IAAI,CAACjE,MAAM,CAAC,KAAK,CAAC;gBAEzE;gBAEA,IAAIgE,OAAOC,IAAI,CAACjE,MAAM,KAAK,GAAG;oBAC5B,oCAAoC;oBACpC,IAAI,CAACJ,OAAO;wBACV,wEAAwE;wBACxE,IAAI,CAACkE,IAAI,CAACX,QAAQY,MAAM,CAACV,eAAe,OAAO;oBACjD;oBACA,IAAI,CAACS,IAAI,CAAC;oBACV;gBACF;gBAEA,IAAIlE,OAAO;oBACT,wBAAwB;oBACxB,MAAMsE,YAAYF,OAAOC,IAAI,CAACzC,GAAG,CAAC,CAACa,MACjCZ,kBACEpF,cAAc;4BAAEgG;4BAAK5E;4BAAQ0D;4BAAyBF;wBAAe;oBAIzE,8EAA8E;oBAC9E,IAAI,CAACiC,kBAAkB;wBACrB,MAAMiB,cAAwB,EAAE;wBAChC,MAAMC,WAAW,IAAIC;wBACrB,KAAK,MAAM3C,OAAOwC,UAAW;4BAC3B,KAAK,MAAMtC,OAAOE,OAAOwC,IAAI,CAAC5C,KAAM;gCAClC,IAAI,CAAC0C,SAASG,GAAG,CAAC3C,MAAM;oCACtBwC,SAASI,GAAG,CAAC5C;oCACbuC,YAAYL,IAAI,CAAClC;gCACnB;4BACF;wBACF;wBACA,oDAAoD;wBACpDqB,aAAaxG,aAAamG,eAAeuB;wBACzCjB,mBAAmB;wBAEnB,IAAI9F,OAAO;4BACTa,IAAIO,OAAO,CAACC,MAAM,CAACrB,KAAK,CAAC;gCACvBqH,kBAAkBN,YAAYnE,MAAM;gCACpC0E,mBAAmBzB,WAAWjD,MAAM;gCACpCgD,KAAK;4BACP;wBACF;oBACF;oBAEA,MAAM2B,aAAaT,UAAU1C,GAAG,CAAC,CAACE;wBAChC,MAAMkD,UAAmC,CAAC;wBAC1C,KAAK,MAAMC,OAAO5B,WAAY;4BAC5B2B,OAAO,CAACC,IAAI,GAAGnD,GAAG,CAACmD,IAAI,IAAI;wBAC7B;wBACA,OAAOD;oBACT;oBAEA,MAAME,YAAY9I,UAAU2I,YAAY;wBACtCI,KAAK1B;wBACL2B,QAAQ3B;wBACR4B,SAAShC;oBACX;oBAEA,IAAI,CAACa,IAAI,CAACX,QAAQY,MAAM,CAACe;gBAC3B,OAAO;oBACL,yBAAyB;oBACzB,MAAMZ,YAAYF,OAAOC,IAAI,CAACzC,GAAG,CAAC,CAACa,MAAQD,mBAAmBC;oBAE9D,uDAAuD;oBACvD,MAAM6C,YAAYhB,UAAU1C,GAAG,CAAC,CAACE,MAAQyD,KAAKnJ,SAAS,CAAC0F,MAAM0D,IAAI,CAAC;oBAEnE,IAAI/B,cAAc;wBAChB,IAAI,CAACS,IAAI,CAACX,QAAQY,MAAM,CAAC,MAAMmB;oBACjC,OAAO;wBACL,IAAI,CAACpB,IAAI,CAACX,QAAQY,MAAM,CAAC,MAAMmB;oBACjC;gBACF;gBAEA3B,WAAWS,OAAOC,IAAI,CAACjE,MAAM;gBAC7BqD,eAAe;gBACfC,oBAAoB;gBAEpB,IAAI,CAACU,OAAOqB,WAAW,IAAI9B,WAAWC,SAAS;oBAC7C,IAAIpG,OAAO;wBACTa,IAAIO,OAAO,CAACC,MAAM,CAACrB,KAAK,CAAC;oBAC3B;oBACA,IAAI,CAACwC,OAAO;wBACV,IAAI,CAACkE,IAAI,CAACX,QAAQY,MAAM,CAAC;oBAC3B;oBACA,IAAI,CAACD,IAAI,CAAC,OAAM,iBAAiB;gBACnC;YACF;QACF;QAEA,OAAO,IAAIwB,SAASpJ,SAASqJ,KAAK,CAAC5B,SAA2B;YAC5D6B,SAAS;gBACP,uBAAuB,CAAC,sBAAsB,EAAExI,KAAK,CAAC,CAAC;gBACvD,gBAAgB4C,QAAQ,aAAa;YACvC;QACF;IACF;IAEA,sCAAsC;IACtC,IAAIxC,OAAO;QACTa,IAAIO,OAAO,CAACC,MAAM,CAACrB,KAAK,CAAC;IAC3B;IAEA,gCAAgC;IAChC,MAAMqI,YAAY7I,2BAA2B;QAAEM;QAAWE;IAAM;IAEhE,qCAAqC;IACrC,MAAMsI,eAAe,CAACrD,MACpBzC,QACI6B,kBAAkBpF,cAAc;YAAEgG;YAAK5E;YAAQ0D;YAAyBF;QAAe,MACvFmB,mBAAmBC;IAEzB,oEAAoE;IACpE,IAAIsD,eAAe;QACjBV,SAAS,EAAE;QACXhB,MAAM,EAAE;QACR2B,cAAc;IAChB;IAEA,IAAI,CAACtF,cAAc;QACjBqF,eAAe,MAAMF,UAAUI,aAAa,CAAC;YAC3C1I;YACA4D,UAAUA;YACVrD;YACA8F,SACE,OAAOtD,uBAAuB,WAAWA,qBAAqBuD,OAAOC,iBAAiB;YACxFzF;YACA6H,WAAWhF;YACX4E;QACF;IACF;IAEA,MAAM,EAAET,SAASd,WAAW,EAAEF,MAAM8B,IAAI,EAAE,GAAGJ;IAC7C,MAAMK,aAAuB,EAAE;IAE/B,uBAAuB;IACvB,IAAIpG,OAAO;QACT,mDAAmD;QACnD,MAAMiD,cACJ/E,WAAW,SAASU,QAAQK,MAAM,CAACiE,YAAY,GAC3CtE,QAAQK,MAAM,CAACiE,YAAY,CAACD,WAAW,GACvC5C;QAEN,MAAM2C,gBAAgBpG,iBAAiB;YACrCoC;YACAwC;YACA3D;YACAK;YACA+E;YACA1B;QACF;QAEA,oDAAoD;QACpD,uFAAuF;QACvF,MAAM8E,eAAexJ,aAAamG,eAAeuB;QAEjD,MAAMQ,aAAaoB,KAAKvE,GAAG,CAAC,CAACE;YAC3B,MAAMkD,UAAmC,CAAC;YAC1C,KAAK,MAAMC,OAAOoB,aAAc;gBAC9BrB,OAAO,CAACC,IAAI,GAAGnD,GAAG,CAACmD,IAAI,IAAI;YAC7B;YACA,OAAOD;QACT;QAEA,+CAA+C;QAC/CoB,WAAWlC,IAAI,CACb9H,UAAU2I,YAAY;YACpBI,KAAK;YACLC,QAAQ;YACRC,SAASgB;QACX;IAEJ,OAAO;QACL,cAAc;QACdD,WAAWlC,IAAI,CAACiC,KAAKvE,GAAG,CAAC,CAACa,MAAQ8C,KAAKnJ,SAAS,CAACqG,MAAM+C,IAAI,CAAC;IAC9D;IAEA,mDAAmD;IACnD,uCAAuC;IACvC,yGAAyG;IACzG,MAAMc,UAAUxI,WAAW,SAAS,CAAC,CAAC,EAAEsI,WAAWZ,IAAI,CAAC,KAAK,CAAC,CAAC,GAAGY,WAAWZ,IAAI,CAAC;IAClF,MAAMe,SAASC,OAAOC,IAAI,CAACH,QAAQlG,MAAM,GAAG,IAAIkG,UAAU;IAC1D,IAAI9I,OAAO;QACTa,IAAIO,OAAO,CAACC,MAAM,CAACrB,KAAK,CAAC,GAAGM,OAAO,yBAAyB,CAAC;IAC/D;IAEA,IAAI,CAACX,IAAI;QACP,IAAIK,OAAO;YACTa,IAAIO,OAAO,CAACC,MAAM,CAACrB,KAAK,CAAC;QAC3B;QACAa,IAAIqI,IAAI,GAAG;YACTtJ;YACAuJ,MAAMJ;YACNK,UAAU5G,QAAQ,aAAa;YAC/B6G,MAAMN,OAAOnG,MAAM;QACrB;IACF,OAAO;QACL,IAAI5C,OAAO;YACTa,IAAIO,OAAO,CAACC,MAAM,CAACrB,KAAK,CAAC,CAAC,kCAAkC,EAAEL,IAAI;QACpE;QACA,MAAMkB,IAAIO,OAAO,CAACkI,MAAM,CAAC;YACvB3J;YACAoC,YAAY3B;YACZ+I,MAAM,CAAC;YACPD,MAAM;gBACJtJ;gBACAuJ,MAAMJ;gBACNK,UAAU5G,QAAQ,aAAa;gBAC/B6G,MAAMN,OAAOnG,MAAM;YACrB;YACA,uGAAuG;YACvGZ,gBAAgB;YAChBnB;QACF;IACF;IACA,IAAIb,OAAO;QACTa,IAAIO,OAAO,CAACC,MAAM,CAACrB,KAAK,CAAC;IAC3B;AACF,EAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"getCreateExportCollectionTask.d.ts","sourceRoot":"","sources":["../../src/export/getCreateExportCollectionTask.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAK/C;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;IACrB,cAAc,EAAE,MAAM,CAAA;CACvB,GAAG,MAAM,CAAA;AAEV,eAAO,MAAM,6BAA6B,WAChC,MAAM,KACb,UAAU,CAAC;IACZ,KAAK,EAAE,cAAc,CAAA;IACrB,MAAM,EAAE,MAAM,CAAA;CACf,CAoCA,CAAA"}
1
+ {"version":3,"file":"getCreateExportCollectionTask.d.ts","sourceRoot":"","sources":["../../src/export/getCreateExportCollectionTask.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAK/C;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;IACrB,cAAc,EAAE,MAAM,CAAA;CACvB,GAAG,MAAM,CAAA;AAEV,eAAO,MAAM,6BAA6B,WAChC,MAAM,KACb,UAAU,CAAC;IACZ,KAAK,EAAE,cAAc,CAAA;IACrB,MAAM,EAAE,MAAM,CAAA;CACf,CAwCA,CAAA"}
@@ -8,8 +8,11 @@ export const getCreateCollectionExportTask = (config)=>{
8
8
  name: 'userCollection',
9
9
  type: 'text'
10
10
  }, {
11
- name: 'exportsCollection',
11
+ name: 'exportCollection',
12
12
  type: 'text'
13
+ }, {
14
+ name: 'maxLimit',
15
+ type: 'number'
13
16
  });
14
17
  return {
15
18
  slug: 'createCollectionExport',
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/export/getCreateExportCollectionTask.ts"],"sourcesContent":["import type { Config, TaskConfig } from 'payload'\n\nimport type { Export } from './createExport.js'\n\nimport { createExport } from './createExport.js'\nimport { getFields } from './getFields.js'\n\n/**\n * Export input type for job queue serialization.\n * When exports are queued as jobs, the user must be serialized as an ID string or number\n * along with the collection name so it can be rehydrated when the job runs.\n */\nexport type ExportJobInput = {\n user: number | string\n userCollection: string\n} & Export\n\nexport const getCreateCollectionExportTask = (\n config: Config,\n): TaskConfig<{\n input: ExportJobInput\n output: object\n}> => {\n const inputSchema = getFields(config).concat(\n {\n name: 'userID',\n type: 'text',\n },\n {\n name: 'userCollection',\n type: 'text',\n },\n {\n name: 'exportsCollection',\n type: 'text',\n },\n )\n\n return {\n slug: 'createCollectionExport',\n handler: async ({ input, req }) => {\n if (!input) {\n req.payload.logger.error('No input provided to createCollectionExport task')\n\n return { output: {} }\n }\n\n await createExport({\n ...input,\n req,\n })\n\n return {\n output: {},\n }\n },\n inputSchema,\n }\n}\n"],"names":["createExport","getFields","getCreateCollectionExportTask","config","inputSchema","concat","name","type","slug","handler","input","req","payload","logger","error","output"],"mappings":"AAIA,SAASA,YAAY,QAAQ,oBAAmB;AAChD,SAASC,SAAS,QAAQ,iBAAgB;AAY1C,OAAO,MAAMC,gCAAgC,CAC3CC;IAKA,MAAMC,cAAcH,UAAUE,QAAQE,MAAM,CAC1C;QACEC,MAAM;QACNC,MAAM;IACR,GACA;QACED,MAAM;QACNC,MAAM;IACR,GACA;QACED,MAAM;QACNC,MAAM;IACR;IAGF,OAAO;QACLC,MAAM;QACNC,SAAS,OAAO,EAAEC,KAAK,EAAEC,GAAG,EAAE;YAC5B,IAAI,CAACD,OAAO;gBACVC,IAAIC,OAAO,CAACC,MAAM,CAACC,KAAK,CAAC;gBAEzB,OAAO;oBAAEC,QAAQ,CAAC;gBAAE;YACtB;YAEA,MAAMf,aAAa;gBACjB,GAAGU,KAAK;gBACRC;YACF;YAEA,OAAO;gBACLI,QAAQ,CAAC;YACX;QACF;QACAX;IACF;AACF,EAAC"}
1
+ {"version":3,"sources":["../../src/export/getCreateExportCollectionTask.ts"],"sourcesContent":["import type { Config, TaskConfig } from 'payload'\n\nimport type { Export } from './createExport.js'\n\nimport { createExport } from './createExport.js'\nimport { getFields } from './getFields.js'\n\n/**\n * Export input type for job queue serialization.\n * When exports are queued as jobs, the user must be serialized as an ID string or number\n * along with the collection name so it can be rehydrated when the job runs.\n */\nexport type ExportJobInput = {\n user: number | string\n userCollection: string\n} & Export\n\nexport const getCreateCollectionExportTask = (\n config: Config,\n): TaskConfig<{\n input: ExportJobInput\n output: object\n}> => {\n const inputSchema = getFields(config).concat(\n {\n name: 'userID',\n type: 'text',\n },\n {\n name: 'userCollection',\n type: 'text',\n },\n {\n name: 'exportCollection',\n type: 'text',\n },\n {\n name: 'maxLimit',\n type: 'number',\n },\n )\n\n return {\n slug: 'createCollectionExport',\n handler: async ({ input, req }) => {\n if (!input) {\n req.payload.logger.error('No input provided to createCollectionExport task')\n\n return { output: {} }\n }\n\n await createExport({\n ...input,\n req,\n })\n\n return {\n output: {},\n }\n },\n inputSchema,\n }\n}\n"],"names":["createExport","getFields","getCreateCollectionExportTask","config","inputSchema","concat","name","type","slug","handler","input","req","payload","logger","error","output"],"mappings":"AAIA,SAASA,YAAY,QAAQ,oBAAmB;AAChD,SAASC,SAAS,QAAQ,iBAAgB;AAY1C,OAAO,MAAMC,gCAAgC,CAC3CC;IAKA,MAAMC,cAAcH,UAAUE,QAAQE,MAAM,CAC1C;QACEC,MAAM;QACNC,MAAM;IACR,GACA;QACED,MAAM;QACNC,MAAM;IACR,GACA;QACED,MAAM;QACNC,MAAM;IACR,GACA;QACED,MAAM;QACNC,MAAM;IACR;IAGF,OAAO;QACLC,MAAM;QACNC,SAAS,OAAO,EAAEC,KAAK,EAAEC,GAAG,EAAE;YAC5B,IAAI,CAACD,OAAO;gBACVC,IAAIC,OAAO,CAACC,MAAM,CAACC,KAAK,CAAC;gBAEzB,OAAO;oBAAEC,QAAQ,CAAC;gBAAE;YACtB;YAEA,MAAMf,aAAa;gBACjB,GAAGU,KAAK;gBACRC;YACF;YAEA,OAAO;gBACLI,QAAQ,CAAC;YACX;QACF;QACAX;IACF;AACF,EAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"getExportCollection.d.ts","sourceRoot":"","sources":["../../src/export/getExportCollection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,gBAAgB,EAChB,MAAM,EACP,MAAM,SAAS,CAAA;AAEhB,OAAO,KAAK,EAAE,YAAY,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA;AAQzE,eAAO,MAAM,mBAAmB,4CAI7B;IACD,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,YAAY,EAAE,wBAAwB,CAAA;CACvC,KAAG,gBAmGH,CAAA"}
1
+ {"version":3,"file":"getExportCollection.d.ts","sourceRoot":"","sources":["../../src/export/getExportCollection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,gBAAgB,EAChB,MAAM,EACP,MAAM,SAAS,CAAA;AAEhB,OAAO,KAAK,EAAE,YAAY,EAAE,wBAAwB,EAAS,MAAM,aAAa,CAAA;AAShF,eAAO,MAAM,mBAAmB,4CAI7B;IACD,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,YAAY,EAAE,wBAAwB,CAAA;CACvC,KAAG,gBA0HH,CAAA"}
@@ -1,3 +1,4 @@
1
+ import { resolveLimit } from '../utilities/resolveLimit.js';
1
2
  import { createExport } from './createExport.js';
2
3
  import { getFields } from './getFields.js';
3
4
  import { handleDownload } from './handleDownload.js';
@@ -65,11 +66,20 @@ export const getExportCollection = ({ config, exportConfig, pluginConfig })=>{
65
66
  }
66
67
  const { user } = req;
67
68
  const debug = pluginConfig.debug;
69
+ // Get max limit from the target collection's config
70
+ const exportData = args.data;
71
+ const targetCollection = req.payload.collections[exportData.collectionSlug];
72
+ const exportLimitConfig = targetCollection?.config.custom?.['plugin-import-export']?.exportLimit;
73
+ const maxLimit = await resolveLimit({
74
+ limit: exportLimitConfig,
75
+ req
76
+ });
68
77
  await createExport({
69
- ...args.data,
78
+ ...exportData,
70
79
  batchSize,
71
80
  debug,
72
- exportsCollection: collectionConfig.slug,
81
+ exportCollection: collectionConfig.slug,
82
+ maxLimit,
73
83
  req,
74
84
  userCollection: user?.collection || user?.user?.collection,
75
85
  userID: user?.id || user?.user?.id
@@ -81,10 +91,20 @@ export const getExportCollection = ({ config, exportConfig, pluginConfig })=>{
81
91
  return;
82
92
  }
83
93
  const { user } = req;
94
+ // Get max limit from the target collection's config
95
+ // For job-based exports, we resolve the limit now since function limits
96
+ // cannot be serialized. This means dynamic limits are resolved at queue time.
97
+ const targetCollection = req.payload.collections[doc.collectionSlug];
98
+ const exportLimitConfig = targetCollection?.config.custom?.['plugin-import-export']?.exportLimit;
99
+ const maxLimit = await resolveLimit({
100
+ limit: exportLimitConfig,
101
+ req
102
+ });
84
103
  const input = {
85
104
  ...doc,
86
105
  batchSize,
87
- exportsCollection: collectionConfig.slug,
106
+ exportCollection: collectionConfig.slug,
107
+ maxLimit,
88
108
  userCollection: user?.collection || user?.user?.collection,
89
109
  userID: user?.id || user?.user?.id
90
110
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/export/getExportCollection.ts"],"sourcesContent":["import type {\n CollectionAfterChangeHook,\n CollectionBeforeOperationHook,\n CollectionConfig,\n Config,\n} from 'payload'\n\nimport type { ExportConfig, ImportExportPluginConfig } from '../types.js'\nimport type { Export } from './createExport.js'\n\nimport { createExport } from './createExport.js'\nimport { getFields } from './getFields.js'\nimport { handleDownload } from './handleDownload.js'\nimport { handlePreview } from './handlePreview.js'\n\nexport const getExportCollection = ({\n config,\n exportConfig,\n pluginConfig,\n}: {\n config: Config\n exportConfig?: ExportConfig\n pluginConfig: ImportExportPluginConfig\n}): CollectionConfig => {\n const beforeOperation: CollectionBeforeOperationHook[] = []\n const afterChange: CollectionAfterChangeHook[] = []\n\n // Extract export-specific settings\n const disableDownload = exportConfig?.disableDownload ?? false\n const disableSave = exportConfig?.disableSave ?? false\n const disableJobsQueue = exportConfig?.disableJobsQueue ?? false\n const batchSize = exportConfig?.batchSize ?? 100\n const format = exportConfig?.format\n\n const collection: CollectionConfig = {\n slug: 'exports',\n access: {\n update: () => false,\n },\n admin: {\n components: {\n edit: {\n SaveButton: '@payloadcms/plugin-import-export/rsc#ExportSaveButton',\n },\n },\n custom: {\n disableDownload,\n disableSave,\n format,\n },\n disableCopyToLocale: true,\n group: false,\n useAsTitle: 'name',\n },\n disableDuplicate: true,\n endpoints: [\n {\n handler: (req) => handleDownload(req, pluginConfig.debug),\n method: 'post',\n path: '/download',\n },\n {\n handler: handlePreview,\n method: 'post',\n path: '/export-preview',\n },\n ],\n fields: getFields(config, { format }),\n hooks: {\n afterChange,\n beforeOperation,\n },\n lockDocuments: false,\n upload: {\n filesRequiredOnCreate: false,\n hideFileInputOnCreate: true,\n hideRemoveFile: true,\n },\n }\n\n if (disableJobsQueue) {\n beforeOperation.push(async ({ args, collection: collectionConfig, operation, req }) => {\n if (operation !== 'create') {\n return\n }\n const { user } = req\n const debug = pluginConfig.debug\n\n await createExport({\n ...(args.data as Export),\n batchSize,\n debug,\n exportsCollection: collectionConfig.slug,\n req,\n userCollection: user?.collection || user?.user?.collection,\n userID: user?.id || user?.user?.id,\n })\n })\n } else {\n afterChange.push(async ({ collection: collectionConfig, doc, operation, req }) => {\n if (operation !== 'create') {\n return\n }\n\n const { user } = req\n\n const input: Export = {\n ...doc,\n batchSize,\n exportsCollection: collectionConfig.slug,\n userCollection: user?.collection || user?.user?.collection,\n userID: user?.id || user?.user?.id,\n }\n\n await req.payload.jobs.queue({\n input,\n task: 'createCollectionExport',\n })\n })\n }\n\n return collection\n}\n"],"names":["createExport","getFields","handleDownload","handlePreview","getExportCollection","config","exportConfig","pluginConfig","beforeOperation","afterChange","disableDownload","disableSave","disableJobsQueue","batchSize","format","collection","slug","access","update","admin","components","edit","SaveButton","custom","disableCopyToLocale","group","useAsTitle","disableDuplicate","endpoints","handler","req","debug","method","path","fields","hooks","lockDocuments","upload","filesRequiredOnCreate","hideFileInputOnCreate","hideRemoveFile","push","args","collectionConfig","operation","user","data","exportsCollection","userCollection","userID","id","doc","input","payload","jobs","queue","task"],"mappings":"AAUA,SAASA,YAAY,QAAQ,oBAAmB;AAChD,SAASC,SAAS,QAAQ,iBAAgB;AAC1C,SAASC,cAAc,QAAQ,sBAAqB;AACpD,SAASC,aAAa,QAAQ,qBAAoB;AAElD,OAAO,MAAMC,sBAAsB,CAAC,EAClCC,MAAM,EACNC,YAAY,EACZC,YAAY,EAKb;IACC,MAAMC,kBAAmD,EAAE;IAC3D,MAAMC,cAA2C,EAAE;IAEnD,mCAAmC;IACnC,MAAMC,kBAAkBJ,cAAcI,mBAAmB;IACzD,MAAMC,cAAcL,cAAcK,eAAe;IACjD,MAAMC,mBAAmBN,cAAcM,oBAAoB;IAC3D,MAAMC,YAAYP,cAAcO,aAAa;IAC7C,MAAMC,SAASR,cAAcQ;IAE7B,MAAMC,aAA+B;QACnCC,MAAM;QACNC,QAAQ;YACNC,QAAQ,IAAM;QAChB;QACAC,OAAO;YACLC,YAAY;gBACVC,MAAM;oBACJC,YAAY;gBACd;YACF;YACAC,QAAQ;gBACNb;gBACAC;gBACAG;YACF;YACAU,qBAAqB;YACrBC,OAAO;YACPC,YAAY;QACd;QACAC,kBAAkB;QAClBC,WAAW;YACT;gBACEC,SAAS,CAACC,MAAQ5B,eAAe4B,KAAKvB,aAAawB,KAAK;gBACxDC,QAAQ;gBACRC,MAAM;YACR;YACA;gBACEJ,SAAS1B;gBACT6B,QAAQ;gBACRC,MAAM;YACR;SACD;QACDC,QAAQjC,UAAUI,QAAQ;YAAES;QAAO;QACnCqB,OAAO;YACL1B;YACAD;QACF;QACA4B,eAAe;QACfC,QAAQ;YACNC,uBAAuB;YACvBC,uBAAuB;YACvBC,gBAAgB;QAClB;IACF;IAEA,IAAI5B,kBAAkB;QACpBJ,gBAAgBiC,IAAI,CAAC,OAAO,EAAEC,IAAI,EAAE3B,YAAY4B,gBAAgB,EAAEC,SAAS,EAAEd,GAAG,EAAE;YAChF,IAAIc,cAAc,UAAU;gBAC1B;YACF;YACA,MAAM,EAAEC,IAAI,EAAE,GAAGf;YACjB,MAAMC,QAAQxB,aAAawB,KAAK;YAEhC,MAAM/B,aAAa;gBACjB,GAAI0C,KAAKI,IAAI;gBACbjC;gBACAkB;gBACAgB,mBAAmBJ,iBAAiB3B,IAAI;gBACxCc;gBACAkB,gBAAgBH,MAAM9B,cAAc8B,MAAMA,MAAM9B;gBAChDkC,QAAQJ,MAAMK,MAAML,MAAMA,MAAMK;YAClC;QACF;IACF,OAAO;QACLzC,YAAYgC,IAAI,CAAC,OAAO,EAAE1B,YAAY4B,gBAAgB,EAAEQ,GAAG,EAAEP,SAAS,EAAEd,GAAG,EAAE;YAC3E,IAAIc,cAAc,UAAU;gBAC1B;YACF;YAEA,MAAM,EAAEC,IAAI,EAAE,GAAGf;YAEjB,MAAMsB,QAAgB;gBACpB,GAAGD,GAAG;gBACNtC;gBACAkC,mBAAmBJ,iBAAiB3B,IAAI;gBACxCgC,gBAAgBH,MAAM9B,cAAc8B,MAAMA,MAAM9B;gBAChDkC,QAAQJ,MAAMK,MAAML,MAAMA,MAAMK;YAClC;YAEA,MAAMpB,IAAIuB,OAAO,CAACC,IAAI,CAACC,KAAK,CAAC;gBAC3BH;gBACAI,MAAM;YACR;QACF;IACF;IAEA,OAAOzC;AACT,EAAC"}
1
+ {"version":3,"sources":["../../src/export/getExportCollection.ts"],"sourcesContent":["import type {\n CollectionAfterChangeHook,\n CollectionBeforeOperationHook,\n CollectionConfig,\n Config,\n} from 'payload'\n\nimport type { ExportConfig, ImportExportPluginConfig, Limit } from '../types.js'\nimport type { Export } from './createExport.js'\n\nimport { resolveLimit } from '../utilities/resolveLimit.js'\nimport { createExport } from './createExport.js'\nimport { getFields } from './getFields.js'\nimport { handleDownload } from './handleDownload.js'\nimport { handlePreview } from './handlePreview.js'\n\nexport const getExportCollection = ({\n config,\n exportConfig,\n pluginConfig,\n}: {\n config: Config\n exportConfig?: ExportConfig\n pluginConfig: ImportExportPluginConfig\n}): CollectionConfig => {\n const beforeOperation: CollectionBeforeOperationHook[] = []\n const afterChange: CollectionAfterChangeHook[] = []\n\n // Extract export-specific settings\n const disableDownload = exportConfig?.disableDownload ?? false\n const disableSave = exportConfig?.disableSave ?? false\n const disableJobsQueue = exportConfig?.disableJobsQueue ?? false\n const batchSize = exportConfig?.batchSize ?? 100\n const format = exportConfig?.format\n\n const collection: CollectionConfig = {\n slug: 'exports',\n access: {\n update: () => false,\n },\n admin: {\n components: {\n edit: {\n SaveButton: '@payloadcms/plugin-import-export/rsc#ExportSaveButton',\n },\n },\n custom: {\n disableDownload,\n disableSave,\n format,\n },\n disableCopyToLocale: true,\n group: false,\n useAsTitle: 'name',\n },\n disableDuplicate: true,\n endpoints: [\n {\n handler: (req) => handleDownload(req, pluginConfig.debug),\n method: 'post',\n path: '/download',\n },\n {\n handler: handlePreview,\n method: 'post',\n path: '/export-preview',\n },\n ],\n fields: getFields(config, { format }),\n hooks: {\n afterChange,\n beforeOperation,\n },\n lockDocuments: false,\n upload: {\n filesRequiredOnCreate: false,\n hideFileInputOnCreate: true,\n hideRemoveFile: true,\n },\n }\n\n if (disableJobsQueue) {\n beforeOperation.push(async ({ args, collection: collectionConfig, operation, req }) => {\n if (operation !== 'create') {\n return\n }\n const { user } = req\n const debug = pluginConfig.debug\n\n // Get max limit from the target collection's config\n const exportData = args.data as Export\n const targetCollection = req.payload.collections[exportData.collectionSlug]\n const exportLimitConfig: Limit | undefined =\n targetCollection?.config.custom?.['plugin-import-export']?.exportLimit\n const maxLimit = await resolveLimit({\n limit: exportLimitConfig,\n req,\n })\n\n await createExport({\n ...exportData,\n batchSize,\n debug,\n exportCollection: collectionConfig.slug,\n maxLimit,\n req,\n userCollection: user?.collection || user?.user?.collection,\n userID: user?.id || user?.user?.id,\n })\n })\n } else {\n afterChange.push(async ({ collection: collectionConfig, doc, operation, req }) => {\n if (operation !== 'create') {\n return\n }\n\n const { user } = req\n\n // Get max limit from the target collection's config\n // For job-based exports, we resolve the limit now since function limits\n // cannot be serialized. This means dynamic limits are resolved at queue time.\n const targetCollection = req.payload.collections[doc.collectionSlug]\n const exportLimitConfig: Limit | undefined =\n targetCollection?.config.custom?.['plugin-import-export']?.exportLimit\n const maxLimit = await resolveLimit({\n limit: exportLimitConfig,\n req,\n })\n\n const input: Export = {\n ...doc,\n batchSize,\n exportCollection: collectionConfig.slug,\n maxLimit,\n userCollection: user?.collection || user?.user?.collection,\n userID: user?.id || user?.user?.id,\n }\n\n await req.payload.jobs.queue({\n input,\n task: 'createCollectionExport',\n })\n })\n }\n\n return collection\n}\n"],"names":["resolveLimit","createExport","getFields","handleDownload","handlePreview","getExportCollection","config","exportConfig","pluginConfig","beforeOperation","afterChange","disableDownload","disableSave","disableJobsQueue","batchSize","format","collection","slug","access","update","admin","components","edit","SaveButton","custom","disableCopyToLocale","group","useAsTitle","disableDuplicate","endpoints","handler","req","debug","method","path","fields","hooks","lockDocuments","upload","filesRequiredOnCreate","hideFileInputOnCreate","hideRemoveFile","push","args","collectionConfig","operation","user","exportData","data","targetCollection","payload","collections","collectionSlug","exportLimitConfig","exportLimit","maxLimit","limit","exportCollection","userCollection","userID","id","doc","input","jobs","queue","task"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"getFields.d.ts","sourceRoot":"","sources":["../../src/export/getFields.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAe,MAAM,SAAS,CAAA;AAKzD,KAAK,gBAAgB,GAAG;IACtB;;OAEG;IACH,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;CACxB,CAAA;AAED,eAAO,MAAM,SAAS,WAAY,MAAM,YAAY,gBAAgB,KAAG,KAAK,EAwP3E,CAAA"}
1
+ {"version":3,"file":"getFields.d.ts","sourceRoot":"","sources":["../../src/export/getFields.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAe,MAAM,SAAS,CAAA;AAKzD,KAAK,gBAAgB,GAAG;IACtB;;OAEG;IACH,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;CACxB,CAAA;AAED,eAAO,MAAM,SAAS,WAAY,MAAM,YAAY,gBAAgB,KAAG,KAAK,EA8P3E,CAAA"}
@@ -43,14 +43,18 @@ export const getFields = (config, options)=>{
43
43
  name: 'format',
44
44
  type: 'select',
45
45
  admin: {
46
- // Hide if a forced format is set via config
47
- condition: ()=>!format,
46
+ readOnly: Boolean(format),
48
47
  width: '33.3333%'
49
48
  },
50
49
  defaultValue: format ?? 'csv',
51
50
  // @ts-expect-error - this is not correctly typed in plugins right now
52
51
  label: ({ t })=>t('plugin-import-export:field-format-label'),
53
- options: [
52
+ options: format ? [
53
+ {
54
+ label: format.toUpperCase(),
55
+ value: format
56
+ }
57
+ ] : [
54
58
  {
55
59
  label: 'CSV',
56
60
  value: 'csv'
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/export/getFields.ts"],"sourcesContent":["import type { TFunction } from '@payloadcms/translations'\nimport type { Config, Field, SelectField } from 'payload'\n\nimport { getFilename } from '../utilities/getFilename.js'\nimport { validateLimitValue } from '../utilities/validateLimitValue.js'\n\ntype GetFieldsOptions = {\n /**\n * Force a specific format, hiding the format dropdown\n */\n format?: 'csv' | 'json'\n}\n\nexport const getFields = (config: Config, options?: GetFieldsOptions): Field[] => {\n const format = options?.format\n let localeField: SelectField | undefined\n if (config.localization) {\n localeField = {\n name: 'locale',\n type: 'select',\n admin: {\n width: '25%',\n },\n defaultValue: 'all',\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:field-locale-label'),\n options: [\n {\n label: ({ t }) => t('general:allLocales'),\n value: 'all',\n },\n ...config.localization.locales.map((locale) => ({\n label: typeof locale === 'string' ? locale : locale.label,\n value: typeof locale === 'string' ? locale : locale.code,\n })),\n ],\n }\n }\n\n return [\n {\n type: 'collapsible',\n fields: [\n {\n name: 'name',\n type: 'text',\n defaultValue: () => getFilename(),\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:field-name-label'),\n },\n {\n type: 'row',\n fields: [\n {\n name: 'format',\n type: 'select',\n admin: {\n // Hide if a forced format is set via config\n condition: () => !format,\n width: '33.3333%',\n },\n defaultValue: format ?? 'csv',\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:field-format-label'),\n options: [\n {\n label: 'CSV',\n value: 'csv',\n },\n {\n label: 'JSON',\n value: 'json',\n },\n ],\n required: true,\n },\n {\n name: 'limit',\n type: 'number',\n admin: {\n placeholder: 'No limit',\n step: 100,\n width: '33.3333%',\n },\n validate: (value: null | number | undefined, { req }: { req: { t: TFunction } }) => {\n return validateLimitValue(value, req.t) ?? true\n },\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:field-limit-label'),\n },\n {\n name: 'page',\n type: 'number',\n admin: {\n components: {\n Field: '@payloadcms/plugin-import-export/rsc#Page',\n },\n condition: ({ limit }) => {\n // Show the page field only if limit is set\n return typeof limit === 'number' && limit !== 0\n },\n width: '33.3333%',\n },\n defaultValue: 1,\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:field-page-label'),\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n name: 'sort',\n type: 'text',\n admin: {\n components: {\n Field: '@payloadcms/plugin-import-export/rsc#SortBy',\n },\n },\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:field-sort-label'),\n },\n {\n name: 'sortOrder',\n type: 'select',\n admin: {\n components: {\n Field: '@payloadcms/plugin-import-export/rsc#SortOrder',\n },\n // Only show when `sort` has a value\n condition: ({ sort }) => typeof sort === 'string' && sort.trim().length > 0,\n },\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:field-sort-order-label'),\n options: [\n { label: 'Ascending', value: 'asc' },\n { label: 'Descending', value: 'desc' },\n ],\n },\n ...(localeField ? [localeField] : []),\n {\n name: 'drafts',\n type: 'select',\n admin: {\n condition: (data) => {\n const collectionConfig = (config.collections ?? []).find(\n (collection) => collection.slug === data.collectionSlug,\n )\n return Boolean(\n typeof collectionConfig?.versions === 'object' &&\n collectionConfig?.versions?.drafts,\n )\n },\n width: '25%',\n },\n defaultValue: 'yes',\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:field-drafts-label'),\n options: [\n {\n label: ({ t }) => t('general:yes'),\n value: 'yes',\n },\n {\n label: ({ t }) => t('general:no'),\n value: 'no',\n },\n ],\n },\n // {\n // name: 'depth',\n // type: 'number',\n // // @ts-expect-error - this is not correctly typed in plugins right now\n // label: ({ t }) => t('plugin-import-export:field-depth-label'),\n // admin: {\n // width: '33%',\n // },\n // defaultValue: 1,\n // required: true,\n // },\n ],\n },\n {\n name: 'selectionToUse',\n type: 'radio',\n admin: {\n components: {\n Field: '@payloadcms/plugin-import-export/rsc#SelectionToUseField',\n },\n },\n options: [\n {\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:selectionToUse-currentSelection'),\n value: 'currentSelection',\n },\n {\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:selectionToUse-currentFilters'),\n value: 'currentFilters',\n },\n {\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:selectionToUse-allDocuments'),\n value: 'all',\n },\n ],\n virtual: true,\n },\n {\n name: 'fields',\n type: 'text',\n admin: {\n components: {\n Field: '@payloadcms/plugin-import-export/rsc#FieldsToExport',\n },\n },\n hasMany: true,\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:field-fields-label'),\n },\n {\n name: 'collectionSlug',\n type: 'text',\n admin: {\n components: {\n Field: '@payloadcms/plugin-import-export/rsc#CollectionField',\n },\n },\n required: true,\n },\n {\n name: 'where',\n type: 'json',\n admin: {\n hidden: true,\n },\n defaultValue: {},\n hooks: {\n beforeValidate: [\n ({ value }) => {\n return value ?? {}\n },\n ],\n },\n },\n ],\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:exportOptions'),\n },\n {\n name: 'preview',\n type: 'ui',\n admin: {\n components: {\n Field: '@payloadcms/plugin-import-export/rsc#ExportPreview',\n },\n },\n },\n ]\n}\n"],"names":["getFilename","validateLimitValue","getFields","config","options","format","localeField","localization","name","type","admin","width","defaultValue","label","t","value","locales","map","locale","code","fields","condition","required","placeholder","step","validate","req","components","Field","limit","sort","trim","length","data","collectionConfig","collections","find","collection","slug","collectionSlug","Boolean","versions","drafts","virtual","hasMany","hidden","hooks","beforeValidate"],"mappings":"AAGA,SAASA,WAAW,QAAQ,8BAA6B;AACzD,SAASC,kBAAkB,QAAQ,qCAAoC;AASvE,OAAO,MAAMC,YAAY,CAACC,QAAgBC;IACxC,MAAMC,SAASD,SAASC;IACxB,IAAIC;IACJ,IAAIH,OAAOI,YAAY,EAAE;QACvBD,cAAc;YACZE,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLC,OAAO;YACT;YACAC,cAAc;YACd,sEAAsE;YACtEC,OAAO,CAAC,EAAEC,CAAC,EAAE,GAAKA,EAAE;YACpBV,SAAS;gBACP;oBACES,OAAO,CAAC,EAAEC,CAAC,EAAE,GAAKA,EAAE;oBACpBC,OAAO;gBACT;mBACGZ,OAAOI,YAAY,CAACS,OAAO,CAACC,GAAG,CAAC,CAACC,SAAY,CAAA;wBAC9CL,OAAO,OAAOK,WAAW,WAAWA,SAASA,OAAOL,KAAK;wBACzDE,OAAO,OAAOG,WAAW,WAAWA,SAASA,OAAOC,IAAI;oBAC1D,CAAA;aACD;QACH;IACF;IAEA,OAAO;QACL;YACEV,MAAM;YACNW,QAAQ;gBACN;oBACEZ,MAAM;oBACNC,MAAM;oBACNG,cAAc,IAAMZ;oBACpB,sEAAsE;oBACtEa,OAAO,CAAC,EAAEC,CAAC,EAAE,GAAKA,EAAE;gBACtB;gBACA;oBACEL,MAAM;oBACNW,QAAQ;wBACN;4BACEZ,MAAM;4BACNC,MAAM;4BACNC,OAAO;gCACL,4CAA4C;gCAC5CW,WAAW,IAAM,CAAChB;gCAClBM,OAAO;4BACT;4BACAC,cAAcP,UAAU;4BACxB,sEAAsE;4BACtEQ,OAAO,CAAC,EAAEC,CAAC,EAAE,GAAKA,EAAE;4BACpBV,SAAS;gCACP;oCACES,OAAO;oCACPE,OAAO;gCACT;gCACA;oCACEF,OAAO;oCACPE,OAAO;gCACT;6BACD;4BACDO,UAAU;wBACZ;wBACA;4BACEd,MAAM;4BACNC,MAAM;4BACNC,OAAO;gCACLa,aAAa;gCACbC,MAAM;gCACNb,OAAO;4BACT;4BACAc,UAAU,CAACV,OAAkC,EAAEW,GAAG,EAA6B;gCAC7E,OAAOzB,mBAAmBc,OAAOW,IAAIZ,CAAC,KAAK;4BAC7C;4BACA,sEAAsE;4BACtED,OAAO,CAAC,EAAEC,CAAC,EAAE,GAAKA,EAAE;wBACtB;wBACA;4BACEN,MAAM;4BACNC,MAAM;4BACNC,OAAO;gCACLiB,YAAY;oCACVC,OAAO;gCACT;gCACAP,WAAW,CAAC,EAAEQ,KAAK,EAAE;oCACnB,2CAA2C;oCAC3C,OAAO,OAAOA,UAAU,YAAYA,UAAU;gCAChD;gCACAlB,OAAO;4BACT;4BACAC,cAAc;4BACd,sEAAsE;4BACtEC,OAAO,CAAC,EAAEC,CAAC,EAAE,GAAKA,EAAE;wBACtB;qBACD;gBACH;gBACA;oBACEL,MAAM;oBACNW,QAAQ;wBACN;4BACEZ,MAAM;4BACNC,MAAM;4BACNC,OAAO;gCACLiB,YAAY;oCACVC,OAAO;gCACT;4BACF;4BACA,sEAAsE;4BACtEf,OAAO,CAAC,EAAEC,CAAC,EAAE,GAAKA,EAAE;wBACtB;wBACA;4BACEN,MAAM;4BACNC,MAAM;4BACNC,OAAO;gCACLiB,YAAY;oCACVC,OAAO;gCACT;gCACA,oCAAoC;gCACpCP,WAAW,CAAC,EAAES,IAAI,EAAE,GAAK,OAAOA,SAAS,YAAYA,KAAKC,IAAI,GAAGC,MAAM,GAAG;4BAC5E;4BACA,sEAAsE;4BACtEnB,OAAO,CAAC,EAAEC,CAAC,EAAE,GAAKA,EAAE;4BACpBV,SAAS;gCACP;oCAAES,OAAO;oCAAaE,OAAO;gCAAM;gCACnC;oCAAEF,OAAO;oCAAcE,OAAO;gCAAO;6BACtC;wBACH;2BACIT,cAAc;4BAACA;yBAAY,GAAG,EAAE;wBACpC;4BACEE,MAAM;4BACNC,MAAM;4BACNC,OAAO;gCACLW,WAAW,CAACY;oCACV,MAAMC,mBAAmB,AAAC/B,CAAAA,OAAOgC,WAAW,IAAI,EAAE,AAAD,EAAGC,IAAI,CACtD,CAACC,aAAeA,WAAWC,IAAI,KAAKL,KAAKM,cAAc;oCAEzD,OAAOC,QACL,OAAON,kBAAkBO,aAAa,YACpCP,kBAAkBO,UAAUC;gCAElC;gCACA/B,OAAO;4BACT;4BACAC,cAAc;4BACd,sEAAsE;4BACtEC,OAAO,CAAC,EAAEC,CAAC,EAAE,GAAKA,EAAE;4BACpBV,SAAS;gCACP;oCACES,OAAO,CAAC,EAAEC,CAAC,EAAE,GAAKA,EAAE;oCACpBC,OAAO;gCACT;gCACA;oCACEF,OAAO,CAAC,EAAEC,CAAC,EAAE,GAAKA,EAAE;oCACpBC,OAAO;gCACT;6BACD;wBACH;qBAYD;gBACH;gBACA;oBACEP,MAAM;oBACNC,MAAM;oBACNC,OAAO;wBACLiB,YAAY;4BACVC,OAAO;wBACT;oBACF;oBACAxB,SAAS;wBACP;4BACE,sEAAsE;4BACtES,OAAO,CAAC,EAAEC,CAAC,EAAE,GAAKA,EAAE;4BACpBC,OAAO;wBACT;wBACA;4BACE,sEAAsE;4BACtEF,OAAO,CAAC,EAAEC,CAAC,EAAE,GAAKA,EAAE;4BACpBC,OAAO;wBACT;wBACA;4BACE,sEAAsE;4BACtEF,OAAO,CAAC,EAAEC,CAAC,EAAE,GAAKA,EAAE;4BACpBC,OAAO;wBACT;qBACD;oBACD4B,SAAS;gBACX;gBACA;oBACEnC,MAAM;oBACNC,MAAM;oBACNC,OAAO;wBACLiB,YAAY;4BACVC,OAAO;wBACT;oBACF;oBACAgB,SAAS;oBACT,sEAAsE;oBACtE/B,OAAO,CAAC,EAAEC,CAAC,EAAE,GAAKA,EAAE;gBACtB;gBACA;oBACEN,MAAM;oBACNC,MAAM;oBACNC,OAAO;wBACLiB,YAAY;4BACVC,OAAO;wBACT;oBACF;oBACAN,UAAU;gBACZ;gBACA;oBACEd,MAAM;oBACNC,MAAM;oBACNC,OAAO;wBACLmC,QAAQ;oBACV;oBACAjC,cAAc,CAAC;oBACfkC,OAAO;wBACLC,gBAAgB;4BACd,CAAC,EAAEhC,KAAK,EAAE;gCACR,OAAOA,SAAS,CAAC;4BACnB;yBACD;oBACH;gBACF;aACD;YACD,sEAAsE;YACtEF,OAAO,CAAC,EAAEC,CAAC,EAAE,GAAKA,EAAE;QACtB;QACA;YACEN,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLiB,YAAY;oBACVC,OAAO;gBACT;YACF;QACF;KACD;AACH,EAAC"}
1
+ {"version":3,"sources":["../../src/export/getFields.ts"],"sourcesContent":["import type { TFunction } from '@payloadcms/translations'\nimport type { Config, Field, SelectField } from 'payload'\n\nimport { getFilename } from '../utilities/getFilename.js'\nimport { validateLimitValue } from '../utilities/validateLimitValue.js'\n\ntype GetFieldsOptions = {\n /**\n * Force a specific format, hiding the format dropdown\n */\n format?: 'csv' | 'json'\n}\n\nexport const getFields = (config: Config, options?: GetFieldsOptions): Field[] => {\n const format = options?.format\n let localeField: SelectField | undefined\n if (config.localization) {\n localeField = {\n name: 'locale',\n type: 'select',\n admin: {\n width: '25%',\n },\n defaultValue: 'all',\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:field-locale-label'),\n options: [\n {\n label: ({ t }) => t('general:allLocales'),\n value: 'all',\n },\n ...config.localization.locales.map((locale) => ({\n label: typeof locale === 'string' ? locale : locale.label,\n value: typeof locale === 'string' ? locale : locale.code,\n })),\n ],\n }\n }\n\n return [\n {\n type: 'collapsible',\n fields: [\n {\n name: 'name',\n type: 'text',\n defaultValue: () => getFilename(),\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:field-name-label'),\n },\n {\n type: 'row',\n fields: [\n {\n name: 'format',\n type: 'select',\n admin: {\n readOnly: Boolean(format),\n width: '33.3333%',\n },\n defaultValue: format ?? 'csv',\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:field-format-label'),\n options: format\n ? [\n {\n label: format.toUpperCase(),\n value: format,\n },\n ]\n : [\n {\n label: 'CSV',\n value: 'csv',\n },\n {\n label: 'JSON',\n value: 'json',\n },\n ],\n required: true,\n },\n {\n name: 'limit',\n type: 'number',\n admin: {\n placeholder: 'No limit',\n step: 100,\n width: '33.3333%',\n },\n validate: (value: null | number | undefined, { req }: { req: { t: TFunction } }) => {\n return validateLimitValue(value, req.t) ?? true\n },\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:field-limit-label'),\n },\n {\n name: 'page',\n type: 'number',\n admin: {\n components: {\n Field: '@payloadcms/plugin-import-export/rsc#Page',\n },\n condition: ({ limit }) => {\n // Show the page field only if limit is set\n return typeof limit === 'number' && limit !== 0\n },\n width: '33.3333%',\n },\n defaultValue: 1,\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:field-page-label'),\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n name: 'sort',\n type: 'text',\n admin: {\n components: {\n Field: '@payloadcms/plugin-import-export/rsc#SortBy',\n },\n },\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:field-sort-label'),\n },\n {\n name: 'sortOrder',\n type: 'select',\n admin: {\n components: {\n Field: '@payloadcms/plugin-import-export/rsc#SortOrder',\n },\n // Only show when `sort` has a value\n condition: ({ sort }) => typeof sort === 'string' && sort.trim().length > 0,\n },\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:field-sort-order-label'),\n options: [\n { label: 'Ascending', value: 'asc' },\n { label: 'Descending', value: 'desc' },\n ],\n },\n ...(localeField ? [localeField] : []),\n {\n name: 'drafts',\n type: 'select',\n admin: {\n condition: (data) => {\n const collectionConfig = (config.collections ?? []).find(\n (collection) => collection.slug === data.collectionSlug,\n )\n return Boolean(\n typeof collectionConfig?.versions === 'object' &&\n collectionConfig?.versions?.drafts,\n )\n },\n width: '25%',\n },\n defaultValue: 'yes',\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:field-drafts-label'),\n options: [\n {\n label: ({ t }) => t('general:yes'),\n value: 'yes',\n },\n {\n label: ({ t }) => t('general:no'),\n value: 'no',\n },\n ],\n },\n // {\n // name: 'depth',\n // type: 'number',\n // // @ts-expect-error - this is not correctly typed in plugins right now\n // label: ({ t }) => t('plugin-import-export:field-depth-label'),\n // admin: {\n // width: '33%',\n // },\n // defaultValue: 1,\n // required: true,\n // },\n ],\n },\n {\n name: 'selectionToUse',\n type: 'radio',\n admin: {\n components: {\n Field: '@payloadcms/plugin-import-export/rsc#SelectionToUseField',\n },\n },\n options: [\n {\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:selectionToUse-currentSelection'),\n value: 'currentSelection',\n },\n {\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:selectionToUse-currentFilters'),\n value: 'currentFilters',\n },\n {\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:selectionToUse-allDocuments'),\n value: 'all',\n },\n ],\n virtual: true,\n },\n {\n name: 'fields',\n type: 'text',\n admin: {\n components: {\n Field: '@payloadcms/plugin-import-export/rsc#FieldsToExport',\n },\n },\n hasMany: true,\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:field-fields-label'),\n },\n {\n name: 'collectionSlug',\n type: 'text',\n admin: {\n components: {\n Field: '@payloadcms/plugin-import-export/rsc#CollectionField',\n },\n },\n required: true,\n },\n {\n name: 'where',\n type: 'json',\n admin: {\n hidden: true,\n },\n defaultValue: {},\n hooks: {\n beforeValidate: [\n ({ value }) => {\n return value ?? {}\n },\n ],\n },\n },\n ],\n // @ts-expect-error - this is not correctly typed in plugins right now\n label: ({ t }) => t('plugin-import-export:exportOptions'),\n },\n {\n name: 'preview',\n type: 'ui',\n admin: {\n components: {\n Field: '@payloadcms/plugin-import-export/rsc#ExportPreview',\n },\n },\n },\n ]\n}\n"],"names":["getFilename","validateLimitValue","getFields","config","options","format","localeField","localization","name","type","admin","width","defaultValue","label","t","value","locales","map","locale","code","fields","readOnly","Boolean","toUpperCase","required","placeholder","step","validate","req","components","Field","condition","limit","sort","trim","length","data","collectionConfig","collections","find","collection","slug","collectionSlug","versions","drafts","virtual","hasMany","hidden","hooks","beforeValidate"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"handleDownload.d.ts","sourceRoot":"","sources":["../../src/export/handleDownload.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAM7C,eAAO,MAAM,cAAc,QAAe,cAAc,uCAqCvD,CAAA"}
1
+ {"version":3,"file":"handleDownload.d.ts","sourceRoot":"","sources":["../../src/export/handleDownload.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAO7C,eAAO,MAAM,cAAc,QAAe,cAAc,uCA2DvD,CAAA"}
@@ -1,4 +1,5 @@
1
1
  import { APIError } from 'payload';
2
+ import { resolveLimit } from '../utilities/resolveLimit.js';
2
3
  import { createExport } from './createExport.js';
3
4
  export const handleDownload = async (req, debug = false)=>{
4
5
  try {
@@ -9,8 +10,23 @@ export const handleDownload = async (req, debug = false)=>{
9
10
  if (!body || !body.data) {
10
11
  throw new APIError('Request data is required.');
11
12
  }
12
- const { collectionSlug } = body.data || {};
13
+ const { collectionSlug, format } = body.data || {};
13
14
  req.payload.logger.info(`Download request received ${collectionSlug}`);
15
+ const targetCollection = req.payload.collections[collectionSlug];
16
+ let maxLimit;
17
+ if (targetCollection) {
18
+ const adminPluginConfig = targetCollection.config.admin?.custom?.['plugin-import-export'];
19
+ const pluginConfig = targetCollection.config.custom?.['plugin-import-export'];
20
+ const forcedFormat = adminPluginConfig?.exportFormat;
21
+ if (forcedFormat && format && format !== forcedFormat) {
22
+ throw new APIError(`Export format '${format}' is not supported for collection '${collectionSlug}'. Only '${forcedFormat}' format is allowed.`);
23
+ }
24
+ // Resolve max limit from the collection config
25
+ maxLimit = await resolveLimit({
26
+ limit: pluginConfig?.exportLimit,
27
+ req
28
+ });
29
+ }
14
30
  const { user } = req;
15
31
  body.data.userID = user?.id || user?.user?.id;
16
32
  body.data.userCollection = user?.collection || user?.user?.collection;
@@ -18,6 +34,7 @@ export const handleDownload = async (req, debug = false)=>{
18
34
  ...body.data,
19
35
  debug,
20
36
  download: true,
37
+ maxLimit,
21
38
  req,
22
39
  user: req.user
23
40
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/export/handleDownload.ts"],"sourcesContent":["import type { PayloadRequest } from 'payload'\n\nimport { APIError } from 'payload'\n\nimport { createExport } from './createExport.js'\n\nexport const handleDownload = async (req: PayloadRequest, debug = false) => {\n try {\n let body\n\n if (typeof req?.json === 'function') {\n body = await req.json()\n }\n\n if (!body || !body.data) {\n throw new APIError('Request data is required.')\n }\n\n const { collectionSlug } = body.data || {}\n\n req.payload.logger.info(`Download request received ${collectionSlug}`)\n\n const { user } = req\n\n body.data.userID = user?.id || user?.user?.id\n body.data.userCollection = user?.collection || user?.user?.collection\n\n const res = await createExport({\n ...body.data,\n debug,\n download: true,\n req,\n user: req.user,\n })\n\n return res as Response\n } catch (err) {\n // Return JSON for front-end toast\n return new Response(\n JSON.stringify({ errors: [{ message: (err as Error).message || 'Something went wrong' }] }),\n { headers: { 'Content-Type': 'application/json' }, status: 400 },\n )\n }\n}\n"],"names":["APIError","createExport","handleDownload","req","debug","body","json","data","collectionSlug","payload","logger","info","user","userID","id","userCollection","collection","res","download","err","Response","JSON","stringify","errors","message","headers","status"],"mappings":"AAEA,SAASA,QAAQ,QAAQ,UAAS;AAElC,SAASC,YAAY,QAAQ,oBAAmB;AAEhD,OAAO,MAAMC,iBAAiB,OAAOC,KAAqBC,QAAQ,KAAK;IACrE,IAAI;QACF,IAAIC;QAEJ,IAAI,OAAOF,KAAKG,SAAS,YAAY;YACnCD,OAAO,MAAMF,IAAIG,IAAI;QACvB;QAEA,IAAI,CAACD,QAAQ,CAACA,KAAKE,IAAI,EAAE;YACvB,MAAM,IAAIP,SAAS;QACrB;QAEA,MAAM,EAAEQ,cAAc,EAAE,GAAGH,KAAKE,IAAI,IAAI,CAAC;QAEzCJ,IAAIM,OAAO,CAACC,MAAM,CAACC,IAAI,CAAC,CAAC,0BAA0B,EAAEH,gBAAgB;QAErE,MAAM,EAAEI,IAAI,EAAE,GAAGT;QAEjBE,KAAKE,IAAI,CAACM,MAAM,GAAGD,MAAME,MAAMF,MAAMA,MAAME;QAC3CT,KAAKE,IAAI,CAACQ,cAAc,GAAGH,MAAMI,cAAcJ,MAAMA,MAAMI;QAE3D,MAAMC,MAAM,MAAMhB,aAAa;YAC7B,GAAGI,KAAKE,IAAI;YACZH;YACAc,UAAU;YACVf;YACAS,MAAMT,IAAIS,IAAI;QAChB;QAEA,OAAOK;IACT,EAAE,OAAOE,KAAK;QACZ,kCAAkC;QAClC,OAAO,IAAIC,SACTC,KAAKC,SAAS,CAAC;YAAEC,QAAQ;gBAAC;oBAAEC,SAAS,AAACL,IAAcK,OAAO,IAAI;gBAAuB;aAAE;QAAC,IACzF;YAAEC,SAAS;gBAAE,gBAAgB;YAAmB;YAAGC,QAAQ;QAAI;IAEnE;AACF,EAAC"}
1
+ {"version":3,"sources":["../../src/export/handleDownload.ts"],"sourcesContent":["import type { PayloadRequest } from 'payload'\n\nimport { APIError } from 'payload'\n\nimport { resolveLimit } from '../utilities/resolveLimit.js'\nimport { createExport } from './createExport.js'\n\nexport const handleDownload = async (req: PayloadRequest, debug = false) => {\n try {\n let body\n\n if (typeof req?.json === 'function') {\n body = await req.json()\n }\n\n if (!body || !body.data) {\n throw new APIError('Request data is required.')\n }\n\n const { collectionSlug, format } = body.data || {}\n\n req.payload.logger.info(`Download request received ${collectionSlug}`)\n\n const targetCollection = req.payload.collections[collectionSlug]\n let maxLimit: number | undefined\n\n if (targetCollection) {\n const adminPluginConfig = targetCollection.config.admin?.custom?.['plugin-import-export']\n const pluginConfig = targetCollection.config.custom?.['plugin-import-export']\n\n const forcedFormat = adminPluginConfig?.exportFormat\n if (forcedFormat && format && format !== forcedFormat) {\n throw new APIError(\n `Export format '${format}' is not supported for collection '${collectionSlug}'. Only '${forcedFormat}' format is allowed.`,\n )\n }\n\n // Resolve max limit from the collection config\n maxLimit = await resolveLimit({\n limit: pluginConfig?.exportLimit,\n req,\n })\n }\n\n const { user } = req\n\n body.data.userID = user?.id || user?.user?.id\n body.data.userCollection = user?.collection || user?.user?.collection\n\n const res = await createExport({\n ...body.data,\n debug,\n download: true,\n maxLimit,\n req,\n user: req.user,\n })\n\n return res as Response\n } catch (err) {\n // Return JSON for front-end toast\n return new Response(\n JSON.stringify({ errors: [{ message: (err as Error).message || 'Something went wrong' }] }),\n { headers: { 'Content-Type': 'application/json' }, status: 400 },\n )\n }\n}\n"],"names":["APIError","resolveLimit","createExport","handleDownload","req","debug","body","json","data","collectionSlug","format","payload","logger","info","targetCollection","collections","maxLimit","adminPluginConfig","config","admin","custom","pluginConfig","forcedFormat","exportFormat","limit","exportLimit","user","userID","id","userCollection","collection","res","download","err","Response","JSON","stringify","errors","message","headers","status"],"mappings":"AAEA,SAASA,QAAQ,QAAQ,UAAS;AAElC,SAASC,YAAY,QAAQ,+BAA8B;AAC3D,SAASC,YAAY,QAAQ,oBAAmB;AAEhD,OAAO,MAAMC,iBAAiB,OAAOC,KAAqBC,QAAQ,KAAK;IACrE,IAAI;QACF,IAAIC;QAEJ,IAAI,OAAOF,KAAKG,SAAS,YAAY;YACnCD,OAAO,MAAMF,IAAIG,IAAI;QACvB;QAEA,IAAI,CAACD,QAAQ,CAACA,KAAKE,IAAI,EAAE;YACvB,MAAM,IAAIR,SAAS;QACrB;QAEA,MAAM,EAAES,cAAc,EAAEC,MAAM,EAAE,GAAGJ,KAAKE,IAAI,IAAI,CAAC;QAEjDJ,IAAIO,OAAO,CAACC,MAAM,CAACC,IAAI,CAAC,CAAC,0BAA0B,EAAEJ,gBAAgB;QAErE,MAAMK,mBAAmBV,IAAIO,OAAO,CAACI,WAAW,CAACN,eAAe;QAChE,IAAIO;QAEJ,IAAIF,kBAAkB;YACpB,MAAMG,oBAAoBH,iBAAiBI,MAAM,CAACC,KAAK,EAAEC,QAAQ,CAAC,uBAAuB;YACzF,MAAMC,eAAeP,iBAAiBI,MAAM,CAACE,MAAM,EAAE,CAAC,uBAAuB;YAE7E,MAAME,eAAeL,mBAAmBM;YACxC,IAAID,gBAAgBZ,UAAUA,WAAWY,cAAc;gBACrD,MAAM,IAAItB,SACR,CAAC,eAAe,EAAEU,OAAO,mCAAmC,EAAED,eAAe,SAAS,EAAEa,aAAa,oBAAoB,CAAC;YAE9H;YAEA,+CAA+C;YAC/CN,WAAW,MAAMf,aAAa;gBAC5BuB,OAAOH,cAAcI;gBACrBrB;YACF;QACF;QAEA,MAAM,EAAEsB,IAAI,EAAE,GAAGtB;QAEjBE,KAAKE,IAAI,CAACmB,MAAM,GAAGD,MAAME,MAAMF,MAAMA,MAAME;QAC3CtB,KAAKE,IAAI,CAACqB,cAAc,GAAGH,MAAMI,cAAcJ,MAAMA,MAAMI;QAE3D,MAAMC,MAAM,MAAM7B,aAAa;YAC7B,GAAGI,KAAKE,IAAI;YACZH;YACA2B,UAAU;YACVhB;YACAZ;YACAsB,MAAMtB,IAAIsB,IAAI;QAChB;QAEA,OAAOK;IACT,EAAE,OAAOE,KAAK;QACZ,kCAAkC;QAClC,OAAO,IAAIC,SACTC,KAAKC,SAAS,CAAC;YAAEC,QAAQ;gBAAC;oBAAEC,SAAS,AAACL,IAAcK,OAAO,IAAI;gBAAuB;aAAE;QAAC,IACzF;YAAEC,SAAS;gBAAE,gBAAgB;YAAmB;YAAGC,QAAQ;QAAI;IAEnE;AACF,EAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"handlePreview.d.ts","sourceRoot":"","sources":["../../src/export/handlePreview.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,cAAc,EAAS,MAAM,SAAS,CAAA;AAqBpE,eAAO,MAAM,aAAa,QAAe,cAAc,KAAG,OAAO,CAAC,QAAQ,CA0MzE,CAAA"}
1
+ {"version":3,"file":"handlePreview.d.ts","sourceRoot":"","sources":["../../src/export/handlePreview.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,cAAc,EAAS,MAAM,SAAS,CAAA;AAuBpE,eAAO,MAAM,aAAa,QAAe,cAAc,KAAG,OAAO,CAAC,QAAQ,CAoOzE,CAAA"}