@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.
- package/dist/components/CollectionField/index.d.ts.map +1 -1
- package/dist/components/CollectionField/index.js +6 -2
- package/dist/components/CollectionField/index.js.map +1 -1
- package/dist/components/ExportPreview/index.d.ts.map +1 -1
- package/dist/components/ExportPreview/index.js +30 -12
- package/dist/components/ExportPreview/index.js.map +1 -1
- package/dist/components/ExportPreview/index.scss +12 -0
- package/dist/components/ImportPreview/index.js +3 -15
- package/dist/components/ImportPreview/index.js.map +1 -1
- package/dist/export/createExport.d.ts +6 -1
- package/dist/export/createExport.d.ts.map +1 -1
- package/dist/export/createExport.js +37 -13
- package/dist/export/createExport.js.map +1 -1
- package/dist/export/getCreateExportCollectionTask.d.ts.map +1 -1
- package/dist/export/getCreateExportCollectionTask.js +4 -1
- package/dist/export/getCreateExportCollectionTask.js.map +1 -1
- package/dist/export/getExportCollection.d.ts.map +1 -1
- package/dist/export/getExportCollection.js +23 -3
- package/dist/export/getExportCollection.js.map +1 -1
- package/dist/export/getFields.d.ts.map +1 -1
- package/dist/export/getFields.js +7 -3
- package/dist/export/getFields.js.map +1 -1
- package/dist/export/handleDownload.d.ts.map +1 -1
- package/dist/export/handleDownload.js +18 -1
- package/dist/export/handleDownload.js.map +1 -1
- package/dist/export/handlePreview.d.ts.map +1 -1
- package/dist/export/handlePreview.js +32 -10
- package/dist/export/handlePreview.js.map +1 -1
- package/dist/exports/types.d.ts +1 -1
- package/dist/exports/types.d.ts.map +1 -1
- package/dist/exports/types.js.map +1 -1
- package/dist/import/batchProcessor.d.ts.map +1 -1
- package/dist/import/batchProcessor.js +54 -55
- package/dist/import/batchProcessor.js.map +1 -1
- package/dist/import/createImport.d.ts +6 -1
- package/dist/import/createImport.d.ts.map +1 -1
- package/dist/import/createImport.js +5 -1
- package/dist/import/createImport.js.map +1 -1
- package/dist/import/getCreateImportCollectionTask.d.ts +9 -6
- package/dist/import/getCreateImportCollectionTask.d.ts.map +1 -1
- package/dist/import/getCreateImportCollectionTask.js +105 -65
- package/dist/import/getCreateImportCollectionTask.js.map +1 -1
- package/dist/import/getImportCollection.d.ts.map +1 -1
- package/dist/import/getImportCollection.js +39 -45
- package/dist/import/getImportCollection.js.map +1 -1
- package/dist/import/handlePreview.d.ts.map +1 -1
- package/dist/import/handlePreview.js +11 -0
- package/dist/import/handlePreview.js.map +1 -1
- package/dist/index.d.ts +22 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -2
- package/dist/index.js.map +1 -1
- package/dist/translations/languages/ar.d.ts.map +1 -1
- package/dist/translations/languages/ar.js +3 -0
- package/dist/translations/languages/ar.js.map +1 -1
- package/dist/translations/languages/az.d.ts.map +1 -1
- package/dist/translations/languages/az.js +3 -0
- package/dist/translations/languages/az.js.map +1 -1
- package/dist/translations/languages/bg.d.ts.map +1 -1
- package/dist/translations/languages/bg.js +3 -0
- package/dist/translations/languages/bg.js.map +1 -1
- package/dist/translations/languages/bnBd.d.ts.map +1 -1
- package/dist/translations/languages/bnBd.js +22 -19
- package/dist/translations/languages/bnBd.js.map +1 -1
- package/dist/translations/languages/bnIn.d.ts.map +1 -1
- package/dist/translations/languages/bnIn.js +22 -19
- package/dist/translations/languages/bnIn.js.map +1 -1
- package/dist/translations/languages/ca.d.ts.map +1 -1
- package/dist/translations/languages/ca.js +3 -0
- package/dist/translations/languages/ca.js.map +1 -1
- package/dist/translations/languages/cs.d.ts.map +1 -1
- package/dist/translations/languages/cs.js +3 -0
- package/dist/translations/languages/cs.js.map +1 -1
- package/dist/translations/languages/da.d.ts.map +1 -1
- package/dist/translations/languages/da.js +3 -0
- package/dist/translations/languages/da.js.map +1 -1
- package/dist/translations/languages/de.d.ts.map +1 -1
- package/dist/translations/languages/de.js +3 -0
- package/dist/translations/languages/de.js.map +1 -1
- package/dist/translations/languages/en.d.ts +3 -0
- package/dist/translations/languages/en.d.ts.map +1 -1
- package/dist/translations/languages/en.js +3 -0
- package/dist/translations/languages/en.js.map +1 -1
- package/dist/translations/languages/es.d.ts.map +1 -1
- package/dist/translations/languages/es.js +3 -0
- package/dist/translations/languages/es.js.map +1 -1
- package/dist/translations/languages/et.d.ts.map +1 -1
- package/dist/translations/languages/et.js +3 -0
- package/dist/translations/languages/et.js.map +1 -1
- package/dist/translations/languages/fa.d.ts.map +1 -1
- package/dist/translations/languages/fa.js +3 -0
- package/dist/translations/languages/fa.js.map +1 -1
- package/dist/translations/languages/fr.d.ts.map +1 -1
- package/dist/translations/languages/fr.js +3 -0
- package/dist/translations/languages/fr.js.map +1 -1
- package/dist/translations/languages/he.d.ts.map +1 -1
- package/dist/translations/languages/he.js +3 -0
- package/dist/translations/languages/he.js.map +1 -1
- package/dist/translations/languages/hr.d.ts.map +1 -1
- package/dist/translations/languages/hr.js +3 -0
- package/dist/translations/languages/hr.js.map +1 -1
- package/dist/translations/languages/hu.d.ts.map +1 -1
- package/dist/translations/languages/hu.js +3 -0
- package/dist/translations/languages/hu.js.map +1 -1
- package/dist/translations/languages/hy.d.ts.map +1 -1
- package/dist/translations/languages/hy.js +3 -0
- package/dist/translations/languages/hy.js.map +1 -1
- package/dist/translations/languages/id.d.ts.map +1 -1
- package/dist/translations/languages/id.js +13 -10
- package/dist/translations/languages/id.js.map +1 -1
- package/dist/translations/languages/is.d.ts.map +1 -1
- package/dist/translations/languages/is.js +3 -0
- package/dist/translations/languages/is.js.map +1 -1
- package/dist/translations/languages/it.d.ts.map +1 -1
- package/dist/translations/languages/it.js +3 -0
- package/dist/translations/languages/it.js.map +1 -1
- package/dist/translations/languages/ja.d.ts.map +1 -1
- package/dist/translations/languages/ja.js +3 -0
- package/dist/translations/languages/ja.js.map +1 -1
- package/dist/translations/languages/ko.d.ts.map +1 -1
- package/dist/translations/languages/ko.js +3 -0
- package/dist/translations/languages/ko.js.map +1 -1
- package/dist/translations/languages/lt.d.ts.map +1 -1
- package/dist/translations/languages/lt.js +3 -0
- package/dist/translations/languages/lt.js.map +1 -1
- package/dist/translations/languages/lv.d.ts.map +1 -1
- package/dist/translations/languages/lv.js +16 -13
- package/dist/translations/languages/lv.js.map +1 -1
- package/dist/translations/languages/my.d.ts.map +1 -1
- package/dist/translations/languages/my.js +3 -0
- package/dist/translations/languages/my.js.map +1 -1
- package/dist/translations/languages/nb.d.ts.map +1 -1
- package/dist/translations/languages/nb.js +3 -0
- package/dist/translations/languages/nb.js.map +1 -1
- package/dist/translations/languages/nl.d.ts.map +1 -1
- package/dist/translations/languages/nl.js +3 -0
- package/dist/translations/languages/nl.js.map +1 -1
- package/dist/translations/languages/pl.d.ts.map +1 -1
- package/dist/translations/languages/pl.js +3 -0
- package/dist/translations/languages/pl.js.map +1 -1
- package/dist/translations/languages/pt.d.ts.map +1 -1
- package/dist/translations/languages/pt.js +3 -0
- package/dist/translations/languages/pt.js.map +1 -1
- package/dist/translations/languages/ro.d.ts.map +1 -1
- package/dist/translations/languages/ro.js +3 -0
- package/dist/translations/languages/ro.js.map +1 -1
- package/dist/translations/languages/rs.d.ts.map +1 -1
- package/dist/translations/languages/rs.js +3 -0
- package/dist/translations/languages/rs.js.map +1 -1
- package/dist/translations/languages/rsLatin.d.ts.map +1 -1
- package/dist/translations/languages/rsLatin.js +3 -0
- package/dist/translations/languages/rsLatin.js.map +1 -1
- package/dist/translations/languages/ru.d.ts.map +1 -1
- package/dist/translations/languages/ru.js +3 -0
- package/dist/translations/languages/ru.js.map +1 -1
- package/dist/translations/languages/sk.d.ts.map +1 -1
- package/dist/translations/languages/sk.js +3 -0
- package/dist/translations/languages/sk.js.map +1 -1
- package/dist/translations/languages/sl.d.ts.map +1 -1
- package/dist/translations/languages/sl.js +3 -0
- package/dist/translations/languages/sl.js.map +1 -1
- package/dist/translations/languages/sv.d.ts.map +1 -1
- package/dist/translations/languages/sv.js +3 -0
- package/dist/translations/languages/sv.js.map +1 -1
- package/dist/translations/languages/ta.d.ts.map +1 -1
- package/dist/translations/languages/ta.js +3 -0
- package/dist/translations/languages/ta.js.map +1 -1
- package/dist/translations/languages/th.d.ts.map +1 -1
- package/dist/translations/languages/th.js +3 -0
- package/dist/translations/languages/th.js.map +1 -1
- package/dist/translations/languages/tr.d.ts.map +1 -1
- package/dist/translations/languages/tr.js +3 -0
- package/dist/translations/languages/tr.js.map +1 -1
- package/dist/translations/languages/uk.d.ts.map +1 -1
- package/dist/translations/languages/uk.js +3 -0
- package/dist/translations/languages/uk.js.map +1 -1
- package/dist/translations/languages/vi.d.ts.map +1 -1
- package/dist/translations/languages/vi.js +3 -0
- package/dist/translations/languages/vi.js.map +1 -1
- package/dist/translations/languages/zh.d.ts.map +1 -1
- package/dist/translations/languages/zh.js +3 -0
- package/dist/translations/languages/zh.js.map +1 -1
- package/dist/translations/languages/zhTw.d.ts.map +1 -1
- package/dist/translations/languages/zhTw.js +3 -0
- package/dist/translations/languages/zhTw.js.map +1 -1
- package/dist/types.d.ts +44 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utilities/buildDisabledFieldRegex.d.ts +11 -2
- package/dist/utilities/buildDisabledFieldRegex.d.ts.map +1 -1
- package/dist/utilities/buildDisabledFieldRegex.js +33 -7
- package/dist/utilities/buildDisabledFieldRegex.js.map +1 -1
- package/dist/utilities/buildDisabledFieldRegex.spec.js +64 -0
- package/dist/utilities/buildDisabledFieldRegex.spec.js.map +1 -0
- package/dist/utilities/collectTimezoneCompanionFields.d.ts +24 -0
- package/dist/utilities/collectTimezoneCompanionFields.d.ts.map +1 -0
- package/dist/utilities/collectTimezoneCompanionFields.js +89 -0
- package/dist/utilities/collectTimezoneCompanionFields.js.map +1 -0
- package/dist/utilities/collectTimezoneCompanionFields.spec.js +319 -0
- package/dist/utilities/collectTimezoneCompanionFields.spec.js.map +1 -0
- package/dist/utilities/fieldToRegex.d.ts +14 -0
- package/dist/utilities/fieldToRegex.d.ts.map +1 -0
- package/dist/utilities/fieldToRegex.js +34 -0
- package/dist/utilities/fieldToRegex.js.map +1 -0
- package/dist/utilities/fieldToRegex.spec.js +151 -0
- package/dist/utilities/fieldToRegex.spec.js.map +1 -0
- package/dist/utilities/flattenObject.d.ts +7 -1
- package/dist/utilities/flattenObject.d.ts.map +1 -1
- package/dist/utilities/flattenObject.js +30 -18
- package/dist/utilities/flattenObject.js.map +1 -1
- package/dist/utilities/getExportFieldFunctions.d.ts.map +1 -1
- package/dist/utilities/getExportFieldFunctions.js +7 -0
- package/dist/utilities/getExportFieldFunctions.js.map +1 -1
- package/dist/utilities/getFileFromDoc.d.ts +26 -0
- package/dist/utilities/getFileFromDoc.d.ts.map +1 -0
- package/dist/utilities/getFileFromDoc.js +67 -0
- package/dist/utilities/getFileFromDoc.js.map +1 -0
- package/dist/utilities/getImportFieldFunctions.d.ts.map +1 -1
- package/dist/utilities/getImportFieldFunctions.js +2 -16
- package/dist/utilities/getImportFieldFunctions.js.map +1 -1
- package/dist/utilities/getPluginCollections.d.ts +1 -0
- package/dist/utilities/getPluginCollections.d.ts.map +1 -1
- package/dist/utilities/getPluginCollections.js +59 -10
- package/dist/utilities/getPluginCollections.js.map +1 -1
- package/dist/utilities/getSchemaColumns.d.ts +8 -2
- package/dist/utilities/getSchemaColumns.d.ts.map +1 -1
- package/dist/utilities/getSchemaColumns.js +61 -27
- package/dist/utilities/getSchemaColumns.js.map +1 -1
- package/dist/utilities/parseCSV.d.ts.map +1 -1
- package/dist/utilities/parseCSV.js +4 -10
- package/dist/utilities/parseCSV.js.map +1 -1
- package/dist/utilities/resolveLimit.d.ts +15 -0
- package/dist/utilities/resolveLimit.d.ts.map +1 -0
- package/dist/utilities/resolveLimit.js +21 -0
- package/dist/utilities/resolveLimit.js.map +1 -0
- package/dist/utilities/unflattenObject.d.ts +13 -0
- package/dist/utilities/unflattenObject.d.ts.map +1 -1
- package/dist/utilities/unflattenObject.js +64 -65
- package/dist/utilities/unflattenObject.js.map +1 -1
- package/package.json +8 -8
- package/dist/utilities/getvalueAtPath.d.ts +0 -15
- package/dist/utilities/getvalueAtPath.d.ts.map +0 -1
- package/dist/utilities/getvalueAtPath.js +0 -49
- package/dist/utilities/getvalueAtPath.js.map +0 -1
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { addDataAndFileToRequest } from 'payload';
|
|
2
|
+
import { getObjectDotNotation } from 'payload/shared';
|
|
2
3
|
import { DEFAULT_PREVIEW_LIMIT, MAX_PREVIEW_LIMIT, MIN_PREVIEW_LIMIT, MIN_PREVIEW_PAGE } from '../constants.js';
|
|
4
|
+
import { collectTimezoneCompanionFields } from '../utilities/collectTimezoneCompanionFields.js';
|
|
3
5
|
import { flattenObject } from '../utilities/flattenObject.js';
|
|
4
6
|
import { getExportFieldFunctions } from '../utilities/getExportFieldFunctions.js';
|
|
5
7
|
import { getFlattenedFieldKeys } from '../utilities/getFlattenedFieldKeys.js';
|
|
6
8
|
import { getSchemaColumns } from '../utilities/getSchemaColumns.js';
|
|
7
9
|
import { getSelect } from '../utilities/getSelect.js';
|
|
8
|
-
import { getValueAtPath } from '../utilities/getvalueAtPath.js';
|
|
9
10
|
import { removeDisabledFields } from '../utilities/removeDisabledFields.js';
|
|
11
|
+
import { resolveLimit } from '../utilities/resolveLimit.js';
|
|
10
12
|
import { setNestedValue } from '../utilities/setNestedValue.js';
|
|
11
13
|
export const handlePreview = async (req)=>{
|
|
12
14
|
await addDataAndFileToRequest(req);
|
|
@@ -22,6 +24,11 @@ export const handlePreview = async (req)=>{
|
|
|
22
24
|
status: 400
|
|
23
25
|
});
|
|
24
26
|
}
|
|
27
|
+
const pluginConfig = targetCollection.config.custom?.['plugin-import-export'];
|
|
28
|
+
const maxLimit = await resolveLimit({
|
|
29
|
+
limit: pluginConfig?.exportLimit,
|
|
30
|
+
req
|
|
31
|
+
});
|
|
25
32
|
const select = Array.isArray(fields) && fields.length > 0 ? getSelect(fields) : undefined;
|
|
26
33
|
const draft = draftFromReq === 'yes';
|
|
27
34
|
const collectionHasVersions = Boolean(targetCollection.config.versions);
|
|
@@ -45,8 +52,17 @@ export const handlePreview = async (req)=>{
|
|
|
45
52
|
where
|
|
46
53
|
});
|
|
47
54
|
const totalMatchingDocs = countResult.totalDocs;
|
|
48
|
-
// Calculate actual export count (respecting export limit)
|
|
49
|
-
|
|
55
|
+
// Calculate actual export count (respecting both export limit and max limit)
|
|
56
|
+
let effectiveLimit = totalMatchingDocs;
|
|
57
|
+
// Apply user's export limit if provided
|
|
58
|
+
if (exportLimit && exportLimit > 0) {
|
|
59
|
+
effectiveLimit = Math.min(effectiveLimit, exportLimit);
|
|
60
|
+
}
|
|
61
|
+
// Apply max limit if configured
|
|
62
|
+
if (typeof maxLimit === 'number' && maxLimit > 0) {
|
|
63
|
+
effectiveLimit = Math.min(effectiveLimit, maxLimit);
|
|
64
|
+
}
|
|
65
|
+
const exportTotalDocs = effectiveLimit;
|
|
50
66
|
// Calculate preview pagination that respects export limit
|
|
51
67
|
// Preview should only show docs that will actually be exported
|
|
52
68
|
const previewStartIndex = (previewPage - 1) * previewLimit;
|
|
@@ -57,16 +73,19 @@ export const handlePreview = async (req)=>{
|
|
|
57
73
|
const localeCodes = locale === 'all' && req.payload.config.localization ? req.payload.config.localization.localeCodes : undefined;
|
|
58
74
|
// Get disabled fields configuration
|
|
59
75
|
const disabledFields = targetCollection.config.admin?.custom?.['plugin-import-export']?.disabledFields ?? [];
|
|
76
|
+
// Collect auto-generated timezone companion fields from schema
|
|
77
|
+
const timezoneCompanionFields = collectTimezoneCompanionFields(targetCollection.config.flattenedFields);
|
|
60
78
|
// Always compute columns for CSV (even if no docs) for consistent schema
|
|
61
79
|
const columns = isCSV ? getSchemaColumns({
|
|
62
80
|
collectionConfig: targetCollection.config,
|
|
63
81
|
disabledFields,
|
|
64
82
|
fields,
|
|
65
83
|
locale: locale ?? undefined,
|
|
66
|
-
localeCodes
|
|
84
|
+
localeCodes,
|
|
85
|
+
timezoneCompanionFields
|
|
67
86
|
}) : undefined;
|
|
68
|
-
// If we're beyond the
|
|
69
|
-
if (
|
|
87
|
+
// If we're beyond the effective limit (considering both user limit and maxLimit), return empty docs
|
|
88
|
+
if (exportTotalDocs > 0 && previewStartIndex >= exportTotalDocs) {
|
|
70
89
|
const response = {
|
|
71
90
|
columns,
|
|
72
91
|
docs: [],
|
|
@@ -74,6 +93,7 @@ export const handlePreview = async (req)=>{
|
|
|
74
93
|
hasNextPage: false,
|
|
75
94
|
hasPrevPage: previewPage > 1,
|
|
76
95
|
limit: previewLimit,
|
|
96
|
+
maxLimit,
|
|
77
97
|
page: previewPage,
|
|
78
98
|
totalDocs: exportTotalDocs,
|
|
79
99
|
totalPages: previewTotalPages
|
|
@@ -95,10 +115,10 @@ export const handlePreview = async (req)=>{
|
|
|
95
115
|
sort,
|
|
96
116
|
where
|
|
97
117
|
});
|
|
98
|
-
// Trim docs to respect
|
|
118
|
+
// Trim docs to respect effective limit boundary (user limit clamped by maxLimit)
|
|
99
119
|
let docs = result.docs;
|
|
100
|
-
if (
|
|
101
|
-
const remainingInExport =
|
|
120
|
+
if (exportTotalDocs > 0) {
|
|
121
|
+
const remainingInExport = exportTotalDocs - previewStartIndex;
|
|
102
122
|
if (remainingInExport < docs.length) {
|
|
103
123
|
docs = docs.slice(0, remainingInExport);
|
|
104
124
|
}
|
|
@@ -116,6 +136,7 @@ export const handlePreview = async (req)=>{
|
|
|
116
136
|
const row = flattenObject({
|
|
117
137
|
doc,
|
|
118
138
|
fields,
|
|
139
|
+
timezoneCompanionFields,
|
|
119
140
|
toCSVFunctions
|
|
120
141
|
});
|
|
121
142
|
for (const key of possibleKeys){
|
|
@@ -136,7 +157,7 @@ export const handlePreview = async (req)=>{
|
|
|
136
157
|
if (Array.isArray(fields) && fields.length > 0) {
|
|
137
158
|
const trimmed = {};
|
|
138
159
|
for (const key of fields){
|
|
139
|
-
const value =
|
|
160
|
+
const value = getObjectDotNotation(output, key);
|
|
140
161
|
setNestedValue(trimmed, key, value ?? null);
|
|
141
162
|
}
|
|
142
163
|
output = trimmed;
|
|
@@ -153,6 +174,7 @@ export const handlePreview = async (req)=>{
|
|
|
153
174
|
hasNextPage,
|
|
154
175
|
hasPrevPage,
|
|
155
176
|
limit: previewLimit,
|
|
177
|
+
maxLimit,
|
|
156
178
|
page: previewPage,
|
|
157
179
|
totalDocs: exportTotalDocs,
|
|
158
180
|
totalPages: previewTotalPages
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/export/handlePreview.ts"],"sourcesContent":["import type { FlattenedField, PayloadRequest, Where } from 'payload'\n\nimport { addDataAndFileToRequest } from 'payload'\n\nimport type { ExportPreviewResponse } from '../types.js'\n\nimport {\n DEFAULT_PREVIEW_LIMIT,\n MAX_PREVIEW_LIMIT,\n MIN_PREVIEW_LIMIT,\n MIN_PREVIEW_PAGE,\n} from '../constants.js'\nimport { flattenObject } from '../utilities/flattenObject.js'\nimport { getExportFieldFunctions } from '../utilities/getExportFieldFunctions.js'\nimport { getFlattenedFieldKeys } from '../utilities/getFlattenedFieldKeys.js'\nimport { getSchemaColumns } from '../utilities/getSchemaColumns.js'\nimport { getSelect } from '../utilities/getSelect.js'\nimport { getValueAtPath } from '../utilities/getvalueAtPath.js'\nimport { removeDisabledFields } from '../utilities/removeDisabledFields.js'\nimport { setNestedValue } from '../utilities/setNestedValue.js'\n\nexport const handlePreview = async (req: PayloadRequest): Promise<Response> => {\n await addDataAndFileToRequest(req)\n\n const {\n collectionSlug,\n draft: draftFromReq,\n fields,\n limit: exportLimit,\n locale,\n previewLimit: rawPreviewLimit = DEFAULT_PREVIEW_LIMIT,\n previewPage: rawPreviewPage = 1,\n sort,\n where: whereFromReq = {},\n } = req.data as {\n collectionSlug: string\n draft?: 'no' | 'yes'\n fields?: string[]\n format?: 'csv' | 'json'\n limit?: number\n locale?: string\n previewLimit?: number\n previewPage?: number\n sort?: any\n where?: any\n }\n\n // Validate and clamp pagination values to safe bounds\n const previewLimit = Math.max(MIN_PREVIEW_LIMIT, Math.min(rawPreviewLimit, MAX_PREVIEW_LIMIT))\n const previewPage = Math.max(MIN_PREVIEW_PAGE, rawPreviewPage)\n\n const targetCollection = req.payload.collections[collectionSlug]\n if (!targetCollection) {\n return Response.json(\n { error: `Collection with slug ${collectionSlug} not found` },\n { status: 400 },\n )\n }\n\n const select = Array.isArray(fields) && fields.length > 0 ? getSelect(fields) : undefined\n const draft = draftFromReq === 'yes'\n const collectionHasVersions = Boolean(targetCollection.config.versions)\n\n // Only filter by _status for versioned collections\n const publishedWhere: Where = collectionHasVersions ? { _status: { equals: 'published' } } : {}\n\n const where: Where = {\n and: [whereFromReq, draft ? {} : publishedWhere],\n }\n\n // Count total docs matching export criteria\n const countResult = await req.payload.count({\n collection: collectionSlug,\n overrideAccess: false,\n req,\n where,\n })\n\n const totalMatchingDocs = countResult.totalDocs\n\n // Calculate actual export count (respecting export limit)\n const exportTotalDocs =\n exportLimit && exportLimit > 0 ? Math.min(totalMatchingDocs, exportLimit) : totalMatchingDocs\n\n // Calculate preview pagination that respects export limit\n // Preview should only show docs that will actually be exported\n const previewStartIndex = (previewPage - 1) * previewLimit\n\n // Calculate pagination info based on export limit (not raw DB results)\n const previewTotalPages = exportTotalDocs === 0 ? 0 : Math.ceil(exportTotalDocs / previewLimit)\n\n const isCSV = req?.data?.format === 'csv'\n\n // Get locale codes for locale expansion when locale='all'\n const localeCodes =\n locale === 'all' && req.payload.config.localization\n ? req.payload.config.localization.localeCodes\n : undefined\n\n // Get disabled fields configuration\n const disabledFields =\n targetCollection.config.admin?.custom?.['plugin-import-export']?.disabledFields ?? []\n\n // Always compute columns for CSV (even if no docs) for consistent schema\n const columns = isCSV\n ? getSchemaColumns({\n collectionConfig: targetCollection.config,\n disabledFields,\n fields,\n locale: locale ?? undefined,\n localeCodes,\n })\n : undefined\n\n // If we're beyond the export limit, return empty docs with columns\n if (exportLimit && exportLimit > 0 && previewStartIndex >= exportLimit) {\n const response: ExportPreviewResponse = {\n columns,\n docs: [],\n exportTotalDocs,\n hasNextPage: false,\n hasPrevPage: previewPage > 1,\n limit: previewLimit,\n page: previewPage,\n totalDocs: exportTotalDocs,\n totalPages: previewTotalPages,\n }\n return Response.json(response)\n }\n\n // Fetch preview page with full previewLimit to maintain consistent pagination offsets\n // We'll trim the results afterwards if needed to respect export limit\n const result = await req.payload.find({\n collection: collectionSlug,\n depth: 1,\n draft,\n limit: previewLimit,\n locale,\n overrideAccess: false,\n page: previewPage,\n req,\n select,\n sort,\n where,\n })\n\n // Trim docs to respect export limit boundary\n let docs = result.docs\n if (exportLimit && exportLimit > 0) {\n const remainingInExport = exportLimit - previewStartIndex\n if (remainingInExport < docs.length) {\n docs = docs.slice(0, remainingInExport)\n }\n }\n\n // Transform docs based on format\n let transformed: Record<string, unknown>[]\n\n if (isCSV) {\n const toCSVFunctions = getExportFieldFunctions({\n fields: targetCollection.config.fields as FlattenedField[],\n })\n\n const possibleKeys = getFlattenedFieldKeys(\n targetCollection.config.fields as FlattenedField[],\n '',\n { localeCodes },\n )\n\n transformed = docs.map((doc) => {\n const row = flattenObject({\n doc,\n fields,\n toCSVFunctions,\n })\n\n for (const key of possibleKeys) {\n if (!(key in row)) {\n row[key] = null\n }\n }\n\n return row\n })\n } else {\n transformed = docs.map((doc) => {\n let output: Record<string, unknown> = { ...doc }\n\n // Remove disabled fields first\n output = removeDisabledFields(output, disabledFields)\n\n // Then trim to selected fields only (if fields are provided)\n if (Array.isArray(fields) && fields.length > 0) {\n const trimmed: Record<string, unknown> = {}\n\n for (const key of fields) {\n const value = getValueAtPath(output, key)\n setNestedValue(trimmed, key, value ?? null)\n }\n\n output = trimmed\n }\n\n return output\n })\n }\n\n const hasNextPage = previewPage < previewTotalPages\n const hasPrevPage = previewPage > 1\n\n const response: ExportPreviewResponse = {\n columns,\n docs: transformed,\n exportTotalDocs,\n hasNextPage,\n hasPrevPage,\n limit: previewLimit,\n page: previewPage,\n totalDocs: exportTotalDocs,\n totalPages: previewTotalPages,\n }\n\n return Response.json(response)\n}\n"],"names":["addDataAndFileToRequest","DEFAULT_PREVIEW_LIMIT","MAX_PREVIEW_LIMIT","MIN_PREVIEW_LIMIT","MIN_PREVIEW_PAGE","flattenObject","getExportFieldFunctions","getFlattenedFieldKeys","getSchemaColumns","getSelect","getValueAtPath","removeDisabledFields","setNestedValue","handlePreview","req","collectionSlug","draft","draftFromReq","fields","limit","exportLimit","locale","previewLimit","rawPreviewLimit","previewPage","rawPreviewPage","sort","where","whereFromReq","data","Math","max","min","targetCollection","payload","collections","Response","json","error","status","select","Array","isArray","length","undefined","collectionHasVersions","Boolean","config","versions","publishedWhere","_status","equals","and","countResult","count","collection","overrideAccess","totalMatchingDocs","totalDocs","exportTotalDocs","previewStartIndex","previewTotalPages","ceil","isCSV","format","localeCodes","localization","disabledFields","admin","custom","columns","collectionConfig","response","docs","hasNextPage","hasPrevPage","page","totalPages","result","find","depth","remainingInExport","slice","transformed","toCSVFunctions","possibleKeys","map","doc","row","key","output","trimmed","value"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/export/handlePreview.ts"],"sourcesContent":["import type { FlattenedField, PayloadRequest, Where } from 'payload'\n\nimport { addDataAndFileToRequest } from 'payload'\nimport { getObjectDotNotation } from 'payload/shared'\n\nimport type { ExportPreviewResponse } from '../types.js'\n\nimport {\n DEFAULT_PREVIEW_LIMIT,\n MAX_PREVIEW_LIMIT,\n MIN_PREVIEW_LIMIT,\n MIN_PREVIEW_PAGE,\n} from '../constants.js'\nimport { collectTimezoneCompanionFields } from '../utilities/collectTimezoneCompanionFields.js'\nimport { flattenObject } from '../utilities/flattenObject.js'\nimport { getExportFieldFunctions } from '../utilities/getExportFieldFunctions.js'\nimport { getFlattenedFieldKeys } from '../utilities/getFlattenedFieldKeys.js'\nimport { getSchemaColumns } from '../utilities/getSchemaColumns.js'\nimport { getSelect } from '../utilities/getSelect.js'\nimport { removeDisabledFields } from '../utilities/removeDisabledFields.js'\nimport { resolveLimit } from '../utilities/resolveLimit.js'\nimport { setNestedValue } from '../utilities/setNestedValue.js'\n\nexport const handlePreview = async (req: PayloadRequest): Promise<Response> => {\n await addDataAndFileToRequest(req)\n\n const {\n collectionSlug,\n draft: draftFromReq,\n fields,\n limit: exportLimit,\n locale,\n previewLimit: rawPreviewLimit = DEFAULT_PREVIEW_LIMIT,\n previewPage: rawPreviewPage = 1,\n sort,\n where: whereFromReq = {},\n } = req.data as {\n collectionSlug: string\n draft?: 'no' | 'yes'\n fields?: string[]\n format?: 'csv' | 'json'\n limit?: number\n locale?: string\n previewLimit?: number\n previewPage?: number\n sort?: any\n where?: any\n }\n\n // Validate and clamp pagination values to safe bounds\n const previewLimit = Math.max(MIN_PREVIEW_LIMIT, Math.min(rawPreviewLimit, MAX_PREVIEW_LIMIT))\n const previewPage = Math.max(MIN_PREVIEW_PAGE, rawPreviewPage)\n\n const targetCollection = req.payload.collections[collectionSlug]\n if (!targetCollection) {\n return Response.json(\n { error: `Collection with slug ${collectionSlug} not found` },\n { status: 400 },\n )\n }\n\n const pluginConfig = targetCollection.config.custom?.['plugin-import-export']\n const maxLimit = await resolveLimit({\n limit: pluginConfig?.exportLimit,\n req,\n })\n\n const select = Array.isArray(fields) && fields.length > 0 ? getSelect(fields) : undefined\n const draft = draftFromReq === 'yes'\n const collectionHasVersions = Boolean(targetCollection.config.versions)\n\n // Only filter by _status for versioned collections\n const publishedWhere: Where = collectionHasVersions ? { _status: { equals: 'published' } } : {}\n\n const where: Where = {\n and: [whereFromReq, draft ? {} : publishedWhere],\n }\n\n // Count total docs matching export criteria\n const countResult = await req.payload.count({\n collection: collectionSlug,\n overrideAccess: false,\n req,\n where,\n })\n\n const totalMatchingDocs = countResult.totalDocs\n\n // Calculate actual export count (respecting both export limit and max limit)\n let effectiveLimit = totalMatchingDocs\n\n // Apply user's export limit if provided\n if (exportLimit && exportLimit > 0) {\n effectiveLimit = Math.min(effectiveLimit, exportLimit)\n }\n\n // Apply max limit if configured\n if (typeof maxLimit === 'number' && maxLimit > 0) {\n effectiveLimit = Math.min(effectiveLimit, maxLimit)\n }\n\n const exportTotalDocs = effectiveLimit\n\n // Calculate preview pagination that respects export limit\n // Preview should only show docs that will actually be exported\n const previewStartIndex = (previewPage - 1) * previewLimit\n\n // Calculate pagination info based on export limit (not raw DB results)\n const previewTotalPages = exportTotalDocs === 0 ? 0 : Math.ceil(exportTotalDocs / previewLimit)\n\n const isCSV = req?.data?.format === 'csv'\n\n // Get locale codes for locale expansion when locale='all'\n const localeCodes =\n locale === 'all' && req.payload.config.localization\n ? req.payload.config.localization.localeCodes\n : undefined\n\n // Get disabled fields configuration\n const disabledFields =\n targetCollection.config.admin?.custom?.['plugin-import-export']?.disabledFields ?? []\n\n // Collect auto-generated timezone companion fields from schema\n const timezoneCompanionFields = collectTimezoneCompanionFields(\n targetCollection.config.flattenedFields,\n )\n\n // Always compute columns for CSV (even if no docs) for consistent schema\n const columns = isCSV\n ? getSchemaColumns({\n collectionConfig: targetCollection.config,\n disabledFields,\n fields,\n locale: locale ?? undefined,\n localeCodes,\n timezoneCompanionFields,\n })\n : undefined\n\n // If we're beyond the effective limit (considering both user limit and maxLimit), return empty docs\n if (exportTotalDocs > 0 && previewStartIndex >= exportTotalDocs) {\n const response: ExportPreviewResponse = {\n columns,\n docs: [],\n exportTotalDocs,\n hasNextPage: false,\n hasPrevPage: previewPage > 1,\n limit: previewLimit,\n maxLimit,\n page: previewPage,\n totalDocs: exportTotalDocs,\n totalPages: previewTotalPages,\n }\n return Response.json(response)\n }\n\n // Fetch preview page with full previewLimit to maintain consistent pagination offsets\n // We'll trim the results afterwards if needed to respect export limit\n const result = await req.payload.find({\n collection: collectionSlug,\n depth: 1,\n draft,\n limit: previewLimit,\n locale,\n overrideAccess: false,\n page: previewPage,\n req,\n select,\n sort,\n where,\n })\n\n // Trim docs to respect effective limit boundary (user limit clamped by maxLimit)\n let docs = result.docs\n if (exportTotalDocs > 0) {\n const remainingInExport = exportTotalDocs - previewStartIndex\n if (remainingInExport < docs.length) {\n docs = docs.slice(0, remainingInExport)\n }\n }\n\n // Transform docs based on format\n let transformed: Record<string, unknown>[]\n\n if (isCSV) {\n const toCSVFunctions = getExportFieldFunctions({\n fields: targetCollection.config.fields as FlattenedField[],\n })\n\n const possibleKeys = getFlattenedFieldKeys(\n targetCollection.config.fields as FlattenedField[],\n '',\n { localeCodes },\n )\n\n transformed = docs.map((doc) => {\n const row = flattenObject({\n doc,\n fields,\n timezoneCompanionFields,\n toCSVFunctions,\n })\n\n for (const key of possibleKeys) {\n if (!(key in row)) {\n row[key] = null\n }\n }\n\n return row\n })\n } else {\n transformed = docs.map((doc) => {\n let output: Record<string, unknown> = { ...doc }\n\n // Remove disabled fields first\n output = removeDisabledFields(output, disabledFields)\n\n // Then trim to selected fields only (if fields are provided)\n if (Array.isArray(fields) && fields.length > 0) {\n const trimmed: Record<string, unknown> = {}\n\n for (const key of fields) {\n const value = getObjectDotNotation(output, key)\n setNestedValue(trimmed, key, value ?? null)\n }\n\n output = trimmed\n }\n\n return output\n })\n }\n\n const hasNextPage = previewPage < previewTotalPages\n const hasPrevPage = previewPage > 1\n\n const response: ExportPreviewResponse = {\n columns,\n docs: transformed,\n exportTotalDocs,\n hasNextPage,\n hasPrevPage,\n limit: previewLimit,\n maxLimit,\n page: previewPage,\n totalDocs: exportTotalDocs,\n totalPages: previewTotalPages,\n }\n\n return Response.json(response)\n}\n"],"names":["addDataAndFileToRequest","getObjectDotNotation","DEFAULT_PREVIEW_LIMIT","MAX_PREVIEW_LIMIT","MIN_PREVIEW_LIMIT","MIN_PREVIEW_PAGE","collectTimezoneCompanionFields","flattenObject","getExportFieldFunctions","getFlattenedFieldKeys","getSchemaColumns","getSelect","removeDisabledFields","resolveLimit","setNestedValue","handlePreview","req","collectionSlug","draft","draftFromReq","fields","limit","exportLimit","locale","previewLimit","rawPreviewLimit","previewPage","rawPreviewPage","sort","where","whereFromReq","data","Math","max","min","targetCollection","payload","collections","Response","json","error","status","pluginConfig","config","custom","maxLimit","select","Array","isArray","length","undefined","collectionHasVersions","Boolean","versions","publishedWhere","_status","equals","and","countResult","count","collection","overrideAccess","totalMatchingDocs","totalDocs","effectiveLimit","exportTotalDocs","previewStartIndex","previewTotalPages","ceil","isCSV","format","localeCodes","localization","disabledFields","admin","timezoneCompanionFields","flattenedFields","columns","collectionConfig","response","docs","hasNextPage","hasPrevPage","page","totalPages","result","find","depth","remainingInExport","slice","transformed","toCSVFunctions","possibleKeys","map","doc","row","key","output","trimmed","value"],"mappings":"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"}
|
package/dist/exports/types.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export type { ImportExportPluginConfig, ToCSVFunction } from '../types.js';
|
|
1
|
+
export type { ImportExportPluginConfig, Limit, LimitFunction, ToCSVFunction } from '../types.js';
|
|
2
2
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/exports/types.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,wBAAwB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/exports/types.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,wBAAwB,EAAE,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/exports/types.ts"],"sourcesContent":["export type { ImportExportPluginConfig, ToCSVFunction } from '../types.js'\n"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"sources":["../../src/exports/types.ts"],"sourcesContent":["export type { ImportExportPluginConfig, Limit, LimitFunction, ToCSVFunction } from '../types.js'\n"],"names":[],"mappings":"AAAA,WAAgG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batchProcessor.d.ts","sourceRoot":"","sources":["../../src/import/batchProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAExD,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEjE,OAAO,EACL,KAAK,UAAU,EAIhB,MAAM,mCAAmC,CAAA;AAE1C;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,oBAAoB,CAAC,EAAE,OAAO,GAAG,WAAW,CAAA;CAC7C;AAED;;GAEG;AACH,MAAM,WAAW,WAAY,SAAQ,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACrC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,CAAA;IAC1B,UAAU,EAAE,KAAK,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QACjC,KAAK,EAAE,MAAM,CAAA;QACb,SAAS,CAAC,EAAE,SAAS,GAAG,SAAS,CAAA;QACjC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAChC,CAAC,CAAA;CACH;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;IACpC,UAAU,EAAE,UAAU,CAAA;IACtB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,GAAG,EAAE,cAAc,CAAA;IACnB,IAAI,CAAC,EAAE,SAAS,CAAA;CACjB;
|
|
1
|
+
{"version":3,"file":"batchProcessor.d.ts","sourceRoot":"","sources":["../../src/import/batchProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAExD,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEjE,OAAO,EACL,KAAK,UAAU,EAIhB,MAAM,mCAAmC,CAAA;AAE1C;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,oBAAoB,CAAC,EAAE,OAAO,GAAG,WAAW,CAAA;CAC7C;AAED;;GAEG;AACH,MAAM,WAAW,WAAY,SAAQ,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACrC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,CAAA;IAC1B,UAAU,EAAE,KAAK,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QACjC,KAAK,EAAE,MAAM,CAAA;QACb,SAAS,CAAC,EAAE,SAAS,GAAG,SAAS,CAAA;QACjC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAChC,CAAC,CAAA;CACH;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;IACpC,UAAU,EAAE,UAAU,CAAA;IACtB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,GAAG,EAAE,cAAc,CAAA;IACnB,IAAI,CAAC,EAAE,SAAS,CAAA;CACjB;AAghBD,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,2BAAgC;oCAMrC,oBAAoB,KAAG,OAAO,CAAC,YAAY,CAAC;EA2D1F"}
|
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import { categorizeError, createBatches, extractErrorMessage } from '../utilities/useBatchProcessor.js';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Separates multi-locale data from a document for sequential locale updates.
|
|
4
|
+
*
|
|
5
|
+
* When a field has locale-keyed values (e.g., { title: { en: 'Hello', es: 'Hola' } }),
|
|
6
|
+
* this extracts the first locale's data for initial create/update, and stores
|
|
7
|
+
* remaining locales for subsequent update calls.
|
|
8
|
+
*
|
|
9
|
+
* @returns
|
|
10
|
+
* - flatData: Document with first locale values extracted (for initial operation)
|
|
11
|
+
* - hasMultiLocale: Whether any multi-locale fields were found
|
|
12
|
+
* - localeUpdates: Map of locale -> field data for follow-up updates
|
|
13
|
+
*/ function extractMultiLocaleData(data, configuredLocales) {
|
|
4
14
|
const flatData = {};
|
|
5
15
|
const localeUpdates = {};
|
|
6
16
|
let hasMultiLocale = false;
|
|
7
|
-
// If no locales configured, skip multi-locale processing
|
|
8
17
|
if (!configuredLocales || configuredLocales.length === 0) {
|
|
9
18
|
return {
|
|
10
19
|
flatData: {
|
|
@@ -18,16 +27,12 @@ function extractMultiLocaleData(data, configuredLocales) {
|
|
|
18
27
|
for (const [key, value] of Object.entries(data)){
|
|
19
28
|
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
20
29
|
const valueObj = value;
|
|
21
|
-
// Check if this object has keys matching configured locales
|
|
22
30
|
const localeKeys = Object.keys(valueObj).filter((k)=>localeSet.has(k));
|
|
23
31
|
if (localeKeys.length > 0) {
|
|
24
32
|
hasMultiLocale = true;
|
|
25
|
-
// This is a localized field with explicit locale keys
|
|
26
|
-
// Use the first locale for initial creation, then update others
|
|
27
33
|
const firstLocale = localeKeys[0];
|
|
28
34
|
if (firstLocale) {
|
|
29
35
|
flatData[key] = valueObj[firstLocale];
|
|
30
|
-
// Store other locales for later update
|
|
31
36
|
for (const locale of localeKeys){
|
|
32
37
|
if (locale !== firstLocale) {
|
|
33
38
|
if (!localeUpdates[locale]) {
|
|
@@ -38,11 +43,9 @@ function extractMultiLocaleData(data, configuredLocales) {
|
|
|
38
43
|
}
|
|
39
44
|
}
|
|
40
45
|
} else {
|
|
41
|
-
// Not locale data, keep as is
|
|
42
46
|
flatData[key] = value;
|
|
43
47
|
}
|
|
44
48
|
} else {
|
|
45
|
-
// Not an object, keep as is. this includes localized fields without locale suffix; ie default locale
|
|
46
49
|
flatData[key] = value;
|
|
47
50
|
}
|
|
48
51
|
}
|
|
@@ -52,17 +55,24 @@ function extractMultiLocaleData(data, configuredLocales) {
|
|
|
52
55
|
localeUpdates
|
|
53
56
|
};
|
|
54
57
|
}
|
|
55
|
-
|
|
58
|
+
/**
|
|
59
|
+
* Processes a batch of documents for import based on the import mode.
|
|
60
|
+
*
|
|
61
|
+
* For each document in the batch:
|
|
62
|
+
* - create: Creates a new document (removes any existing ID)
|
|
63
|
+
* - update: Finds existing document by matchField and updates it
|
|
64
|
+
* - upsert: Updates if found, creates if not found
|
|
65
|
+
*
|
|
66
|
+
* Handles versioned collections, multi-locale data, and MongoDB ObjectID validation.
|
|
67
|
+
* Continues processing remaining documents even if individual imports fail.
|
|
68
|
+
*/ async function processImportBatch({ batch, batchIndex, collectionSlug, importMode, matchField, options, req, user }) {
|
|
56
69
|
const result = {
|
|
57
70
|
failed: [],
|
|
58
71
|
successful: []
|
|
59
72
|
};
|
|
60
|
-
// Check if the collection has versions enabled
|
|
61
73
|
const collectionConfig = req.payload.collections[collectionSlug]?.config;
|
|
62
74
|
const collectionHasVersions = Boolean(collectionConfig?.versions);
|
|
63
|
-
// Get configured locales for multi-locale data detection
|
|
64
75
|
const configuredLocales = req.payload.config.localization ? req.payload.config.localization.localeCodes : undefined;
|
|
65
|
-
// Calculate the starting row number for this batch
|
|
66
76
|
const startingRowNumber = batchIndex * options.batchSize;
|
|
67
77
|
for(let i = 0; i < batch.length; i++){
|
|
68
78
|
const document = batch[i];
|
|
@@ -71,23 +81,18 @@ async function processImportBatch({ batch, batchIndex, collectionSlug, importMod
|
|
|
71
81
|
}
|
|
72
82
|
const rowNumber = startingRowNumber + i + 1;
|
|
73
83
|
try {
|
|
74
|
-
let
|
|
75
|
-
let
|
|
84
|
+
let savedDocument;
|
|
85
|
+
let existingDocResult;
|
|
76
86
|
if (importMode === 'create') {
|
|
77
|
-
// Remove ID field when creating new document
|
|
78
87
|
const createData = {
|
|
79
88
|
...document
|
|
80
89
|
};
|
|
81
90
|
delete createData.id;
|
|
82
|
-
// Only handle _status for versioned collections
|
|
83
91
|
let draftOption;
|
|
84
92
|
if (collectionHasVersions) {
|
|
85
|
-
// Check if _status is set - use defaultVersionStatus from config
|
|
86
|
-
// If no _status field provided, use the configured default
|
|
87
93
|
const statusValue = createData._status || options.defaultVersionStatus;
|
|
88
94
|
const isPublished = statusValue !== 'draft';
|
|
89
95
|
draftOption = !isPublished;
|
|
90
|
-
// Debug: log status handling
|
|
91
96
|
if (req.payload.config.debug) {
|
|
92
97
|
req.payload.logger.info({
|
|
93
98
|
_status: createData._status,
|
|
@@ -96,9 +101,9 @@ async function processImportBatch({ batch, batchIndex, collectionSlug, importMod
|
|
|
96
101
|
willSetDraft: draftOption
|
|
97
102
|
});
|
|
98
103
|
}
|
|
99
|
-
|
|
104
|
+
// Remove _status from data - it's controlled via draft option
|
|
105
|
+
delete createData._status;
|
|
100
106
|
}
|
|
101
|
-
// Debug: log what we're about to create
|
|
102
107
|
if (req.payload.config.debug && 'title' in createData) {
|
|
103
108
|
req.payload.logger.info({
|
|
104
109
|
msg: 'Creating document',
|
|
@@ -111,7 +116,7 @@ async function processImportBatch({ batch, batchIndex, collectionSlug, importMod
|
|
|
111
116
|
const { flatData, hasMultiLocale, localeUpdates } = extractMultiLocaleData(createData, configuredLocales);
|
|
112
117
|
if (hasMultiLocale) {
|
|
113
118
|
// Create with default locale data
|
|
114
|
-
|
|
119
|
+
savedDocument = await req.payload.create({
|
|
115
120
|
collection: collectionSlug,
|
|
116
121
|
data: flatData,
|
|
117
122
|
draft: draftOption,
|
|
@@ -120,7 +125,7 @@ async function processImportBatch({ batch, batchIndex, collectionSlug, importMod
|
|
|
120
125
|
user
|
|
121
126
|
});
|
|
122
127
|
// Update for other locales
|
|
123
|
-
if (
|
|
128
|
+
if (savedDocument && Object.keys(localeUpdates).length > 0) {
|
|
124
129
|
for (const [locale, localeData] of Object.entries(localeUpdates)){
|
|
125
130
|
try {
|
|
126
131
|
const localeReq = {
|
|
@@ -128,7 +133,7 @@ async function processImportBatch({ batch, batchIndex, collectionSlug, importMod
|
|
|
128
133
|
locale
|
|
129
134
|
};
|
|
130
135
|
await req.payload.update({
|
|
131
|
-
id:
|
|
136
|
+
id: savedDocument.id,
|
|
132
137
|
collection: collectionSlug,
|
|
133
138
|
data: localeData,
|
|
134
139
|
draft: collectionHasVersions ? false : undefined,
|
|
@@ -140,14 +145,14 @@ async function processImportBatch({ batch, batchIndex, collectionSlug, importMod
|
|
|
140
145
|
// Log but don't fail the entire import if a locale update fails
|
|
141
146
|
req.payload.logger.error({
|
|
142
147
|
err: error,
|
|
143
|
-
msg: `Failed to update locale ${locale} for document ${String(
|
|
148
|
+
msg: `Failed to update locale ${locale} for document ${String(savedDocument.id)}`
|
|
144
149
|
});
|
|
145
150
|
}
|
|
146
151
|
}
|
|
147
152
|
}
|
|
148
153
|
} else {
|
|
149
154
|
// No multi-locale data, create normally
|
|
150
|
-
|
|
155
|
+
savedDocument = await req.payload.create({
|
|
151
156
|
collection: collectionSlug,
|
|
152
157
|
data: createData,
|
|
153
158
|
draft: draftOption,
|
|
@@ -178,9 +183,8 @@ async function processImportBatch({ batch, batchIndex, collectionSlug, importMod
|
|
|
178
183
|
matchValueStr = JSON.stringify(matchValue);
|
|
179
184
|
}
|
|
180
185
|
const isValidObjectIdFormat = /^[0-9a-f]{24}$/i.test(matchValueStr);
|
|
181
|
-
// Try to search normally first, catch errors for invalid IDs
|
|
182
186
|
try {
|
|
183
|
-
|
|
187
|
+
existingDocResult = await req.payload.find({
|
|
184
188
|
collection: collectionSlug,
|
|
185
189
|
depth: 0,
|
|
186
190
|
limit: 1,
|
|
@@ -194,23 +198,19 @@ async function processImportBatch({ batch, batchIndex, collectionSlug, importMod
|
|
|
194
198
|
}
|
|
195
199
|
});
|
|
196
200
|
} catch (error) {
|
|
197
|
-
//
|
|
198
|
-
// and we're in upsert mode, treat as non-existent
|
|
201
|
+
// MongoDB may throw for invalid ObjectID format - handle gracefully for upsert
|
|
199
202
|
if (isMatchingById && importMode === 'upsert' && !isValidObjectIdFormat) {
|
|
200
|
-
|
|
203
|
+
existingDocResult = {
|
|
201
204
|
docs: []
|
|
202
205
|
};
|
|
203
206
|
} else if (isMatchingById && importMode === 'update' && !isValidObjectIdFormat) {
|
|
204
|
-
// For update mode with invalid ID, this should fail
|
|
205
207
|
throw new Error(`Invalid ID format for update: ${matchValueStr}`);
|
|
206
208
|
} else {
|
|
207
|
-
// Re-throw other errors
|
|
208
209
|
throw error;
|
|
209
210
|
}
|
|
210
211
|
}
|
|
211
|
-
if (
|
|
212
|
-
|
|
213
|
-
const existingDoc = existing.docs[0];
|
|
212
|
+
if (existingDocResult.docs.length > 0) {
|
|
213
|
+
const existingDoc = existingDocResult.docs[0];
|
|
214
214
|
if (!existingDoc) {
|
|
215
215
|
throw new Error(`Document not found`);
|
|
216
216
|
}
|
|
@@ -250,7 +250,7 @@ async function processImportBatch({ batch, batchIndex, collectionSlug, importMod
|
|
|
250
250
|
}
|
|
251
251
|
if (hasMultiLocale) {
|
|
252
252
|
// Update with default locale data
|
|
253
|
-
|
|
253
|
+
savedDocument = await req.payload.update({
|
|
254
254
|
id: existingDoc.id,
|
|
255
255
|
collection: collectionSlug,
|
|
256
256
|
data: flatData,
|
|
@@ -261,7 +261,7 @@ async function processImportBatch({ batch, batchIndex, collectionSlug, importMod
|
|
|
261
261
|
user
|
|
262
262
|
});
|
|
263
263
|
// Update for other locales
|
|
264
|
-
if (
|
|
264
|
+
if (savedDocument && Object.keys(localeUpdates).length > 0) {
|
|
265
265
|
for (const [locale, localeData] of Object.entries(localeUpdates)){
|
|
266
266
|
try {
|
|
267
267
|
// Clone the request with the specific locale
|
|
@@ -302,7 +302,7 @@ async function processImportBatch({ batch, batchIndex, collectionSlug, importMod
|
|
|
302
302
|
}
|
|
303
303
|
// Update the document - don't specify draft to let Payload handle versions properly
|
|
304
304
|
// This will create a new draft version for collections with versions enabled
|
|
305
|
-
|
|
305
|
+
savedDocument = await req.payload.update({
|
|
306
306
|
id: existingDoc.id,
|
|
307
307
|
collection: collectionSlug,
|
|
308
308
|
data: updateData,
|
|
@@ -312,13 +312,12 @@ async function processImportBatch({ batch, batchIndex, collectionSlug, importMod
|
|
|
312
312
|
req,
|
|
313
313
|
user
|
|
314
314
|
});
|
|
315
|
-
|
|
316
|
-
if (req.payload.config.debug && processedDoc) {
|
|
315
|
+
if (req.payload.config.debug && savedDocument) {
|
|
317
316
|
req.payload.logger.info({
|
|
318
|
-
id:
|
|
317
|
+
id: savedDocument.id,
|
|
319
318
|
msg: 'Update completed',
|
|
320
|
-
status:
|
|
321
|
-
title:
|
|
319
|
+
status: savedDocument._status,
|
|
320
|
+
title: savedDocument.title
|
|
322
321
|
});
|
|
323
322
|
}
|
|
324
323
|
} catch (updateError) {
|
|
@@ -351,13 +350,14 @@ async function processImportBatch({ batch, batchIndex, collectionSlug, importMod
|
|
|
351
350
|
const statusValue = createData._status || options.defaultVersionStatus;
|
|
352
351
|
const isPublished = statusValue !== 'draft';
|
|
353
352
|
draftOption = !isPublished;
|
|
354
|
-
|
|
353
|
+
// Remove _status from data - it's controlled via draft option
|
|
354
|
+
delete createData._status;
|
|
355
355
|
}
|
|
356
356
|
// Check if we have multi-locale data and extract it
|
|
357
357
|
const { flatData, hasMultiLocale, localeUpdates } = extractMultiLocaleData(createData, configuredLocales);
|
|
358
358
|
if (hasMultiLocale) {
|
|
359
359
|
// Create with default locale data
|
|
360
|
-
|
|
360
|
+
savedDocument = await req.payload.create({
|
|
361
361
|
collection: collectionSlug,
|
|
362
362
|
data: flatData,
|
|
363
363
|
draft: draftOption,
|
|
@@ -366,7 +366,7 @@ async function processImportBatch({ batch, batchIndex, collectionSlug, importMod
|
|
|
366
366
|
user
|
|
367
367
|
});
|
|
368
368
|
// Update for other locales
|
|
369
|
-
if (
|
|
369
|
+
if (savedDocument && Object.keys(localeUpdates).length > 0) {
|
|
370
370
|
for (const [locale, localeData] of Object.entries(localeUpdates)){
|
|
371
371
|
try {
|
|
372
372
|
// Clone the request with the specific locale
|
|
@@ -375,7 +375,7 @@ async function processImportBatch({ batch, batchIndex, collectionSlug, importMod
|
|
|
375
375
|
locale
|
|
376
376
|
};
|
|
377
377
|
await req.payload.update({
|
|
378
|
-
id:
|
|
378
|
+
id: savedDocument.id,
|
|
379
379
|
collection: collectionSlug,
|
|
380
380
|
data: localeData,
|
|
381
381
|
draft: collectionHasVersions ? false : undefined,
|
|
@@ -386,14 +386,14 @@ async function processImportBatch({ batch, batchIndex, collectionSlug, importMod
|
|
|
386
386
|
// Log but don't fail the entire import if a locale update fails
|
|
387
387
|
req.payload.logger.error({
|
|
388
388
|
err: error,
|
|
389
|
-
msg: `Failed to update locale ${locale} for document ${String(
|
|
389
|
+
msg: `Failed to update locale ${locale} for document ${String(savedDocument.id)}`
|
|
390
390
|
});
|
|
391
391
|
}
|
|
392
392
|
}
|
|
393
393
|
}
|
|
394
394
|
} else {
|
|
395
395
|
// No multi-locale data, create normally
|
|
396
|
-
|
|
396
|
+
savedDocument = await req.payload.create({
|
|
397
397
|
collection: collectionSlug,
|
|
398
398
|
data: createData,
|
|
399
399
|
draft: draftOption,
|
|
@@ -420,7 +420,7 @@ async function processImportBatch({ batch, batchIndex, collectionSlug, importMod
|
|
|
420
420
|
} else {
|
|
421
421
|
throw new Error(`Unknown import mode: ${String(importMode)}`);
|
|
422
422
|
}
|
|
423
|
-
if (
|
|
423
|
+
if (savedDocument) {
|
|
424
424
|
// Determine operation type for proper counting
|
|
425
425
|
let operation;
|
|
426
426
|
if (importMode === 'create') {
|
|
@@ -428,8 +428,7 @@ async function processImportBatch({ batch, batchIndex, collectionSlug, importMod
|
|
|
428
428
|
} else if (importMode === 'update') {
|
|
429
429
|
operation = 'updated';
|
|
430
430
|
} else if (importMode === 'upsert') {
|
|
431
|
-
|
|
432
|
-
if (existing && existing.docs.length > 0) {
|
|
431
|
+
if (existingDocResult && existingDocResult.docs.length > 0) {
|
|
433
432
|
operation = 'updated';
|
|
434
433
|
} else {
|
|
435
434
|
operation = 'created';
|
|
@@ -439,7 +438,7 @@ async function processImportBatch({ batch, batchIndex, collectionSlug, importMod
|
|
|
439
438
|
document,
|
|
440
439
|
index: rowNumber - 1,
|
|
441
440
|
operation,
|
|
442
|
-
result:
|
|
441
|
+
result: savedDocument
|
|
443
442
|
});
|
|
444
443
|
}
|
|
445
444
|
} catch (error) {
|