@payloadcms/plugin-import-export 3.48.0-canary.6 → 3.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/FieldsToExport/reduceFields.d.ts.map +1 -1
- package/dist/components/FieldsToExport/reduceFields.js +1 -1
- package/dist/components/FieldsToExport/reduceFields.js.map +1 -1
- package/dist/components/Preview/index.d.ts.map +1 -1
- package/dist/components/Preview/index.js +8 -6
- package/dist/components/Preview/index.js.map +1 -1
- package/dist/export/createExport.d.ts.map +1 -1
- package/dist/export/createExport.js +10 -5
- package/dist/export/createExport.js.map +1 -1
- package/dist/export/flattenObject.d.ts.map +1 -1
- package/dist/export/flattenObject.js +5 -3
- package/dist/export/flattenObject.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -7
- package/dist/index.js.map +1 -1
- package/dist/utilities/buildDisabledFieldRegex.d.ts +5 -0
- package/dist/utilities/buildDisabledFieldRegex.d.ts.map +1 -0
- package/dist/utilities/buildDisabledFieldRegex.js +12 -0
- package/dist/utilities/buildDisabledFieldRegex.js.map +1 -0
- package/dist/utilities/collectDisabledFieldPaths.d.ts +15 -0
- package/dist/utilities/collectDisabledFieldPaths.d.ts.map +1 -0
- package/dist/utilities/collectDisabledFieldPaths.js +62 -0
- package/dist/utilities/collectDisabledFieldPaths.js.map +1 -0
- package/dist/utilities/getFlattenedFieldKeys.d.ts.map +1 -1
- package/dist/utilities/getFlattenedFieldKeys.js +9 -5
- package/dist/utilities/getFlattenedFieldKeys.js.map +1 -1
- package/package.json +7 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reduceFields.d.ts","sourceRoot":"","sources":["../../../src/components/FieldsToExport/reduceFields.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAG1C,OAAO,KAAmB,MAAM,OAAO,CAAA;AAyCvC,eAAO,MAAM,YAAY,mDAKtB;IACD,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB,MAAM,EAAE,WAAW,EAAE,CAAA;IACrB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,KAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"reduceFields.d.ts","sourceRoot":"","sources":["../../../src/components/FieldsToExport/reduceFields.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAG1C,OAAO,KAAmB,MAAM,OAAO,CAAA;AAyCvC,eAAO,MAAM,YAAY,mDAKtB;IACD,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB,MAAM,EAAE,WAAW,EAAE,CAAA;IACrB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,KAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAgFxD,CAAA"}
|
|
@@ -88,7 +88,7 @@ export const reduceFields = ({ disabledFields = [], fields, labelPrefix = null,
|
|
|
88
88
|
}
|
|
89
89
|
const val = createNestedClientFieldPath(path, field);
|
|
90
90
|
// If the field is disabled, skip it
|
|
91
|
-
if (disabledFields.
|
|
91
|
+
if (disabledFields.some((disabledField)=>val === disabledField || val.startsWith(`${disabledField}.`))) {
|
|
92
92
|
return fieldsToUse;
|
|
93
93
|
}
|
|
94
94
|
const formattedField = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/FieldsToExport/reduceFields.tsx"],"sourcesContent":["import type { ClientField } from 'payload'\n\nimport { fieldAffectsData, fieldHasSubFields } from 'payload/shared'\nimport React, { Fragment } from 'react'\n\nconst createNestedClientFieldPath = (parentPath: string, field: ClientField): string => {\n if (parentPath) {\n if (fieldAffectsData(field)) {\n return `${parentPath}.${field.name}`\n }\n return parentPath\n }\n\n if (fieldAffectsData(field)) {\n return field.name\n }\n\n return ''\n}\n\nconst combineLabel = ({\n field,\n prefix,\n}: {\n field: ClientField\n prefix?: React.ReactNode\n}): React.ReactNode => {\n return (\n <Fragment>\n {prefix ? (\n <Fragment>\n <span style={{ display: 'inline-block' }}>{prefix}</span>\n {' > '}\n </Fragment>\n ) : null}\n <span style={{ display: 'inline-block' }}>\n {'label' in field && typeof field.label === 'string'\n ? field.label\n : (('name' in field && field.name) ?? 'unnamed field')}\n </span>\n </Fragment>\n )\n}\n\nexport const reduceFields = ({\n disabledFields = [],\n fields,\n labelPrefix = null,\n path = '',\n}: {\n disabledFields?: string[]\n fields: ClientField[]\n labelPrefix?: React.ReactNode\n path?: string\n}): { id: string; label: React.ReactNode; value: string }[] => {\n if (!fields) {\n return []\n }\n\n return fields.reduce<{ id: string; label: React.ReactNode; value: string }[]>(\n (fieldsToUse, field) => {\n // escape for a variety of reasons, include ui fields as they have `name`.\n if (field.type === 'ui') {\n return fieldsToUse\n }\n\n if (!(field.type === 'array' || field.type === 'blocks') && fieldHasSubFields(field)) {\n return [\n ...fieldsToUse,\n ...reduceFields({\n disabledFields,\n fields: field.fields,\n labelPrefix: combineLabel({ field, prefix: labelPrefix }),\n path: createNestedClientFieldPath(path, field),\n }),\n ]\n }\n\n if (field.type === 'tabs' && 'tabs' in field) {\n return [\n ...fieldsToUse,\n ...field.tabs.reduce<{ id: string; label: React.ReactNode; value: string }[]>(\n (tabFields, tab) => {\n if ('fields' in tab) {\n const isNamedTab = 'name' in tab && tab.name\n\n const newPath = isNamedTab ? `${path}${path ? '.' : ''}${tab.name}` : path\n\n return [\n ...tabFields,\n ...reduceFields({\n disabledFields,\n fields: tab.fields,\n labelPrefix: isNamedTab\n ? combineLabel({\n field: {\n name: tab.name,\n label: tab.label ?? tab.name,\n } as any,\n prefix: labelPrefix,\n })\n : labelPrefix,\n path: newPath,\n }),\n ]\n }\n return tabFields\n },\n [],\n ),\n ]\n }\n\n const val = createNestedClientFieldPath(path, field)\n\n // If the field is disabled, skip it\n if (disabledFields.
|
|
1
|
+
{"version":3,"sources":["../../../src/components/FieldsToExport/reduceFields.tsx"],"sourcesContent":["import type { ClientField } from 'payload'\n\nimport { fieldAffectsData, fieldHasSubFields } from 'payload/shared'\nimport React, { Fragment } from 'react'\n\nconst createNestedClientFieldPath = (parentPath: string, field: ClientField): string => {\n if (parentPath) {\n if (fieldAffectsData(field)) {\n return `${parentPath}.${field.name}`\n }\n return parentPath\n }\n\n if (fieldAffectsData(field)) {\n return field.name\n }\n\n return ''\n}\n\nconst combineLabel = ({\n field,\n prefix,\n}: {\n field: ClientField\n prefix?: React.ReactNode\n}): React.ReactNode => {\n return (\n <Fragment>\n {prefix ? (\n <Fragment>\n <span style={{ display: 'inline-block' }}>{prefix}</span>\n {' > '}\n </Fragment>\n ) : null}\n <span style={{ display: 'inline-block' }}>\n {'label' in field && typeof field.label === 'string'\n ? field.label\n : (('name' in field && field.name) ?? 'unnamed field')}\n </span>\n </Fragment>\n )\n}\n\nexport const reduceFields = ({\n disabledFields = [],\n fields,\n labelPrefix = null,\n path = '',\n}: {\n disabledFields?: string[]\n fields: ClientField[]\n labelPrefix?: React.ReactNode\n path?: string\n}): { id: string; label: React.ReactNode; value: string }[] => {\n if (!fields) {\n return []\n }\n\n return fields.reduce<{ id: string; label: React.ReactNode; value: string }[]>(\n (fieldsToUse, field) => {\n // escape for a variety of reasons, include ui fields as they have `name`.\n if (field.type === 'ui') {\n return fieldsToUse\n }\n\n if (!(field.type === 'array' || field.type === 'blocks') && fieldHasSubFields(field)) {\n return [\n ...fieldsToUse,\n ...reduceFields({\n disabledFields,\n fields: field.fields,\n labelPrefix: combineLabel({ field, prefix: labelPrefix }),\n path: createNestedClientFieldPath(path, field),\n }),\n ]\n }\n\n if (field.type === 'tabs' && 'tabs' in field) {\n return [\n ...fieldsToUse,\n ...field.tabs.reduce<{ id: string; label: React.ReactNode; value: string }[]>(\n (tabFields, tab) => {\n if ('fields' in tab) {\n const isNamedTab = 'name' in tab && tab.name\n\n const newPath = isNamedTab ? `${path}${path ? '.' : ''}${tab.name}` : path\n\n return [\n ...tabFields,\n ...reduceFields({\n disabledFields,\n fields: tab.fields,\n labelPrefix: isNamedTab\n ? combineLabel({\n field: {\n name: tab.name,\n label: tab.label ?? tab.name,\n } as any,\n prefix: labelPrefix,\n })\n : labelPrefix,\n path: newPath,\n }),\n ]\n }\n return tabFields\n },\n [],\n ),\n ]\n }\n\n const val = createNestedClientFieldPath(path, field)\n\n // If the field is disabled, skip it\n if (\n disabledFields.some(\n (disabledField) => val === disabledField || val.startsWith(`${disabledField}.`),\n )\n ) {\n return fieldsToUse\n }\n\n const formattedField = {\n id: val,\n label: combineLabel({ field, prefix: labelPrefix }),\n value: val,\n }\n\n return [...fieldsToUse, formattedField]\n },\n [],\n )\n}\n"],"names":["fieldAffectsData","fieldHasSubFields","React","Fragment","createNestedClientFieldPath","parentPath","field","name","combineLabel","prefix","span","style","display","label","reduceFields","disabledFields","fields","labelPrefix","path","reduce","fieldsToUse","type","tabs","tabFields","tab","isNamedTab","newPath","val","some","disabledField","startsWith","formattedField","id","value"],"mappings":";AAEA,SAASA,gBAAgB,EAAEC,iBAAiB,QAAQ,iBAAgB;AACpE,OAAOC,SAASC,QAAQ,QAAQ,QAAO;AAEvC,MAAMC,8BAA8B,CAACC,YAAoBC;IACvD,IAAID,YAAY;QACd,IAAIL,iBAAiBM,QAAQ;YAC3B,OAAO,GAAGD,WAAW,CAAC,EAAEC,MAAMC,IAAI,EAAE;QACtC;QACA,OAAOF;IACT;IAEA,IAAIL,iBAAiBM,QAAQ;QAC3B,OAAOA,MAAMC,IAAI;IACnB;IAEA,OAAO;AACT;AAEA,MAAMC,eAAe,CAAC,EACpBF,KAAK,EACLG,MAAM,EAIP;IACC,qBACE,MAACN;;YACEM,uBACC,MAACN;;kCACC,KAACO;wBAAKC,OAAO;4BAAEC,SAAS;wBAAe;kCAAIH;;oBAC1C;;iBAED;0BACJ,KAACC;gBAAKC,OAAO;oBAAEC,SAAS;gBAAe;0BACpC,WAAWN,SAAS,OAAOA,MAAMO,KAAK,KAAK,WACxCP,MAAMO,KAAK,GACV,AAAC,CAAA,UAAUP,SAASA,MAAMC,IAAI,AAAD,KAAM;;;;AAIhD;AAEA,OAAO,MAAMO,eAAe,CAAC,EAC3BC,iBAAiB,EAAE,EACnBC,MAAM,EACNC,cAAc,IAAI,EAClBC,OAAO,EAAE,EAMV;IACC,IAAI,CAACF,QAAQ;QACX,OAAO,EAAE;IACX;IAEA,OAAOA,OAAOG,MAAM,CAClB,CAACC,aAAad;QACZ,0EAA0E;QAC1E,IAAIA,MAAMe,IAAI,KAAK,MAAM;YACvB,OAAOD;QACT;QAEA,IAAI,CAAEd,CAAAA,MAAMe,IAAI,KAAK,WAAWf,MAAMe,IAAI,KAAK,QAAO,KAAMpB,kBAAkBK,QAAQ;YACpF,OAAO;mBACFc;mBACAN,aAAa;oBACdC;oBACAC,QAAQV,MAAMU,MAAM;oBACpBC,aAAaT,aAAa;wBAAEF;wBAAOG,QAAQQ;oBAAY;oBACvDC,MAAMd,4BAA4Bc,MAAMZ;gBAC1C;aACD;QACH;QAEA,IAAIA,MAAMe,IAAI,KAAK,UAAU,UAAUf,OAAO;YAC5C,OAAO;mBACFc;mBACAd,MAAMgB,IAAI,CAACH,MAAM,CAClB,CAACI,WAAWC;oBACV,IAAI,YAAYA,KAAK;wBACnB,MAAMC,aAAa,UAAUD,OAAOA,IAAIjB,IAAI;wBAE5C,MAAMmB,UAAUD,aAAa,GAAGP,OAAOA,OAAO,MAAM,KAAKM,IAAIjB,IAAI,EAAE,GAAGW;wBAEtE,OAAO;+BACFK;+BACAT,aAAa;gCACdC;gCACAC,QAAQQ,IAAIR,MAAM;gCAClBC,aAAaQ,aACTjB,aAAa;oCACXF,OAAO;wCACLC,MAAMiB,IAAIjB,IAAI;wCACdM,OAAOW,IAAIX,KAAK,IAAIW,IAAIjB,IAAI;oCAC9B;oCACAE,QAAQQ;gCACV,KACAA;gCACJC,MAAMQ;4BACR;yBACD;oBACH;oBACA,OAAOH;gBACT,GACA,EAAE;aAEL;QACH;QAEA,MAAMI,MAAMvB,4BAA4Bc,MAAMZ;QAE9C,oCAAoC;QACpC,IACES,eAAea,IAAI,CACjB,CAACC,gBAAkBF,QAAQE,iBAAiBF,IAAIG,UAAU,CAAC,GAAGD,cAAc,CAAC,CAAC,IAEhF;YACA,OAAOT;QACT;QAEA,MAAMW,iBAAiB;YACrBC,IAAIL;YACJd,OAAOL,aAAa;gBAAEF;gBAAOG,QAAQQ;YAAY;YACjDgB,OAAON;QACT;QAEA,OAAO;eAAIP;YAAaW;SAAe;IACzC,GACA,EAAE;AAEN,EAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Preview/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,MAAM,OAAO,CAAA;AAQzB,OAAO,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Preview/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,MAAM,OAAO,CAAA;AAQzB,OAAO,cAAc,CAAA;AAKrB,eAAO,MAAM,OAAO,yBAuKnB,CAAA"}
|
|
@@ -3,8 +3,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { getTranslation } from '@payloadcms/translations';
|
|
4
4
|
import { CodeEditorLazy, Table, Translation, useConfig, useField, useTranslation } from '@payloadcms/ui';
|
|
5
5
|
import React from 'react';
|
|
6
|
-
import {
|
|
6
|
+
import { buildDisabledFieldRegex } from '../../utilities/buildDisabledFieldRegex.js';
|
|
7
7
|
import './index.scss';
|
|
8
|
+
import { useImportExport } from '../ImportExportProvider/index.js';
|
|
8
9
|
const baseClass = 'preview';
|
|
9
10
|
export const Preview = ()=>{
|
|
10
11
|
const { collection } = useImportExport();
|
|
@@ -36,8 +37,9 @@ export const Preview = ()=>{
|
|
|
36
37
|
const { i18n, t } = useTranslation();
|
|
37
38
|
const collectionSlug = typeof collection === 'string' && collection;
|
|
38
39
|
const collectionConfig = config.collections.find((collection)=>collection.slug === collectionSlug);
|
|
39
|
-
const
|
|
40
|
-
|
|
40
|
+
const disabledFieldRegexes = React.useMemo(()=>{
|
|
41
|
+
const disabledFieldPaths = collectionConfig?.admin?.custom?.['plugin-import-export']?.disabledFields ?? [];
|
|
42
|
+
return disabledFieldPaths.map(buildDisabledFieldRegex);
|
|
41
43
|
}, [
|
|
42
44
|
collectionConfig
|
|
43
45
|
]);
|
|
@@ -84,8 +86,8 @@ export const Preview = ()=>{
|
|
|
84
86
|
// Construct final list of field keys to match field order + meta order
|
|
85
87
|
const selectedKeys = Array.isArray(fields) && fields.length > 0 ? fields.flatMap((field)=>{
|
|
86
88
|
const regex = fieldToRegex(field);
|
|
87
|
-
return allKeys.filter((key)=>regex.test(key));
|
|
88
|
-
}) : allKeys.filter((key)=>!defaultMetaFields.includes(key) && !
|
|
89
|
+
return allKeys.filter((key)=>regex.test(key) && !disabledFieldRegexes.some((disabledRegex)=>disabledRegex.test(key)));
|
|
90
|
+
}) : allKeys.filter((key)=>!defaultMetaFields.includes(key) && !disabledFieldRegexes.some((regex)=>regex.test(key)));
|
|
89
91
|
const fieldKeys = Array.isArray(fields) && fields.length > 0 ? selectedKeys // strictly only what was selected
|
|
90
92
|
: [
|
|
91
93
|
...selectedKeys,
|
|
@@ -124,7 +126,7 @@ export const Preview = ()=>{
|
|
|
124
126
|
}, [
|
|
125
127
|
collectionConfig,
|
|
126
128
|
collectionSlug,
|
|
127
|
-
|
|
129
|
+
disabledFieldRegexes,
|
|
128
130
|
draft,
|
|
129
131
|
fields,
|
|
130
132
|
i18n,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/Preview/index.tsx"],"sourcesContent":["'use client'\nimport type { Column } from '@payloadcms/ui'\nimport type { ClientField } from 'payload'\n\nimport { getTranslation } from '@payloadcms/translations'\nimport {\n CodeEditorLazy,\n Table,\n Translation,\n useConfig,\n useField,\n useTranslation,\n} from '@payloadcms/ui'\nimport React from 'react'\n\nimport type {\n PluginImportExportTranslationKeys,\n PluginImportExportTranslations,\n} from '../../translations/index.js'\n\nimport { useImportExport } from '../ImportExportProvider/index.js'\nimport './index.scss'\n\nconst baseClass = 'preview'\n\nexport const Preview = () => {\n const { collection } = useImportExport()\n const { config } = useConfig()\n const { value: where } = useField({ path: 'where' })\n const { value: limit } = useField<number>({ path: 'limit' })\n const { value: fields } = useField<string[]>({ path: 'fields' })\n const { value: sort } = useField({ path: 'sort' })\n const { value: draft } = useField({ path: 'drafts' })\n const { value: locale } = useField({ path: 'locale' })\n const { value: format } = useField({ path: 'format' })\n const [dataToRender, setDataToRender] = React.useState<any[]>([])\n const [resultCount, setResultCount] = React.useState<any>('')\n const [columns, setColumns] = React.useState<Column[]>([])\n const { i18n, t } = useTranslation<\n PluginImportExportTranslations,\n PluginImportExportTranslationKeys\n >()\n\n const collectionSlug = typeof collection === 'string' && collection\n const collectionConfig = config.collections.find(\n (collection) => collection.slug === collectionSlug,\n )\n\n const disabledFieldsUnderscored = React.useMemo(() => {\n return (\n collectionConfig?.admin?.custom?.['plugin-import-export']?.disabledFields?.map((f: string) =>\n f.replace(/\\./g, '_'),\n ) ?? []\n )\n }, [collectionConfig])\n\n const isCSV = format === 'csv'\n\n React.useEffect(() => {\n const fetchData = async () => {\n if (!collectionSlug || !collectionConfig) {\n return\n }\n\n try {\n const res = await fetch('/api/preview-data', {\n body: JSON.stringify({\n collectionSlug,\n draft,\n fields,\n limit,\n locale,\n sort,\n where,\n }),\n credentials: 'include',\n headers: { 'Content-Type': 'application/json' },\n method: 'POST',\n })\n\n if (!res.ok) {\n return\n }\n\n const { docs, totalDocs }: { docs: Record<string, unknown>[]; totalDocs: number } =\n await res.json()\n\n setResultCount(limit && limit < totalDocs ? limit : totalDocs)\n\n const allKeys = Array.from(new Set(docs.flatMap((doc) => Object.keys(doc))))\n const defaultMetaFields = ['createdAt', 'updatedAt', '_status', 'id']\n\n // Match CSV column ordering by building keys based on fields and regex\n const fieldToRegex = (field: string): RegExp => {\n const parts = field.split('.').map((part) => `${part}(?:_\\\\d+)?`)\n return new RegExp(`^${parts.join('_')}`)\n }\n\n // Construct final list of field keys to match field order + meta order\n const selectedKeys =\n Array.isArray(fields) && fields.length > 0\n ? fields.flatMap((field) => {\n const regex = fieldToRegex(field)\n return allKeys.filter((key) => regex.test(key))\n })\n : allKeys.filter(\n (key) =>\n !defaultMetaFields.includes(key) && !disabledFieldsUnderscored.includes(key),\n )\n\n const fieldKeys =\n Array.isArray(fields) && fields.length > 0\n ? selectedKeys // strictly only what was selected\n : [...selectedKeys, ...defaultMetaFields.filter((key) => allKeys.includes(key))]\n\n // Build columns based on flattened keys\n const newColumns: Column[] = fieldKeys.map((key) => ({\n accessor: key,\n active: true,\n field: { name: key } as ClientField,\n Heading: getTranslation(key, i18n),\n renderedCells: docs.map((doc: Record<string, unknown>) => {\n const val = doc[key]\n\n if (val === undefined || val === null) {\n return null\n }\n\n // Avoid ESLint warning by type-checking before calling String()\n if (typeof val === 'string' || typeof val === 'number' || typeof val === 'boolean') {\n return String(val)\n }\n\n if (Array.isArray(val)) {\n return val.map(String).join(', ')\n }\n\n return JSON.stringify(val)\n }),\n }))\n\n setColumns(newColumns)\n setDataToRender(docs)\n } catch (error) {\n console.error('Error fetching preview data:', error)\n }\n }\n\n void fetchData()\n }, [\n collectionConfig,\n collectionSlug,\n disabledFieldsUnderscored,\n draft,\n fields,\n i18n,\n limit,\n locale,\n sort,\n where,\n ])\n\n return (\n <div className={baseClass}>\n <div className={`${baseClass}__header`}>\n <h3>\n <Translation i18nKey=\"version:preview\" t={t} />\n </h3>\n {resultCount && (\n <Translation\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n i18nKey=\"plugin-import-export:totalDocumentsCount\"\n t={t}\n variables={{\n count: resultCount,\n }}\n />\n )}\n </div>\n {dataToRender &&\n (isCSV ? (\n <Table columns={columns} data={dataToRender} />\n ) : (\n <CodeEditorLazy language=\"json\" readOnly value={JSON.stringify(dataToRender, null, 2)} />\n ))}\n </div>\n )\n}\n"],"names":["getTranslation","CodeEditorLazy","Table","Translation","useConfig","useField","useTranslation","React","useImportExport","baseClass","Preview","collection","config","value","where","path","limit","fields","sort","draft","locale","format","dataToRender","setDataToRender","useState","resultCount","setResultCount","columns","setColumns","i18n","t","collectionSlug","collectionConfig","collections","find","slug","disabledFieldsUnderscored","useMemo","admin","custom","disabledFields","map","f","replace","isCSV","useEffect","fetchData","res","fetch","body","JSON","stringify","credentials","headers","method","ok","docs","totalDocs","json","allKeys","Array","from","Set","flatMap","doc","Object","keys","defaultMetaFields","fieldToRegex","field","parts","split","part","RegExp","join","selectedKeys","isArray","length","regex","filter","key","test","includes","fieldKeys","newColumns","accessor","active","name","Heading","renderedCells","val","undefined","String","error","console","div","className","h3","i18nKey","variables","count","data","language","readOnly"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/Preview/index.tsx"],"sourcesContent":["'use client'\nimport type { Column } from '@payloadcms/ui'\nimport type { ClientField } from 'payload'\n\nimport { getTranslation } from '@payloadcms/translations'\nimport {\n CodeEditorLazy,\n Table,\n Translation,\n useConfig,\n useField,\n useTranslation,\n} from '@payloadcms/ui'\nimport React from 'react'\n\nimport type {\n PluginImportExportTranslationKeys,\n PluginImportExportTranslations,\n} from '../../translations/index.js'\n\nimport { buildDisabledFieldRegex } from '../../utilities/buildDisabledFieldRegex.js'\nimport './index.scss'\nimport { useImportExport } from '../ImportExportProvider/index.js'\n\nconst baseClass = 'preview'\n\nexport const Preview = () => {\n const { collection } = useImportExport()\n const { config } = useConfig()\n const { value: where } = useField({ path: 'where' })\n const { value: limit } = useField<number>({ path: 'limit' })\n const { value: fields } = useField<string[]>({ path: 'fields' })\n const { value: sort } = useField({ path: 'sort' })\n const { value: draft } = useField({ path: 'drafts' })\n const { value: locale } = useField({ path: 'locale' })\n const { value: format } = useField({ path: 'format' })\n const [dataToRender, setDataToRender] = React.useState<any[]>([])\n const [resultCount, setResultCount] = React.useState<any>('')\n const [columns, setColumns] = React.useState<Column[]>([])\n const { i18n, t } = useTranslation<\n PluginImportExportTranslations,\n PluginImportExportTranslationKeys\n >()\n\n const collectionSlug = typeof collection === 'string' && collection\n const collectionConfig = config.collections.find(\n (collection) => collection.slug === collectionSlug,\n )\n\n const disabledFieldRegexes: RegExp[] = React.useMemo(() => {\n const disabledFieldPaths =\n collectionConfig?.admin?.custom?.['plugin-import-export']?.disabledFields ?? []\n\n return disabledFieldPaths.map(buildDisabledFieldRegex)\n }, [collectionConfig])\n\n const isCSV = format === 'csv'\n\n React.useEffect(() => {\n const fetchData = async () => {\n if (!collectionSlug || !collectionConfig) {\n return\n }\n\n try {\n const res = await fetch('/api/preview-data', {\n body: JSON.stringify({\n collectionSlug,\n draft,\n fields,\n limit,\n locale,\n sort,\n where,\n }),\n credentials: 'include',\n headers: { 'Content-Type': 'application/json' },\n method: 'POST',\n })\n\n if (!res.ok) {\n return\n }\n\n const { docs, totalDocs }: { docs: Record<string, unknown>[]; totalDocs: number } =\n await res.json()\n\n setResultCount(limit && limit < totalDocs ? limit : totalDocs)\n\n const allKeys = Array.from(new Set(docs.flatMap((doc) => Object.keys(doc))))\n const defaultMetaFields = ['createdAt', 'updatedAt', '_status', 'id']\n\n // Match CSV column ordering by building keys based on fields and regex\n const fieldToRegex = (field: string): RegExp => {\n const parts = field.split('.').map((part) => `${part}(?:_\\\\d+)?`)\n return new RegExp(`^${parts.join('_')}`)\n }\n\n // Construct final list of field keys to match field order + meta order\n const selectedKeys =\n Array.isArray(fields) && fields.length > 0\n ? fields.flatMap((field) => {\n const regex = fieldToRegex(field)\n return allKeys.filter(\n (key) =>\n regex.test(key) &&\n !disabledFieldRegexes.some((disabledRegex) => disabledRegex.test(key)),\n )\n })\n : allKeys.filter(\n (key) =>\n !defaultMetaFields.includes(key) &&\n !disabledFieldRegexes.some((regex) => regex.test(key)),\n )\n\n const fieldKeys =\n Array.isArray(fields) && fields.length > 0\n ? selectedKeys // strictly only what was selected\n : [...selectedKeys, ...defaultMetaFields.filter((key) => allKeys.includes(key))]\n\n // Build columns based on flattened keys\n const newColumns: Column[] = fieldKeys.map((key) => ({\n accessor: key,\n active: true,\n field: { name: key } as ClientField,\n Heading: getTranslation(key, i18n),\n renderedCells: docs.map((doc: Record<string, unknown>) => {\n const val = doc[key]\n\n if (val === undefined || val === null) {\n return null\n }\n\n // Avoid ESLint warning by type-checking before calling String()\n if (typeof val === 'string' || typeof val === 'number' || typeof val === 'boolean') {\n return String(val)\n }\n\n if (Array.isArray(val)) {\n return val.map(String).join(', ')\n }\n\n return JSON.stringify(val)\n }),\n }))\n\n setColumns(newColumns)\n setDataToRender(docs)\n } catch (error) {\n console.error('Error fetching preview data:', error)\n }\n }\n\n void fetchData()\n }, [\n collectionConfig,\n collectionSlug,\n disabledFieldRegexes,\n draft,\n fields,\n i18n,\n limit,\n locale,\n sort,\n where,\n ])\n\n return (\n <div className={baseClass}>\n <div className={`${baseClass}__header`}>\n <h3>\n <Translation i18nKey=\"version:preview\" t={t} />\n </h3>\n {resultCount && (\n <Translation\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n i18nKey=\"plugin-import-export:totalDocumentsCount\"\n t={t}\n variables={{\n count: resultCount,\n }}\n />\n )}\n </div>\n {dataToRender &&\n (isCSV ? (\n <Table columns={columns} data={dataToRender} />\n ) : (\n <CodeEditorLazy language=\"json\" readOnly value={JSON.stringify(dataToRender, null, 2)} />\n ))}\n </div>\n )\n}\n"],"names":["getTranslation","CodeEditorLazy","Table","Translation","useConfig","useField","useTranslation","React","buildDisabledFieldRegex","useImportExport","baseClass","Preview","collection","config","value","where","path","limit","fields","sort","draft","locale","format","dataToRender","setDataToRender","useState","resultCount","setResultCount","columns","setColumns","i18n","t","collectionSlug","collectionConfig","collections","find","slug","disabledFieldRegexes","useMemo","disabledFieldPaths","admin","custom","disabledFields","map","isCSV","useEffect","fetchData","res","fetch","body","JSON","stringify","credentials","headers","method","ok","docs","totalDocs","json","allKeys","Array","from","Set","flatMap","doc","Object","keys","defaultMetaFields","fieldToRegex","field","parts","split","part","RegExp","join","selectedKeys","isArray","length","regex","filter","key","test","some","disabledRegex","includes","fieldKeys","newColumns","accessor","active","name","Heading","renderedCells","val","undefined","String","error","console","div","className","h3","i18nKey","variables","count","data","language","readOnly"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createExport.d.ts","sourceRoot":"","sources":["../../src/export/createExport.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"createExport.d.ts","sourceRoot":"","sources":["../../src/export/createExport.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAYrE,MAAM,MAAM,MAAM,GAAG;IACnB,cAAc,EAAE,MAAM,CAAA;IACtB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,MAAM,CAAC,EAAE,IAAI,GAAG,KAAK,CAAA;IACrB,iBAAiB,EAAE,MAAM,CAAA;IACzB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,MAAM,EAAE,KAAK,GAAG,MAAM,CAAA;IACtB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,IAAI,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,cAAc,EAAE,MAAM,CAAA;IACtB,KAAK,CAAC,EAAE,KAAK,CAAA;CACd,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,cAAc,CAAA;IACnB,IAAI,CAAC,EAAE,SAAS,CAAA;CACjB,CAAA;AAED,eAAO,MAAM,YAAY,SAAgB,gBAAgB,kCAgRxD,CAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* eslint-disable perfectionist/sort-objects */ import { stringify } from 'csv-stringify/sync';
|
|
2
2
|
import { APIError } from 'payload';
|
|
3
3
|
import { Readable } from 'stream';
|
|
4
|
+
import { buildDisabledFieldRegex } from '../utilities/buildDisabledFieldRegex.js';
|
|
4
5
|
import { flattenObject } from './flattenObject.js';
|
|
5
6
|
import { getCustomFieldFunctions } from './getCustomFieldFunctions.js';
|
|
6
7
|
import { getFilename } from './getFilename.js';
|
|
@@ -54,13 +55,17 @@ export const createExport = async (args)=>{
|
|
|
54
55
|
const toCSVFunctions = getCustomFieldFunctions({
|
|
55
56
|
fields: collectionConfig.flattenedFields
|
|
56
57
|
});
|
|
57
|
-
const
|
|
58
|
-
const
|
|
58
|
+
const disabledFields = collectionConfig.admin?.custom?.['plugin-import-export']?.disabledFields ?? [];
|
|
59
|
+
const disabledRegexes = disabledFields.map(buildDisabledFieldRegex);
|
|
59
60
|
const filterDisabled = (row)=>{
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
const filtered = {};
|
|
62
|
+
for (const [key, value] of Object.entries(row)){
|
|
63
|
+
const isDisabled = disabledRegexes.some((regex)=>regex.test(key));
|
|
64
|
+
if (!isDisabled) {
|
|
65
|
+
filtered[key] = value;
|
|
66
|
+
}
|
|
62
67
|
}
|
|
63
|
-
return
|
|
68
|
+
return filtered;
|
|
64
69
|
};
|
|
65
70
|
if (download) {
|
|
66
71
|
if (debug) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/export/createExport.ts"],"sourcesContent":["/* eslint-disable perfectionist/sort-objects */\nimport type { PayloadRequest, Sort, TypedUser, Where } from 'payload'\n\nimport { stringify } from 'csv-stringify/sync'\nimport { APIError } from 'payload'\nimport { Readable } from 'stream'\n\nimport { flattenObject } from './flattenObject.js'\nimport { getCustomFieldFunctions } from './getCustomFieldFunctions.js'\nimport { getFilename } from './getFilename.js'\nimport { getSelect } from './getSelect.js'\n\nexport type Export = {\n collectionSlug: string\n /**\n * If true, enables debug logging\n */\n debug?: boolean\n drafts?: 'no' | 'yes'\n exportsCollection: string\n fields?: string[]\n format: 'csv' | 'json'\n globals?: string[]\n id: number | string\n locale?: string\n name: string\n slug: string\n sort: Sort\n user: string\n userCollection: 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 input: Export\n req: PayloadRequest\n user?: TypedUser\n}\n\nexport const createExport = async (args: CreateExportArgs) => {\n const {\n download,\n input: {\n id,\n name: nameArg,\n collectionSlug,\n debug = false,\n drafts,\n exportsCollection,\n fields,\n format,\n locale: localeInput,\n sort,\n user,\n where,\n },\n req: { locale: localeArg, payload },\n req,\n } = args\n\n if (debug) {\n req.payload.logger.info({\n message: 'Starting export process with args:',\n collectionSlug,\n drafts,\n fields,\n format,\n })\n }\n\n const locale = localeInput ?? localeArg\n const collectionConfig = payload.config.collections.find(({ slug }) => slug === collectionSlug)\n if (!collectionConfig) {\n throw new APIError(`Collection with slug ${collectionSlug} not found`)\n }\n\n const name = `${nameArg ?? `${getFilename()}-${collectionSlug}`}.${format}`\n const isCSV = format === 'csv'\n const select = Array.isArray(fields) && fields.length > 0 ? getSelect(fields) : undefined\n\n if (debug) {\n req.payload.logger.info({ message: 'Export configuration:', name, isCSV, locale })\n }\n\n const findArgs = {\n collection: collectionSlug,\n depth: 1,\n draft: drafts === 'yes',\n limit: 100,\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.info({ message: 'Find arguments:', findArgs })\n }\n\n const toCSVFunctions = getCustomFieldFunctions({\n fields: collectionConfig.flattenedFields,\n })\n\n const disabledFieldsDot =\n collectionConfig.admin?.custom?.['plugin-import-export']?.disabledFields ?? []\n const disabledFields = disabledFieldsDot.map((f: string) => f.replace(/\\./g, '_'))\n\n const filterDisabled = (row: Record<string, unknown>): Record<string, unknown> => {\n for (const key of disabledFields) {\n delete row[key]\n }\n return row\n }\n\n if (download) {\n if (debug) {\n req.payload.logger.info('Pre-scanning all columns before streaming')\n }\n\n const allColumnsSet = new Set<string>()\n const allColumns: string[] = []\n let scanPage = 1\n let hasMore = true\n\n while (hasMore) {\n const result = await payload.find({ ...findArgs, page: scanPage })\n\n result.docs.forEach((doc) => {\n const flat = filterDisabled(flattenObject({ doc, fields, toCSVFunctions }))\n Object.keys(flat).forEach((key) => {\n if (!allColumnsSet.has(key)) {\n allColumnsSet.add(key)\n allColumns.push(key)\n }\n })\n })\n\n hasMore = result.hasNextPage\n scanPage += 1\n }\n\n if (debug) {\n req.payload.logger.info(`Discovered ${allColumns.length} columns`)\n }\n\n const encoder = new TextEncoder()\n let isFirstBatch = true\n let streamPage = 1\n\n const stream = new Readable({\n async read() {\n const result = await payload.find({ ...findArgs, page: streamPage })\n\n if (debug) {\n req.payload.logger.info(`Streaming batch ${streamPage} with ${result.docs.length} docs`)\n }\n\n if (result.docs.length === 0) {\n this.push(null)\n return\n }\n\n const batchRows = result.docs.map((doc) =>\n filterDisabled(flattenObject({ doc, fields, toCSVFunctions })),\n )\n\n const paddedRows = batchRows.map((row) => {\n const fullRow: Record<string, unknown> = {}\n for (const col of allColumns) {\n fullRow[col] = row[col] ?? ''\n }\n return fullRow\n })\n\n const csvString = stringify(paddedRows, {\n header: isFirstBatch,\n columns: allColumns,\n })\n\n this.push(encoder.encode(csvString))\n isFirstBatch = false\n streamPage += 1\n\n if (!result.hasNextPage) {\n if (debug) {\n req.payload.logger.info('Stream complete - no more pages')\n }\n this.push(null) // End the stream\n }\n },\n })\n\n return new Response(stream as any, {\n headers: {\n 'Content-Disposition': `attachment; filename=\"${name}\"`,\n 'Content-Type': isCSV ? 'text/csv' : 'application/json',\n },\n })\n }\n\n // Non-download path (buffered export)\n if (debug) {\n req.payload.logger.info('Starting file generation')\n }\n\n const outputData: string[] = []\n const rows: Record<string, unknown>[] = []\n const columnsSet = new Set<string>()\n const columns: string[] = []\n let page = 1\n let hasNextPage = true\n\n while (hasNextPage) {\n const result = await payload.find({\n ...findArgs,\n page,\n })\n\n if (debug) {\n req.payload.logger.info(\n `Processing batch ${findArgs.page} with ${result.docs.length} documents`,\n )\n }\n\n if (isCSV) {\n const batchRows = result.docs.map((doc) =>\n filterDisabled(flattenObject({ doc, fields, toCSVFunctions })),\n )\n\n // Track discovered column keys\n batchRows.forEach((row) => {\n Object.keys(row).forEach((key) => {\n if (!columnsSet.has(key)) {\n columnsSet.add(key)\n columns.push(key)\n }\n })\n })\n\n rows.push(...batchRows)\n } else {\n const jsonInput = result.docs.map((doc) => JSON.stringify(doc))\n outputData.push(jsonInput.join(',\\n'))\n }\n\n hasNextPage = result.hasNextPage\n page += 1\n }\n\n if (isCSV) {\n const paddedRows = rows.map((row) => {\n const fullRow: Record<string, unknown> = {}\n for (const col of columns) {\n fullRow[col] = row[col] ?? ''\n }\n return fullRow\n })\n\n outputData.push(\n stringify(paddedRows, {\n header: true,\n columns,\n }),\n )\n }\n\n const buffer = Buffer.from(format === 'json' ? `[${outputData.join(',')}]` : outputData.join(''))\n if (debug) {\n req.payload.logger.info(`${format} file generation complete`)\n }\n\n if (!id) {\n if (debug) {\n req.payload.logger.info('Creating new export file')\n }\n req.file = {\n name,\n data: buffer,\n mimetype: isCSV ? 'text/csv' : 'application/json',\n size: buffer.length,\n }\n } else {\n if (debug) {\n req.payload.logger.info(`Updating existing export with id: ${id}`)\n }\n await req.payload.update({\n id,\n collection: exportsCollection,\n data: {},\n file: {\n name,\n data: buffer,\n mimetype: isCSV ? 'text/csv' : 'application/json',\n size: buffer.length,\n },\n user,\n })\n }\n if (debug) {\n req.payload.logger.info('Export process completed successfully')\n }\n}\n"],"names":["stringify","APIError","Readable","flattenObject","getCustomFieldFunctions","getFilename","getSelect","createExport","args","download","input","id","name","nameArg","collectionSlug","debug","drafts","exportsCollection","fields","format","locale","localeInput","sort","user","where","req","localeArg","payload","logger","info","message","collectionConfig","config","collections","find","slug","isCSV","select","Array","isArray","length","undefined","findArgs","collection","depth","draft","limit","overrideAccess","page","toCSVFunctions","flattenedFields","disabledFieldsDot","admin","custom","disabledFields","map","f","replace","filterDisabled","row","key","allColumnsSet","Set","allColumns","scanPage","hasMore","result","docs","forEach","doc","flat","Object","keys","has","add","push","hasNextPage","encoder","TextEncoder","isFirstBatch","streamPage","stream","read","batchRows","paddedRows","fullRow","col","csvString","header","columns","encode","Response","headers","outputData","rows","columnsSet","jsonInput","JSON","join","buffer","Buffer","from","file","data","mimetype","size","update"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/export/createExport.ts"],"sourcesContent":["/* eslint-disable perfectionist/sort-objects */\nimport type { PayloadRequest, Sort, TypedUser, Where } from 'payload'\n\nimport { stringify } from 'csv-stringify/sync'\nimport { APIError } from 'payload'\nimport { Readable } from 'stream'\n\nimport { buildDisabledFieldRegex } from '../utilities/buildDisabledFieldRegex.js'\nimport { flattenObject } from './flattenObject.js'\nimport { getCustomFieldFunctions } from './getCustomFieldFunctions.js'\nimport { getFilename } from './getFilename.js'\nimport { getSelect } from './getSelect.js'\n\nexport type Export = {\n collectionSlug: string\n /**\n * If true, enables debug logging\n */\n debug?: boolean\n drafts?: 'no' | 'yes'\n exportsCollection: string\n fields?: string[]\n format: 'csv' | 'json'\n globals?: string[]\n id: number | string\n locale?: string\n name: string\n slug: string\n sort: Sort\n user: string\n userCollection: 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 input: Export\n req: PayloadRequest\n user?: TypedUser\n}\n\nexport const createExport = async (args: CreateExportArgs) => {\n const {\n download,\n input: {\n id,\n name: nameArg,\n collectionSlug,\n debug = false,\n drafts,\n exportsCollection,\n fields,\n format,\n locale: localeInput,\n sort,\n user,\n where,\n },\n req: { locale: localeArg, payload },\n req,\n } = args\n\n if (debug) {\n req.payload.logger.info({\n message: 'Starting export process with args:',\n collectionSlug,\n drafts,\n fields,\n format,\n })\n }\n\n const locale = localeInput ?? localeArg\n const collectionConfig = payload.config.collections.find(({ slug }) => slug === collectionSlug)\n if (!collectionConfig) {\n throw new APIError(`Collection with slug ${collectionSlug} not found`)\n }\n\n const name = `${nameArg ?? `${getFilename()}-${collectionSlug}`}.${format}`\n const isCSV = format === 'csv'\n const select = Array.isArray(fields) && fields.length > 0 ? getSelect(fields) : undefined\n\n if (debug) {\n req.payload.logger.info({ message: 'Export configuration:', name, isCSV, locale })\n }\n\n const findArgs = {\n collection: collectionSlug,\n depth: 1,\n draft: drafts === 'yes',\n limit: 100,\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.info({ message: 'Find arguments:', findArgs })\n }\n\n const toCSVFunctions = getCustomFieldFunctions({\n fields: collectionConfig.flattenedFields,\n })\n\n const disabledFields =\n collectionConfig.admin?.custom?.['plugin-import-export']?.disabledFields ?? []\n\n const disabledRegexes: RegExp[] = disabledFields.map(buildDisabledFieldRegex)\n\n const filterDisabled = (row: Record<string, unknown>): Record<string, unknown> => {\n const filtered: Record<string, unknown> = {}\n\n for (const [key, value] of Object.entries(row)) {\n const isDisabled = disabledRegexes.some((regex) => regex.test(key))\n if (!isDisabled) {\n filtered[key] = value\n }\n }\n\n return filtered\n }\n\n if (download) {\n if (debug) {\n req.payload.logger.info('Pre-scanning all columns before streaming')\n }\n\n const allColumnsSet = new Set<string>()\n const allColumns: string[] = []\n let scanPage = 1\n let hasMore = true\n\n while (hasMore) {\n const result = await payload.find({ ...findArgs, page: scanPage })\n\n result.docs.forEach((doc) => {\n const flat = filterDisabled(flattenObject({ doc, fields, toCSVFunctions }))\n Object.keys(flat).forEach((key) => {\n if (!allColumnsSet.has(key)) {\n allColumnsSet.add(key)\n allColumns.push(key)\n }\n })\n })\n\n hasMore = result.hasNextPage\n scanPage += 1\n }\n\n if (debug) {\n req.payload.logger.info(`Discovered ${allColumns.length} columns`)\n }\n\n const encoder = new TextEncoder()\n let isFirstBatch = true\n let streamPage = 1\n\n const stream = new Readable({\n async read() {\n const result = await payload.find({ ...findArgs, page: streamPage })\n\n if (debug) {\n req.payload.logger.info(`Streaming batch ${streamPage} with ${result.docs.length} docs`)\n }\n\n if (result.docs.length === 0) {\n this.push(null)\n return\n }\n\n const batchRows = result.docs.map((doc) =>\n filterDisabled(flattenObject({ doc, fields, toCSVFunctions })),\n )\n\n const paddedRows = batchRows.map((row) => {\n const fullRow: Record<string, unknown> = {}\n for (const col of allColumns) {\n fullRow[col] = row[col] ?? ''\n }\n return fullRow\n })\n\n const csvString = stringify(paddedRows, {\n header: isFirstBatch,\n columns: allColumns,\n })\n\n this.push(encoder.encode(csvString))\n isFirstBatch = false\n streamPage += 1\n\n if (!result.hasNextPage) {\n if (debug) {\n req.payload.logger.info('Stream complete - no more pages')\n }\n this.push(null) // End the stream\n }\n },\n })\n\n return new Response(stream as any, {\n headers: {\n 'Content-Disposition': `attachment; filename=\"${name}\"`,\n 'Content-Type': isCSV ? 'text/csv' : 'application/json',\n },\n })\n }\n\n // Non-download path (buffered export)\n if (debug) {\n req.payload.logger.info('Starting file generation')\n }\n\n const outputData: string[] = []\n const rows: Record<string, unknown>[] = []\n const columnsSet = new Set<string>()\n const columns: string[] = []\n let page = 1\n let hasNextPage = true\n\n while (hasNextPage) {\n const result = await payload.find({\n ...findArgs,\n page,\n })\n\n if (debug) {\n req.payload.logger.info(\n `Processing batch ${findArgs.page} with ${result.docs.length} documents`,\n )\n }\n\n if (isCSV) {\n const batchRows = result.docs.map((doc) =>\n filterDisabled(flattenObject({ doc, fields, toCSVFunctions })),\n )\n\n // Track discovered column keys\n batchRows.forEach((row) => {\n Object.keys(row).forEach((key) => {\n if (!columnsSet.has(key)) {\n columnsSet.add(key)\n columns.push(key)\n }\n })\n })\n\n rows.push(...batchRows)\n } else {\n const jsonInput = result.docs.map((doc) => JSON.stringify(doc))\n outputData.push(jsonInput.join(',\\n'))\n }\n\n hasNextPage = result.hasNextPage\n page += 1\n }\n\n if (isCSV) {\n const paddedRows = rows.map((row) => {\n const fullRow: Record<string, unknown> = {}\n for (const col of columns) {\n fullRow[col] = row[col] ?? ''\n }\n return fullRow\n })\n\n outputData.push(\n stringify(paddedRows, {\n header: true,\n columns,\n }),\n )\n }\n\n const buffer = Buffer.from(format === 'json' ? `[${outputData.join(',')}]` : outputData.join(''))\n if (debug) {\n req.payload.logger.info(`${format} file generation complete`)\n }\n\n if (!id) {\n if (debug) {\n req.payload.logger.info('Creating new export file')\n }\n req.file = {\n name,\n data: buffer,\n mimetype: isCSV ? 'text/csv' : 'application/json',\n size: buffer.length,\n }\n } else {\n if (debug) {\n req.payload.logger.info(`Updating existing export with id: ${id}`)\n }\n await req.payload.update({\n id,\n collection: exportsCollection,\n data: {},\n file: {\n name,\n data: buffer,\n mimetype: isCSV ? 'text/csv' : 'application/json',\n size: buffer.length,\n },\n user,\n })\n }\n if (debug) {\n req.payload.logger.info('Export process completed successfully')\n }\n}\n"],"names":["stringify","APIError","Readable","buildDisabledFieldRegex","flattenObject","getCustomFieldFunctions","getFilename","getSelect","createExport","args","download","input","id","name","nameArg","collectionSlug","debug","drafts","exportsCollection","fields","format","locale","localeInput","sort","user","where","req","localeArg","payload","logger","info","message","collectionConfig","config","collections","find","slug","isCSV","select","Array","isArray","length","undefined","findArgs","collection","depth","draft","limit","overrideAccess","page","toCSVFunctions","flattenedFields","disabledFields","admin","custom","disabledRegexes","map","filterDisabled","row","filtered","key","value","Object","entries","isDisabled","some","regex","test","allColumnsSet","Set","allColumns","scanPage","hasMore","result","docs","forEach","doc","flat","keys","has","add","push","hasNextPage","encoder","TextEncoder","isFirstBatch","streamPage","stream","read","batchRows","paddedRows","fullRow","col","csvString","header","columns","encode","Response","headers","outputData","rows","columnsSet","jsonInput","JSON","join","buffer","Buffer","from","file","data","mimetype","size","update"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flattenObject.d.ts","sourceRoot":"","sources":["../../src/export/flattenObject.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEhD,KAAK,IAAI,GAAG;IACV,GAAG,EAAE,QAAQ,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;CAC9C,CAAA;AAED,eAAO,MAAM,aAAa,6CAKvB,IAAI,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"flattenObject.d.ts","sourceRoot":"","sources":["../../src/export/flattenObject.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEhD,KAAK,IAAI,GAAG;IACV,GAAG,EAAE,QAAQ,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;CAC9C,CAAA;AAED,eAAO,MAAM,aAAa,6CAKvB,IAAI,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAmI/B,CAAA"}
|
|
@@ -6,13 +6,15 @@ export const flattenObject = ({ doc, fields, prefix, toCSVFunctions })=>{
|
|
|
6
6
|
if (Array.isArray(value)) {
|
|
7
7
|
value.forEach((item, index)=>{
|
|
8
8
|
if (typeof item === 'object' && item !== null) {
|
|
9
|
+
const blockType = typeof item.blockType === 'string' ? item.blockType : undefined;
|
|
10
|
+
const itemPrefix = blockType ? `${newKey}_${index}_${blockType}` : `${newKey}_${index}`;
|
|
9
11
|
// Case: hasMany polymorphic relationships
|
|
10
12
|
if ('relationTo' in item && 'value' in item && typeof item.value === 'object' && item.value !== null) {
|
|
11
|
-
row[`${
|
|
12
|
-
row[`${
|
|
13
|
+
row[`${itemPrefix}_relationTo`] = item.relationTo;
|
|
14
|
+
row[`${itemPrefix}_id`] = item.value.id;
|
|
13
15
|
return;
|
|
14
16
|
}
|
|
15
|
-
flatten(item,
|
|
17
|
+
flatten(item, itemPrefix);
|
|
16
18
|
} else {
|
|
17
19
|
if (toCSVFunctions?.[newKey]) {
|
|
18
20
|
const columnName = `${newKey}_${index}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/export/flattenObject.ts"],"sourcesContent":["import type { Document } from 'payload'\n\nimport type { ToCSVFunction } from '../types.js'\n\ntype Args = {\n doc: Document\n fields?: string[]\n prefix?: string\n toCSVFunctions: Record<string, ToCSVFunction>\n}\n\nexport const flattenObject = ({\n doc,\n fields,\n prefix,\n toCSVFunctions,\n}: Args): Record<string, unknown> => {\n const row: Record<string, unknown> = {}\n\n const flatten = (siblingDoc: Document, prefix?: string) => {\n Object.entries(siblingDoc).forEach(([key, value]) => {\n const newKey = prefix ? `${prefix}_${key}` : key\n\n if (Array.isArray(value)) {\n value.forEach((item, index) => {\n if (typeof item === 'object' && item !== null) {\n // Case: hasMany polymorphic relationships\n if (\n 'relationTo' in item &&\n 'value' in item &&\n typeof item.value === 'object' &&\n item.value !== null\n ) {\n row[`${
|
|
1
|
+
{"version":3,"sources":["../../src/export/flattenObject.ts"],"sourcesContent":["import type { Document } from 'payload'\n\nimport type { ToCSVFunction } from '../types.js'\n\ntype Args = {\n doc: Document\n fields?: string[]\n prefix?: string\n toCSVFunctions: Record<string, ToCSVFunction>\n}\n\nexport const flattenObject = ({\n doc,\n fields,\n prefix,\n toCSVFunctions,\n}: Args): Record<string, unknown> => {\n const row: Record<string, unknown> = {}\n\n const flatten = (siblingDoc: Document, prefix?: string) => {\n Object.entries(siblingDoc).forEach(([key, value]) => {\n const newKey = prefix ? `${prefix}_${key}` : key\n\n if (Array.isArray(value)) {\n value.forEach((item, index) => {\n if (typeof item === 'object' && item !== null) {\n const blockType = typeof item.blockType === 'string' ? item.blockType : undefined\n\n const itemPrefix = blockType ? `${newKey}_${index}_${blockType}` : `${newKey}_${index}`\n\n // Case: hasMany polymorphic relationships\n if (\n 'relationTo' in item &&\n 'value' in item &&\n typeof item.value === 'object' &&\n item.value !== null\n ) {\n row[`${itemPrefix}_relationTo`] = item.relationTo\n row[`${itemPrefix}_id`] = item.value.id\n return\n }\n\n flatten(item, itemPrefix)\n } else {\n if (toCSVFunctions?.[newKey]) {\n const columnName = `${newKey}_${index}`\n try {\n const result = toCSVFunctions[newKey]({\n columnName,\n data: row,\n doc,\n row,\n siblingDoc,\n value: item,\n })\n if (typeof result !== 'undefined') {\n row[columnName] = result\n }\n } catch (error) {\n throw new Error(\n `Error in toCSVFunction for array item \"${columnName}\": ${JSON.stringify(item)}\\n${\n (error as Error).message\n }`,\n )\n }\n } else {\n row[`${newKey}_${index}`] = item\n }\n }\n })\n } else if (typeof value === 'object' && value !== null) {\n if (!toCSVFunctions?.[newKey]) {\n flatten(value, newKey)\n } else {\n try {\n const result = toCSVFunctions[newKey]({\n columnName: newKey,\n data: row,\n doc,\n row,\n siblingDoc,\n value,\n })\n if (typeof result !== 'undefined') {\n row[newKey] = result\n }\n } catch (error) {\n throw new Error(\n `Error in toCSVFunction for nested object \"${newKey}\": ${JSON.stringify(value)}\\n${(error as Error).message}`,\n )\n }\n }\n } else {\n if (toCSVFunctions?.[newKey]) {\n try {\n const result = toCSVFunctions[newKey]({\n columnName: newKey,\n data: row,\n doc,\n row,\n siblingDoc,\n value,\n })\n if (typeof result !== 'undefined') {\n row[newKey] = result\n }\n } catch (error) {\n throw new Error(\n `Error in toCSVFunction for field \"${newKey}\": ${JSON.stringify(value)}\\n${(error as Error).message}`,\n )\n }\n } else {\n row[newKey] = value\n }\n }\n })\n }\n\n flatten(doc, prefix)\n\n if (Array.isArray(fields) && fields.length > 0) {\n const orderedResult: Record<string, unknown> = {}\n\n const fieldToRegex = (field: string): RegExp => {\n const parts = field.split('.').map((part) => `${part}(?:_\\\\d+)?`)\n const pattern = `^${parts.join('_')}`\n return new RegExp(pattern)\n }\n\n fields.forEach((field) => {\n if (row[field.replace(/\\./g, '_')]) {\n const sanitizedField = field.replace(/\\./g, '_')\n orderedResult[sanitizedField] = row[sanitizedField]\n } else {\n const regex = fieldToRegex(field)\n Object.keys(row).forEach((key) => {\n if (regex.test(key)) {\n orderedResult[key] = row[key]\n }\n })\n }\n })\n\n return orderedResult\n }\n\n return row\n}\n"],"names":["flattenObject","doc","fields","prefix","toCSVFunctions","row","flatten","siblingDoc","Object","entries","forEach","key","value","newKey","Array","isArray","item","index","blockType","undefined","itemPrefix","relationTo","id","columnName","result","data","error","Error","JSON","stringify","message","length","orderedResult","fieldToRegex","field","parts","split","map","part","pattern","join","RegExp","replace","sanitizedField","regex","keys","test"],"mappings":"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"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAkB,MAAM,SAAS,CAAA;AAKrD,OAAO,KAAK,EAAE,wBAAwB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAkB,MAAM,SAAS,CAAA;AAKrD,OAAO,KAAK,EAAE,wBAAwB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAWzE,eAAO,MAAM,kBAAkB,iBACd,wBAAwB,cAC9B,MAAM,KAAG,MA0JjB,CAAA;AAEH,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAiB,WAAW;QAC1B,sBAAsB,CAAC,EAAE;YACvB;;;;;;eAMG;YACH,QAAQ,CAAC,EAAE,OAAO,CAAA;YAClB,KAAK,CAAC,EAAE,aAAa,CAAA;SACtB,CAAA;KACF;CACF"}
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { addDataAndFileToRequest, deepMergeSimple
|
|
1
|
+
import { addDataAndFileToRequest, deepMergeSimple } from 'payload';
|
|
2
2
|
import { flattenObject } from './export/flattenObject.js';
|
|
3
3
|
import { getCreateCollectionExportTask } from './export/getCreateExportCollectionTask.js';
|
|
4
4
|
import { getCustomFieldFunctions } from './export/getCustomFieldFunctions.js';
|
|
5
5
|
import { getSelect } from './export/getSelect.js';
|
|
6
6
|
import { getExportCollection } from './getExportCollection.js';
|
|
7
7
|
import { translations } from './translations/index.js';
|
|
8
|
+
import { collectDisabledFieldPaths } from './utilities/collectDisabledFieldPaths.js';
|
|
8
9
|
import { getFlattenedFieldKeys } from './utilities/getFlattenedFieldKeys.js';
|
|
9
10
|
export const importExportPlugin = (pluginConfig)=>(config)=>{
|
|
10
11
|
const exportCollection = getExportCollection({
|
|
@@ -49,12 +50,8 @@ export const importExportPlugin = (pluginConfig)=>(config)=>{
|
|
|
49
50
|
},
|
|
50
51
|
path: '@payloadcms/plugin-import-export/rsc#ExportListMenuItem'
|
|
51
52
|
});
|
|
52
|
-
//
|
|
53
|
-
const
|
|
54
|
-
moveSubFieldsToTop: true
|
|
55
|
-
});
|
|
56
|
-
// Find fields explicitly marked as disabled for import/export
|
|
57
|
-
const disabledFieldAccessors = flattenedFields.filter((field)=>field.custom?.['plugin-import-export']?.disabled).map((field)=>field.accessor || field.name);
|
|
53
|
+
// // Find fields explicitly marked as disabled for import/export
|
|
54
|
+
const disabledFieldAccessors = collectDisabledFieldPaths(collection.fields);
|
|
58
55
|
// Store disabled field accessors in the admin config for use in the UI
|
|
59
56
|
collection.admin.custom = {
|
|
60
57
|
...collection.admin.custom || {},
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { Config, FlattenedField } from 'payload'\n\nimport { addDataAndFileToRequest, deepMergeSimple, flattenTopLevelFields } from 'payload'\n\nimport type { PluginDefaultTranslationsObject } from './translations/types.js'\nimport type { ImportExportPluginConfig, ToCSVFunction } from './types.js'\n\nimport { flattenObject } from './export/flattenObject.js'\nimport { getCreateCollectionExportTask } from './export/getCreateExportCollectionTask.js'\nimport { getCustomFieldFunctions } from './export/getCustomFieldFunctions.js'\nimport { getSelect } from './export/getSelect.js'\nimport { getExportCollection } from './getExportCollection.js'\nimport { translations } from './translations/index.js'\nimport { getFlattenedFieldKeys } from './utilities/getFlattenedFieldKeys.js'\n\nexport const importExportPlugin =\n (pluginConfig: ImportExportPluginConfig) =>\n (config: Config): Config => {\n const exportCollection = getExportCollection({ config, pluginConfig })\n if (config.collections) {\n config.collections.push(exportCollection)\n } else {\n config.collections = [exportCollection]\n }\n\n // inject custom import export provider\n config.admin = config.admin || {}\n config.admin.components = config.admin.components || {}\n config.admin.components.providers = config.admin.components.providers || []\n config.admin.components.providers.push(\n '@payloadcms/plugin-import-export/rsc#ImportExportProvider',\n )\n\n // inject the createExport job into the config\n ;((config.jobs ??= {}).tasks ??= []).push(getCreateCollectionExportTask(config, pluginConfig))\n\n let collectionsToUpdate = config.collections\n\n const usePluginCollections = pluginConfig.collections && pluginConfig.collections?.length > 0\n\n if (usePluginCollections) {\n collectionsToUpdate = config.collections?.filter((collection) => {\n return pluginConfig.collections?.includes(collection.slug)\n })\n }\n\n collectionsToUpdate.forEach((collection) => {\n if (!collection.admin) {\n collection.admin = { components: { listMenuItems: [] } }\n }\n const components = collection.admin.components || {}\n if (!components.listMenuItems) {\n components.listMenuItems = []\n }\n components.listMenuItems.push({\n clientProps: {\n exportCollectionSlug: exportCollection.slug,\n },\n path: '@payloadcms/plugin-import-export/rsc#ExportListMenuItem',\n })\n\n // Flatten top-level fields to expose nested fields for export config\n const flattenedFields = flattenTopLevelFields(collection.fields, {\n moveSubFieldsToTop: true,\n })\n\n // Find fields explicitly marked as disabled for import/export\n const disabledFieldAccessors = flattenedFields\n .filter((field) => field.custom?.['plugin-import-export']?.disabled)\n .map((field) => field.accessor || field.name)\n\n // Store disabled field accessors in the admin config for use in the UI\n collection.admin.custom = {\n ...(collection.admin.custom || {}),\n 'plugin-import-export': {\n ...(collection.admin.custom?.['plugin-import-export'] || {}),\n disabledFields: disabledFieldAccessors,\n },\n }\n\n collection.admin.components = components\n })\n\n if (!config.i18n) {\n config.i18n = {}\n }\n\n // config.i18n.translations = deepMergeSimple(translations, config.i18n?.translations ?? {})\n\n // Inject custom REST endpoints into the config\n config.endpoints = config.endpoints || []\n config.endpoints.push({\n handler: async (req) => {\n await addDataAndFileToRequest(req)\n\n const { collectionSlug, draft, fields, limit, locale, sort, where } = req.data as {\n collectionSlug: string\n draft?: 'no' | 'yes'\n fields?: string[]\n limit?: number\n locale?: string\n sort?: any\n where?: any\n }\n\n const collection = req.payload.collections[collectionSlug]\n if (!collection) {\n return Response.json(\n { error: `Collection with slug ${collectionSlug} not found` },\n { status: 400 },\n )\n }\n\n const select = Array.isArray(fields) && fields.length > 0 ? getSelect(fields) : undefined\n\n const result = await req.payload.find({\n collection: collectionSlug,\n depth: 1,\n draft: draft === 'yes',\n limit: limit && limit > 10 ? 10 : limit,\n locale,\n overrideAccess: false,\n req,\n select,\n sort,\n where,\n })\n\n const docs = result.docs\n\n const toCSVFunctions = getCustomFieldFunctions({\n fields: collection.config.fields as FlattenedField[],\n })\n\n const possibleKeys = getFlattenedFieldKeys(collection.config.fields as FlattenedField[])\n\n const transformed = docs.map((doc) => {\n const row = flattenObject({\n doc,\n fields,\n toCSVFunctions,\n })\n\n for (const key of possibleKeys) {\n if (!(key in row)) {\n row[key] = null\n }\n }\n\n return row\n })\n\n return Response.json({\n docs: transformed,\n totalDocs: result.totalDocs,\n })\n },\n method: 'post',\n path: '/preview-data',\n })\n\n /**\n * Merge plugin translations\n */\n const simplifiedTranslations = Object.entries(translations).reduce(\n (acc, [key, value]) => {\n acc[key] = value.translations\n return acc\n },\n {} as Record<string, PluginDefaultTranslationsObject>,\n )\n\n config.i18n = {\n ...config.i18n,\n translations: deepMergeSimple(simplifiedTranslations, config.i18n?.translations ?? {}),\n }\n\n return config\n }\n\ndeclare module 'payload' {\n export interface FieldCustom {\n 'plugin-import-export'?: {\n /**\n * When `true` the field is **completely excluded** from the import-export plugin:\n * - It will not appear in the “Fields to export” selector.\n * - It is hidden from the preview list when no specific fields are chosen.\n * - Its data is omitted from the final CSV / JSON export.\n * @default false\n */\n disabled?: boolean\n toCSV?: ToCSVFunction\n }\n }\n}\n"],"names":["addDataAndFileToRequest","deepMergeSimple","flattenTopLevelFields","flattenObject","getCreateCollectionExportTask","getCustomFieldFunctions","getSelect","getExportCollection","translations","getFlattenedFieldKeys","importExportPlugin","pluginConfig","config","exportCollection","collections","push","admin","components","providers","jobs","tasks","collectionsToUpdate","usePluginCollections","length","filter","collection","includes","slug","forEach","listMenuItems","clientProps","exportCollectionSlug","path","flattenedFields","fields","moveSubFieldsToTop","disabledFieldAccessors","field","custom","disabled","map","accessor","name","disabledFields","i18n","endpoints","handler","req","collectionSlug","draft","limit","locale","sort","where","data","payload","Response","json","error","status","select","Array","isArray","undefined","result","find","depth","overrideAccess","docs","toCSVFunctions","possibleKeys","transformed","doc","row","key","totalDocs","method","simplifiedTranslations","Object","entries","reduce","acc","value"],"mappings":"AAEA,SAASA,uBAAuB,EAAEC,eAAe,EAAEC,qBAAqB,QAAQ,UAAS;AAKzF,SAASC,aAAa,QAAQ,4BAA2B;AACzD,SAASC,6BAA6B,QAAQ,4CAA2C;AACzF,SAASC,uBAAuB,QAAQ,sCAAqC;AAC7E,SAASC,SAAS,QAAQ,wBAAuB;AACjD,SAASC,mBAAmB,QAAQ,2BAA0B;AAC9D,SAASC,YAAY,QAAQ,0BAAyB;AACtD,SAASC,qBAAqB,QAAQ,uCAAsC;AAE5E,OAAO,MAAMC,qBACX,CAACC,eACD,CAACC;QACC,MAAMC,mBAAmBN,oBAAoB;YAAEK;YAAQD;QAAa;QACpE,IAAIC,OAAOE,WAAW,EAAE;YACtBF,OAAOE,WAAW,CAACC,IAAI,CAACF;QAC1B,OAAO;YACLD,OAAOE,WAAW,GAAG;gBAACD;aAAiB;QACzC;QAEA,uCAAuC;QACvCD,OAAOI,KAAK,GAAGJ,OAAOI,KAAK,IAAI,CAAC;QAChCJ,OAAOI,KAAK,CAACC,UAAU,GAAGL,OAAOI,KAAK,CAACC,UAAU,IAAI,CAAC;QACtDL,OAAOI,KAAK,CAACC,UAAU,CAACC,SAAS,GAAGN,OAAOI,KAAK,CAACC,UAAU,CAACC,SAAS,IAAI,EAAE;QAC3EN,OAAOI,KAAK,CAACC,UAAU,CAACC,SAAS,CAACH,IAAI,CACpC;QAIA,CAAA,AAACH,CAAAA,OAAOO,IAAI,KAAK,CAAC,CAAA,EAAGC,KAAK,KAAK,EAAE,AAAD,EAAGL,IAAI,CAACX,8BAA8BQ,QAAQD;QAEhF,IAAIU,sBAAsBT,OAAOE,WAAW;QAE5C,MAAMQ,uBAAuBX,aAAaG,WAAW,IAAIH,aAAaG,WAAW,EAAES,SAAS;QAE5F,IAAID,sBAAsB;YACxBD,sBAAsBT,OAAOE,WAAW,EAAEU,OAAO,CAACC;gBAChD,OAAOd,aAAaG,WAAW,EAAEY,SAASD,WAAWE,IAAI;YAC3D;QACF;QAEAN,oBAAoBO,OAAO,CAAC,CAACH;YAC3B,IAAI,CAACA,WAAWT,KAAK,EAAE;gBACrBS,WAAWT,KAAK,GAAG;oBAAEC,YAAY;wBAAEY,eAAe,EAAE;oBAAC;gBAAE;YACzD;YACA,MAAMZ,aAAaQ,WAAWT,KAAK,CAACC,UAAU,IAAI,CAAC;YACnD,IAAI,CAACA,WAAWY,aAAa,EAAE;gBAC7BZ,WAAWY,aAAa,GAAG,EAAE;YAC/B;YACAZ,WAAWY,aAAa,CAACd,IAAI,CAAC;gBAC5Be,aAAa;oBACXC,sBAAsBlB,iBAAiBc,IAAI;gBAC7C;gBACAK,MAAM;YACR;YAEA,qEAAqE;YACrE,MAAMC,kBAAkB/B,sBAAsBuB,WAAWS,MAAM,EAAE;gBAC/DC,oBAAoB;YACtB;YAEA,8DAA8D;YAC9D,MAAMC,yBAAyBH,gBAC5BT,MAAM,CAAC,CAACa,QAAUA,MAAMC,MAAM,EAAE,CAAC,uBAAuB,EAAEC,UAC1DC,GAAG,CAAC,CAACH,QAAUA,MAAMI,QAAQ,IAAIJ,MAAMK,IAAI;YAE9C,uEAAuE;YACvEjB,WAAWT,KAAK,CAACsB,MAAM,GAAG;gBACxB,GAAIb,WAAWT,KAAK,CAACsB,MAAM,IAAI,CAAC,CAAC;gBACjC,wBAAwB;oBACtB,GAAIb,WAAWT,KAAK,CAACsB,MAAM,EAAE,CAAC,uBAAuB,IAAI,CAAC,CAAC;oBAC3DK,gBAAgBP;gBAClB;YACF;YAEAX,WAAWT,KAAK,CAACC,UAAU,GAAGA;QAChC;QAEA,IAAI,CAACL,OAAOgC,IAAI,EAAE;YAChBhC,OAAOgC,IAAI,GAAG,CAAC;QACjB;QAEA,4FAA4F;QAE5F,+CAA+C;QAC/ChC,OAAOiC,SAAS,GAAGjC,OAAOiC,SAAS,IAAI,EAAE;QACzCjC,OAAOiC,SAAS,CAAC9B,IAAI,CAAC;YACpB+B,SAAS,OAAOC;gBACd,MAAM/C,wBAAwB+C;gBAE9B,MAAM,EAAEC,cAAc,EAAEC,KAAK,EAAEf,MAAM,EAAEgB,KAAK,EAAEC,MAAM,EAAEC,IAAI,EAAEC,KAAK,EAAE,GAAGN,IAAIO,IAAI;gBAU9E,MAAM7B,aAAasB,IAAIQ,OAAO,CAACzC,WAAW,CAACkC,eAAe;gBAC1D,IAAI,CAACvB,YAAY;oBACf,OAAO+B,SAASC,IAAI,CAClB;wBAAEC,OAAO,CAAC,qBAAqB,EAAEV,eAAe,UAAU,CAAC;oBAAC,GAC5D;wBAAEW,QAAQ;oBAAI;gBAElB;gBAEA,MAAMC,SAASC,MAAMC,OAAO,CAAC5B,WAAWA,OAAOX,MAAM,GAAG,IAAIjB,UAAU4B,UAAU6B;gBAEhF,MAAMC,SAAS,MAAMjB,IAAIQ,OAAO,CAACU,IAAI,CAAC;oBACpCxC,YAAYuB;oBACZkB,OAAO;oBACPjB,OAAOA,UAAU;oBACjBC,OAAOA,SAASA,QAAQ,KAAK,KAAKA;oBAClCC;oBACAgB,gBAAgB;oBAChBpB;oBACAa;oBACAR;oBACAC;gBACF;gBAEA,MAAMe,OAAOJ,OAAOI,IAAI;gBAExB,MAAMC,iBAAiBhE,wBAAwB;oBAC7C6B,QAAQT,WAAWb,MAAM,CAACsB,MAAM;gBAClC;gBAEA,MAAMoC,eAAe7D,sBAAsBgB,WAAWb,MAAM,CAACsB,MAAM;gBAEnE,MAAMqC,cAAcH,KAAK5B,GAAG,CAAC,CAACgC;oBAC5B,MAAMC,MAAMtE,cAAc;wBACxBqE;wBACAtC;wBACAmC;oBACF;oBAEA,KAAK,MAAMK,OAAOJ,aAAc;wBAC9B,IAAI,CAAEI,CAAAA,OAAOD,GAAE,GAAI;4BACjBA,GAAG,CAACC,IAAI,GAAG;wBACb;oBACF;oBAEA,OAAOD;gBACT;gBAEA,OAAOjB,SAASC,IAAI,CAAC;oBACnBW,MAAMG;oBACNI,WAAWX,OAAOW,SAAS;gBAC7B;YACF;YACAC,QAAQ;YACR5C,MAAM;QACR;QAEA;;KAEC,GACD,MAAM6C,yBAAyBC,OAAOC,OAAO,CAACvE,cAAcwE,MAAM,CAChE,CAACC,KAAK,CAACP,KAAKQ,MAAM;YAChBD,GAAG,CAACP,IAAI,GAAGQ,MAAM1E,YAAY;YAC7B,OAAOyE;QACT,GACA,CAAC;QAGHrE,OAAOgC,IAAI,GAAG;YACZ,GAAGhC,OAAOgC,IAAI;YACdpC,cAAcP,gBAAgB4E,wBAAwBjE,OAAOgC,IAAI,EAAEpC,gBAAgB,CAAC;QACtF;QAEA,OAAOI;IACT,EAAC"}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { Config, FlattenedField } from 'payload'\n\nimport { addDataAndFileToRequest, deepMergeSimple } from 'payload'\n\nimport type { PluginDefaultTranslationsObject } from './translations/types.js'\nimport type { ImportExportPluginConfig, ToCSVFunction } from './types.js'\n\nimport { flattenObject } from './export/flattenObject.js'\nimport { getCreateCollectionExportTask } from './export/getCreateExportCollectionTask.js'\nimport { getCustomFieldFunctions } from './export/getCustomFieldFunctions.js'\nimport { getSelect } from './export/getSelect.js'\nimport { getExportCollection } from './getExportCollection.js'\nimport { translations } from './translations/index.js'\nimport { collectDisabledFieldPaths } from './utilities/collectDisabledFieldPaths.js'\nimport { getFlattenedFieldKeys } from './utilities/getFlattenedFieldKeys.js'\n\nexport const importExportPlugin =\n (pluginConfig: ImportExportPluginConfig) =>\n (config: Config): Config => {\n const exportCollection = getExportCollection({ config, pluginConfig })\n if (config.collections) {\n config.collections.push(exportCollection)\n } else {\n config.collections = [exportCollection]\n }\n\n // inject custom import export provider\n config.admin = config.admin || {}\n config.admin.components = config.admin.components || {}\n config.admin.components.providers = config.admin.components.providers || []\n config.admin.components.providers.push(\n '@payloadcms/plugin-import-export/rsc#ImportExportProvider',\n )\n\n // inject the createExport job into the config\n ;((config.jobs ??= {}).tasks ??= []).push(getCreateCollectionExportTask(config, pluginConfig))\n\n let collectionsToUpdate = config.collections\n\n const usePluginCollections = pluginConfig.collections && pluginConfig.collections?.length > 0\n\n if (usePluginCollections) {\n collectionsToUpdate = config.collections?.filter((collection) => {\n return pluginConfig.collections?.includes(collection.slug)\n })\n }\n\n collectionsToUpdate.forEach((collection) => {\n if (!collection.admin) {\n collection.admin = { components: { listMenuItems: [] } }\n }\n const components = collection.admin.components || {}\n if (!components.listMenuItems) {\n components.listMenuItems = []\n }\n components.listMenuItems.push({\n clientProps: {\n exportCollectionSlug: exportCollection.slug,\n },\n path: '@payloadcms/plugin-import-export/rsc#ExportListMenuItem',\n })\n\n // // Find fields explicitly marked as disabled for import/export\n const disabledFieldAccessors = collectDisabledFieldPaths(collection.fields)\n\n // Store disabled field accessors in the admin config for use in the UI\n collection.admin.custom = {\n ...(collection.admin.custom || {}),\n 'plugin-import-export': {\n ...(collection.admin.custom?.['plugin-import-export'] || {}),\n disabledFields: disabledFieldAccessors,\n },\n }\n\n collection.admin.components = components\n })\n\n if (!config.i18n) {\n config.i18n = {}\n }\n\n // config.i18n.translations = deepMergeSimple(translations, config.i18n?.translations ?? {})\n\n // Inject custom REST endpoints into the config\n config.endpoints = config.endpoints || []\n config.endpoints.push({\n handler: async (req) => {\n await addDataAndFileToRequest(req)\n\n const { collectionSlug, draft, fields, limit, locale, sort, where } = req.data as {\n collectionSlug: string\n draft?: 'no' | 'yes'\n fields?: string[]\n limit?: number\n locale?: string\n sort?: any\n where?: any\n }\n\n const collection = req.payload.collections[collectionSlug]\n if (!collection) {\n return Response.json(\n { error: `Collection with slug ${collectionSlug} not found` },\n { status: 400 },\n )\n }\n\n const select = Array.isArray(fields) && fields.length > 0 ? getSelect(fields) : undefined\n\n const result = await req.payload.find({\n collection: collectionSlug,\n depth: 1,\n draft: draft === 'yes',\n limit: limit && limit > 10 ? 10 : limit,\n locale,\n overrideAccess: false,\n req,\n select,\n sort,\n where,\n })\n\n const docs = result.docs\n\n const toCSVFunctions = getCustomFieldFunctions({\n fields: collection.config.fields as FlattenedField[],\n })\n\n const possibleKeys = getFlattenedFieldKeys(collection.config.fields as FlattenedField[])\n\n const transformed = docs.map((doc) => {\n const row = flattenObject({\n doc,\n fields,\n toCSVFunctions,\n })\n\n for (const key of possibleKeys) {\n if (!(key in row)) {\n row[key] = null\n }\n }\n\n return row\n })\n\n return Response.json({\n docs: transformed,\n totalDocs: result.totalDocs,\n })\n },\n method: 'post',\n path: '/preview-data',\n })\n\n /**\n * Merge plugin translations\n */\n const simplifiedTranslations = Object.entries(translations).reduce(\n (acc, [key, value]) => {\n acc[key] = value.translations\n return acc\n },\n {} as Record<string, PluginDefaultTranslationsObject>,\n )\n\n config.i18n = {\n ...config.i18n,\n translations: deepMergeSimple(simplifiedTranslations, config.i18n?.translations ?? {}),\n }\n\n return config\n }\n\ndeclare module 'payload' {\n export interface FieldCustom {\n 'plugin-import-export'?: {\n /**\n * When `true` the field is **completely excluded** from the import-export plugin:\n * - It will not appear in the “Fields to export” selector.\n * - It is hidden from the preview list when no specific fields are chosen.\n * - Its data is omitted from the final CSV / JSON export.\n * @default false\n */\n disabled?: boolean\n toCSV?: ToCSVFunction\n }\n }\n}\n"],"names":["addDataAndFileToRequest","deepMergeSimple","flattenObject","getCreateCollectionExportTask","getCustomFieldFunctions","getSelect","getExportCollection","translations","collectDisabledFieldPaths","getFlattenedFieldKeys","importExportPlugin","pluginConfig","config","exportCollection","collections","push","admin","components","providers","jobs","tasks","collectionsToUpdate","usePluginCollections","length","filter","collection","includes","slug","forEach","listMenuItems","clientProps","exportCollectionSlug","path","disabledFieldAccessors","fields","custom","disabledFields","i18n","endpoints","handler","req","collectionSlug","draft","limit","locale","sort","where","data","payload","Response","json","error","status","select","Array","isArray","undefined","result","find","depth","overrideAccess","docs","toCSVFunctions","possibleKeys","transformed","map","doc","row","key","totalDocs","method","simplifiedTranslations","Object","entries","reduce","acc","value"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildDisabledFieldRegex.d.ts","sourceRoot":"","sources":["../../src/utilities/buildDisabledFieldRegex.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,uBAAuB,SAAU,MAAM,KAAG,MAStD,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds a RegExp that matches flattened field keys from a given dot-notated path.
|
|
3
|
+
*/ export const buildDisabledFieldRegex = (path)=>{
|
|
4
|
+
const parts = path.split('.');
|
|
5
|
+
const patternParts = parts.map((part)=>{
|
|
6
|
+
return `${part}(?:_\\d+)?(?:_[^_]+)?`;
|
|
7
|
+
});
|
|
8
|
+
const pattern = `^${patternParts.join('_')}(?:_.*)?$`;
|
|
9
|
+
return new RegExp(pattern);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=buildDisabledFieldRegex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/buildDisabledFieldRegex.ts"],"sourcesContent":["/**\n * Builds a RegExp that matches flattened field keys from a given dot-notated path.\n */\nexport const buildDisabledFieldRegex = (path: string): RegExp => {\n const parts = path.split('.')\n\n const patternParts = parts.map((part) => {\n return `${part}(?:_\\\\d+)?(?:_[^_]+)?`\n })\n\n const pattern = `^${patternParts.join('_')}(?:_.*)?$`\n return new RegExp(pattern)\n}\n"],"names":["buildDisabledFieldRegex","path","parts","split","patternParts","map","part","pattern","join","RegExp"],"mappings":"AAAA;;CAEC,GACD,OAAO,MAAMA,0BAA0B,CAACC;IACtC,MAAMC,QAAQD,KAAKE,KAAK,CAAC;IAEzB,MAAMC,eAAeF,MAAMG,GAAG,CAAC,CAACC;QAC9B,OAAO,GAAGA,KAAK,qBAAqB,CAAC;IACvC;IAEA,MAAMC,UAAU,CAAC,CAAC,EAAEH,aAAaI,IAAI,CAAC,KAAK,SAAS,CAAC;IACrD,OAAO,IAAIC,OAAOF;AACpB,EAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Field } from 'payload';
|
|
2
|
+
/**
|
|
3
|
+
* Recursively traverses a Payload field schema to collect all field paths
|
|
4
|
+
* that are explicitly disabled for the import/export plugin via:
|
|
5
|
+
* field.custom['plugin-import-export'].disabled
|
|
6
|
+
*
|
|
7
|
+
* Handles nested fields including named tabs, groups, arrays, blocks, etc.
|
|
8
|
+
* Tracks each field’s path by storing it in `ref.path` and manually propagating
|
|
9
|
+
* it through named tab layers via a temporary `__manualRef` marker.
|
|
10
|
+
*
|
|
11
|
+
* @param fields - The top-level array of Payload field definitions
|
|
12
|
+
* @returns An array of dot-notated field paths that are marked as disabled
|
|
13
|
+
*/
|
|
14
|
+
export declare const collectDisabledFieldPaths: (fields: Field[]) => string[];
|
|
15
|
+
//# sourceMappingURL=collectDisabledFieldPaths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collectDisabledFieldPaths.d.ts","sourceRoot":"","sources":["../../src/utilities/collectDisabledFieldPaths.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAKpC;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,yBAAyB,WAAY,KAAK,EAAE,KAAG,MAAM,EAgEjE,CAAA"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { traverseFields } from 'payload';
|
|
2
|
+
import { fieldAffectsData } from 'payload/shared';
|
|
3
|
+
/**
|
|
4
|
+
* Recursively traverses a Payload field schema to collect all field paths
|
|
5
|
+
* that are explicitly disabled for the import/export plugin via:
|
|
6
|
+
* field.custom['plugin-import-export'].disabled
|
|
7
|
+
*
|
|
8
|
+
* Handles nested fields including named tabs, groups, arrays, blocks, etc.
|
|
9
|
+
* Tracks each field’s path by storing it in `ref.path` and manually propagating
|
|
10
|
+
* it through named tab layers via a temporary `__manualRef` marker.
|
|
11
|
+
*
|
|
12
|
+
* @param fields - The top-level array of Payload field definitions
|
|
13
|
+
* @returns An array of dot-notated field paths that are marked as disabled
|
|
14
|
+
*/ export const collectDisabledFieldPaths = (fields)=>{
|
|
15
|
+
const disabledPaths = [];
|
|
16
|
+
traverseFields({
|
|
17
|
+
callback: ({ field, next, parentRef, ref })=>{
|
|
18
|
+
// Handle named tabs
|
|
19
|
+
if (field.type === 'tabs' && Array.isArray(field.tabs)) {
|
|
20
|
+
for (const tab of field.tabs){
|
|
21
|
+
if ('name' in tab && typeof tab.name === 'string') {
|
|
22
|
+
// Build the path prefix for this tab
|
|
23
|
+
const parentPath = parentRef && typeof parentRef.path === 'string' ? parentRef.path : '';
|
|
24
|
+
const tabPath = parentPath ? `${parentPath}.${tab.name}` : tab.name;
|
|
25
|
+
// Prepare a ref for this named tab's children to inherit the path
|
|
26
|
+
const refObj = ref;
|
|
27
|
+
const tabRef = refObj[tab.name] ?? {};
|
|
28
|
+
tabRef.path = tabPath;
|
|
29
|
+
tabRef.__manualRef = true // flag this as a manually constructed parentRef
|
|
30
|
+
;
|
|
31
|
+
refObj[tab.name] = tabRef;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Skip further processing of the tab container itself
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
// Skip unnamed fields (e.g. rows/collapsibles)
|
|
38
|
+
if (!('name' in field) || typeof field.name !== 'string') {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
// Determine the path to the current field
|
|
42
|
+
let parentPath;
|
|
43
|
+
if (parentRef && typeof parentRef === 'object' && 'path' in parentRef && typeof parentRef.path === 'string') {
|
|
44
|
+
parentPath = parentRef.path;
|
|
45
|
+
} else if (ref?.__manualRef && typeof ref?.path === 'string') {
|
|
46
|
+
// Fallback: if current ref is a manual tabRef, use its path
|
|
47
|
+
parentPath = ref.path;
|
|
48
|
+
}
|
|
49
|
+
const fullPath = parentPath ? `${parentPath}.${field.name}` : field.name;
|
|
50
|
+
ref.path = fullPath;
|
|
51
|
+
// If field is a data-affecting field and disabled via plugin config, collect its path
|
|
52
|
+
if (fieldAffectsData(field) && field.custom?.['plugin-import-export']?.disabled) {
|
|
53
|
+
disabledPaths.push(fullPath);
|
|
54
|
+
return next?.();
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
fields
|
|
58
|
+
});
|
|
59
|
+
return disabledPaths;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
//# sourceMappingURL=collectDisabledFieldPaths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/collectDisabledFieldPaths.ts"],"sourcesContent":["import type { Field } from 'payload'\n\nimport { traverseFields } from 'payload'\nimport { fieldAffectsData } from 'payload/shared'\n\n/**\n * Recursively traverses a Payload field schema to collect all field paths\n * that are explicitly disabled for the import/export plugin via:\n * field.custom['plugin-import-export'].disabled\n *\n * Handles nested fields including named tabs, groups, arrays, blocks, etc.\n * Tracks each field’s path by storing it in `ref.path` and manually propagating\n * it through named tab layers via a temporary `__manualRef` marker.\n *\n * @param fields - The top-level array of Payload field definitions\n * @returns An array of dot-notated field paths that are marked as disabled\n */\nexport const collectDisabledFieldPaths = (fields: Field[]): string[] => {\n const disabledPaths: string[] = []\n\n traverseFields({\n callback: ({ field, next, parentRef, ref }) => {\n // Handle named tabs\n if (field.type === 'tabs' && Array.isArray(field.tabs)) {\n for (const tab of field.tabs) {\n if ('name' in tab && typeof tab.name === 'string') {\n // Build the path prefix for this tab\n const parentPath =\n parentRef && typeof (parentRef as { path?: unknown }).path === 'string'\n ? (parentRef as { path: string }).path\n : ''\n const tabPath = parentPath ? `${parentPath}.${tab.name}` : tab.name\n\n // Prepare a ref for this named tab's children to inherit the path\n const refObj = ref as Record<string, any>\n const tabRef = refObj[tab.name] ?? {}\n tabRef.path = tabPath\n tabRef.__manualRef = true // flag this as a manually constructed parentRef\n refObj[tab.name] = tabRef\n }\n }\n\n // Skip further processing of the tab container itself\n return\n }\n\n // Skip unnamed fields (e.g. rows/collapsibles)\n if (!('name' in field) || typeof field.name !== 'string') {\n return\n }\n\n // Determine the path to the current field\n let parentPath: string | undefined\n\n if (\n parentRef &&\n typeof parentRef === 'object' &&\n 'path' in parentRef &&\n typeof (parentRef as { path?: unknown }).path === 'string'\n ) {\n parentPath = (parentRef as { path: string }).path\n } else if ((ref as any)?.__manualRef && typeof (ref as any)?.path === 'string') {\n // Fallback: if current ref is a manual tabRef, use its path\n parentPath = (ref as any).path\n }\n\n const fullPath = parentPath ? `${parentPath}.${field.name}` : field.name\n\n // Store current path for any nested children to use\n ;(ref as any).path = fullPath\n\n // If field is a data-affecting field and disabled via plugin config, collect its path\n if (fieldAffectsData(field) && field.custom?.['plugin-import-export']?.disabled) {\n disabledPaths.push(fullPath)\n return next?.()\n }\n },\n fields,\n })\n\n return disabledPaths\n}\n"],"names":["traverseFields","fieldAffectsData","collectDisabledFieldPaths","fields","disabledPaths","callback","field","next","parentRef","ref","type","Array","isArray","tabs","tab","name","parentPath","path","tabPath","refObj","tabRef","__manualRef","fullPath","custom","disabled","push"],"mappings":"AAEA,SAASA,cAAc,QAAQ,UAAS;AACxC,SAASC,gBAAgB,QAAQ,iBAAgB;AAEjD;;;;;;;;;;;CAWC,GACD,OAAO,MAAMC,4BAA4B,CAACC;IACxC,MAAMC,gBAA0B,EAAE;IAElCJ,eAAe;QACbK,UAAU,CAAC,EAAEC,KAAK,EAAEC,IAAI,EAAEC,SAAS,EAAEC,GAAG,EAAE;YACxC,oBAAoB;YACpB,IAAIH,MAAMI,IAAI,KAAK,UAAUC,MAAMC,OAAO,CAACN,MAAMO,IAAI,GAAG;gBACtD,KAAK,MAAMC,OAAOR,MAAMO,IAAI,CAAE;oBAC5B,IAAI,UAAUC,OAAO,OAAOA,IAAIC,IAAI,KAAK,UAAU;wBACjD,qCAAqC;wBACrC,MAAMC,aACJR,aAAa,OAAO,AAACA,UAAiCS,IAAI,KAAK,WAC3D,AAACT,UAA+BS,IAAI,GACpC;wBACN,MAAMC,UAAUF,aAAa,GAAGA,WAAW,CAAC,EAAEF,IAAIC,IAAI,EAAE,GAAGD,IAAIC,IAAI;wBAEnE,kEAAkE;wBAClE,MAAMI,SAASV;wBACf,MAAMW,SAASD,MAAM,CAACL,IAAIC,IAAI,CAAC,IAAI,CAAC;wBACpCK,OAAOH,IAAI,GAAGC;wBACdE,OAAOC,WAAW,GAAG,KAAK,gDAAgD;;wBAC1EF,MAAM,CAACL,IAAIC,IAAI,CAAC,GAAGK;oBACrB;gBACF;gBAEA,sDAAsD;gBACtD;YACF;YAEA,+CAA+C;YAC/C,IAAI,CAAE,CAAA,UAAUd,KAAI,KAAM,OAAOA,MAAMS,IAAI,KAAK,UAAU;gBACxD;YACF;YAEA,0CAA0C;YAC1C,IAAIC;YAEJ,IACER,aACA,OAAOA,cAAc,YACrB,UAAUA,aACV,OAAO,AAACA,UAAiCS,IAAI,KAAK,UAClD;gBACAD,aAAa,AAACR,UAA+BS,IAAI;YACnD,OAAO,IAAI,AAACR,KAAaY,eAAe,OAAQZ,KAAaQ,SAAS,UAAU;gBAC9E,4DAA4D;gBAC5DD,aAAa,AAACP,IAAYQ,IAAI;YAChC;YAEA,MAAMK,WAAWN,aAAa,GAAGA,WAAW,CAAC,EAAEV,MAAMS,IAAI,EAAE,GAAGT,MAAMS,IAAI;YAGtEN,IAAYQ,IAAI,GAAGK;YAErB,sFAAsF;YACtF,IAAIrB,iBAAiBK,UAAUA,MAAMiB,MAAM,EAAE,CAAC,uBAAuB,EAAEC,UAAU;gBAC/EpB,cAAcqB,IAAI,CAACH;gBACnB,OAAOf;YACT;QACF;QACAJ;IACF;IAEA,OAAOC;AACT,EAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFlattenedFieldKeys.d.ts","sourceRoot":"","sources":["../../src/utilities/getFlattenedFieldKeys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,SAAS,CAAA;AAE7C,KAAK,uBAAuB,GACxB;IACE,MAAM,CAAC,EAAE,cAAc,EAAE,CAAA;IACzB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE;QACL,MAAM,EAAE,cAAc,EAAE,CAAA;QACxB,IAAI,CAAC,EAAE,MAAM,CAAA;KACd,EAAE,CAAA;IACH,IAAI,EAAE,aAAa,GAAG,KAAK,GAAG,MAAM,CAAA;CACrC,GACD,cAAc,CAAA;AAElB,eAAO,MAAM,qBAAqB,WAAY,uBAAuB,EAAE,sBAAgB,MAAM,
|
|
1
|
+
{"version":3,"file":"getFlattenedFieldKeys.d.ts","sourceRoot":"","sources":["../../src/utilities/getFlattenedFieldKeys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,SAAS,CAAA;AAE7C,KAAK,uBAAuB,GACxB;IACE,MAAM,CAAC,EAAE,cAAc,EAAE,CAAA;IACzB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE;QACL,MAAM,EAAE,cAAc,EAAE,CAAA;QACxB,IAAI,CAAC,EAAE,MAAM,CAAA;KACd,EAAE,CAAA;IACH,IAAI,EAAE,aAAa,GAAG,KAAK,GAAG,MAAM,CAAA;CACrC,GACD,cAAc,CAAA;AAElB,eAAO,MAAM,qBAAqB,WAAY,uBAAuB,EAAE,sBAAgB,MAAM,EA+E5F,CAAA"}
|
|
@@ -14,11 +14,15 @@ export const getFlattenedFieldKeys = (fields, prefix = '')=>{
|
|
|
14
14
|
break;
|
|
15
15
|
}
|
|
16
16
|
case 'blocks':
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
{
|
|
18
|
+
field.blocks.forEach((block)=>{
|
|
19
|
+
const blockPrefix = `${name}_0_${block.slug}`;
|
|
20
|
+
keys.push(`${blockPrefix}_blockType`);
|
|
21
|
+
keys.push(`${blockPrefix}_id`);
|
|
22
|
+
keys.push(...getFlattenedFieldKeys(block.fields, blockPrefix));
|
|
23
|
+
});
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
22
26
|
case 'collapsible':
|
|
23
27
|
case 'group':
|
|
24
28
|
case 'row':
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/getFlattenedFieldKeys.ts"],"sourcesContent":["import { type FlattenedField } from 'payload'\n\ntype FieldWithPresentational =\n | {\n fields?: FlattenedField[]\n name?: string\n tabs?: {\n fields: FlattenedField[]\n name?: string\n }[]\n type: 'collapsible' | 'row' | 'tabs'\n }\n | FlattenedField\n\nexport const getFlattenedFieldKeys = (fields: FieldWithPresentational[], prefix = ''): string[] => {\n const keys: string[] = []\n\n fields.forEach((field) => {\n const fieldHasToCSVFunction =\n 'custom' in field &&\n typeof field.custom === 'object' &&\n 'plugin-import-export' in field.custom &&\n field.custom['plugin-import-export']?.toCSV\n\n if (!('name' in field) || typeof field.name !== 'string' || fieldHasToCSVFunction) {\n return\n }\n\n const name = prefix ? `${prefix}_${field.name}` : field.name\n\n switch (field.type) {\n case 'array': {\n const subKeys = getFlattenedFieldKeys(field.fields as FlattenedField[], `${name}_0`)\n keys.push(...subKeys)\n break\n }\n case 'blocks'
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/getFlattenedFieldKeys.ts"],"sourcesContent":["import { type FlattenedField } from 'payload'\n\ntype FieldWithPresentational =\n | {\n fields?: FlattenedField[]\n name?: string\n tabs?: {\n fields: FlattenedField[]\n name?: string\n }[]\n type: 'collapsible' | 'row' | 'tabs'\n }\n | FlattenedField\n\nexport const getFlattenedFieldKeys = (fields: FieldWithPresentational[], prefix = ''): string[] => {\n const keys: string[] = []\n\n fields.forEach((field) => {\n const fieldHasToCSVFunction =\n 'custom' in field &&\n typeof field.custom === 'object' &&\n 'plugin-import-export' in field.custom &&\n field.custom['plugin-import-export']?.toCSV\n\n if (!('name' in field) || typeof field.name !== 'string' || fieldHasToCSVFunction) {\n return\n }\n\n const name = prefix ? `${prefix}_${field.name}` : field.name\n\n switch (field.type) {\n case 'array': {\n const subKeys = getFlattenedFieldKeys(field.fields as FlattenedField[], `${name}_0`)\n keys.push(...subKeys)\n break\n }\n case 'blocks': {\n field.blocks.forEach((block) => {\n const blockPrefix = `${name}_0_${block.slug}`\n keys.push(`${blockPrefix}_blockType`)\n keys.push(`${blockPrefix}_id`)\n keys.push(...getFlattenedFieldKeys(block.fields as FlattenedField[], blockPrefix))\n })\n break\n }\n case 'collapsible':\n case 'group':\n case 'row':\n keys.push(...getFlattenedFieldKeys(field.fields as FlattenedField[], name))\n break\n case 'relationship':\n if (field.hasMany) {\n if (Array.isArray(field.relationTo)) {\n // hasMany polymorphic\n keys.push(`${name}_0_relationTo`, `${name}_0_id`)\n } else {\n // hasMany monomorphic\n keys.push(`${name}_0`)\n }\n } else {\n if (Array.isArray(field.relationTo)) {\n // hasOne polymorphic\n keys.push(`${name}_relationTo`, `${name}_id`)\n } else {\n // hasOne monomorphic\n keys.push(name)\n }\n }\n break\n case 'tabs':\n if (field.tabs) {\n field.tabs.forEach((tab) => {\n if (tab.name) {\n const tabPrefix = prefix ? `${prefix}_${tab.name}` : tab.name\n keys.push(...getFlattenedFieldKeys(tab.fields, tabPrefix))\n } else {\n keys.push(...getFlattenedFieldKeys(tab.fields, prefix))\n }\n })\n }\n break\n default:\n if ('hasMany' in field && field.hasMany) {\n // Push placeholder for first index\n keys.push(`${name}_0`)\n } else {\n keys.push(name)\n }\n break\n }\n })\n\n return keys\n}\n"],"names":["getFlattenedFieldKeys","fields","prefix","keys","forEach","field","fieldHasToCSVFunction","custom","toCSV","name","type","subKeys","push","blocks","block","blockPrefix","slug","hasMany","Array","isArray","relationTo","tabs","tab","tabPrefix"],"mappings":"AAcA,OAAO,MAAMA,wBAAwB,CAACC,QAAmCC,SAAS,EAAE;IAClF,MAAMC,OAAiB,EAAE;IAEzBF,OAAOG,OAAO,CAAC,CAACC;QACd,MAAMC,wBACJ,YAAYD,SACZ,OAAOA,MAAME,MAAM,KAAK,YACxB,0BAA0BF,MAAME,MAAM,IACtCF,MAAME,MAAM,CAAC,uBAAuB,EAAEC;QAExC,IAAI,CAAE,CAAA,UAAUH,KAAI,KAAM,OAAOA,MAAMI,IAAI,KAAK,YAAYH,uBAAuB;YACjF;QACF;QAEA,MAAMG,OAAOP,SAAS,GAAGA,OAAO,CAAC,EAAEG,MAAMI,IAAI,EAAE,GAAGJ,MAAMI,IAAI;QAE5D,OAAQJ,MAAMK,IAAI;YAChB,KAAK;gBAAS;oBACZ,MAAMC,UAAUX,sBAAsBK,MAAMJ,MAAM,EAAsB,GAAGQ,KAAK,EAAE,CAAC;oBACnFN,KAAKS,IAAI,IAAID;oBACb;gBACF;YACA,KAAK;gBAAU;oBACbN,MAAMQ,MAAM,CAACT,OAAO,CAAC,CAACU;wBACpB,MAAMC,cAAc,GAAGN,KAAK,GAAG,EAAEK,MAAME,IAAI,EAAE;wBAC7Cb,KAAKS,IAAI,CAAC,GAAGG,YAAY,UAAU,CAAC;wBACpCZ,KAAKS,IAAI,CAAC,GAAGG,YAAY,GAAG,CAAC;wBAC7BZ,KAAKS,IAAI,IAAIZ,sBAAsBc,MAAMb,MAAM,EAAsBc;oBACvE;oBACA;gBACF;YACA,KAAK;YACL,KAAK;YACL,KAAK;gBACHZ,KAAKS,IAAI,IAAIZ,sBAAsBK,MAAMJ,MAAM,EAAsBQ;gBACrE;YACF,KAAK;gBACH,IAAIJ,MAAMY,OAAO,EAAE;oBACjB,IAAIC,MAAMC,OAAO,CAACd,MAAMe,UAAU,GAAG;wBACnC,sBAAsB;wBACtBjB,KAAKS,IAAI,CAAC,GAAGH,KAAK,aAAa,CAAC,EAAE,GAAGA,KAAK,KAAK,CAAC;oBAClD,OAAO;wBACL,sBAAsB;wBACtBN,KAAKS,IAAI,CAAC,GAAGH,KAAK,EAAE,CAAC;oBACvB;gBACF,OAAO;oBACL,IAAIS,MAAMC,OAAO,CAACd,MAAMe,UAAU,GAAG;wBACnC,qBAAqB;wBACrBjB,KAAKS,IAAI,CAAC,GAAGH,KAAK,WAAW,CAAC,EAAE,GAAGA,KAAK,GAAG,CAAC;oBAC9C,OAAO;wBACL,qBAAqB;wBACrBN,KAAKS,IAAI,CAACH;oBACZ;gBACF;gBACA;YACF,KAAK;gBACH,IAAIJ,MAAMgB,IAAI,EAAE;oBACdhB,MAAMgB,IAAI,CAACjB,OAAO,CAAC,CAACkB;wBAClB,IAAIA,IAAIb,IAAI,EAAE;4BACZ,MAAMc,YAAYrB,SAAS,GAAGA,OAAO,CAAC,EAAEoB,IAAIb,IAAI,EAAE,GAAGa,IAAIb,IAAI;4BAC7DN,KAAKS,IAAI,IAAIZ,sBAAsBsB,IAAIrB,MAAM,EAAEsB;wBACjD,OAAO;4BACLpB,KAAKS,IAAI,IAAIZ,sBAAsBsB,IAAIrB,MAAM,EAAEC;wBACjD;oBACF;gBACF;gBACA;YACF;gBACE,IAAI,aAAaG,SAASA,MAAMY,OAAO,EAAE;oBACvC,mCAAmC;oBACnCd,KAAKS,IAAI,CAAC,GAAGH,KAAK,EAAE,CAAC;gBACvB,OAAO;oBACLN,KAAKS,IAAI,CAACH;gBACZ;gBACA;QACJ;IACF;IAEA,OAAON;AACT,EAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@payloadcms/plugin-import-export",
|
|
3
|
-
"version": "3.48.0
|
|
3
|
+
"version": "3.48.0",
|
|
4
4
|
"description": "Import-Export plugin for Payload",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"payload",
|
|
@@ -64,17 +64,17 @@
|
|
|
64
64
|
"csv-parse": "^5.6.0",
|
|
65
65
|
"csv-stringify": "^6.5.2",
|
|
66
66
|
"qs-esm": "7.0.2",
|
|
67
|
-
"@payloadcms/
|
|
68
|
-
"@payloadcms/
|
|
67
|
+
"@payloadcms/translations": "3.48.0",
|
|
68
|
+
"@payloadcms/ui": "3.48.0"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@payloadcms/eslint-config": "3.28.0",
|
|
72
|
-
"
|
|
73
|
-
"
|
|
72
|
+
"@payloadcms/ui": "3.48.0",
|
|
73
|
+
"payload": "3.48.0"
|
|
74
74
|
},
|
|
75
75
|
"peerDependencies": {
|
|
76
|
-
"@payloadcms/ui": "3.48.0
|
|
77
|
-
"payload": "3.48.0
|
|
76
|
+
"@payloadcms/ui": "3.48.0",
|
|
77
|
+
"payload": "3.48.0"
|
|
78
78
|
},
|
|
79
79
|
"homepage:": "https://payloadcms.com",
|
|
80
80
|
"scripts": {
|