@payloadcms/plugin-import-export 4.0.0-internal.ea6e8f8 → 4.0.0-internal.ec73d44
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/FormatField/index.d.ts.map +1 -1
- package/dist/components/FormatField/index.js.map +1 -1
- package/dist/export/createExport.js.map +1 -1
- package/dist/export/getFields.js.map +1 -1
- package/dist/export/handlePreview.js.map +1 -1
- package/dist/import/batchProcessor.js.map +1 -1
- package/dist/import/handlePreview.js.map +1 -1
- package/dist/utilities/applyFieldHooks.js.map +1 -1
- package/dist/utilities/getFileFromDoc.js.map +1 -1
- package/package.json +24 -27
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/FormatField/index.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAA;AAGrD,OAAO,KAA0C,MAAM,OAAO,CAAA;AAW9D,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/FormatField/index.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAA;AAGrD,OAAO,KAA0C,MAAM,OAAO,CAAA;AAW9D,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAgExD,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/FormatField/index.tsx"],"sourcesContent":["'use client'\n\nimport type { ReactSelectOption } from '@payloadcms/ui'\nimport type { SelectFieldClientProps } from 'payload'\n\nimport { FieldLabel, ReactSelect, useConfig, useField } from '@payloadcms/ui'\nimport React, { useCallback, useEffect, useMemo } from 'react'\n\nconst baseClass = 'field-type select'\n\ntype Format = 'csv' | 'json'\n\nconst allOptions: ReactSelectOption[] = [\n { label: 'CSV', value: 'csv' },\n { label: 'JSON', value: 'json' },\n]\n\nexport const FormatField: React.FC<SelectFieldClientProps> = (props) => {\n const { getEntityConfig } = useConfig()\n const width = props.field.admin?.width\n\n const styles = useMemo<React.CSSProperties>(\n () => ({ '--field-width': width }) as React.CSSProperties,\n [width],\n )\n\n const { setValue, value: formatValue } = useField<Format>()\n const { value: targetCollectionSlug } = useField<string>({ path: 'collectionSlug' })\n\n const targetCollectionConfig = getEntityConfig({ collectionSlug: targetCollectionSlug })\n const forcedFormat = targetCollectionConfig?.admin?.custom?.['plugin-import-export']
|
|
1
|
+
{"version":3,"sources":["../../../src/components/FormatField/index.tsx"],"sourcesContent":["'use client'\n\nimport type { ReactSelectOption } from '@payloadcms/ui'\nimport type { SelectFieldClientProps } from 'payload'\n\nimport { FieldLabel, ReactSelect, useConfig, useField } from '@payloadcms/ui'\nimport React, { useCallback, useEffect, useMemo } from 'react'\n\nconst baseClass = 'field-type select'\n\ntype Format = 'csv' | 'json'\n\nconst allOptions: ReactSelectOption[] = [\n { label: 'CSV', value: 'csv' },\n { label: 'JSON', value: 'json' },\n]\n\nexport const FormatField: React.FC<SelectFieldClientProps> = (props) => {\n const { getEntityConfig } = useConfig()\n const width = props.field.admin?.width\n\n const styles = useMemo<React.CSSProperties>(\n () => ({ '--field-width': width }) as React.CSSProperties,\n [width],\n )\n\n const { setValue, value: formatValue } = useField<Format>()\n const { value: targetCollectionSlug } = useField<string>({ path: 'collectionSlug' })\n\n const targetCollectionConfig = getEntityConfig({ collectionSlug: targetCollectionSlug })\n const forcedFormat = targetCollectionConfig?.admin?.custom?.['plugin-import-export']?.exportFormat\n\n const options = useMemo<ReactSelectOption[]>(() => {\n if (forcedFormat) {\n return [{ label: forcedFormat.toUpperCase(), value: forcedFormat }]\n }\n return allOptions\n }, [forcedFormat])\n\n const selectedOption = useMemo<ReactSelectOption | undefined>(() => {\n const effectiveValue = forcedFormat || formatValue || 'csv'\n return options.find((o) => o.value === effectiveValue) ?? options[0]\n }, [forcedFormat, formatValue, options])\n\n useEffect(() => {\n if (forcedFormat && formatValue !== forcedFormat) {\n setValue(forcedFormat)\n }\n }, [forcedFormat, formatValue, setValue])\n\n const handleChange = useCallback(\n (selected: ReactSelectOption | ReactSelectOption[]) => {\n if (forcedFormat) {\n return\n }\n if (Array.isArray(selected)) {\n setValue(selected[0]?.value ?? 'csv')\n } else {\n setValue(selected?.value ?? 'csv')\n }\n },\n [forcedFormat, setValue],\n )\n\n const isReadOnly = Boolean(forcedFormat) || props.readOnly\n\n return (\n <div className={baseClass} style={styles}>\n <FieldLabel label={props.field.label} path={props.path} />\n <ReactSelect\n className={'format-field'}\n disabled={isReadOnly}\n inputId={`field-${props.path.replace(/\\./g, '__')}`}\n isClearable={false}\n isSearchable={false}\n onChange={handleChange}\n options={options}\n value={selectedOption}\n />\n </div>\n )\n}\n"],"names":["FieldLabel","ReactSelect","useConfig","useField","React","useCallback","useEffect","useMemo","baseClass","allOptions","label","value","FormatField","props","getEntityConfig","width","field","admin","styles","setValue","formatValue","targetCollectionSlug","path","targetCollectionConfig","collectionSlug","forcedFormat","custom","exportFormat","options","toUpperCase","selectedOption","effectiveValue","find","o","handleChange","selected","Array","isArray","isReadOnly","Boolean","readOnly","div","className","style","disabled","inputId","replace","isClearable","isSearchable","onChange"],"mappings":"AAAA;;AAKA,SAASA,UAAU,EAAEC,WAAW,EAAEC,SAAS,EAAEC,QAAQ,QAAQ,iBAAgB;AAC7E,OAAOC,SAASC,WAAW,EAAEC,SAAS,EAAEC,OAAO,QAAQ,QAAO;AAE9D,MAAMC,YAAY;AAIlB,MAAMC,aAAkC;IACtC;QAAEC,OAAO;QAAOC,OAAO;IAAM;IAC7B;QAAED,OAAO;QAAQC,OAAO;IAAO;CAChC;AAED,OAAO,MAAMC,cAAgD,CAACC;IAC5D,MAAM,EAAEC,eAAe,EAAE,GAAGZ;IAC5B,MAAMa,QAAQF,MAAMG,KAAK,CAACC,KAAK,EAAEF;IAEjC,MAAMG,SAASX,QACb,IAAO,CAAA;YAAE,iBAAiBQ;QAAM,CAAA,GAChC;QAACA;KAAM;IAGT,MAAM,EAAEI,QAAQ,EAAER,OAAOS,WAAW,EAAE,GAAGjB;IACzC,MAAM,EAAEQ,OAAOU,oBAAoB,EAAE,GAAGlB,SAAiB;QAAEmB,MAAM;IAAiB;IAElF,MAAMC,yBAAyBT,gBAAgB;QAAEU,gBAAgBH;IAAqB;IACtF,MAAMI,eAAeF,wBAAwBN,OAAOS,QAAQ,CAAC,uBAAuB,EAAEC;IAEtF,MAAMC,UAAUrB,QAA6B;QAC3C,IAAIkB,cAAc;YAChB,OAAO;gBAAC;oBAAEf,OAAOe,aAAaI,WAAW;oBAAIlB,OAAOc;gBAAa;aAAE;QACrE;QACA,OAAOhB;IACT,GAAG;QAACgB;KAAa;IAEjB,MAAMK,iBAAiBvB,QAAuC;QAC5D,MAAMwB,iBAAiBN,gBAAgBL,eAAe;QACtD,OAAOQ,QAAQI,IAAI,CAAC,CAACC,IAAMA,EAAEtB,KAAK,KAAKoB,mBAAmBH,OAAO,CAAC,EAAE;IACtE,GAAG;QAACH;QAAcL;QAAaQ;KAAQ;IAEvCtB,UAAU;QACR,IAAImB,gBAAgBL,gBAAgBK,cAAc;YAChDN,SAASM;QACX;IACF,GAAG;QAACA;QAAcL;QAAaD;KAAS;IAExC,MAAMe,eAAe7B,YACnB,CAAC8B;QACC,IAAIV,cAAc;YAChB;QACF;QACA,IAAIW,MAAMC,OAAO,CAACF,WAAW;YAC3BhB,SAASgB,QAAQ,CAAC,EAAE,EAAExB,SAAS;QACjC,OAAO;YACLQ,SAASgB,UAAUxB,SAAS;QAC9B;IACF,GACA;QAACc;QAAcN;KAAS;IAG1B,MAAMmB,aAAaC,QAAQd,iBAAiBZ,MAAM2B,QAAQ;IAE1D,qBACE,MAACC;QAAIC,WAAWlC;QAAWmC,OAAOzB;;0BAChC,KAAClB;gBAAWU,OAAOG,MAAMG,KAAK,CAACN,KAAK;gBAAEY,MAAMT,MAAMS,IAAI;;0BACtD,KAACrB;gBACCyC,WAAW;gBACXE,UAAUN;gBACVO,SAAS,CAAC,MAAM,EAAEhC,MAAMS,IAAI,CAACwB,OAAO,CAAC,OAAO,OAAO;gBACnDC,aAAa;gBACbC,cAAc;gBACdC,UAAUf;gBACVN,SAASA;gBACTjB,OAAOmB;;;;AAIf,EAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/export/createExport.ts"],"sourcesContent":["/* eslint-disable perfectionist/sort-objects */\nimport type { PayloadRequest, Sort, User, Where } from 'payload'\n\nimport { stringify } from 'csv-stringify/sync'\nimport { APIError } from 'payload'\nimport { Readable } from 'stream'\n\nimport type { ExportDoc } from '../types.js'\n\nimport { applyFieldHooks } from '../utilities/applyFieldHooks.js'\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 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 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 exportDoc: ExportDoc\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 exportDoc,\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 msg: '[createExport] Starting export process',\n exportDocId: id,\n exportName: nameArg,\n collectionSlug,\n exportCollection,\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: undefined | User\n\n if (userCollection && userID) {\n user = (await req.payload.findByID({\n id: userID,\n collection: userCollection,\n overrideAccess: true,\n })) as User\n }\n\n if (!user && req.user) {\n user = req.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 baseName = nameArg ?? getFilename()\n const name = `${baseName}-${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({ isCSV, locale, msg: 'Export configuration:', name })\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 collectionSlug,\n msg: 'Access denied for collection, creating empty export',\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({ findArgs, msg: 'Find arguments:' })\n }\n\n const exportFieldHooks = getExportFieldFunctions({\n fields: collectionConfig.flattenedFields,\n })\n\n const exportHooks = collectionConfig.custom?.['plugin-import-export']?.exportHooks\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: unknown, parentPath = ''): unknown => {\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, unknown> = {}\n for (const [key, value] of Object.entries(doc as Record<string, unknown>)) {\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 currentBatchPage = adjustedPage\n let fetched = 0\n const maxDocs =\n typeof maxExportDocuments === 'number' ? maxExportDocuments : Number.POSITIVE_INFINITY\n\n const effectiveStreamDocs =\n typeof maxExportDocuments === 'number' ? Math.min(totalDocs, maxExportDocuments) : totalDocs\n const totalBatches = effectiveStreamDocs > 0 ? Math.ceil(effectiveStreamDocs / batchSize) : 1\n let streamBatchNumber = 0\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 streamBatchNumber++\n\n if (isCSV) {\n // --- CSV Streaming ---\n const batchRows = result.docs.map((doc) =>\n filterDisabledCSV(\n flattenObject({\n data: doc as Record<string, unknown>,\n fields,\n format,\n exportFieldHooks,\n req,\n }),\n ),\n )\n\n const originalDocs = result.docs as Record<string, unknown>[]\n let batchRowsToWrite = batchRows\n if (exportHooks?.before && batchRows.length > 0) {\n batchRowsToWrite = await exportHooks.before({\n batchNumber: streamBatchNumber,\n data: batchRows,\n exportDoc,\n format,\n originalData: originalDocs,\n req,\n totalBatches,\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 batchRowsToWrite) {\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 // When a before hook is active and rows exist, restrict to columns actually present\n // in the data so that the hook can remove fields by not returning them.\n const mergedColumns = mergeColumns(schemaColumns, dataColumns)\n allColumns =\n Boolean(exportHooks?.before) && batchRowsToWrite.length > 0\n ? mergedColumns.filter((col) => dataColumns.includes(col))\n : mergedColumns\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 = batchRowsToWrite.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\n if (exportHooks?.after && batchRowsToWrite.length > 0) {\n await exportHooks.after({\n batchNumber: streamBatchNumber,\n data: batchRowsToWrite,\n exportDoc,\n format,\n originalData: originalDocs,\n req,\n totalBatches,\n })\n }\n } else {\n // --- JSON Streaming ---\n const batchRows = result.docs.map(\n (doc) =>\n filterDisabledJSON(\n applyFieldHooks({\n data: doc as Record<string, unknown>,\n fieldHooks: exportFieldHooks,\n fields: collectionConfig.flattenedFields,\n format,\n operation: 'export',\n req,\n type: 'beforeExport',\n }),\n ) as Record<string, unknown>,\n )\n\n const originalDocs = result.docs as Record<string, unknown>[]\n let batchRowsToWrite = batchRows\n if (exportHooks?.before && batchRows.length > 0) {\n batchRowsToWrite = await exportHooks.before({\n batchNumber: streamBatchNumber,\n data: batchRows,\n exportDoc,\n format,\n originalData: originalDocs,\n req,\n totalBatches,\n })\n }\n\n // Convert each filtered/flattened row into JSON string\n const batchJSON = batchRowsToWrite.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 if (exportHooks?.after && batchRowsToWrite.length > 0) {\n await exportHooks.after({\n batchNumber: streamBatchNumber,\n data: batchRowsToWrite,\n exportDoc,\n format,\n originalData: originalDocs,\n req,\n totalBatches,\n })\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; charset=utf-8' : '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(\n flattenObject({\n data: doc as Record<string, unknown>,\n fields,\n format,\n exportFieldHooks,\n req,\n }),\n )\n : (filterDisabledJSON(\n applyFieldHooks({\n data: doc as Record<string, unknown>,\n fieldHooks: exportFieldHooks,\n fields: collectionConfig.flattenedFields,\n format,\n operation: 'export',\n req,\n type: 'beforeExport',\n }),\n ) as Record<string, unknown>)\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 exportDoc,\n findArgs: findArgs as ExportFindArgs,\n format,\n hooks: exportHooks,\n maxDocs:\n typeof maxExportDocuments === 'number' ? maxExportDocuments : Number.POSITIVE_INFINITY,\n req,\n startPage: adjustedPage,\n totalDocs,\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 // When a before hook is active and rows exist, restrict to columns actually present in the data\n // so that the hook can remove fields by not returning them\n const mergedColumns = mergeColumns(schemaColumns, dataColumns)\n const finalColumns =\n Boolean(exportHooks?.before) && rows.length > 0\n ? mergedColumns.filter((col) => dataColumns.includes(col))\n : mergedColumns\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; charset=utf-8' : 'application/json',\n size: buffer.length,\n }\n } else {\n if (debug) {\n req.payload.logger.debug({\n msg: '[createExport] Updating export document with file',\n exportDocId: id,\n exportCollection,\n fileName: name,\n fileSize: buffer.length,\n mimeType: isCSV ? 'text/csv; charset=utf-8' : 'application/json',\n })\n }\n try {\n await req.payload.update({\n id,\n collection: exportCollection,\n data: {},\n file: {\n name,\n data: buffer,\n mimetype: isCSV ? 'text/csv; charset=utf-8' : '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 } catch (error) {\n const errorDetails =\n error instanceof Error\n ? {\n message: error.message,\n name: error.name,\n stack: error.stack,\n // @ts-expect-error - data might exist on Payload errors\n data: error.data,\n }\n : error\n req.payload.logger.error({\n msg: '[createExport] Failed to update export document with file',\n err: errorDetails,\n exportDocId: id,\n exportCollection,\n fileName: name,\n })\n throw error\n }\n }\n if (debug) {\n req.payload.logger.debug('Export process completed successfully')\n }\n}\n"],"names":["stringify","APIError","Readable","applyFieldHooks","buildDisabledFieldRegex","flattenObject","getExportFieldFunctions","getFilename","getSchemaColumns","mergeColumns","getSelect","validateLimitValue","createExportBatchProcessor","createExport","args","id","name","nameArg","batchSize","collectionSlug","debug","download","drafts","draftsFromInput","exportCollection","exportDoc","fields","format","limit","incomingLimit","maxLimit","locale","localeFromInput","page","req","sort","userCollection","userID","where","whereFromInput","localeFromReq","payload","logger","msg","exportDocId","exportName","draft","collectionConfig","config","collections","find","slug","user","findByID","collection","overrideAccess","hasVersions","Boolean","versions","publishedWhere","_status","equals","and","baseName","isCSV","select","Array","isArray","length","undefined","maxExportDocuments","Math","min","totalDocs","accessDenied","countResult","count","error","totalPages","max","ceil","requestedPage","adjustedPage","findArgs","depth","exportFieldHooks","flattenedFields","exportHooks","custom","disabledFields","admin","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","allColumns","columnsFinalized","encoder","TextEncoder","isFirstBatch","currentBatchPage","fetched","maxDocs","Number","POSITIVE_INFINITY","effectiveStreamDocs","totalBatches","streamBatchNumber","stream","read","remaining","push","encode","result","docs","batchRows","data","originalDocs","batchRowsToWrite","before","batchNumber","originalData","dataColumns","seenCols","Set","keys","has","add","mergedColumns","filter","col","dataColumnsCount","finalColumnsCount","paddedRows","fullRow","csvString","bom","header","columns","after","fieldHooks","operation","type","batchJSON","JSON","join","hasNextPage","Response","toWeb","headers","processor","transformDoc","exportResult","fetchedCount","processExport","hooks","startPage","rows","outputData","finalColumns","content","buffer","Buffer","from","file","mimetype","size","fileName","fileSize","mimeType","update","errorDetails","Error","message","stack","err"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/export/createExport.ts"],"sourcesContent":["/* eslint-disable perfectionist/sort-objects */\nimport type { PayloadRequest, Sort, User, Where } from 'payload'\n\nimport { stringify } from 'csv-stringify/sync'\nimport { APIError } from 'payload'\nimport { Readable } from 'stream'\n\nimport type { ExportDoc } from '../types.js'\n\nimport { applyFieldHooks } from '../utilities/applyFieldHooks.js'\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 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 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 exportDoc: ExportDoc\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 exportDoc,\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 msg: '[createExport] Starting export process',\n exportDocId: id,\n exportName: nameArg,\n collectionSlug,\n exportCollection,\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: undefined | User\n\n if (userCollection && userID) {\n user = (await req.payload.findByID({\n id: userID,\n collection: userCollection,\n overrideAccess: true,\n })) as User\n }\n\n if (!user && req.user) {\n user = req.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 baseName = nameArg ?? getFilename()\n const name = `${baseName}-${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({ isCSV, locale, msg: 'Export configuration:', name })\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 collectionSlug,\n msg: 'Access denied for collection, creating empty export',\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({ findArgs, msg: 'Find arguments:' })\n }\n\n const exportFieldHooks = getExportFieldFunctions({\n fields: collectionConfig.flattenedFields,\n })\n\n const exportHooks = collectionConfig.custom?.['plugin-import-export']?.exportHooks\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: unknown, parentPath = ''): unknown => {\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, unknown> = {}\n for (const [key, value] of Object.entries(doc as Record<string, unknown>)) {\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 currentBatchPage = adjustedPage\n let fetched = 0\n const maxDocs =\n typeof maxExportDocuments === 'number' ? maxExportDocuments : Number.POSITIVE_INFINITY\n\n const effectiveStreamDocs =\n typeof maxExportDocuments === 'number' ? Math.min(totalDocs, maxExportDocuments) : totalDocs\n const totalBatches = effectiveStreamDocs > 0 ? Math.ceil(effectiveStreamDocs / batchSize) : 1\n let streamBatchNumber = 0\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 streamBatchNumber++\n\n if (isCSV) {\n // --- CSV Streaming ---\n const batchRows = result.docs.map((doc) =>\n filterDisabledCSV(\n flattenObject({\n data: doc,\n fields,\n format,\n exportFieldHooks,\n req,\n }),\n ),\n )\n\n const originalDocs = result.docs as Record<string, unknown>[]\n let batchRowsToWrite = batchRows\n if (exportHooks?.before && batchRows.length > 0) {\n batchRowsToWrite = await exportHooks.before({\n batchNumber: streamBatchNumber,\n data: batchRows,\n exportDoc,\n format,\n originalData: originalDocs,\n req,\n totalBatches,\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 batchRowsToWrite) {\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 // When a before hook is active and rows exist, restrict to columns actually present\n // in the data so that the hook can remove fields by not returning them.\n const mergedColumns = mergeColumns(schemaColumns, dataColumns)\n allColumns =\n Boolean(exportHooks?.before) && batchRowsToWrite.length > 0\n ? mergedColumns.filter((col) => dataColumns.includes(col))\n : mergedColumns\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 = batchRowsToWrite.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\n if (exportHooks?.after && batchRowsToWrite.length > 0) {\n await exportHooks.after({\n batchNumber: streamBatchNumber,\n data: batchRowsToWrite,\n exportDoc,\n format,\n originalData: originalDocs,\n req,\n totalBatches,\n })\n }\n } else {\n // --- JSON Streaming ---\n const batchRows = result.docs.map(\n (doc) =>\n filterDisabledJSON(\n applyFieldHooks({\n data: doc,\n fieldHooks: exportFieldHooks,\n fields: collectionConfig.flattenedFields,\n format,\n operation: 'export',\n req,\n type: 'beforeExport',\n }),\n ) as Record<string, unknown>,\n )\n\n const originalDocs = result.docs as Record<string, unknown>[]\n let batchRowsToWrite = batchRows\n if (exportHooks?.before && batchRows.length > 0) {\n batchRowsToWrite = await exportHooks.before({\n batchNumber: streamBatchNumber,\n data: batchRows,\n exportDoc,\n format,\n originalData: originalDocs,\n req,\n totalBatches,\n })\n }\n\n // Convert each filtered/flattened row into JSON string\n const batchJSON = batchRowsToWrite.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 if (exportHooks?.after && batchRowsToWrite.length > 0) {\n await exportHooks.after({\n batchNumber: streamBatchNumber,\n data: batchRowsToWrite,\n exportDoc,\n format,\n originalData: originalDocs,\n req,\n totalBatches,\n })\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; charset=utf-8' : '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(\n flattenObject({\n data: doc as Record<string, unknown>,\n fields,\n format,\n exportFieldHooks,\n req,\n }),\n )\n : (filterDisabledJSON(\n applyFieldHooks({\n data: doc as Record<string, unknown>,\n fieldHooks: exportFieldHooks,\n fields: collectionConfig.flattenedFields,\n format,\n operation: 'export',\n req,\n type: 'beforeExport',\n }),\n ) as Record<string, unknown>)\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 exportDoc,\n findArgs: findArgs as ExportFindArgs,\n format,\n hooks: exportHooks,\n maxDocs:\n typeof maxExportDocuments === 'number' ? maxExportDocuments : Number.POSITIVE_INFINITY,\n req,\n startPage: adjustedPage,\n totalDocs,\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 // When a before hook is active and rows exist, restrict to columns actually present in the data\n // so that the hook can remove fields by not returning them\n const mergedColumns = mergeColumns(schemaColumns, dataColumns)\n const finalColumns =\n Boolean(exportHooks?.before) && rows.length > 0\n ? mergedColumns.filter((col) => dataColumns.includes(col))\n : mergedColumns\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; charset=utf-8' : 'application/json',\n size: buffer.length,\n }\n } else {\n if (debug) {\n req.payload.logger.debug({\n msg: '[createExport] Updating export document with file',\n exportDocId: id,\n exportCollection,\n fileName: name,\n fileSize: buffer.length,\n mimeType: isCSV ? 'text/csv; charset=utf-8' : 'application/json',\n })\n }\n try {\n await req.payload.update({\n id,\n collection: exportCollection,\n data: {},\n file: {\n name,\n data: buffer,\n mimetype: isCSV ? 'text/csv; charset=utf-8' : '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 } catch (error) {\n const errorDetails =\n error instanceof Error\n ? {\n message: error.message,\n name: error.name,\n stack: error.stack,\n // @ts-expect-error - data might exist on Payload errors\n data: error.data,\n }\n : error\n req.payload.logger.error({\n msg: '[createExport] Failed to update export document with file',\n err: errorDetails,\n exportDocId: id,\n exportCollection,\n fileName: name,\n })\n throw error\n }\n }\n if (debug) {\n req.payload.logger.debug('Export process completed successfully')\n }\n}\n"],"names":["stringify","APIError","Readable","applyFieldHooks","buildDisabledFieldRegex","flattenObject","getExportFieldFunctions","getFilename","getSchemaColumns","mergeColumns","getSelect","validateLimitValue","createExportBatchProcessor","createExport","args","id","name","nameArg","batchSize","collectionSlug","debug","download","drafts","draftsFromInput","exportCollection","exportDoc","fields","format","limit","incomingLimit","maxLimit","locale","localeFromInput","page","req","sort","userCollection","userID","where","whereFromInput","localeFromReq","payload","logger","msg","exportDocId","exportName","draft","collectionConfig","config","collections","find","slug","user","findByID","collection","overrideAccess","hasVersions","Boolean","versions","publishedWhere","_status","equals","and","baseName","isCSV","select","Array","isArray","length","undefined","maxExportDocuments","Math","min","totalDocs","accessDenied","countResult","count","error","totalPages","max","ceil","requestedPage","adjustedPage","findArgs","depth","exportFieldHooks","flattenedFields","exportHooks","custom","disabledFields","admin","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","allColumns","columnsFinalized","encoder","TextEncoder","isFirstBatch","currentBatchPage","fetched","maxDocs","Number","POSITIVE_INFINITY","effectiveStreamDocs","totalBatches","streamBatchNumber","stream","read","remaining","push","encode","result","docs","batchRows","data","originalDocs","batchRowsToWrite","before","batchNumber","originalData","dataColumns","seenCols","Set","keys","has","add","mergedColumns","filter","col","dataColumnsCount","finalColumnsCount","paddedRows","fullRow","csvString","bom","header","columns","after","fieldHooks","operation","type","batchJSON","JSON","join","hasNextPage","Response","toWeb","headers","processor","transformDoc","exportResult","fetchedCount","processExport","hooks","startPage","rows","outputData","finalColumns","content","buffer","Buffer","from","file","mimetype","size","fileName","fileSize","mimeType","update","errorDetails","Error","message","stack","err"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/export/getFields.ts"],"sourcesContent":["import type { TFunction } from '@payloadcms/translations'\nimport type { Config, Field, PayloadRequest, SelectField } from 'payload'\n\nimport { getFilename } from '../utilities/getFilename.js'\nimport { validateLimitValue } from '../utilities/validateLimitValue.js'\n\ntype GetFieldsOptions = {\n /**\n * Collection slugs that this export collection supports.\n * Used for schema/types and as the options in the select field.\n */\n collectionSlugs: string[]\n config: Config\n /**\n * Force a specific format, hiding the format dropdown\n */\n format?: 'csv' | 'json'\n}\n\nexport const getFields = (options: GetFieldsOptions): Field[] => {\n const { collectionSlugs, config, format } = options\n\n let localeField: SelectField | undefined\n\n if (config.localization) {\n localeField = {\n name: 'locale',\n type: 'select',\n admin: {\n components: {\n Field: '@payloadcms/plugin-import-export/rsc#LocaleField',\n },\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 components: {\n Field: '@payloadcms/plugin-import-export/rsc#FormatField',\n },\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 components: {\n Field: '@payloadcms/plugin-import-export/rsc#LimitField',\n },\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 defaultValue: collectionSlugs[0],\n required: true,\n validate: (value: null | string | undefined, { req }: { req: PayloadRequest }) => {\n if (!value) {\n return 'Collection is required'\n }\n // Validate that the collection exists\n const collectionExists = req?.payload?.collections?.[value]\n if (!collectionExists) {\n return `Collection \"${value}\" does not exist`\n }\n return true\n },\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","options","collectionSlugs","config","format","localeField","localization","name","type","admin","components","Field","width","defaultValue","label","t","value","locales","map","locale","code","fields","required","placeholder","step","validate","req","condition","limit","sort","trim","length","data","collectionConfig","collections","find","collection","slug","collectionSlug","Boolean","versions","drafts","virtual","hasMany","collectionExists","payload","hidden","hooks","beforeValidate"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/export/getFields.ts"],"sourcesContent":["import type { TFunction } from '@payloadcms/translations'\nimport type { Config, Field, PayloadRequest, SelectField } from 'payload'\n\nimport { getFilename } from '../utilities/getFilename.js'\nimport { validateLimitValue } from '../utilities/validateLimitValue.js'\n\ntype GetFieldsOptions = {\n /**\n * Collection slugs that this export collection supports.\n * Used for schema/types and as the options in the select field.\n */\n collectionSlugs: string[]\n config: Config\n /**\n * Force a specific format, hiding the format dropdown\n */\n format?: 'csv' | 'json'\n}\n\nexport const getFields = (options: GetFieldsOptions): Field[] => {\n const { collectionSlugs, config, format } = options\n\n let localeField: SelectField | undefined\n\n if (config.localization) {\n localeField = {\n name: 'locale',\n type: 'select',\n admin: {\n components: {\n Field: '@payloadcms/plugin-import-export/rsc#LocaleField',\n },\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 components: {\n Field: '@payloadcms/plugin-import-export/rsc#FormatField',\n },\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 components: {\n Field: '@payloadcms/plugin-import-export/rsc#LimitField',\n },\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 defaultValue: collectionSlugs[0],\n required: true,\n validate: (value: null | string | undefined, { req }: { req: PayloadRequest }) => {\n if (!value) {\n return 'Collection is required'\n }\n // Validate that the collection exists\n const collectionExists = req?.payload?.collections?.[value]\n if (!collectionExists) {\n return `Collection \"${value}\" does not exist`\n }\n return true\n },\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","options","collectionSlugs","config","format","localeField","localization","name","type","admin","components","Field","width","defaultValue","label","t","value","locales","map","locale","code","fields","required","placeholder","step","validate","req","condition","limit","sort","trim","length","data","collectionConfig","collections","find","collection","slug","collectionSlug","Boolean","versions","drafts","virtual","hasMany","collectionExists","payload","hidden","hooks","beforeValidate"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/export/handlePreview.ts"],"sourcesContent":["import type { PayloadRequest, Sort, Where } from 'payload'\n\nimport { addDataAndFileToRequest } from 'payload'\nimport { getObjectDotNotation } from 'payload/shared'\n\nimport type { ExportBeforeHook, ExportDoc, 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 { applyFieldHooks } from '../utilities/applyFieldHooks.js'\nimport { flattenObject } from '../utilities/flattenObject.js'\nimport { getExportFieldFunctions } from '../utilities/getExportFieldFunctions.js'\nimport { getFlattenedFieldKeys } from '../utilities/getFlattenedFieldKeys.js'\nimport { getSchemaColumns, mergeColumns } from '../utilities/getSchemaColumns.js'\nimport { getSelect } from '../utilities/getSelect.js'\nimport { getSubmittedFormValues } from '../utilities/getSubmittedFormValues.js'\nimport { removeDisabledFields } from '../utilities/removeDisabledFields.js'\nimport { resolveLimit } from '../utilities/resolveLimit.js'\nimport { setNestedValue } from '../utilities/setNestedValue.js'\n\nconst applyExportBeforeHook = async ({\n data,\n exportDoc,\n format,\n hook,\n originalDocs,\n req,\n}: {\n data: Record<string, unknown>[]\n exportDoc: ExportDoc\n format: 'csv' | 'json' | ({} & string)\n hook: ExportBeforeHook | undefined\n originalDocs: unknown[]\n req: PayloadRequest\n}): Promise<Record<string, unknown>[]> => {\n if (!hook || data.length === 0) {\n return data\n }\n return hook({\n batchNumber: 1,\n data,\n exportDoc,\n format,\n originalData: originalDocs as Record<string, unknown>[],\n req,\n totalBatches: 1,\n })\n}\n\nexport const handlePreview = async (req: PayloadRequest): Promise<Response> => {\n await addDataAndFileToRequest(req)\n\n const {\n collectionSlug,\n draft: draftFromReq,\n fields,\n formData,\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 formData?: Record<string, unknown>\n limit?: number\n locale?: string\n previewLimit?: number\n previewPage?: number\n sort?: Sort\n where?: Where\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 exportDoc = getSubmittedFormValues({\n formData: formData ?? {},\n }) as ExportDoc\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 // Compute schema-based columns for CSV (provides base ordering and handles empty exports)\n const schemaColumns = isCSV\n ? getSchemaColumns({\n collectionConfig: targetCollection.config,\n disabledFields,\n fields,\n locale: locale ?? undefined,\n localeCodes,\n })\n : undefined\n\n // columns will be finalized after data is available (merged with data-discovered columns)\n let columns = schemaColumns\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 const exportFieldHooks = getExportFieldFunctions({\n fields: targetCollection.config.flattenedFields,\n })\n\n const exportHooks = targetCollection.config.custom?.['plugin-import-export']?.exportHooks\n\n if (isCSV) {\n const possibleKeys = getFlattenedFieldKeys(targetCollection.config.flattenedFields, '', {\n localeCodes,\n })\n\n // Flatten docs without padding yet. This preserves the exact keys produced by beforeExport hooks,\n // allowing mergeColumns to detect which schema columns were replaced with derived ones.\n transformed = docs.map((doc) =>\n flattenObject({\n data: doc,\n exportFieldHooks,\n fields,\n format: 'csv',\n req,\n }),\n )\n\n transformed = await applyExportBeforeHook({\n data: transformed,\n exportDoc,\n format: 'csv',\n hook: exportHooks?.before,\n originalDocs: docs,\n req,\n })\n\n if (schemaColumns && transformed.length > 0) {\n const dataColumns: string[] = []\n const seenCols = new Set<string>()\n for (const row of transformed) {\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 const mergedColumns = mergeColumns(schemaColumns, dataColumns)\n columns =\n Boolean(exportHooks?.before) && transformed.length > 0\n ? mergedColumns.filter((col) => dataColumns.includes(col))\n : mergedColumns\n }\n\n // Pad rows with null for missing columns (uses merged columns, not raw schema)\n if (!fields || fields.length === 0) {\n const paddingKeys = columns ?? possibleKeys\n for (const row of transformed) {\n for (const key of paddingKeys) {\n if (!(key in row)) {\n row[key] = null\n }\n }\n }\n }\n } else {\n transformed = docs.map((doc) => {\n // Apply field-level export hooks for JSON format\n let output: Record<string, unknown> = applyFieldHooks({\n type: 'beforeExport',\n data: doc as Record<string, unknown>,\n fieldHooks: exportFieldHooks,\n fields: targetCollection.config.flattenedFields,\n format: 'json',\n operation: 'export',\n req,\n })\n\n // Remove disabled fields\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, output)\n }\n\n output = trimmed\n }\n\n return output\n })\n\n transformed = await applyExportBeforeHook({\n data: transformed,\n exportDoc,\n format: 'json',\n hook: exportHooks?.before,\n originalDocs: docs,\n req,\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","applyFieldHooks","flattenObject","getExportFieldFunctions","getFlattenedFieldKeys","getSchemaColumns","mergeColumns","getSelect","getSubmittedFormValues","removeDisabledFields","resolveLimit","setNestedValue","applyExportBeforeHook","data","exportDoc","format","hook","originalDocs","req","length","batchNumber","originalData","totalBatches","handlePreview","collectionSlug","draft","draftFromReq","fields","formData","limit","exportLimit","locale","previewLimit","rawPreviewLimit","previewPage","rawPreviewPage","sort","where","whereFromReq","Math","max","min","targetCollection","payload","collections","Response","json","error","status","pluginConfig","config","custom","maxLimit","select","Array","isArray","undefined","collectionHasVersions","Boolean","versions","publishedWhere","_status","equals","and","countResult","count","collection","overrideAccess","totalMatchingDocs","totalDocs","effectiveLimit","exportTotalDocs","previewStartIndex","previewTotalPages","ceil","isCSV","localeCodes","localization","disabledFields","admin","schemaColumns","collectionConfig","columns","response","docs","hasNextPage","hasPrevPage","page","totalPages","result","find","depth","remainingInExport","slice","transformed","exportFieldHooks","flattenedFields","exportHooks","possibleKeys","map","doc","before","dataColumns","seenCols","Set","row","key","Object","keys","has","add","push","mergedColumns","filter","col","includes","paddingKeys","output","type","fieldHooks","operation","trimmed","value"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/export/handlePreview.ts"],"sourcesContent":["import type { PayloadRequest, Sort, Where } from 'payload'\n\nimport { addDataAndFileToRequest } from 'payload'\nimport { getObjectDotNotation } from 'payload/shared'\n\nimport type { ExportBeforeHook, ExportDoc, 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 { applyFieldHooks } from '../utilities/applyFieldHooks.js'\nimport { flattenObject } from '../utilities/flattenObject.js'\nimport { getExportFieldFunctions } from '../utilities/getExportFieldFunctions.js'\nimport { getFlattenedFieldKeys } from '../utilities/getFlattenedFieldKeys.js'\nimport { getSchemaColumns, mergeColumns } from '../utilities/getSchemaColumns.js'\nimport { getSelect } from '../utilities/getSelect.js'\nimport { getSubmittedFormValues } from '../utilities/getSubmittedFormValues.js'\nimport { removeDisabledFields } from '../utilities/removeDisabledFields.js'\nimport { resolveLimit } from '../utilities/resolveLimit.js'\nimport { setNestedValue } from '../utilities/setNestedValue.js'\n\nconst applyExportBeforeHook = async ({\n data,\n exportDoc,\n format,\n hook,\n originalDocs,\n req,\n}: {\n data: Record<string, unknown>[]\n exportDoc: ExportDoc\n format: 'csv' | 'json' | ({} & string)\n hook: ExportBeforeHook | undefined\n originalDocs: unknown[]\n req: PayloadRequest\n}): Promise<Record<string, unknown>[]> => {\n if (!hook || data.length === 0) {\n return data\n }\n return hook({\n batchNumber: 1,\n data,\n exportDoc,\n format,\n originalData: originalDocs as Record<string, unknown>[],\n req,\n totalBatches: 1,\n })\n}\n\nexport const handlePreview = async (req: PayloadRequest): Promise<Response> => {\n await addDataAndFileToRequest(req)\n\n const {\n collectionSlug,\n draft: draftFromReq,\n fields,\n formData,\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 formData?: Record<string, unknown>\n limit?: number\n locale?: string\n previewLimit?: number\n previewPage?: number\n sort?: Sort\n where?: Where\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 exportDoc = getSubmittedFormValues({\n formData: formData ?? {},\n }) as ExportDoc\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 // Compute schema-based columns for CSV (provides base ordering and handles empty exports)\n const schemaColumns = isCSV\n ? getSchemaColumns({\n collectionConfig: targetCollection.config,\n disabledFields,\n fields,\n locale: locale ?? undefined,\n localeCodes,\n })\n : undefined\n\n // columns will be finalized after data is available (merged with data-discovered columns)\n let columns = schemaColumns\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 const exportFieldHooks = getExportFieldFunctions({\n fields: targetCollection.config.flattenedFields,\n })\n\n const exportHooks = targetCollection.config.custom?.['plugin-import-export']?.exportHooks\n\n if (isCSV) {\n const possibleKeys = getFlattenedFieldKeys(targetCollection.config.flattenedFields, '', {\n localeCodes,\n })\n\n // Flatten docs without padding yet. This preserves the exact keys produced by beforeExport hooks,\n // allowing mergeColumns to detect which schema columns were replaced with derived ones.\n transformed = docs.map((doc) =>\n flattenObject({\n data: doc,\n exportFieldHooks,\n fields,\n format: 'csv',\n req,\n }),\n )\n\n transformed = await applyExportBeforeHook({\n data: transformed,\n exportDoc,\n format: 'csv',\n hook: exportHooks?.before,\n originalDocs: docs,\n req,\n })\n\n if (schemaColumns && transformed.length > 0) {\n const dataColumns: string[] = []\n const seenCols = new Set<string>()\n for (const row of transformed) {\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 const mergedColumns = mergeColumns(schemaColumns, dataColumns)\n columns =\n Boolean(exportHooks?.before) && transformed.length > 0\n ? mergedColumns.filter((col) => dataColumns.includes(col))\n : mergedColumns\n }\n\n // Pad rows with null for missing columns (uses merged columns, not raw schema)\n if (!fields || fields.length === 0) {\n const paddingKeys = columns ?? possibleKeys\n for (const row of transformed) {\n for (const key of paddingKeys) {\n if (!(key in row)) {\n row[key] = null\n }\n }\n }\n }\n } else {\n transformed = docs.map((doc) => {\n // Apply field-level export hooks for JSON format\n let output: Record<string, unknown> = applyFieldHooks({\n type: 'beforeExport',\n data: doc,\n fieldHooks: exportFieldHooks,\n fields: targetCollection.config.flattenedFields,\n format: 'json',\n operation: 'export',\n req,\n })\n\n // Remove disabled fields\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, output)\n }\n\n output = trimmed\n }\n\n return output\n })\n\n transformed = await applyExportBeforeHook({\n data: transformed,\n exportDoc,\n format: 'json',\n hook: exportHooks?.before,\n originalDocs: docs,\n req,\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","applyFieldHooks","flattenObject","getExportFieldFunctions","getFlattenedFieldKeys","getSchemaColumns","mergeColumns","getSelect","getSubmittedFormValues","removeDisabledFields","resolveLimit","setNestedValue","applyExportBeforeHook","data","exportDoc","format","hook","originalDocs","req","length","batchNumber","originalData","totalBatches","handlePreview","collectionSlug","draft","draftFromReq","fields","formData","limit","exportLimit","locale","previewLimit","rawPreviewLimit","previewPage","rawPreviewPage","sort","where","whereFromReq","Math","max","min","targetCollection","payload","collections","Response","json","error","status","pluginConfig","config","custom","maxLimit","select","Array","isArray","undefined","collectionHasVersions","Boolean","versions","publishedWhere","_status","equals","and","countResult","count","collection","overrideAccess","totalMatchingDocs","totalDocs","effectiveLimit","exportTotalDocs","previewStartIndex","previewTotalPages","ceil","isCSV","localeCodes","localization","disabledFields","admin","schemaColumns","collectionConfig","columns","response","docs","hasNextPage","hasPrevPage","page","totalPages","result","find","depth","remainingInExport","slice","transformed","exportFieldHooks","flattenedFields","exportHooks","possibleKeys","map","doc","before","dataColumns","seenCols","Set","row","key","Object","keys","has","add","push","mergedColumns","filter","col","includes","paddingKeys","output","type","fieldHooks","operation","trimmed","value"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/import/batchProcessor.ts"],"sourcesContent":["import type { PayloadRequest, User } from 'payload'\n\nimport { getDataLoader, isolateObjectProperty } from 'payload'\n\nimport type { ImportAfterHook, ImportBeforeHook, ImportDoc, ImportResult } from '../types.js'\nimport type { ImportMode } from './createImport.js'\n\nimport {\n type BatchError,\n categorizeError,\n createBatches,\n extractErrorMessage,\n} from '../utilities/useBatchProcessor.js'\n\n/**\n * Import-specific batch processor options\n */\nexport interface ImportBatchProcessorOptions {\n batchSize?: number\n defaultVersionStatus?: 'draft' | 'published'\n}\n\n/**\n * Import-specific error type extending the generic BatchError\n */\nexport interface ImportError extends BatchError<Record<string, unknown>> {\n documentData: Record<string, unknown>\n field?: string\n fieldLabel?: string\n rowNumber: number // 1-indexed for user clarity\n}\n\n/**\n * Result from processing a single import batch\n */\nexport interface ImportBatchResult {\n failed: Array<ImportError>\n successful: Array<{\n document: Record<string, unknown>\n index: number\n operation?: 'created' | 'updated'\n result: Record<string, unknown>\n }>\n}\n\n/**\n * Options for processing an import operation\n */\nexport interface ImportProcessOptions {\n collectionSlug: string\n docs: Record<string, unknown>[]\n /** Export format — passed through to hook args */\n format?: 'csv' | 'json'\n /** Lifecycle hooks for this import operation */\n hooks?: {\n after?: ImportAfterHook\n before?: ImportBeforeHook\n }\n importDoc: ImportDoc\n importMode: ImportMode\n matchField?: string\n /** Raw parsed rows before unflattening — used as originalData in hooks */\n originalDocs?: Record<string, unknown>[]\n req: PayloadRequest\n /** Total number of batches (pre-computed for hook args) */\n totalBatches?: number\n user?: User\n}\n\n/**\n * Separates multi-locale data from a document for sequential locale updates.\n *\n * When a field has locale-keyed values (e.g., { title: { en: 'Hello', es: 'Hola' } }),\n * this extracts the default locale's data for initial create/update, and stores\n * remaining locales for subsequent update calls.\n *\n * @returns\n * - flatData: Document with default locale values extracted (for initial operation)\n * - hasMultiLocale: Whether any multi-locale fields were found\n * - localeUpdates: Map of locale -> field data for follow-up updates\n */\nfunction extractMultiLocaleData(\n data: Record<string, unknown>,\n configuredLocales?: string[],\n defaultLocale?: string,\n): {\n flatData: Record<string, unknown>\n hasMultiLocale: boolean\n localeUpdates: Record<string, Record<string, unknown>>\n} {\n const flatData: Record<string, unknown> = {}\n const localeUpdates: Record<string, Record<string, unknown>> = {}\n let hasMultiLocale = false\n\n if (!configuredLocales || configuredLocales.length === 0) {\n return { flatData: { ...data }, hasMultiLocale: false, localeUpdates: {} }\n }\n\n const localeSet = new Set(configuredLocales)\n\n for (const [key, value] of Object.entries(data)) {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const valueObj = value as Record<string, unknown>\n const localeKeys = Object.keys(valueObj).filter((k) => localeSet.has(k))\n\n if (localeKeys.length > 0) {\n hasMultiLocale = true\n const baseLocale =\n defaultLocale && localeKeys.includes(defaultLocale) ? defaultLocale : localeKeys[0]\n if (baseLocale) {\n flatData[key] = valueObj[baseLocale]\n for (const locale of localeKeys) {\n if (locale !== baseLocale) {\n if (!localeUpdates[locale]) {\n localeUpdates[locale] = {}\n }\n localeUpdates[locale][key] = valueObj[locale]\n }\n }\n }\n } else {\n flatData[key] = value\n }\n } else {\n flatData[key] = value\n }\n }\n\n return { flatData, hasMultiLocale, localeUpdates }\n}\n\ntype ProcessImportBatchOptions = {\n batch: Record<string, unknown>[]\n batchIndex: number\n collectionSlug: string\n importMode: ImportMode\n matchField: string | undefined\n options: { batchSize: number; defaultVersionStatus: 'draft' | 'published' }\n req: PayloadRequest\n user?: User\n}\n\n/**\n * Processes a batch of documents for import based on the import mode.\n *\n * For each document in the batch:\n * - create: Creates a new document (removes any existing ID)\n * - update: Finds existing document by matchField and updates it\n * - upsert: Updates if found, creates if not found\n *\n * Handles versioned collections, multi-locale data, and MongoDB ObjectID validation.\n * Continues processing remaining documents even if individual imports fail.\n */\nasync function processImportBatch({\n batch,\n batchIndex,\n collectionSlug,\n importMode,\n matchField,\n options,\n req: reqFromArgs,\n user,\n}: ProcessImportBatchOptions): Promise<ImportBatchResult> {\n const result: ImportBatchResult = {\n failed: [],\n successful: [],\n }\n // Isolate + clear `transactionID` so a failing nested op (e.g. Forbidden) kills its own\n // transaction, not the parent's, on `killTransaction`.\n // Also isolate `payloadDataLoader`: the shared loader mutates the parent's `req.transactionID`\n // while batching relationship population (`batchAndLoadDocs`), so populating a nested doc's\n // relationship (e.g. authorship `createdBy`/`updatedBy`) would leak the nested transaction onto\n // the parent. A fresh loader keeps each request's transaction isolated.\n const req = isolateObjectProperty(reqFromArgs, ['payloadDataLoader', 'transactionID'])\n req.transactionID = undefined\n req.payloadDataLoader = getDataLoader(req)\n\n const collectionEntry = req.payload.collections[collectionSlug]\n\n const collectionConfig = collectionEntry?.config\n const collectionHasVersions = Boolean(collectionConfig?.versions)\n const hasCustomIdField = Boolean(collectionEntry?.customIDType)\n\n const configuredLocales = req.payload.config.localization\n ? req.payload.config.localization.localeCodes\n : undefined\n\n const defaultLocale = req.payload.config.localization\n ? req.payload.config.localization.defaultLocale\n : undefined\n\n const startingRowNumber = batchIndex * options.batchSize\n\n for (let i = 0; i < batch.length; i++) {\n const document = batch[i]\n if (!document) {\n continue\n }\n const rowNumber = startingRowNumber + i + 1\n\n try {\n let savedDocument: Record<string, unknown> | undefined\n let existingDocResult: { docs: Array<Record<string, unknown>> } | undefined\n\n if (importMode === 'create') {\n const createData = { ...document }\n if (!hasCustomIdField) {\n delete createData.id\n }\n\n let draftOption: boolean | undefined\n if (collectionHasVersions) {\n const statusValue = createData._status || options.defaultVersionStatus\n const isPublished = statusValue !== 'draft'\n draftOption = !isPublished\n createData._status = statusValue\n\n if (req.payload.config.debug) {\n req.payload.logger.info({\n _status: createData._status,\n isPublished,\n msg: 'Status handling in create',\n willSetDraft: draftOption,\n })\n }\n }\n\n if (req.payload.config.debug && 'title' in createData) {\n req.payload.logger.info({\n msg: 'Creating document',\n title: createData.title,\n titleIsNull: createData.title === null,\n titleType: typeof createData.title,\n })\n }\n\n // Check if we have multi-locale data and extract it\n const { flatData, hasMultiLocale, localeUpdates } = extractMultiLocaleData(\n createData,\n configuredLocales,\n defaultLocale,\n )\n\n if (hasMultiLocale) {\n // Create with default locale data\n const defaultLocaleReq = defaultLocale ? { ...req, locale: defaultLocale } : req\n savedDocument = await req.payload.create({\n collection: collectionSlug,\n data: flatData,\n draft: draftOption,\n overrideAccess: false,\n req: defaultLocaleReq,\n user,\n })\n\n if (savedDocument && Object.keys(localeUpdates).length > 0) {\n for (const [locale, localeData] of Object.entries(localeUpdates)) {\n try {\n await req.payload.update({\n id: savedDocument.id as number | string,\n collection: collectionSlug,\n data: localeData,\n draft: collectionHasVersions ? false : undefined,\n overrideAccess: false,\n req: { ...req, locale },\n user,\n })\n } catch (error) {\n req.payload.logger.error({\n err: error,\n msg: `Failed to update locale ${locale} for document ${String(savedDocument.id)}`,\n })\n }\n }\n }\n } else {\n // No multi-locale data, create normally\n savedDocument = await req.payload.create({\n collection: collectionSlug,\n data: createData,\n draft: draftOption,\n overrideAccess: false,\n req,\n user,\n })\n }\n } else if (importMode === 'update' || importMode === 'upsert') {\n const matchValue = document[matchField || 'id']\n if (!matchValue) {\n throw new Error(`Match field \"${matchField || 'id'}\" not found in document`)\n }\n\n // Special handling for ID field with MongoDB\n // If matching by 'id' and it's not a valid ObjectID format, handle specially\n const isMatchingById = (matchField || 'id') === 'id'\n\n // Check if it's a valid MongoDB ObjectID format (24 hex chars)\n // Note: matchValue could be string, number, or ObjectID object\n let matchValueStr: string\n if (typeof matchValue === 'object' && matchValue !== null) {\n matchValueStr = JSON.stringify(matchValue)\n } else if (typeof matchValue === 'string') {\n matchValueStr = matchValue\n } else if (typeof matchValue === 'number') {\n matchValueStr = matchValue.toString()\n } else {\n // For other types, use JSON.stringify\n matchValueStr = JSON.stringify(matchValue)\n }\n const isValidObjectIdFormat = /^[0-9a-f]{24}$/i.test(matchValueStr)\n\n try {\n existingDocResult = await req.payload.find({\n collection: collectionSlug,\n depth: 0,\n limit: 1,\n overrideAccess: false,\n req,\n user,\n where: {\n [matchField || 'id']: {\n equals: matchValue,\n },\n },\n })\n } catch (error) {\n // MongoDB may throw for invalid ObjectID format - handle gracefully for upsert\n if (isMatchingById && importMode === 'upsert' && !isValidObjectIdFormat) {\n existingDocResult = { docs: [] }\n } else if (isMatchingById && importMode === 'update' && !isValidObjectIdFormat) {\n throw new Error(`Invalid ID format for update: ${matchValueStr}`)\n } else {\n throw error\n }\n }\n\n if (existingDocResult.docs.length > 0) {\n const existingDoc = existingDocResult.docs[0]\n if (!existingDoc) {\n throw new Error(`Document not found`)\n }\n\n // Debug: log what we found\n if (req.payload.config.debug) {\n req.payload.logger.info({\n existingId: existingDoc.id,\n existingStatus: existingDoc._status,\n existingTitle: existingDoc.title,\n incomingDocument: document,\n mode: importMode,\n msg: 'Found existing document for update',\n })\n }\n\n const updateData = { ...document }\n // Remove ID and internal fields from update data\n delete updateData.id\n delete updateData._id\n delete updateData.createdAt\n delete updateData.updatedAt\n\n // Check if we have multi-locale data and extract it\n const { flatData, hasMultiLocale, localeUpdates } = extractMultiLocaleData(\n updateData,\n configuredLocales,\n defaultLocale,\n )\n\n if (req.payload.config.debug) {\n req.payload.logger.info({\n existingId: existingDoc.id,\n hasMultiLocale,\n mode: importMode,\n msg: 'Updating document in upsert/update mode',\n updateData: Object.keys(hasMultiLocale ? flatData : updateData).reduce(\n (acc, key) => {\n const val = (hasMultiLocale ? flatData : updateData)[key]\n acc[key] =\n typeof val === 'string' && val.length > 50 ? val.substring(0, 50) + '...' : val\n return acc\n },\n {} as Record<string, unknown>,\n ),\n })\n }\n\n if (hasMultiLocale) {\n // Update with default locale data\n const defaultLocaleReq = defaultLocale ? { ...req, locale: defaultLocale } : req\n savedDocument = await req.payload.update({\n id: existingDoc.id as number | string,\n collection: collectionSlug,\n data: flatData,\n depth: 0,\n // Don't specify draft - this creates a new draft for versioned collections\n overrideAccess: false,\n req: defaultLocaleReq,\n user,\n })\n\n if (savedDocument && Object.keys(localeUpdates).length > 0) {\n for (const [locale, localeData] of Object.entries(localeUpdates)) {\n try {\n await req.payload.update({\n id: existingDoc.id as number | string,\n collection: collectionSlug,\n data: localeData,\n depth: 0,\n overrideAccess: false,\n req: { ...req, locale },\n user,\n })\n } catch (error) {\n req.payload.logger.error({\n err: error,\n msg: `Failed to update locale ${locale} for document ${String(existingDoc.id)}`,\n })\n }\n }\n }\n } else {\n // No multi-locale data, update normally\n try {\n // Extra debug: log before update\n if (req.payload.config.debug) {\n req.payload.logger.info({\n existingId: existingDoc.id,\n existingTitle: existingDoc.title,\n msg: 'About to update document',\n newData: updateData,\n })\n }\n\n // Update the document - don't specify draft to let Payload handle versions properly\n // This will create a new draft version for collections with versions enabled\n savedDocument = await req.payload.update({\n id: existingDoc.id as number | string,\n collection: collectionSlug,\n data: updateData,\n depth: 0,\n // Don't specify draft - this creates a new draft for versioned collections\n overrideAccess: false,\n req,\n user,\n })\n\n if (req.payload.config.debug && savedDocument) {\n req.payload.logger.info({\n id: savedDocument.id,\n msg: 'Update completed',\n status: savedDocument._status,\n title: savedDocument.title,\n })\n }\n } catch (updateError) {\n req.payload.logger.error({\n id: existingDoc.id,\n err: updateError,\n msg: 'Update failed',\n })\n throw updateError\n }\n }\n } else if (importMode === 'upsert') {\n // Create new in upsert mode\n if (req.payload.config.debug) {\n req.payload.logger.info({\n document,\n matchField: matchField || 'id',\n matchValue: document[matchField || 'id'],\n msg: 'No existing document found, creating new in upsert mode',\n })\n }\n\n const createData = { ...document }\n if (!hasCustomIdField) {\n delete createData.id\n }\n\n // Only handle _status for versioned collections\n let draftOption: boolean | undefined\n if (collectionHasVersions) {\n // Use defaultVersionStatus from config if _status not provided\n const statusValue = createData._status || options.defaultVersionStatus\n const isPublished = statusValue !== 'draft'\n draftOption = !isPublished\n createData._status = statusValue\n }\n\n // Check if we have multi-locale data and extract it\n const { flatData, hasMultiLocale, localeUpdates } = extractMultiLocaleData(\n createData,\n configuredLocales,\n defaultLocale,\n )\n\n if (hasMultiLocale) {\n // Create with default locale data\n const defaultLocaleReq = defaultLocale ? { ...req, locale: defaultLocale } : req\n savedDocument = await req.payload.create({\n collection: collectionSlug,\n data: flatData,\n draft: draftOption,\n overrideAccess: false,\n req: defaultLocaleReq,\n user,\n })\n\n if (savedDocument && Object.keys(localeUpdates).length > 0) {\n for (const [locale, localeData] of Object.entries(localeUpdates)) {\n try {\n await req.payload.update({\n id: savedDocument.id as number | string,\n collection: collectionSlug,\n data: localeData,\n draft: collectionHasVersions ? false : undefined,\n overrideAccess: false,\n req: { ...req, locale },\n user,\n })\n } catch (error) {\n req.payload.logger.error({\n err: error,\n msg: `Failed to update locale ${locale} for document ${String(savedDocument.id)}`,\n })\n }\n }\n }\n } else {\n // No multi-locale data, create normally\n savedDocument = await req.payload.create({\n collection: collectionSlug,\n data: createData,\n draft: draftOption,\n overrideAccess: false,\n req,\n user,\n })\n }\n } else {\n // Update mode but document not found\n let matchValueDisplay: string\n if (typeof matchValue === 'object' && matchValue !== null) {\n matchValueDisplay = JSON.stringify(matchValue)\n } else if (typeof matchValue === 'string') {\n matchValueDisplay = matchValue\n } else if (typeof matchValue === 'number') {\n matchValueDisplay = matchValue.toString()\n } else {\n // For other types, use JSON.stringify to avoid [object Object]\n matchValueDisplay = JSON.stringify(matchValue)\n }\n throw new Error(`Document with ${matchField || 'id'}=\"${matchValueDisplay}\" not found`)\n }\n } else {\n throw new Error(`Unknown import mode: ${String(importMode)}`)\n }\n\n if (savedDocument) {\n // Determine operation type for proper counting\n let operation: 'created' | 'updated' | undefined\n if (importMode === 'create') {\n operation = 'created'\n } else if (importMode === 'update') {\n operation = 'updated'\n } else if (importMode === 'upsert') {\n if (existingDocResult && existingDocResult.docs.length > 0) {\n operation = 'updated'\n } else {\n operation = 'created'\n }\n }\n\n result.successful.push({\n document,\n index: rowNumber - 1, // Store as 0-indexed\n operation,\n result: savedDocument,\n })\n }\n } catch (error) {\n const importError: ImportError = {\n type: categorizeError(error),\n documentData: document || {},\n error: extractErrorMessage(error),\n item: document || {},\n itemIndex: rowNumber - 1,\n rowNumber,\n }\n\n // Try to extract field information from validation errors\n if (error && typeof error === 'object' && 'data' in error) {\n const errorData = error as { data?: { errors?: Array<{ path?: string }> } }\n if (errorData.data?.errors && Array.isArray(errorData.data.errors)) {\n const firstError = errorData.data.errors[0]\n if (firstError?.path) {\n importError.field = firstError.path\n }\n }\n }\n\n result.failed.push(importError)\n // Always continue processing all rows\n }\n }\n\n return result\n}\n\nexport function createImportBatchProcessor(options: ImportBatchProcessorOptions = {}) {\n const processorOptions = {\n batchSize: options.batchSize ?? 100,\n defaultVersionStatus: options.defaultVersionStatus ?? 'published',\n }\n\n const processImport = async (processOptions: ImportProcessOptions): Promise<ImportResult> => {\n const {\n collectionSlug,\n docs: documents,\n format = 'csv',\n hooks,\n importDoc,\n importMode,\n matchField,\n originalDocs: originalDocs,\n req,\n totalBatches: totalBatchesFromOptions,\n user,\n } = processOptions\n const batches = createBatches(documents, processorOptions.batchSize)\n const totalBatches = totalBatchesFromOptions ?? batches.length\n\n const result: ImportResult = {\n errors: [],\n imported: 0,\n total: documents.length,\n updated: 0,\n }\n\n for (let i = 0; i < batches.length; i++) {\n const currentBatch = batches[i]\n if (!currentBatch) {\n continue\n }\n\n const batchNumber = i + 1\n const batchStart = i * processorOptions.batchSize\n const originalBatch = originalDocs\n ? originalDocs.slice(batchStart, batchStart + currentBatch.length)\n : currentBatch\n\n const batchToProcess: Record<string, unknown>[] =\n hooks?.before && currentBatch.length > 0\n ? ((await hooks.before({\n batchNumber,\n data: currentBatch as Parameters<ImportBeforeHook>[0]['data'],\n format,\n importDoc,\n originalData: originalBatch,\n req,\n totalBatches,\n })) as Record<string, unknown>[])\n : currentBatch\n\n const batchResult = await processImportBatch({\n batch: batchToProcess,\n batchIndex: i,\n collectionSlug,\n importMode,\n matchField,\n options: processorOptions,\n req,\n user,\n })\n\n let batchImported = 0\n let batchUpdated = 0\n for (const success of batchResult.successful) {\n if (success.operation === 'created') {\n result.imported++\n batchImported++\n } else if (success.operation === 'updated') {\n result.updated++\n batchUpdated++\n } else {\n // Fallback\n if (importMode === 'create') {\n result.imported++\n batchImported++\n } else {\n result.updated++\n batchUpdated++\n }\n }\n }\n\n for (const error of batchResult.failed) {\n result.errors.push({\n doc: error.documentData,\n error: error.error,\n index: error.rowNumber - 1, // Convert back to 0-indexed\n })\n }\n\n if (hooks?.after) {\n const batchHookResult: ImportResult = {\n errors:\n batchResult.failed.length > 0 ? result.errors.slice(-batchResult.failed.length) : [],\n imported: batchImported,\n total: batchToProcess.length,\n updated: batchUpdated,\n }\n await hooks.after({\n batchNumber,\n format,\n importDoc,\n originalData: originalBatch,\n req,\n result: batchHookResult,\n totalBatches,\n })\n }\n }\n\n return result\n }\n\n return {\n processImport,\n }\n}\n"],"names":["getDataLoader","isolateObjectProperty","categorizeError","createBatches","extractErrorMessage","extractMultiLocaleData","data","configuredLocales","defaultLocale","flatData","localeUpdates","hasMultiLocale","length","localeSet","Set","key","value","Object","entries","Array","isArray","valueObj","localeKeys","keys","filter","k","has","baseLocale","includes","locale","processImportBatch","batch","batchIndex","collectionSlug","importMode","matchField","options","req","reqFromArgs","user","result","failed","successful","transactionID","undefined","payloadDataLoader","collectionEntry","payload","collections","collectionConfig","config","collectionHasVersions","Boolean","versions","hasCustomIdField","customIDType","localization","localeCodes","startingRowNumber","batchSize","i","document","rowNumber","savedDocument","existingDocResult","createData","id","draftOption","statusValue","_status","defaultVersionStatus","isPublished","debug","logger","info","msg","willSetDraft","title","titleIsNull","titleType","defaultLocaleReq","create","collection","draft","overrideAccess","localeData","update","error","err","String","matchValue","Error","isMatchingById","matchValueStr","JSON","stringify","toString","isValidObjectIdFormat","test","find","depth","limit","where","equals","docs","existingDoc","existingId","existingStatus","existingTitle","incomingDocument","mode","updateData","_id","createdAt","updatedAt","reduce","acc","val","substring","newData","status","updateError","matchValueDisplay","operation","push","index","importError","type","documentData","item","itemIndex","errorData","errors","firstError","path","field","createImportBatchProcessor","processorOptions","processImport","processOptions","documents","format","hooks","importDoc","originalDocs","totalBatches","totalBatchesFromOptions","batches","imported","total","updated","currentBatch","batchNumber","batchStart","originalBatch","slice","batchToProcess","before","originalData","batchResult","batchImported","batchUpdated","success","doc","after","batchHookResult"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/import/batchProcessor.ts"],"sourcesContent":["import type { PayloadRequest, User } from 'payload'\n\nimport { getDataLoader, isolateObjectProperty } from 'payload'\n\nimport type { ImportAfterHook, ImportBeforeHook, ImportDoc, ImportResult } from '../types.js'\nimport type { ImportMode } from './createImport.js'\n\nimport {\n type BatchError,\n categorizeError,\n createBatches,\n extractErrorMessage,\n} from '../utilities/useBatchProcessor.js'\n\n/**\n * Import-specific batch processor options\n */\nexport interface ImportBatchProcessorOptions {\n batchSize?: number\n defaultVersionStatus?: 'draft' | 'published'\n}\n\n/**\n * Import-specific error type extending the generic BatchError\n */\nexport interface ImportError extends BatchError<Record<string, unknown>> {\n documentData: Record<string, unknown>\n field?: string\n fieldLabel?: string\n rowNumber: number // 1-indexed for user clarity\n}\n\n/**\n * Result from processing a single import batch\n */\nexport interface ImportBatchResult {\n failed: Array<ImportError>\n successful: Array<{\n document: Record<string, unknown>\n index: number\n operation?: 'created' | 'updated'\n result: Record<string, unknown>\n }>\n}\n\n/**\n * Options for processing an import operation\n */\nexport interface ImportProcessOptions {\n collectionSlug: string\n docs: Record<string, unknown>[]\n /** Export format — passed through to hook args */\n format?: 'csv' | 'json'\n /** Lifecycle hooks for this import operation */\n hooks?: {\n after?: ImportAfterHook\n before?: ImportBeforeHook\n }\n importDoc: ImportDoc\n importMode: ImportMode\n matchField?: string\n /** Raw parsed rows before unflattening — used as originalData in hooks */\n originalDocs?: Record<string, unknown>[]\n req: PayloadRequest\n /** Total number of batches (pre-computed for hook args) */\n totalBatches?: number\n user?: User\n}\n\n/**\n * Separates multi-locale data from a document for sequential locale updates.\n *\n * When a field has locale-keyed values (e.g., { title: { en: 'Hello', es: 'Hola' } }),\n * this extracts the default locale's data for initial create/update, and stores\n * remaining locales for subsequent update calls.\n *\n * @returns\n * - flatData: Document with default locale values extracted (for initial operation)\n * - hasMultiLocale: Whether any multi-locale fields were found\n * - localeUpdates: Map of locale -> field data for follow-up updates\n */\nfunction extractMultiLocaleData(\n data: Record<string, unknown>,\n configuredLocales?: string[],\n defaultLocale?: string,\n): {\n flatData: Record<string, unknown>\n hasMultiLocale: boolean\n localeUpdates: Record<string, Record<string, unknown>>\n} {\n const flatData: Record<string, unknown> = {}\n const localeUpdates: Record<string, Record<string, unknown>> = {}\n let hasMultiLocale = false\n\n if (!configuredLocales || configuredLocales.length === 0) {\n return { flatData: { ...data }, hasMultiLocale: false, localeUpdates: {} }\n }\n\n const localeSet = new Set(configuredLocales)\n\n for (const [key, value] of Object.entries(data)) {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const valueObj = value as Record<string, unknown>\n const localeKeys = Object.keys(valueObj).filter((k) => localeSet.has(k))\n\n if (localeKeys.length > 0) {\n hasMultiLocale = true\n const baseLocale =\n defaultLocale && localeKeys.includes(defaultLocale) ? defaultLocale : localeKeys[0]\n if (baseLocale) {\n flatData[key] = valueObj[baseLocale]\n for (const locale of localeKeys) {\n if (locale !== baseLocale) {\n if (!localeUpdates[locale]) {\n localeUpdates[locale] = {}\n }\n localeUpdates[locale][key] = valueObj[locale]\n }\n }\n }\n } else {\n flatData[key] = value\n }\n } else {\n flatData[key] = value\n }\n }\n\n return { flatData, hasMultiLocale, localeUpdates }\n}\n\ntype ProcessImportBatchOptions = {\n batch: Record<string, unknown>[]\n batchIndex: number\n collectionSlug: string\n importMode: ImportMode\n matchField: string | undefined\n options: { batchSize: number; defaultVersionStatus: 'draft' | 'published' }\n req: PayloadRequest\n user?: User\n}\n\n/**\n * Processes a batch of documents for import based on the import mode.\n *\n * For each document in the batch:\n * - create: Creates a new document (removes any existing ID)\n * - update: Finds existing document by matchField and updates it\n * - upsert: Updates if found, creates if not found\n *\n * Handles versioned collections, multi-locale data, and MongoDB ObjectID validation.\n * Continues processing remaining documents even if individual imports fail.\n */\nasync function processImportBatch({\n batch,\n batchIndex,\n collectionSlug,\n importMode,\n matchField,\n options,\n req: reqFromArgs,\n user,\n}: ProcessImportBatchOptions): Promise<ImportBatchResult> {\n const result: ImportBatchResult = {\n failed: [],\n successful: [],\n }\n // Isolate + clear `transactionID` so a failing nested op (e.g. Forbidden) kills its own\n // transaction, not the parent's, on `killTransaction`.\n // Also isolate `payloadDataLoader`: the shared loader mutates the parent's `req.transactionID`\n // while batching relationship population (`batchAndLoadDocs`), so populating a nested doc's\n // relationship (e.g. authorship `createdBy`/`updatedBy`) would leak the nested transaction onto\n // the parent. A fresh loader keeps each request's transaction isolated.\n const req = isolateObjectProperty(reqFromArgs, ['payloadDataLoader', 'transactionID'])\n req.transactionID = undefined\n req.payloadDataLoader = getDataLoader(req)\n\n const collectionEntry = req.payload.collections[collectionSlug]\n\n const collectionConfig = collectionEntry?.config\n const collectionHasVersions = Boolean(collectionConfig?.versions)\n const hasCustomIdField = Boolean(collectionEntry?.customIDType)\n\n const configuredLocales = req.payload.config.localization\n ? req.payload.config.localization.localeCodes\n : undefined\n\n const defaultLocale = req.payload.config.localization\n ? req.payload.config.localization.defaultLocale\n : undefined\n\n const startingRowNumber = batchIndex * options.batchSize\n\n for (let i = 0; i < batch.length; i++) {\n const document = batch[i]\n if (!document) {\n continue\n }\n const rowNumber = startingRowNumber + i + 1\n\n try {\n let savedDocument: Record<string, unknown> | undefined\n let existingDocResult: { docs: Array<Record<string, unknown>> } | undefined\n\n if (importMode === 'create') {\n const createData = { ...document }\n if (!hasCustomIdField) {\n delete createData.id\n }\n\n let draftOption: boolean | undefined\n if (collectionHasVersions) {\n const statusValue = createData._status || options.defaultVersionStatus\n const isPublished = statusValue !== 'draft'\n draftOption = !isPublished\n createData._status = statusValue\n\n if (req.payload.config.debug) {\n req.payload.logger.info({\n _status: createData._status,\n isPublished,\n msg: 'Status handling in create',\n willSetDraft: draftOption,\n })\n }\n }\n\n if (req.payload.config.debug && 'title' in createData) {\n req.payload.logger.info({\n msg: 'Creating document',\n title: createData.title,\n titleIsNull: createData.title === null,\n titleType: typeof createData.title,\n })\n }\n\n // Check if we have multi-locale data and extract it\n const { flatData, hasMultiLocale, localeUpdates } = extractMultiLocaleData(\n createData,\n configuredLocales,\n defaultLocale,\n )\n\n if (hasMultiLocale) {\n // Create with default locale data\n const defaultLocaleReq = defaultLocale ? { ...req, locale: defaultLocale } : req\n savedDocument = await req.payload.create({\n collection: collectionSlug,\n data: flatData,\n draft: draftOption,\n overrideAccess: false,\n req: defaultLocaleReq,\n user,\n })\n\n if (savedDocument && Object.keys(localeUpdates).length > 0) {\n for (const [locale, localeData] of Object.entries(localeUpdates)) {\n try {\n await req.payload.update({\n id: savedDocument.id as number | string,\n collection: collectionSlug,\n data: localeData,\n draft: collectionHasVersions ? false : undefined,\n overrideAccess: false,\n req: { ...req, locale },\n user,\n })\n } catch (error) {\n req.payload.logger.error({\n err: error,\n msg: `Failed to update locale ${locale} for document ${String(savedDocument.id)}`,\n })\n }\n }\n }\n } else {\n // No multi-locale data, create normally\n savedDocument = await req.payload.create({\n collection: collectionSlug,\n data: createData,\n draft: draftOption,\n overrideAccess: false,\n req,\n user,\n })\n }\n } else if (importMode === 'update' || importMode === 'upsert') {\n const matchValue = document[matchField || 'id']\n if (!matchValue) {\n throw new Error(`Match field \"${matchField || 'id'}\" not found in document`)\n }\n\n // Special handling for ID field with MongoDB\n // If matching by 'id' and it's not a valid ObjectID format, handle specially\n const isMatchingById = (matchField || 'id') === 'id'\n\n // Check if it's a valid MongoDB ObjectID format (24 hex chars)\n // Note: matchValue could be string, number, or ObjectID object\n let matchValueStr: string\n if (typeof matchValue === 'object' && matchValue !== null) {\n matchValueStr = JSON.stringify(matchValue)\n } else if (typeof matchValue === 'string') {\n matchValueStr = matchValue\n } else if (typeof matchValue === 'number') {\n matchValueStr = matchValue.toString()\n } else {\n // For other types, use JSON.stringify\n matchValueStr = JSON.stringify(matchValue)\n }\n const isValidObjectIdFormat = /^[0-9a-f]{24}$/i.test(matchValueStr)\n\n try {\n existingDocResult = await req.payload.find({\n collection: collectionSlug,\n depth: 0,\n limit: 1,\n overrideAccess: false,\n req,\n user,\n where: {\n [matchField || 'id']: {\n equals: matchValue,\n },\n },\n })\n } catch (error) {\n // MongoDB may throw for invalid ObjectID format - handle gracefully for upsert\n if (isMatchingById && importMode === 'upsert' && !isValidObjectIdFormat) {\n existingDocResult = { docs: [] }\n } else if (isMatchingById && importMode === 'update' && !isValidObjectIdFormat) {\n throw new Error(`Invalid ID format for update: ${matchValueStr}`)\n } else {\n throw error\n }\n }\n\n if (existingDocResult.docs.length > 0) {\n const existingDoc = existingDocResult.docs[0]\n if (!existingDoc) {\n throw new Error(`Document not found`)\n }\n\n // Debug: log what we found\n if (req.payload.config.debug) {\n req.payload.logger.info({\n existingId: existingDoc.id,\n existingStatus: existingDoc._status,\n existingTitle: existingDoc.title,\n incomingDocument: document,\n mode: importMode,\n msg: 'Found existing document for update',\n })\n }\n\n const updateData = { ...document }\n // Remove ID and internal fields from update data\n delete updateData.id\n delete updateData._id\n delete updateData.createdAt\n delete updateData.updatedAt\n\n // Check if we have multi-locale data and extract it\n const { flatData, hasMultiLocale, localeUpdates } = extractMultiLocaleData(\n updateData,\n configuredLocales,\n defaultLocale,\n )\n\n if (req.payload.config.debug) {\n req.payload.logger.info({\n existingId: existingDoc.id,\n hasMultiLocale,\n mode: importMode,\n msg: 'Updating document in upsert/update mode',\n updateData: Object.keys(hasMultiLocale ? flatData : updateData).reduce(\n (acc, key) => {\n const val = (hasMultiLocale ? flatData : updateData)[key]\n acc[key] =\n typeof val === 'string' && val.length > 50 ? val.substring(0, 50) + '...' : val\n return acc\n },\n {} as Record<string, unknown>,\n ),\n })\n }\n\n if (hasMultiLocale) {\n // Update with default locale data\n const defaultLocaleReq = defaultLocale ? { ...req, locale: defaultLocale } : req\n savedDocument = await req.payload.update({\n id: existingDoc.id as number | string,\n collection: collectionSlug,\n data: flatData,\n depth: 0,\n // Don't specify draft - this creates a new draft for versioned collections\n overrideAccess: false,\n req: defaultLocaleReq,\n user,\n })\n\n if (savedDocument && Object.keys(localeUpdates).length > 0) {\n for (const [locale, localeData] of Object.entries(localeUpdates)) {\n try {\n await req.payload.update({\n id: existingDoc.id as number | string,\n collection: collectionSlug,\n data: localeData,\n depth: 0,\n overrideAccess: false,\n req: { ...req, locale },\n user,\n })\n } catch (error) {\n req.payload.logger.error({\n err: error,\n msg: `Failed to update locale ${locale} for document ${String(existingDoc.id)}`,\n })\n }\n }\n }\n } else {\n // No multi-locale data, update normally\n try {\n // Extra debug: log before update\n if (req.payload.config.debug) {\n req.payload.logger.info({\n existingId: existingDoc.id,\n existingTitle: existingDoc.title,\n msg: 'About to update document',\n newData: updateData,\n })\n }\n\n // Update the document - don't specify draft to let Payload handle versions properly\n // This will create a new draft version for collections with versions enabled\n savedDocument = await req.payload.update({\n id: existingDoc.id as number | string,\n collection: collectionSlug,\n data: updateData,\n depth: 0,\n // Don't specify draft - this creates a new draft for versioned collections\n overrideAccess: false,\n req,\n user,\n })\n\n if (req.payload.config.debug && savedDocument) {\n req.payload.logger.info({\n id: savedDocument.id,\n msg: 'Update completed',\n status: savedDocument._status,\n title: savedDocument.title,\n })\n }\n } catch (updateError) {\n req.payload.logger.error({\n id: existingDoc.id,\n err: updateError,\n msg: 'Update failed',\n })\n throw updateError\n }\n }\n } else if (importMode === 'upsert') {\n // Create new in upsert mode\n if (req.payload.config.debug) {\n req.payload.logger.info({\n document,\n matchField: matchField || 'id',\n matchValue: document[matchField || 'id'],\n msg: 'No existing document found, creating new in upsert mode',\n })\n }\n\n const createData = { ...document }\n if (!hasCustomIdField) {\n delete createData.id\n }\n\n // Only handle _status for versioned collections\n let draftOption: boolean | undefined\n if (collectionHasVersions) {\n // Use defaultVersionStatus from config if _status not provided\n const statusValue = createData._status || options.defaultVersionStatus\n const isPublished = statusValue !== 'draft'\n draftOption = !isPublished\n createData._status = statusValue\n }\n\n // Check if we have multi-locale data and extract it\n const { flatData, hasMultiLocale, localeUpdates } = extractMultiLocaleData(\n createData,\n configuredLocales,\n defaultLocale,\n )\n\n if (hasMultiLocale) {\n // Create with default locale data\n const defaultLocaleReq = defaultLocale ? { ...req, locale: defaultLocale } : req\n savedDocument = await req.payload.create({\n collection: collectionSlug,\n data: flatData,\n draft: draftOption,\n overrideAccess: false,\n req: defaultLocaleReq,\n user,\n })\n\n if (savedDocument && Object.keys(localeUpdates).length > 0) {\n for (const [locale, localeData] of Object.entries(localeUpdates)) {\n try {\n await req.payload.update({\n id: savedDocument.id as number | string,\n collection: collectionSlug,\n data: localeData,\n draft: collectionHasVersions ? false : undefined,\n overrideAccess: false,\n req: { ...req, locale },\n user,\n })\n } catch (error) {\n req.payload.logger.error({\n err: error,\n msg: `Failed to update locale ${locale} for document ${String(savedDocument.id)}`,\n })\n }\n }\n }\n } else {\n // No multi-locale data, create normally\n savedDocument = await req.payload.create({\n collection: collectionSlug,\n data: createData,\n draft: draftOption,\n overrideAccess: false,\n req,\n user,\n })\n }\n } else {\n // Update mode but document not found\n let matchValueDisplay: string\n if (typeof matchValue === 'object' && matchValue !== null) {\n matchValueDisplay = JSON.stringify(matchValue)\n } else if (typeof matchValue === 'string') {\n matchValueDisplay = matchValue\n } else if (typeof matchValue === 'number') {\n matchValueDisplay = matchValue.toString()\n } else {\n // For other types, use JSON.stringify to avoid [object Object]\n matchValueDisplay = JSON.stringify(matchValue)\n }\n throw new Error(`Document with ${matchField || 'id'}=\"${matchValueDisplay}\" not found`)\n }\n } else {\n throw new Error(`Unknown import mode: ${String(importMode)}`)\n }\n\n if (savedDocument) {\n // Determine operation type for proper counting\n let operation: 'created' | 'updated' | undefined\n if (importMode === 'create') {\n operation = 'created'\n } else if (importMode === 'update') {\n operation = 'updated'\n } else if (importMode === 'upsert') {\n if (existingDocResult && existingDocResult.docs.length > 0) {\n operation = 'updated'\n } else {\n operation = 'created'\n }\n }\n\n result.successful.push({\n document,\n index: rowNumber - 1, // Store as 0-indexed\n operation,\n result: savedDocument,\n })\n }\n } catch (error) {\n const importError: ImportError = {\n type: categorizeError(error),\n documentData: document || {},\n error: extractErrorMessage(error),\n item: document || {},\n itemIndex: rowNumber - 1,\n rowNumber,\n }\n\n // Try to extract field information from validation errors\n if (error && typeof error === 'object' && 'data' in error) {\n const errorData = error as { data?: { errors?: Array<{ path?: string }> } }\n if (errorData.data?.errors && Array.isArray(errorData.data.errors)) {\n const firstError = errorData.data.errors[0]\n if (firstError?.path) {\n importError.field = firstError.path\n }\n }\n }\n\n result.failed.push(importError)\n // Always continue processing all rows\n }\n }\n\n return result\n}\n\nexport function createImportBatchProcessor(options: ImportBatchProcessorOptions = {}) {\n const processorOptions = {\n batchSize: options.batchSize ?? 100,\n defaultVersionStatus: options.defaultVersionStatus ?? 'published',\n }\n\n const processImport = async (processOptions: ImportProcessOptions): Promise<ImportResult> => {\n const {\n collectionSlug,\n docs: documents,\n format = 'csv',\n hooks,\n importDoc,\n importMode,\n matchField,\n originalDocs: originalDocs,\n req,\n totalBatches: totalBatchesFromOptions,\n user,\n } = processOptions\n const batches = createBatches(documents, processorOptions.batchSize)\n const totalBatches = totalBatchesFromOptions ?? batches.length\n\n const result: ImportResult = {\n errors: [],\n imported: 0,\n total: documents.length,\n updated: 0,\n }\n\n for (let i = 0; i < batches.length; i++) {\n const currentBatch = batches[i]\n if (!currentBatch) {\n continue\n }\n\n const batchNumber = i + 1\n const batchStart = i * processorOptions.batchSize\n const originalBatch = originalDocs\n ? originalDocs.slice(batchStart, batchStart + currentBatch.length)\n : currentBatch\n\n const batchToProcess: Record<string, unknown>[] =\n hooks?.before && currentBatch.length > 0\n ? await hooks.before({\n batchNumber,\n data: currentBatch,\n format,\n importDoc,\n originalData: originalBatch,\n req,\n totalBatches,\n })\n : currentBatch\n\n const batchResult = await processImportBatch({\n batch: batchToProcess,\n batchIndex: i,\n collectionSlug,\n importMode,\n matchField,\n options: processorOptions,\n req,\n user,\n })\n\n let batchImported = 0\n let batchUpdated = 0\n for (const success of batchResult.successful) {\n if (success.operation === 'created') {\n result.imported++\n batchImported++\n } else if (success.operation === 'updated') {\n result.updated++\n batchUpdated++\n } else {\n // Fallback\n if (importMode === 'create') {\n result.imported++\n batchImported++\n } else {\n result.updated++\n batchUpdated++\n }\n }\n }\n\n for (const error of batchResult.failed) {\n result.errors.push({\n doc: error.documentData,\n error: error.error,\n index: error.rowNumber - 1, // Convert back to 0-indexed\n })\n }\n\n if (hooks?.after) {\n const batchHookResult: ImportResult = {\n errors:\n batchResult.failed.length > 0 ? result.errors.slice(-batchResult.failed.length) : [],\n imported: batchImported,\n total: batchToProcess.length,\n updated: batchUpdated,\n }\n await hooks.after({\n batchNumber,\n format,\n importDoc,\n originalData: originalBatch,\n req,\n result: batchHookResult,\n totalBatches,\n })\n }\n }\n\n return result\n }\n\n return {\n processImport,\n }\n}\n"],"names":["getDataLoader","isolateObjectProperty","categorizeError","createBatches","extractErrorMessage","extractMultiLocaleData","data","configuredLocales","defaultLocale","flatData","localeUpdates","hasMultiLocale","length","localeSet","Set","key","value","Object","entries","Array","isArray","valueObj","localeKeys","keys","filter","k","has","baseLocale","includes","locale","processImportBatch","batch","batchIndex","collectionSlug","importMode","matchField","options","req","reqFromArgs","user","result","failed","successful","transactionID","undefined","payloadDataLoader","collectionEntry","payload","collections","collectionConfig","config","collectionHasVersions","Boolean","versions","hasCustomIdField","customIDType","localization","localeCodes","startingRowNumber","batchSize","i","document","rowNumber","savedDocument","existingDocResult","createData","id","draftOption","statusValue","_status","defaultVersionStatus","isPublished","debug","logger","info","msg","willSetDraft","title","titleIsNull","titleType","defaultLocaleReq","create","collection","draft","overrideAccess","localeData","update","error","err","String","matchValue","Error","isMatchingById","matchValueStr","JSON","stringify","toString","isValidObjectIdFormat","test","find","depth","limit","where","equals","docs","existingDoc","existingId","existingStatus","existingTitle","incomingDocument","mode","updateData","_id","createdAt","updatedAt","reduce","acc","val","substring","newData","status","updateError","matchValueDisplay","operation","push","index","importError","type","documentData","item","itemIndex","errorData","errors","firstError","path","field","createImportBatchProcessor","processorOptions","processImport","processOptions","documents","format","hooks","importDoc","originalDocs","totalBatches","totalBatchesFromOptions","batches","imported","total","updated","currentBatch","batchNumber","batchStart","originalBatch","slice","batchToProcess","before","originalData","batchResult","batchImported","batchUpdated","success","doc","after","batchHookResult"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/import/handlePreview.ts"],"sourcesContent":["import type { PayloadRequest } from 'payload'\n\nimport { addDataAndFileToRequest } from 'payload'\n\nimport type { ImportDoc, ImportPreviewResponse } 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 { applyFieldHooks } from '../utilities/applyFieldHooks.js'\nimport { getImportFieldFunctions } from '../utilities/getImportFieldFunctions.js'\nimport { getSubmittedFormValues } from '../utilities/getSubmittedFormValues.js'\nimport { parseCSV } from '../utilities/parseCSV.js'\nimport { parseJSON } from '../utilities/parseJSON.js'\nimport { removeDisabledFields } from '../utilities/removeDisabledFields.js'\nimport { resolveLimit } from '../utilities/resolveLimit.js'\nimport { unflattenObject } from '../utilities/unflattenObject.js'\n\nexport const handlePreview = async (req: PayloadRequest): Promise<Response> => {\n await addDataAndFileToRequest(req)\n\n const {\n collectionSlug,\n fileData,\n format,\n formData,\n previewLimit: rawPreviewLimit = DEFAULT_PREVIEW_LIMIT,\n previewPage: rawPreviewPage = 1,\n } = req.data as {\n collectionSlug: string\n fileData?: string\n format?: 'csv' | 'json'\n formData?: Record<string, unknown>\n previewLimit?: number\n previewPage?: number\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 // Resolve max limit from the collection config\n const pluginConfig = targetCollection.config.custom?.['plugin-import-export']\n const maxLimit = await resolveLimit({\n limit: pluginConfig?.importLimit,\n req,\n })\n\n if (!fileData) {\n return Response.json({ error: 'No file data provided' }, { status: 400 })\n }\n\n try {\n // Parse the file data\n let parsedData: Record<string, unknown>[]\n let originalDocs: Record<string, unknown>[] = []\n const buffer = Buffer.from(fileData, 'base64')\n\n const importFieldHooks = getImportFieldFunctions({\n fields: targetCollection.config.flattenedFields || [],\n })\n\n if (format === 'csv') {\n const rawData = await parseCSV({ data: buffer, req })\n originalDocs = rawData\n\n // Unflatten CSV data\n parsedData = rawData\n .map((doc) => {\n const unflattened = unflattenObject({\n data: doc,\n fields: targetCollection.config.flattenedFields ?? [],\n format: 'csv',\n importFieldHooks,\n req,\n })\n return unflattened ?? {}\n })\n .filter((doc) => doc && Object.keys(doc).length > 0)\n } else {\n const parsedDocs = parseJSON({ data: buffer, req })\n originalDocs = parsedDocs\n // Apply field-level import hooks for JSON format\n parsedData = parsedDocs.map((doc) =>\n applyFieldHooks({\n type: 'beforeImport',\n data: doc,\n fieldHooks: importFieldHooks,\n fields: targetCollection.config.flattenedFields ?? [],\n format: 'json',\n operation: 'import',\n req,\n }),\n )\n }\n\n const importHooks = targetCollection.config.custom?.['plugin-import-export']?.importHooks\n if (importHooks?.before && parsedData.length > 0) {\n const result = await importHooks.before({\n batchNumber: 1,\n data: parsedData
|
|
1
|
+
{"version":3,"sources":["../../src/import/handlePreview.ts"],"sourcesContent":["import type { PayloadRequest } from 'payload'\n\nimport { addDataAndFileToRequest } from 'payload'\n\nimport type { ImportDoc, ImportPreviewResponse } 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 { applyFieldHooks } from '../utilities/applyFieldHooks.js'\nimport { getImportFieldFunctions } from '../utilities/getImportFieldFunctions.js'\nimport { getSubmittedFormValues } from '../utilities/getSubmittedFormValues.js'\nimport { parseCSV } from '../utilities/parseCSV.js'\nimport { parseJSON } from '../utilities/parseJSON.js'\nimport { removeDisabledFields } from '../utilities/removeDisabledFields.js'\nimport { resolveLimit } from '../utilities/resolveLimit.js'\nimport { unflattenObject } from '../utilities/unflattenObject.js'\n\nexport const handlePreview = async (req: PayloadRequest): Promise<Response> => {\n await addDataAndFileToRequest(req)\n\n const {\n collectionSlug,\n fileData,\n format,\n formData,\n previewLimit: rawPreviewLimit = DEFAULT_PREVIEW_LIMIT,\n previewPage: rawPreviewPage = 1,\n } = req.data as {\n collectionSlug: string\n fileData?: string\n format?: 'csv' | 'json'\n formData?: Record<string, unknown>\n previewLimit?: number\n previewPage?: number\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 // Resolve max limit from the collection config\n const pluginConfig = targetCollection.config.custom?.['plugin-import-export']\n const maxLimit = await resolveLimit({\n limit: pluginConfig?.importLimit,\n req,\n })\n\n if (!fileData) {\n return Response.json({ error: 'No file data provided' }, { status: 400 })\n }\n\n try {\n // Parse the file data\n let parsedData: Record<string, unknown>[]\n let originalDocs: Record<string, unknown>[] = []\n const buffer = Buffer.from(fileData, 'base64')\n\n const importFieldHooks = getImportFieldFunctions({\n fields: targetCollection.config.flattenedFields || [],\n })\n\n if (format === 'csv') {\n const rawData = await parseCSV({ data: buffer, req })\n originalDocs = rawData\n\n // Unflatten CSV data\n parsedData = rawData\n .map((doc) => {\n const unflattened = unflattenObject({\n data: doc,\n fields: targetCollection.config.flattenedFields ?? [],\n format: 'csv',\n importFieldHooks,\n req,\n })\n return unflattened ?? {}\n })\n .filter((doc) => doc && Object.keys(doc).length > 0)\n } else {\n const parsedDocs = parseJSON({ data: buffer, req })\n originalDocs = parsedDocs\n // Apply field-level import hooks for JSON format\n parsedData = parsedDocs.map((doc) =>\n applyFieldHooks({\n type: 'beforeImport',\n data: doc,\n fieldHooks: importFieldHooks,\n fields: targetCollection.config.flattenedFields ?? [],\n format: 'json',\n operation: 'import',\n req,\n }),\n )\n }\n\n const importHooks = targetCollection.config.custom?.['plugin-import-export']?.importHooks\n if (importHooks?.before && parsedData.length > 0) {\n const result = await importHooks.before({\n batchNumber: 1,\n data: parsedData,\n format: format ?? 'csv',\n importDoc: getSubmittedFormValues({\n formData: formData ?? {},\n }),\n originalData: originalDocs,\n req,\n totalBatches: 1,\n })\n parsedData = result\n }\n\n // Remove disabled fields from the documents\n const disabledFields =\n targetCollection.config.admin?.custom?.['plugin-import-export']?.disabledFields ?? []\n\n if (disabledFields.length > 0) {\n parsedData = parsedData.map((doc) => removeDisabledFields(doc, disabledFields))\n }\n\n // Calculate pagination\n const totalDocs = parsedData.length\n const totalPages = totalDocs === 0 ? 0 : Math.ceil(totalDocs / previewLimit)\n const startIndex = (previewPage - 1) * previewLimit\n const endIndex = startIndex + previewLimit\n const paginatedDocs = parsedData.slice(startIndex, endIndex)\n\n const hasNextPage = previewPage < totalPages\n const hasPrevPage = previewPage > 1\n\n // Check if the file exceeds the max limit\n const limitExceeded = typeof maxLimit === 'number' && maxLimit > 0 && totalDocs > maxLimit\n\n const response: ImportPreviewResponse = {\n docs: paginatedDocs,\n hasNextPage,\n hasPrevPage,\n limit: previewLimit,\n limitExceeded,\n maxLimit,\n page: previewPage,\n totalDocs,\n totalPages,\n }\n\n return Response.json(response)\n } catch (error) {\n req.payload.logger.error({ err: error, msg: 'Error parsing import preview data' })\n return Response.json({ error: 'Failed to parse file data' }, { status: 500 })\n }\n}\n"],"names":["addDataAndFileToRequest","DEFAULT_PREVIEW_LIMIT","MAX_PREVIEW_LIMIT","MIN_PREVIEW_LIMIT","MIN_PREVIEW_PAGE","applyFieldHooks","getImportFieldFunctions","getSubmittedFormValues","parseCSV","parseJSON","removeDisabledFields","resolveLimit","unflattenObject","handlePreview","req","collectionSlug","fileData","format","formData","previewLimit","rawPreviewLimit","previewPage","rawPreviewPage","data","Math","max","min","targetCollection","payload","collections","Response","json","error","status","pluginConfig","config","custom","maxLimit","limit","importLimit","parsedData","originalDocs","buffer","Buffer","from","importFieldHooks","fields","flattenedFields","rawData","map","doc","unflattened","filter","Object","keys","length","parsedDocs","type","fieldHooks","operation","importHooks","before","result","batchNumber","importDoc","originalData","totalBatches","disabledFields","admin","totalDocs","totalPages","ceil","startIndex","endIndex","paginatedDocs","slice","hasNextPage","hasPrevPage","limitExceeded","response","docs","page","logger","err","msg"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/applyFieldHooks.ts"],"sourcesContent":["import type { FlattenedBlock, FlattenedField, PayloadRequest } from 'payload'\n\nimport type {\n ExportFieldHookEntry,\n FieldBeforeExportHook,\n FieldBeforeImportHook,\n ImportFieldHookEntry,\n} from '../types.js'\n\nimport { isPlainObject } from './isPlainObject.js'\n\nexport type FieldHook = FieldBeforeExportHook | FieldBeforeImportHook\n\nexport type FieldHookEntry = ExportFieldHookEntry | ImportFieldHookEntry\n\nconst joinPath = (parent: string | undefined, segment: string): string =>\n parent ? `${parent}_${segment}` : segment\n\nexport type Args = {\n data: Record<string, unknown>\n fieldHooks: Record<string, FieldHookEntry>\n fields: FlattenedField[]\n format: 'csv' | 'json' | ({} & string)\n operation: 'export' | 'import'\n req: PayloadRequest\n type: 'beforeExport' | 'beforeImport'\n}\n\nconst operationLabel = { export: 'Export', import: 'Import' } as const\n\ntype TraverseArgs = {\n path: string | undefined\n schemaPath: string | undefined\n siblingData: Record<string, unknown>\n} & Args\n\nconst traverseFields = ({\n type,\n data,\n fieldHooks,\n fields,\n format,\n operation,\n path,\n req,\n schemaPath,\n siblingData,\n}: TraverseArgs): Record<string, unknown> => {\n const result: Record<string, unknown> = { ...siblingData }\n\n for (const field of fields) {\n if (!('name' in field) || !field.name) {\n continue\n }\n\n const fieldPath = joinPath(path, field.name)\n const fieldSchemaPath = joinPath(schemaPath, field.name)\n const entry = fieldHooks[fieldSchemaPath]\n const hook = entry?.type === type ?
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/applyFieldHooks.ts"],"sourcesContent":["import type { FlattenedBlock, FlattenedField, PayloadRequest } from 'payload'\n\nimport type {\n ExportFieldHookEntry,\n FieldBeforeExportHook,\n FieldBeforeImportHook,\n ImportFieldHookEntry,\n} from '../types.js'\n\nimport { isPlainObject } from './isPlainObject.js'\n\nexport type FieldHook = FieldBeforeExportHook | FieldBeforeImportHook\n\nexport type FieldHookEntry = ExportFieldHookEntry | ImportFieldHookEntry\n\nconst joinPath = (parent: string | undefined, segment: string): string =>\n parent ? `${parent}_${segment}` : segment\n\nexport type Args = {\n data: Record<string, unknown>\n fieldHooks: Record<string, FieldHookEntry>\n fields: FlattenedField[]\n format: 'csv' | 'json' | ({} & string)\n operation: 'export' | 'import'\n req: PayloadRequest\n type: 'beforeExport' | 'beforeImport'\n}\n\nconst operationLabel = { export: 'Export', import: 'Import' } as const\n\ntype TraverseArgs = {\n path: string | undefined\n schemaPath: string | undefined\n siblingData: Record<string, unknown>\n} & Args\n\nconst traverseFields = ({\n type,\n data,\n fieldHooks,\n fields,\n format,\n operation,\n path,\n req,\n schemaPath,\n siblingData,\n}: TraverseArgs): Record<string, unknown> => {\n const result: Record<string, unknown> = { ...siblingData }\n\n for (const field of fields) {\n if (!('name' in field) || !field.name) {\n continue\n }\n\n const fieldPath = joinPath(path, field.name)\n const fieldSchemaPath = joinPath(schemaPath, field.name)\n const entry = fieldHooks[fieldSchemaPath]\n const hook = entry?.type === type ? entry.fn : undefined\n\n if (typeof hook === 'function' && field.name in result) {\n try {\n const transformed = hook({\n columnName: fieldPath,\n data,\n format,\n siblingData: result,\n siblingDoc: siblingData,\n value: result[field.name],\n })\n\n if (typeof transformed !== 'undefined') {\n result[field.name] = transformed\n }\n } catch (error) {\n req.payload.logger.error({\n err: error,\n msg: `[plugin-import-export] Field-level before${operationLabel[operation]} hook for \"${fieldPath}\" threw — falling back to original value`,\n })\n }\n }\n\n if (!(field.name in result)) {\n continue\n }\n\n const value = result[field.name]\n\n if ((field.type === 'group' || field.type === 'tab') && isPlainObject(value)) {\n result[field.name] = traverseFields({\n type,\n data,\n fieldHooks,\n fields: field.flattenedFields,\n format,\n operation,\n path: fieldPath,\n req,\n schemaPath: fieldSchemaPath,\n siblingData: value,\n })\n } else if (field.type === 'array' && Array.isArray(value)) {\n result[field.name] = value.map((item, index) => {\n if (!isPlainObject(item)) {\n return item\n }\n return traverseFields({\n type,\n data,\n fieldHooks,\n fields: field.flattenedFields,\n format,\n operation,\n path: `${fieldPath}_${index}`,\n req,\n schemaPath: fieldSchemaPath,\n siblingData: item,\n })\n })\n } else if (field.type === 'blocks' && Array.isArray(value)) {\n result[field.name] = value.map((item, index) => {\n if (!isPlainObject(item)) {\n return item\n }\n const blockType = typeof item.blockType === 'string' ? item.blockType : undefined\n const block = blockType\n ? (req.payload.blocks[blockType] ??\n field.blocks.find(\n (b): b is FlattenedBlock => typeof b !== 'string' && b.slug === blockType,\n ))\n : undefined\n return traverseFields({\n type,\n data,\n fieldHooks,\n fields: block?.flattenedFields ?? [],\n format,\n operation,\n path: blockType ? `${fieldPath}_${index}_${blockType}` : `${fieldPath}_${index}`,\n req,\n schemaPath: blockType ? `${fieldSchemaPath}_${blockType}` : fieldSchemaPath,\n siblingData: item,\n })\n })\n }\n }\n\n return result\n}\n\n/**\n * Walks a nested document and applies each field's `beforeExport` or\n * `beforeImport` hook.\n *\n * Field-level hook errors are logged and the field falls back to its\n * original value so a single bad doc does not abort the batch.\n */\nexport const applyFieldHooks = (args: Args): Record<string, unknown> => {\n const { data, fieldHooks } = args\n if (!data || typeof data !== 'object' || Object.keys(fieldHooks).length === 0) {\n return data\n }\n\n return traverseFields({\n ...args,\n path: undefined,\n schemaPath: undefined,\n siblingData: data,\n })\n}\n"],"names":["isPlainObject","joinPath","parent","segment","operationLabel","export","import","traverseFields","type","data","fieldHooks","fields","format","operation","path","req","schemaPath","siblingData","result","field","name","fieldPath","fieldSchemaPath","entry","hook","fn","undefined","transformed","columnName","siblingDoc","value","error","payload","logger","err","msg","flattenedFields","Array","isArray","map","item","index","blockType","block","blocks","find","b","slug","applyFieldHooks","args","Object","keys","length"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/getFileFromDoc.ts"],"sourcesContent":["import type { CollectionConfig, FileData, PayloadRequest, UploadConfig } from 'payload'\n\nimport { FileRetrievalError, getFileByPath } from 'payload'\nimport { downloadFileToBuffer } from 'payload/internal'\nimport { formatAdminURL } from 'payload/shared'\n\ntype Args = {\n collectionConfig: CollectionConfig\n doc: { filename: string; mimeType?: string; url?: string }\n req: PayloadRequest\n}\n\ntype Result = {\n data: Buffer\n mimetype: string\n}\n\n/**\n * Retrieves file data from an uploaded document, handling both local storage\n * and cloud storage (S3, Azure, GCS, etc.) scenarios correctly.\n *\n * This function uses the same pattern as Payload's internal file retrieval:\n * - For local storage: reads directly from disk (efficient, no HTTP roundtrip)\n * - For cloud storage: fetches via Payload's file endpoint, which triggers\n * the storage adapter's staticHandler to serve the file\n */\nexport const getFileFromDoc = async ({ collectionConfig, doc, req }: Args): Promise<Result> => {\n const uploadConfig: UploadConfig =\n typeof collectionConfig.upload === 'object' ? collectionConfig.upload : {}\n const disableLocalStorage = uploadConfig.disableLocalStorage ?? false\n const staticDir = uploadConfig.staticDir || collectionConfig.slug\n\n const serverURL = req.payload.config.serverURL\n const isLocalFile = (serverURL && doc.url?.startsWith(serverURL)) || doc.url?.startsWith('/')\n\n if (!disableLocalStorage && isLocalFile && doc.filename) {\n // Local storage enabled - read directly from disk (efficient, no HTTP roundtrip)\n const filePath = `${staticDir}/${doc.filename}`\n const file = await getFileByPath(filePath)\n\n if (!file) {\n throw new Error(`File not found at path: ${filePath}`)\n }\n\n const mimetype = file.mimetype || doc.mimeType\n\n if (!mimetype) {\n throw new FileRetrievalError(req.t, `Unable to determine mimetype for file: ${doc.filename}`)\n }\n\n return {\n data: file.data,\n mimetype,\n }\n }\n\n if (doc.filename && doc.url) {\n // Cloud storage or external - fetch via Payload's file endpoint\n // downloadFileToBuffer constructs full URL, includes cookies for auth, and\n // the request goes through Payload's handler chain (including storage adapter)\n\n // For relative URLs, construct a full URL using formatAdminURL which properly\n // handles serverURL, basePath, and other config. This is important in job contexts\n // where request headers may not be available for URL construction.\n // Use serverURL from config, falling back to req.origin for local/job requests.\n const fileUrl = doc.url.startsWith('http')\n ? doc.url\n : formatAdminURL({\n apiRoute: '',\n path: doc.url as `/${string}`,\n serverURL: serverURL || req.origin,\n })\n\n const file = await downloadFileToBuffer({\n data: { filename: doc.filename, url: fileUrl }
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/getFileFromDoc.ts"],"sourcesContent":["import type { CollectionConfig, FileData, PayloadRequest, UploadConfig } from 'payload'\n\nimport { FileRetrievalError, getFileByPath } from 'payload'\nimport { downloadFileToBuffer } from 'payload/internal'\nimport { formatAdminURL } from 'payload/shared'\n\ntype Args = {\n collectionConfig: CollectionConfig\n doc: { filename: string; mimeType?: string; url?: string }\n req: PayloadRequest\n}\n\ntype Result = {\n data: Buffer\n mimetype: string\n}\n\n/**\n * Retrieves file data from an uploaded document, handling both local storage\n * and cloud storage (S3, Azure, GCS, etc.) scenarios correctly.\n *\n * This function uses the same pattern as Payload's internal file retrieval:\n * - For local storage: reads directly from disk (efficient, no HTTP roundtrip)\n * - For cloud storage: fetches via Payload's file endpoint, which triggers\n * the storage adapter's staticHandler to serve the file\n */\nexport const getFileFromDoc = async ({ collectionConfig, doc, req }: Args): Promise<Result> => {\n const uploadConfig: UploadConfig =\n typeof collectionConfig.upload === 'object' ? collectionConfig.upload : {}\n const disableLocalStorage = uploadConfig.disableLocalStorage ?? false\n const staticDir = uploadConfig.staticDir || collectionConfig.slug\n\n const serverURL = req.payload.config.serverURL\n const isLocalFile = (serverURL && doc.url?.startsWith(serverURL)) || doc.url?.startsWith('/')\n\n if (!disableLocalStorage && isLocalFile && doc.filename) {\n // Local storage enabled - read directly from disk (efficient, no HTTP roundtrip)\n const filePath = `${staticDir}/${doc.filename}`\n const file = await getFileByPath(filePath)\n\n if (!file) {\n throw new Error(`File not found at path: ${filePath}`)\n }\n\n const mimetype = file.mimetype || doc.mimeType\n\n if (!mimetype) {\n throw new FileRetrievalError(req.t, `Unable to determine mimetype for file: ${doc.filename}`)\n }\n\n return {\n data: file.data,\n mimetype,\n }\n }\n\n if (doc.filename && doc.url) {\n // Cloud storage or external - fetch via Payload's file endpoint\n // downloadFileToBuffer constructs full URL, includes cookies for auth, and\n // the request goes through Payload's handler chain (including storage adapter)\n\n // For relative URLs, construct a full URL using formatAdminURL which properly\n // handles serverURL, basePath, and other config. This is important in job contexts\n // where request headers may not be available for URL construction.\n // Use serverURL from config, falling back to req.origin for local/job requests.\n const fileUrl = doc.url.startsWith('http')\n ? doc.url\n : formatAdminURL({\n apiRoute: '',\n path: doc.url as `/${string}`,\n serverURL: serverURL || req.origin,\n })\n\n const file = await downloadFileToBuffer({\n data: { filename: doc.filename, url: fileUrl },\n req,\n uploadConfig,\n })\n\n const mimetype = file.mimetype || doc.mimeType\n\n if (!mimetype) {\n throw new FileRetrievalError(req.t, `Unable to determine mimetype for file: ${doc.filename}`)\n }\n\n return {\n data: file.data,\n mimetype,\n }\n }\n\n throw new Error('Unable to retrieve file: missing filename or url')\n}\n"],"names":["FileRetrievalError","getFileByPath","downloadFileToBuffer","formatAdminURL","getFileFromDoc","collectionConfig","doc","req","uploadConfig","upload","disableLocalStorage","staticDir","slug","serverURL","payload","config","isLocalFile","url","startsWith","filename","filePath","file","Error","mimetype","mimeType","t","data","fileUrl","apiRoute","path","origin"],"mappings":"AAEA,SAASA,kBAAkB,EAAEC,aAAa,QAAQ,UAAS;AAC3D,SAASC,oBAAoB,QAAQ,mBAAkB;AACvD,SAASC,cAAc,QAAQ,iBAAgB;AAa/C;;;;;;;;CAQC,GACD,OAAO,MAAMC,iBAAiB,OAAO,EAAEC,gBAAgB,EAAEC,GAAG,EAAEC,GAAG,EAAQ;IACvE,MAAMC,eACJ,OAAOH,iBAAiBI,MAAM,KAAK,WAAWJ,iBAAiBI,MAAM,GAAG,CAAC;IAC3E,MAAMC,sBAAsBF,aAAaE,mBAAmB,IAAI;IAChE,MAAMC,YAAYH,aAAaG,SAAS,IAAIN,iBAAiBO,IAAI;IAEjE,MAAMC,YAAYN,IAAIO,OAAO,CAACC,MAAM,CAACF,SAAS;IAC9C,MAAMG,cAAc,AAACH,aAAaP,IAAIW,GAAG,EAAEC,WAAWL,cAAeP,IAAIW,GAAG,EAAEC,WAAW;IAEzF,IAAI,CAACR,uBAAuBM,eAAeV,IAAIa,QAAQ,EAAE;QACvD,iFAAiF;QACjF,MAAMC,WAAW,GAAGT,UAAU,CAAC,EAAEL,IAAIa,QAAQ,EAAE;QAC/C,MAAME,OAAO,MAAMpB,cAAcmB;QAEjC,IAAI,CAACC,MAAM;YACT,MAAM,IAAIC,MAAM,CAAC,wBAAwB,EAAEF,UAAU;QACvD;QAEA,MAAMG,WAAWF,KAAKE,QAAQ,IAAIjB,IAAIkB,QAAQ;QAE9C,IAAI,CAACD,UAAU;YACb,MAAM,IAAIvB,mBAAmBO,IAAIkB,CAAC,EAAE,CAAC,uCAAuC,EAAEnB,IAAIa,QAAQ,EAAE;QAC9F;QAEA,OAAO;YACLO,MAAML,KAAKK,IAAI;YACfH;QACF;IACF;IAEA,IAAIjB,IAAIa,QAAQ,IAAIb,IAAIW,GAAG,EAAE;QAC3B,gEAAgE;QAChE,2EAA2E;QAC3E,+EAA+E;QAE/E,8EAA8E;QAC9E,mFAAmF;QACnF,mEAAmE;QACnE,gFAAgF;QAChF,MAAMU,UAAUrB,IAAIW,GAAG,CAACC,UAAU,CAAC,UAC/BZ,IAAIW,GAAG,GACPd,eAAe;YACbyB,UAAU;YACVC,MAAMvB,IAAIW,GAAG;YACbJ,WAAWA,aAAaN,IAAIuB,MAAM;QACpC;QAEJ,MAAMT,OAAO,MAAMnB,qBAAqB;YACtCwB,MAAM;gBAAEP,UAAUb,IAAIa,QAAQ;gBAAEF,KAAKU;YAAQ;YAC7CpB;YACAC;QACF;QAEA,MAAMe,WAAWF,KAAKE,QAAQ,IAAIjB,IAAIkB,QAAQ;QAE9C,IAAI,CAACD,UAAU;YACb,MAAM,IAAIvB,mBAAmBO,IAAIkB,CAAC,EAAE,CAAC,uCAAuC,EAAEnB,IAAIa,QAAQ,EAAE;QAC9F;QAEA,OAAO;YACLO,MAAML,KAAKK,IAAI;YACfH;QACF;IACF;IAEA,MAAM,IAAID,MAAM;AAClB,EAAC"}
|
package/package.json
CHANGED
|
@@ -1,22 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@payloadcms/plugin-import-export",
|
|
3
|
-
"version": "4.0.0-internal.
|
|
3
|
+
"version": "4.0.0-internal.ec73d44",
|
|
4
4
|
"description": "Import-Export plugin for Payload",
|
|
5
5
|
"keywords": [
|
|
6
|
-
"payload",
|
|
7
6
|
"cms",
|
|
7
|
+
"export",
|
|
8
|
+
"import",
|
|
9
|
+
"nextjs",
|
|
10
|
+
"payload",
|
|
8
11
|
"plugin",
|
|
9
|
-
"typescript",
|
|
10
12
|
"react",
|
|
11
|
-
"
|
|
12
|
-
"import",
|
|
13
|
-
"export"
|
|
13
|
+
"typescript"
|
|
14
14
|
],
|
|
15
|
-
"repository": {
|
|
16
|
-
"type": "git",
|
|
17
|
-
"url": "https://github.com/payloadcms/payload.git",
|
|
18
|
-
"directory": "packages/plugin-import-export"
|
|
19
|
-
},
|
|
20
15
|
"license": "MIT",
|
|
21
16
|
"author": "Payload <dev@payloadcms.com> (https://payloadcms.com)",
|
|
22
17
|
"maintainers": [
|
|
@@ -26,7 +21,17 @@
|
|
|
26
21
|
"url": "https://payloadcms.com"
|
|
27
22
|
}
|
|
28
23
|
],
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "https://github.com/payloadcms/payload.git",
|
|
27
|
+
"directory": "packages/plugin-import-export"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"dist"
|
|
31
|
+
],
|
|
29
32
|
"type": "module",
|
|
33
|
+
"main": "./dist/index.js",
|
|
34
|
+
"types": "./dist/index.d.ts",
|
|
30
35
|
"exports": {
|
|
31
36
|
".": {
|
|
32
37
|
"import": "./dist/index.js",
|
|
@@ -54,27 +59,21 @@
|
|
|
54
59
|
"default": "./dist/translations/languages/*.js"
|
|
55
60
|
}
|
|
56
61
|
},
|
|
57
|
-
"main": "./dist/index.js",
|
|
58
|
-
"types": "./dist/index.d.ts",
|
|
59
|
-
"files": [
|
|
60
|
-
"dist"
|
|
61
|
-
],
|
|
62
62
|
"dependencies": {
|
|
63
63
|
"@faceless-ui/modal": "3.0.2",
|
|
64
|
+
"@payloadcms/translations": "4.0.0-internal.ec73d44",
|
|
65
|
+
"@payloadcms/ui": "4.0.0-internal.ec73d44",
|
|
64
66
|
"csv-parse": "5.6.0",
|
|
65
67
|
"csv-stringify": "6.5.2",
|
|
66
|
-
"qs-esm": "8.0.1"
|
|
67
|
-
"@payloadcms/translations": "4.0.0-internal.ea6e8f8",
|
|
68
|
-
"@payloadcms/ui": "4.0.0-internal.ea6e8f8"
|
|
68
|
+
"qs-esm": "8.0.1"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
-
"@payloadcms/
|
|
72
|
-
"payload": "4.0.0-internal.
|
|
73
|
-
"@payloadcms/ui": "4.0.0-internal.ea6e8f8"
|
|
71
|
+
"@payloadcms/ui": "4.0.0-internal.ec73d44",
|
|
72
|
+
"payload": "4.0.0-internal.ec73d44"
|
|
74
73
|
},
|
|
75
74
|
"peerDependencies": {
|
|
76
|
-
"@payloadcms/ui": "4.0.0-internal.
|
|
77
|
-
"payload": "4.0.0-internal.
|
|
75
|
+
"@payloadcms/ui": "4.0.0-internal.ec73d44",
|
|
76
|
+
"payload": "4.0.0-internal.ec73d44"
|
|
78
77
|
},
|
|
79
78
|
"homepage:": "https://payloadcms.com",
|
|
80
79
|
"scripts": {
|
|
@@ -83,8 +82,6 @@
|
|
|
83
82
|
"build:swc": "swc ./src -d ./dist --config-file .swcrc --strip-leading-paths",
|
|
84
83
|
"build:types": "tsc --emitDeclarationOnly --outDir dist",
|
|
85
84
|
"clean": "rimraf {dist,*.tsbuildinfo}",
|
|
86
|
-
"copyfiles": "copyfiles -u 1 -e \"**/*.spec.*\" \"src/**/*.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png,json}\" dist/"
|
|
87
|
-
"lint": "eslint .",
|
|
88
|
-
"lint:fix": "eslint . --fix"
|
|
85
|
+
"copyfiles": "copyfiles -u 1 -e \"**/*.spec.*\" \"src/**/*.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png,json}\" dist/"
|
|
89
86
|
}
|
|
90
87
|
}
|