@payloadcms/plugin-import-export 3.45.0-internal.5103e58 → 3.45.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/Preview/index.d.ts.map +1 -1
- package/dist/components/Preview/index.js +4 -8
- package/dist/components/Preview/index.js.map +1 -1
- package/dist/export/createExport.d.ts +2 -2
- package/dist/export/createExport.d.ts.map +1 -1
- package/dist/export/createExport.js +71 -18
- package/dist/export/createExport.js.map +1 -1
- package/dist/export/getCreateExportCollectionTask.d.ts.map +1 -1
- package/dist/export/getCreateExportCollectionTask.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/dist/utilities/getFlattenedFieldKeys.d.ts +13 -0
- package/dist/utilities/getFlattenedFieldKeys.d.ts.map +1 -0
- package/dist/utilities/getFlattenedFieldKeys.js +60 -0
- package/dist/utilities/getFlattenedFieldKeys.js.map +1 -0
- package/package.json +7 -7
|
@@ -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;AAIrB,eAAO,MAAM,OAAO,
|
|
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;AAIrB,eAAO,MAAM,OAAO,yBA6InB,CAAA"}
|
|
@@ -64,7 +64,7 @@ export const Preview = ()=>{
|
|
|
64
64
|
}
|
|
65
65
|
const { docs, totalDocs } = await res.json();
|
|
66
66
|
setResultCount(limit && limit < totalDocs ? limit : totalDocs);
|
|
67
|
-
const allKeys = Object.keys(
|
|
67
|
+
const allKeys = Array.from(new Set(docs.flatMap((doc)=>Object.keys(doc))));
|
|
68
68
|
const defaultMetaFields = [
|
|
69
69
|
'createdAt',
|
|
70
70
|
'updatedAt',
|
|
@@ -81,14 +81,10 @@ export const Preview = ()=>{
|
|
|
81
81
|
const regex = fieldToRegex(field);
|
|
82
82
|
return allKeys.filter((key)=>regex.test(key));
|
|
83
83
|
}) : allKeys.filter((key)=>!defaultMetaFields.includes(key));
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
const regex = fieldToRegex(field);
|
|
87
|
-
return allKeys.filter((key)=>regex.test(key) && !includedMeta.has(key));
|
|
88
|
-
});
|
|
89
|
-
const fieldKeys = [
|
|
84
|
+
const fieldKeys = Array.isArray(fields) && fields.length > 0 ? selectedKeys // strictly only what was selected
|
|
85
|
+
: [
|
|
90
86
|
...selectedKeys,
|
|
91
|
-
...
|
|
87
|
+
...defaultMetaFields.filter((key)=>allKeys.includes(key))
|
|
92
88
|
];
|
|
93
89
|
// Build columns based on flattened keys
|
|
94
90
|
const newColumns = fieldKeys.map((key)=>({
|
|
@@ -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 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 } = await res.json()\n\n setResultCount(limit && limit < totalDocs ? limit : totalDocs)\n\n const allKeys = Object.keys(docs[0] || {})\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((key) => !defaultMetaFields.includes(key))\n\n const includedMeta = new Set(selectedKeys)\n const missingMetaFields = defaultMetaFields.flatMap((field) => {\n const regex = fieldToRegex(field)\n return allKeys.filter((key) => regex.test(key) && !includedMeta.has(key))\n })\n\n const fieldKeys = [...selectedKeys, ...missingMetaFields]\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 }, [collectionConfig, collectionSlug, draft, fields, i18n, limit, locale, sort, where])\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","isCSV","useEffect","fetchData","res","fetch","body","JSON","stringify","credentials","headers","method","ok","docs","totalDocs","json","allKeys","Object","keys","defaultMetaFields","fieldToRegex","field","parts","split","map","part","RegExp","join","selectedKeys","Array","isArray","length","flatMap","regex","filter","key","test","includes","includedMeta","Set","missingMetaFields","has","fieldKeys","newColumns","accessor","active","name","Heading","renderedCells","doc","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 { 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 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((key) => !defaultMetaFields.includes(key))\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 }, [collectionConfig, collectionSlug, draft, fields, i18n, limit, locale, sort, where])\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","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","map","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,4 +1,4 @@
|
|
|
1
|
-
import type { PayloadRequest, Sort,
|
|
1
|
+
import type { PayloadRequest, Sort, TypedUser, Where } from 'payload';
|
|
2
2
|
export type Export = {
|
|
3
3
|
collectionSlug: string;
|
|
4
4
|
/**
|
|
@@ -26,7 +26,7 @@ export type CreateExportArgs = {
|
|
|
26
26
|
download?: boolean;
|
|
27
27
|
input: Export;
|
|
28
28
|
req: PayloadRequest;
|
|
29
|
-
user?:
|
|
29
|
+
user?: TypedUser;
|
|
30
30
|
};
|
|
31
31
|
export declare const createExport: (args: CreateExportArgs) => Promise<Response | undefined>;
|
|
32
32
|
//# sourceMappingURL=createExport.d.ts.map
|
|
@@ -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,
|
|
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;AAWrE,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,kCA2PxD,CAAA"}
|
|
@@ -57,39 +57,71 @@ export const createExport = async (args)=>{
|
|
|
57
57
|
});
|
|
58
58
|
if (download) {
|
|
59
59
|
if (debug) {
|
|
60
|
-
req.payload.logger.info('
|
|
60
|
+
req.payload.logger.info('Pre-scanning all columns before streaming');
|
|
61
|
+
}
|
|
62
|
+
const allColumnsSet = new Set();
|
|
63
|
+
const allColumns = [];
|
|
64
|
+
let scanPage = 1;
|
|
65
|
+
let hasMore = true;
|
|
66
|
+
while(hasMore){
|
|
67
|
+
const result = await payload.find({
|
|
68
|
+
...findArgs,
|
|
69
|
+
page: scanPage
|
|
70
|
+
});
|
|
71
|
+
result.docs.forEach((doc)=>{
|
|
72
|
+
const flat = flattenObject({
|
|
73
|
+
doc,
|
|
74
|
+
fields,
|
|
75
|
+
toCSVFunctions
|
|
76
|
+
});
|
|
77
|
+
Object.keys(flat).forEach((key)=>{
|
|
78
|
+
if (!allColumnsSet.has(key)) {
|
|
79
|
+
allColumnsSet.add(key);
|
|
80
|
+
allColumns.push(key);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
hasMore = result.hasNextPage;
|
|
85
|
+
scanPage += 1;
|
|
86
|
+
}
|
|
87
|
+
if (debug) {
|
|
88
|
+
req.payload.logger.info(`Discovered ${allColumns.length} columns`);
|
|
61
89
|
}
|
|
62
90
|
const encoder = new TextEncoder();
|
|
63
91
|
let isFirstBatch = true;
|
|
64
|
-
let
|
|
65
|
-
let page = 1;
|
|
92
|
+
let streamPage = 1;
|
|
66
93
|
const stream = new Readable({
|
|
67
94
|
async read () {
|
|
68
95
|
const result = await payload.find({
|
|
69
96
|
...findArgs,
|
|
70
|
-
page
|
|
97
|
+
page: streamPage
|
|
71
98
|
});
|
|
72
99
|
if (debug) {
|
|
73
|
-
req.payload.logger.info(`
|
|
100
|
+
req.payload.logger.info(`Streaming batch ${streamPage} with ${result.docs.length} docs`);
|
|
74
101
|
}
|
|
75
102
|
if (result.docs.length === 0) {
|
|
76
103
|
this.push(null);
|
|
77
104
|
return;
|
|
78
105
|
}
|
|
79
|
-
const
|
|
106
|
+
const batchRows = result.docs.map((doc)=>flattenObject({
|
|
80
107
|
doc,
|
|
81
108
|
fields,
|
|
82
109
|
toCSVFunctions
|
|
83
110
|
}));
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
111
|
+
const paddedRows = batchRows.map((row)=>{
|
|
112
|
+
const fullRow = {};
|
|
113
|
+
for (const col of allColumns){
|
|
114
|
+
fullRow[col] = row[col] ?? '';
|
|
115
|
+
}
|
|
116
|
+
return fullRow;
|
|
117
|
+
});
|
|
118
|
+
const csvString = stringify(paddedRows, {
|
|
88
119
|
header: isFirstBatch,
|
|
89
|
-
columns
|
|
120
|
+
columns: allColumns
|
|
90
121
|
});
|
|
91
122
|
this.push(encoder.encode(csvString));
|
|
92
123
|
isFirstBatch = false;
|
|
124
|
+
streamPage += 1;
|
|
93
125
|
if (!result.hasNextPage) {
|
|
94
126
|
if (debug) {
|
|
95
127
|
req.payload.logger.info('Stream complete - no more pages');
|
|
@@ -97,7 +129,6 @@ export const createExport = async (args)=>{
|
|
|
97
129
|
this.push(null) // End the stream
|
|
98
130
|
;
|
|
99
131
|
}
|
|
100
|
-
page += 1;
|
|
101
132
|
}
|
|
102
133
|
});
|
|
103
134
|
return new Response(stream, {
|
|
@@ -107,11 +138,14 @@ export const createExport = async (args)=>{
|
|
|
107
138
|
}
|
|
108
139
|
});
|
|
109
140
|
}
|
|
141
|
+
// Non-download path (buffered export)
|
|
110
142
|
if (debug) {
|
|
111
143
|
req.payload.logger.info('Starting file generation');
|
|
112
144
|
}
|
|
113
145
|
const outputData = [];
|
|
114
|
-
|
|
146
|
+
const rows = [];
|
|
147
|
+
const columnsSet = new Set();
|
|
148
|
+
const columns = [];
|
|
115
149
|
let page = 1;
|
|
116
150
|
let hasNextPage = true;
|
|
117
151
|
while(hasNextPage){
|
|
@@ -123,15 +157,21 @@ export const createExport = async (args)=>{
|
|
|
123
157
|
req.payload.logger.info(`Processing batch ${findArgs.page} with ${result.docs.length} documents`);
|
|
124
158
|
}
|
|
125
159
|
if (isCSV) {
|
|
126
|
-
const
|
|
160
|
+
const batchRows = result.docs.map((doc)=>flattenObject({
|
|
127
161
|
doc,
|
|
128
162
|
fields,
|
|
129
163
|
toCSVFunctions
|
|
130
164
|
}));
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
165
|
+
// Track discovered column keys
|
|
166
|
+
batchRows.forEach((row)=>{
|
|
167
|
+
Object.keys(row).forEach((key)=>{
|
|
168
|
+
if (!columnsSet.has(key)) {
|
|
169
|
+
columnsSet.add(key);
|
|
170
|
+
columns.push(key);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
rows.push(...batchRows);
|
|
135
175
|
} else {
|
|
136
176
|
const jsonInput = result.docs.map((doc)=>JSON.stringify(doc));
|
|
137
177
|
outputData.push(jsonInput.join(',\n'));
|
|
@@ -139,6 +179,19 @@ export const createExport = async (args)=>{
|
|
|
139
179
|
hasNextPage = result.hasNextPage;
|
|
140
180
|
page += 1;
|
|
141
181
|
}
|
|
182
|
+
if (isCSV) {
|
|
183
|
+
const paddedRows = rows.map((row)=>{
|
|
184
|
+
const fullRow = {};
|
|
185
|
+
for (const col of columns){
|
|
186
|
+
fullRow[col] = row[col] ?? '';
|
|
187
|
+
}
|
|
188
|
+
return fullRow;
|
|
189
|
+
});
|
|
190
|
+
outputData.push(stringify(paddedRows, {
|
|
191
|
+
header: true,
|
|
192
|
+
columns
|
|
193
|
+
}));
|
|
194
|
+
}
|
|
142
195
|
const buffer = Buffer.from(format === 'json' ? `[${outputData.join(',')}]` : outputData.join(''));
|
|
143
196
|
if (debug) {
|
|
144
197
|
req.payload.logger.info(`${format} file generation complete`);
|
|
@@ -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 { 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?: User\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 select,\n })\n\n if (download) {\n if (debug) {\n req.payload.logger.info('Starting download stream')\n }\n\n const encoder = new TextEncoder()\n let isFirstBatch = true\n let columns: string[] | undefined\n let page = 1\n\n const stream = new Readable({\n async read() {\n const result = await payload.find({\n ...findArgs,\n page,\n })\n\n if (debug) {\n req.payload.logger.info(`Processing batch ${page} with ${result.docs.length} documents`)\n }\n\n if (result.docs.length === 0) {\n this.push(null)\n return\n }\n\n const csvInput = result.docs.map((doc) => flattenObject({ doc, fields, toCSVFunctions }))\n\n if (isFirstBatch) {\n columns = Object.keys(csvInput[0] ?? {})\n }\n\n const csvString = stringify(csvInput, {\n header: isFirstBatch,\n columns,\n })\n\n this.push(encoder.encode(csvString))\n isFirstBatch = false\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 page += 1\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 if (debug) {\n req.payload.logger.info('Starting file generation')\n }\n const outputData: string[] = []\n let isFirstBatch = true\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 csvInput = result.docs.map((doc) => flattenObject({ doc, fields, toCSVFunctions }))\n outputData.push(stringify(csvInput, { header: isFirstBatch }))\n isFirstBatch = false\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 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","encoder","TextEncoder","isFirstBatch","columns","stream","read","result","docs","push","csvInput","map","doc","Object","keys","csvString","header","encode","hasNextPage","Response","headers","outputData","jsonInput","JSON","join","buffer","Buffer","from","file","data","mimetype","size","update"],"mappings":"AAAA,6CAA6C,GAG7C,SAASA,SAAS,QAAQ,qBAAoB;AAC9C,SAASC,QAAQ,QAAQ,UAAS;AAClC,SAASC,QAAQ,QAAQ,SAAQ;AAEjC,SAASC,aAAa,QAAQ,qBAAoB;AAClD,SAASC,uBAAuB,QAAQ,+BAA8B;AACtE,SAASC,WAAW,QAAQ,mBAAkB;AAC9C,SAASC,SAAS,QAAQ,iBAAgB;AAiC1C,OAAO,MAAMC,eAAe,OAAOC;IACjC,MAAM,EACJC,QAAQ,EACRC,OAAO,EACLC,EAAE,EACFC,MAAMC,OAAO,EACbC,cAAc,EACdC,QAAQ,KAAK,EACbC,MAAM,EACNC,iBAAiB,EACjBC,MAAM,EACNC,MAAM,EACNC,QAAQC,WAAW,EACnBC,IAAI,EACJC,IAAI,EACJC,KAAK,EACN,EACDC,KAAK,EAAEL,QAAQM,SAAS,EAAEC,OAAO,EAAE,EACnCF,GAAG,EACJ,GAAGjB;IAEJ,IAAIO,OAAO;QACTU,IAAIE,OAAO,CAACC,MAAM,CAACC,IAAI,CAAC;YACtBC,SAAS;YACThB;YACAE;YACAE;YACAC;QACF;IACF;IAEA,MAAMC,SAASC,eAAeK;IAC9B,MAAMK,mBAAmBJ,QAAQK,MAAM,CAACC,WAAW,CAACC,IAAI,CAAC,CAAC,EAAEC,IAAI,EAAE,GAAKA,SAASrB;IAChF,IAAI,CAACiB,kBAAkB;QACrB,MAAM,IAAI9B,SAAS,CAAC,qBAAqB,EAAEa,eAAe,UAAU,CAAC;IACvE;IAEA,MAAMF,OAAO,GAAGC,WAAW,GAAGR,cAAc,CAAC,EAAES,gBAAgB,CAAC,CAAC,EAAEK,QAAQ;IAC3E,MAAMiB,QAAQjB,WAAW;IACzB,MAAMkB,SAASC,MAAMC,OAAO,CAACrB,WAAWA,OAAOsB,MAAM,GAAG,IAAIlC,UAAUY,UAAUuB;IAEhF,IAAI1B,OAAO;QACTU,IAAIE,OAAO,CAACC,MAAM,CAACC,IAAI,CAAC;YAAEC,SAAS;YAAyBlB;YAAMwB;YAAOhB;QAAO;IAClF;IAEA,MAAMsB,WAAW;QACfC,YAAY7B;QACZ8B,OAAO;QACPC,OAAO7B,WAAW;QAClB8B,OAAO;QACP1B;QACA2B,gBAAgB;QAChBC,MAAM;QACNX;QACAf;QACAC;QACAC;IACF;IAEA,IAAIT,OAAO;QACTU,IAAIE,OAAO,CAACC,MAAM,CAACC,IAAI,CAAC;YAAEC,SAAS;YAAmBY;QAAS;IACjE;IAEA,MAAMO,iBAAiB7C,wBAAwB;QAC7Cc,QAAQa,iBAAiBmB,eAAe;QACxCb;IACF;IAEA,IAAI5B,UAAU;QACZ,IAAIM,OAAO;YACTU,IAAIE,OAAO,CAACC,MAAM,CAACC,IAAI,CAAC;QAC1B;QAEA,MAAMsB,UAAU,IAAIC;QACpB,IAAIC,eAAe;QACnB,IAAIC;QACJ,IAAIN,OAAO;QAEX,MAAMO,SAAS,IAAIrD,SAAS;YAC1B,MAAMsD;gBACJ,MAAMC,SAAS,MAAM9B,QAAQO,IAAI,CAAC;oBAChC,GAAGQ,QAAQ;oBACXM;gBACF;gBAEA,IAAIjC,OAAO;oBACTU,IAAIE,OAAO,CAACC,MAAM,CAACC,IAAI,CAAC,CAAC,iBAAiB,EAAEmB,KAAK,MAAM,EAAES,OAAOC,IAAI,CAAClB,MAAM,CAAC,UAAU,CAAC;gBACzF;gBAEA,IAAIiB,OAAOC,IAAI,CAAClB,MAAM,KAAK,GAAG;oBAC5B,IAAI,CAACmB,IAAI,CAAC;oBACV;gBACF;gBAEA,MAAMC,WAAWH,OAAOC,IAAI,CAACG,GAAG,CAAC,CAACC,MAAQ3D,cAAc;wBAAE2D;wBAAK5C;wBAAQ+B;oBAAe;gBAEtF,IAAII,cAAc;oBAChBC,UAAUS,OAAOC,IAAI,CAACJ,QAAQ,CAAC,EAAE,IAAI,CAAC;gBACxC;gBAEA,MAAMK,YAAYjE,UAAU4D,UAAU;oBACpCM,QAAQb;oBACRC;gBACF;gBAEA,IAAI,CAACK,IAAI,CAACR,QAAQgB,MAAM,CAACF;gBACzBZ,eAAe;gBAEf,IAAI,CAACI,OAAOW,WAAW,EAAE;oBACvB,IAAIrD,OAAO;wBACTU,IAAIE,OAAO,CAACC,MAAM,CAACC,IAAI,CAAC;oBAC1B;oBACA,IAAI,CAAC8B,IAAI,CAAC,MAAM,iBAAiB;;gBACnC;gBAEAX,QAAQ;YACV;QACF;QAEA,OAAO,IAAIqB,SAASd,QAAe;YACjCe,SAAS;gBACP,uBAAuB,CAAC,sBAAsB,EAAE1D,KAAK,CAAC,CAAC;gBACvD,gBAAgBwB,QAAQ,aAAa;YACvC;QACF;IACF;IAEA,IAAIrB,OAAO;QACTU,IAAIE,OAAO,CAACC,MAAM,CAACC,IAAI,CAAC;IAC1B;IACA,MAAM0C,aAAuB,EAAE;IAC/B,IAAIlB,eAAe;IACnB,IAAIL,OAAO;IACX,IAAIoB,cAAc;IAElB,MAAOA,YAAa;QAClB,MAAMX,SAAS,MAAM9B,QAAQO,IAAI,CAAC;YAChC,GAAGQ,QAAQ;YACXM;QACF;QAEA,IAAIjC,OAAO;YACTU,IAAIE,OAAO,CAACC,MAAM,CAACC,IAAI,CACrB,CAAC,iBAAiB,EAAEa,SAASM,IAAI,CAAC,MAAM,EAAES,OAAOC,IAAI,CAAClB,MAAM,CAAC,UAAU,CAAC;QAE5E;QAEA,IAAIJ,OAAO;YACT,MAAMwB,WAAWH,OAAOC,IAAI,CAACG,GAAG,CAAC,CAACC,MAAQ3D,cAAc;oBAAE2D;oBAAK5C;oBAAQ+B;gBAAe;YACtFsB,WAAWZ,IAAI,CAAC3D,UAAU4D,UAAU;gBAAEM,QAAQb;YAAa;YAC3DA,eAAe;QACjB,OAAO;YACL,MAAMmB,YAAYf,OAAOC,IAAI,CAACG,GAAG,CAAC,CAACC,MAAQW,KAAKzE,SAAS,CAAC8D;YAC1DS,WAAWZ,IAAI,CAACa,UAAUE,IAAI,CAAC;QACjC;QAEAN,cAAcX,OAAOW,WAAW;QAChCpB,QAAQ;IACV;IAEA,MAAM2B,SAASC,OAAOC,IAAI,CAAC1D,WAAW,SAAS,CAAC,CAAC,EAAEoD,WAAWG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAGH,WAAWG,IAAI,CAAC;IAC7F,IAAI3D,OAAO;QACTU,IAAIE,OAAO,CAACC,MAAM,CAACC,IAAI,CAAC,GAAGV,OAAO,yBAAyB,CAAC;IAC9D;IAEA,IAAI,CAACR,IAAI;QACP,IAAII,OAAO;YACTU,IAAIE,OAAO,CAACC,MAAM,CAACC,IAAI,CAAC;QAC1B;QACAJ,IAAIqD,IAAI,GAAG;YACTlE;YACAmE,MAAMJ;YACNK,UAAU5C,QAAQ,aAAa;YAC/B6C,MAAMN,OAAOnC,MAAM;QACrB;IACF,OAAO;QACL,IAAIzB,OAAO;YACTU,IAAIE,OAAO,CAACC,MAAM,CAACC,IAAI,CAAC,CAAC,kCAAkC,EAAElB,IAAI;QACnE;QACA,MAAMc,IAAIE,OAAO,CAACuD,MAAM,CAAC;YACvBvE;YACAgC,YAAY1B;YACZ8D,MAAM,CAAC;YACPD,MAAM;gBACJlE;gBACAmE,MAAMJ;gBACNK,UAAU5C,QAAQ,aAAa;gBAC/B6C,MAAMN,OAAOnC,MAAM;YACrB;YACAjB;QACF;IACF;IACA,IAAIR,OAAO;QACTU,IAAIE,OAAO,CAACC,MAAM,CAACC,IAAI,CAAC;IAC1B;AACF,EAAC"}
|
|
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 select,\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 = 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) => flattenObject({ doc, fields, toCSVFunctions }))\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) => flattenObject({ doc, fields, toCSVFunctions }))\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","allColumnsSet","Set","allColumns","scanPage","hasMore","result","docs","forEach","doc","flat","Object","keys","key","has","add","push","hasNextPage","encoder","TextEncoder","isFirstBatch","streamPage","stream","read","batchRows","map","paddedRows","row","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":"getCreateExportCollectionTask.d.ts","sourceRoot":"","sources":["../../src/export/getCreateExportCollectionTask.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"getCreateExportCollectionTask.d.ts","sourceRoot":"","sources":["../../src/export/getCreateExportCollectionTask.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAa,MAAM,SAAS,CAAA;AAE5D,OAAO,KAAK,EAAoB,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAKjE,eAAO,MAAM,6BAA6B,WAChC,MAAM,KACb,UAAU,CAAC;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf,CAwCA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/export/getCreateExportCollectionTask.ts"],"sourcesContent":["import type { Config, TaskConfig,
|
|
1
|
+
{"version":3,"sources":["../../src/export/getCreateExportCollectionTask.ts"],"sourcesContent":["import type { Config, TaskConfig, TypedUser } from 'payload'\n\nimport type { CreateExportArgs, Export } from './createExport.js'\n\nimport { createExport } from './createExport.js'\nimport { getFields } from './getFields.js'\n\nexport const getCreateCollectionExportTask = (\n config: Config,\n): TaskConfig<{\n input: Export\n output: object\n}> => {\n const inputSchema = getFields(config).concat(\n {\n name: 'user',\n type: 'text',\n },\n {\n name: 'userCollection',\n type: 'text',\n },\n {\n name: 'exportsCollection',\n type: 'text',\n },\n )\n\n return {\n slug: 'createCollectionExport',\n handler: async ({ input, req }: CreateExportArgs) => {\n let user: TypedUser | undefined\n\n if (input.userCollection && input.user) {\n user = (await req.payload.findByID({\n id: input.user,\n collection: input.userCollection,\n })) as TypedUser\n }\n\n if (!user) {\n throw new Error('User not found')\n }\n\n await createExport({ input, req, user })\n\n return {\n output: {},\n }\n },\n inputSchema,\n }\n}\n"],"names":["createExport","getFields","getCreateCollectionExportTask","config","inputSchema","concat","name","type","slug","handler","input","req","user","userCollection","payload","findByID","id","collection","Error","output"],"mappings":"AAIA,SAASA,YAAY,QAAQ,oBAAmB;AAChD,SAASC,SAAS,QAAQ,iBAAgB;AAE1C,OAAO,MAAMC,gCAAgC,CAC3CC;IAKA,MAAMC,cAAcH,UAAUE,QAAQE,MAAM,CAC1C;QACEC,MAAM;QACNC,MAAM;IACR,GACA;QACED,MAAM;QACNC,MAAM;IACR,GACA;QACED,MAAM;QACNC,MAAM;IACR;IAGF,OAAO;QACLC,MAAM;QACNC,SAAS,OAAO,EAAEC,KAAK,EAAEC,GAAG,EAAoB;YAC9C,IAAIC;YAEJ,IAAIF,MAAMG,cAAc,IAAIH,MAAME,IAAI,EAAE;gBACtCA,OAAQ,MAAMD,IAAIG,OAAO,CAACC,QAAQ,CAAC;oBACjCC,IAAIN,MAAME,IAAI;oBACdK,YAAYP,MAAMG,cAAc;gBAClC;YACF;YAEA,IAAI,CAACD,MAAM;gBACT,MAAM,IAAIM,MAAM;YAClB;YAEA,MAAMlB,aAAa;gBAAEU;gBAAOC;gBAAKC;YAAK;YAEtC,OAAO;gBACLO,QAAQ,CAAC;YACX;QACF;QACAf;IACF;AACF,EAAC"}
|
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;AAUzE,eAAO,MAAM,kBAAkB,iBACd,wBAAwB,cAC9B,MAAM,KAAG,MA8IjB,CAAA;AAEH,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAiB,WAAW;QAC1B,sBAAsB,CAAC,EAAE;YACvB,KAAK,CAAC,EAAE,aAAa,CAAA;SACtB,CAAA;KACF;CACF"}
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ 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 { getFlattenedFieldKeys } from './utilities/getFlattenedFieldKeys.js';
|
|
8
9
|
export const importExportPlugin = (pluginConfig)=>(config)=>{
|
|
9
10
|
const exportCollection = getExportCollection({
|
|
10
11
|
config,
|
|
@@ -86,11 +87,20 @@ export const importExportPlugin = (pluginConfig)=>(config)=>{
|
|
|
86
87
|
fields: collection.config.fields,
|
|
87
88
|
select
|
|
88
89
|
});
|
|
89
|
-
const
|
|
90
|
+
const possibleKeys = getFlattenedFieldKeys(collection.config.fields);
|
|
91
|
+
const transformed = docs.map((doc)=>{
|
|
92
|
+
const row = flattenObject({
|
|
90
93
|
doc,
|
|
91
94
|
fields,
|
|
92
95
|
toCSVFunctions
|
|
93
|
-
})
|
|
96
|
+
});
|
|
97
|
+
for (const key of possibleKeys){
|
|
98
|
+
if (!(key in row)) {
|
|
99
|
+
row[key] = null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return row;
|
|
103
|
+
});
|
|
94
104
|
return Response.json({
|
|
95
105
|
docs: transformed,
|
|
96
106
|
totalDocs: result.totalDocs
|
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 } 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'\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))\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 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 select,\n })\n\n const transformed = docs.map((doc)
|
|
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 { 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))\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 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 select,\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 toCSV?: ToCSVFunction\n }\n }\n}\n"],"names":["addDataAndFileToRequest","deepMergeSimple","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","i18n","endpoints","handler","req","collectionSlug","draft","fields","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,13 @@
|
|
|
1
|
+
import { type FlattenedField } from 'payload';
|
|
2
|
+
type FieldWithPresentational = {
|
|
3
|
+
fields?: FlattenedField[];
|
|
4
|
+
name?: string;
|
|
5
|
+
tabs?: {
|
|
6
|
+
fields: FlattenedField[];
|
|
7
|
+
name?: string;
|
|
8
|
+
}[];
|
|
9
|
+
type: 'collapsible' | 'row' | 'tabs';
|
|
10
|
+
} | FlattenedField;
|
|
11
|
+
export declare const getFlattenedFieldKeys: (fields: FieldWithPresentational[], prefix?: string) => string[];
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=getFlattenedFieldKeys.d.ts.map
|
|
@@ -0,0 +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,EA4D5F,CAAA"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export const getFlattenedFieldKeys = (fields, prefix = '')=>{
|
|
2
|
+
const keys = [];
|
|
3
|
+
fields.forEach((field)=>{
|
|
4
|
+
if (!('name' in field) || typeof field.name !== 'string') {
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
const name = prefix ? `${prefix}_${field.name}` : field.name;
|
|
8
|
+
switch(field.type){
|
|
9
|
+
case 'array':
|
|
10
|
+
{
|
|
11
|
+
const subKeys = getFlattenedFieldKeys(field.fields, `${name}_0`);
|
|
12
|
+
keys.push(...subKeys);
|
|
13
|
+
break;
|
|
14
|
+
}
|
|
15
|
+
case 'blocks':
|
|
16
|
+
field.blocks.forEach((block)=>{
|
|
17
|
+
const blockKeys = getFlattenedFieldKeys(block.fields, `${name}_0`);
|
|
18
|
+
keys.push(...blockKeys);
|
|
19
|
+
});
|
|
20
|
+
break;
|
|
21
|
+
case 'collapsible':
|
|
22
|
+
case 'group':
|
|
23
|
+
case 'row':
|
|
24
|
+
keys.push(...getFlattenedFieldKeys(field.fields, name));
|
|
25
|
+
break;
|
|
26
|
+
case 'relationship':
|
|
27
|
+
if (field.hasMany) {
|
|
28
|
+
// e.g. hasManyPolymorphic_0_value_id
|
|
29
|
+
keys.push(`${name}_0_relationTo`, `${name}_0_value_id`);
|
|
30
|
+
} else {
|
|
31
|
+
// e.g. hasOnePolymorphic_id
|
|
32
|
+
keys.push(`${name}_id`, `${name}_relationTo`);
|
|
33
|
+
}
|
|
34
|
+
break;
|
|
35
|
+
case 'tabs':
|
|
36
|
+
if (field.tabs) {
|
|
37
|
+
field.tabs.forEach((tab)=>{
|
|
38
|
+
if (tab.name) {
|
|
39
|
+
const tabPrefix = prefix ? `${prefix}_${tab.name}` : tab.name;
|
|
40
|
+
keys.push(...getFlattenedFieldKeys(tab.fields, tabPrefix));
|
|
41
|
+
} else {
|
|
42
|
+
keys.push(...getFlattenedFieldKeys(tab.fields, prefix));
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
break;
|
|
47
|
+
default:
|
|
48
|
+
if ('hasMany' in field && field.hasMany) {
|
|
49
|
+
// Push placeholder for first index
|
|
50
|
+
keys.push(`${name}_0`);
|
|
51
|
+
} else {
|
|
52
|
+
keys.push(name);
|
|
53
|
+
}
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
return keys;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
//# sourceMappingURL=getFlattenedFieldKeys.js.map
|
|
@@ -0,0 +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 if (!('name' in field) || typeof field.name !== 'string') {\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 blockKeys = getFlattenedFieldKeys(block.fields as FlattenedField[], `${name}_0`)\n keys.push(...blockKeys)\n })\n break\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 // e.g. hasManyPolymorphic_0_value_id\n keys.push(`${name}_0_relationTo`, `${name}_0_value_id`)\n } else {\n // e.g. hasOnePolymorphic_id\n keys.push(`${name}_id`, `${name}_relationTo`)\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","name","type","subKeys","push","blocks","block","blockKeys","hasMany","tabs","tab","tabPrefix"],"mappings":"AAcA,OAAO,MAAMA,wBAAwB,CAACC,QAAmCC,SAAS,EAAE;IAClF,MAAMC,OAAiB,EAAE;IAEzBF,OAAOG,OAAO,CAAC,CAACC;QACd,IAAI,CAAE,CAAA,UAAUA,KAAI,KAAM,OAAOA,MAAMC,IAAI,KAAK,UAAU;YACxD;QACF;QAEA,MAAMA,OAAOJ,SAAS,GAAGA,OAAO,CAAC,EAAEG,MAAMC,IAAI,EAAE,GAAGD,MAAMC,IAAI;QAE5D,OAAQD,MAAME,IAAI;YAChB,KAAK;gBAAS;oBACZ,MAAMC,UAAUR,sBAAsBK,MAAMJ,MAAM,EAAsB,GAAGK,KAAK,EAAE,CAAC;oBACnFH,KAAKM,IAAI,IAAID;oBACb;gBACF;YACA,KAAK;gBACHH,MAAMK,MAAM,CAACN,OAAO,CAAC,CAACO;oBACpB,MAAMC,YAAYZ,sBAAsBW,MAAMV,MAAM,EAAsB,GAAGK,KAAK,EAAE,CAAC;oBACrFH,KAAKM,IAAI,IAAIG;gBACf;gBACA;YACF,KAAK;YACL,KAAK;YACL,KAAK;gBACHT,KAAKM,IAAI,IAAIT,sBAAsBK,MAAMJ,MAAM,EAAsBK;gBACrE;YACF,KAAK;gBACH,IAAID,MAAMQ,OAAO,EAAE;oBACjB,qCAAqC;oBACrCV,KAAKM,IAAI,CAAC,GAAGH,KAAK,aAAa,CAAC,EAAE,GAAGA,KAAK,WAAW,CAAC;gBACxD,OAAO;oBACL,4BAA4B;oBAC5BH,KAAKM,IAAI,CAAC,GAAGH,KAAK,GAAG,CAAC,EAAE,GAAGA,KAAK,WAAW,CAAC;gBAC9C;gBACA;YACF,KAAK;gBACH,IAAID,MAAMS,IAAI,EAAE;oBACdT,MAAMS,IAAI,CAACV,OAAO,CAAC,CAACW;wBAClB,IAAIA,IAAIT,IAAI,EAAE;4BACZ,MAAMU,YAAYd,SAAS,GAAGA,OAAO,CAAC,EAAEa,IAAIT,IAAI,EAAE,GAAGS,IAAIT,IAAI;4BAC7DH,KAAKM,IAAI,IAAIT,sBAAsBe,IAAId,MAAM,EAAEe;wBACjD,OAAO;4BACLb,KAAKM,IAAI,IAAIT,sBAAsBe,IAAId,MAAM,EAAEC;wBACjD;oBACF;gBACF;gBACA;YACF;gBACE,IAAI,aAAaG,SAASA,MAAMQ,OAAO,EAAE;oBACvC,mCAAmC;oBACnCV,KAAKM,IAAI,CAAC,GAAGH,KAAK,EAAE,CAAC;gBACvB,OAAO;oBACLH,KAAKM,IAAI,CAACH;gBACZ;gBACA;QACJ;IACF;IAEA,OAAOH;AACT,EAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@payloadcms/plugin-import-export",
|
|
3
|
-
"version": "3.45.0
|
|
3
|
+
"version": "3.45.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.45.0",
|
|
68
|
+
"@payloadcms/ui": "3.45.0"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
+
"@payloadcms/ui": "3.45.0",
|
|
71
72
|
"@payloadcms/eslint-config": "3.28.0",
|
|
72
|
-
"
|
|
73
|
-
"payload": "3.45.0-internal.5103e58"
|
|
73
|
+
"payload": "3.45.0"
|
|
74
74
|
},
|
|
75
75
|
"peerDependencies": {
|
|
76
|
-
"@payloadcms/ui": "3.45.0
|
|
77
|
-
"payload": "3.45.0
|
|
76
|
+
"@payloadcms/ui": "3.45.0",
|
|
77
|
+
"payload": "3.45.0"
|
|
78
78
|
},
|
|
79
79
|
"homepage:": "https://payloadcms.com",
|
|
80
80
|
"scripts": {
|