@payloadcms/plugin-import-export 3.44.0-canary.9 → 3.44.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/FieldsToExport/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAmB,0BAA0B,EAAE,MAAM,SAAS,CAAA;AAkB1E,eAAO,MAAM,cAAc,EAAE,0BAiF5B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/FieldsToExport/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAyB,0BAA0B,EAAE,MAAM,SAAS,CAAA;AAkBhF,eAAO,MAAM,cAAc,EAAE,0BAkF5B,CAAA"}
@@ -49,7 +49,7 @@ export const FieldsToExport = (props)=>{
49
49
  return;
50
50
  }
51
51
  const doAsync = async ()=>{
52
- const currentPreferences = await getPreference(`${collectionSlug}-list`);
52
+ const currentPreferences = await getPreference(`collection-${collectionSlug}`);
53
53
  const columns = currentPreferences?.columns?.filter((a)=>a.active).map((b)=>b.accessor);
54
54
  setValue(columns ?? collectionConfig?.admin?.defaultColumns ?? []);
55
55
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/FieldsToExport/index.tsx"],"sourcesContent":["'use client'\n\nimport type { ListPreferences, SelectFieldClientComponent } from 'payload'\nimport type { ReactNode } from 'react'\n\nimport {\n FieldLabel,\n ReactSelect,\n useConfig,\n useDocumentInfo,\n useField,\n usePreferences,\n} from '@payloadcms/ui'\nimport React, { useEffect, useState } from 'react'\n\nimport { useImportExport } from '../ImportExportProvider/index.js'\nimport { reduceFields } from './reduceFields.js'\n\nconst baseClass = 'fields-to-export'\n\nexport const FieldsToExport: SelectFieldClientComponent = (props) => {\n const { id } = useDocumentInfo()\n const { setValue, value } = useField<string[]>()\n const { value: collectionSlug } = useField<string>({ path: 'collectionSlug' })\n const { getEntityConfig } = useConfig()\n const { collection } = useImportExport()\n const { getPreference } = usePreferences()\n const [displayedValue, setDisplayedValue] = useState<\n { id: string; label: ReactNode; value: string }[]\n >([])\n\n const collectionConfig = getEntityConfig({ collectionSlug: collectionSlug ?? collection })\n const fieldOptions = reduceFields({ fields: collectionConfig?.fields })\n\n useEffect(() => {\n if (value && value.length > 0) {\n setDisplayedValue((prevDisplayedValue) => {\n if (prevDisplayedValue.length > 0) {\n return prevDisplayedValue\n } // Prevent unnecessary updates\n\n return value.map((field) => {\n const match = fieldOptions.find((option) => option.value === field)\n return match ? { ...match, id: field } : { id: field, label: field, value: field }\n })\n })\n }\n }, [value, fieldOptions])\n\n useEffect(() => {\n if (id || !collectionSlug) {\n return\n }\n const doAsync = async () => {\n const currentPreferences = await getPreference<{\n columns: ListPreferences['columns']\n }>(`${collectionSlug}-list`)\n\n const columns = currentPreferences?.columns?.filter((a) => a.active).map((b) => b.accessor)\n setValue(columns ?? collectionConfig?.admin?.defaultColumns ?? [])\n }\n\n void doAsync()\n }, [\n getPreference,\n collection,\n setValue,\n collectionSlug,\n id,\n collectionConfig?.admin?.defaultColumns,\n ])\n const onChange = (options: { id: string; label: ReactNode; value: string }[]) => {\n if (!options) {\n setValue([])\n return\n }\n const updatedValue = options?.map((option) =>\n typeof option === 'object' ? option.value : option,\n )\n setValue(updatedValue)\n setDisplayedValue(options)\n }\n\n return (\n <div className={baseClass}>\n <FieldLabel label={props.field.label} path={props.path} />\n <ReactSelect\n className={baseClass}\n disabled={props.readOnly}\n getOptionValue={(option) => String(option.value)}\n inputId={`field-${props.path.replace(/\\./g, '__')}`}\n isClearable={true}\n isMulti={true}\n isSortable={true}\n // @ts-expect-error react select option\n onChange={onChange}\n options={fieldOptions}\n value={displayedValue}\n />\n </div>\n )\n}\n"],"names":["FieldLabel","ReactSelect","useConfig","useDocumentInfo","useField","usePreferences","React","useEffect","useState","useImportExport","reduceFields","baseClass","FieldsToExport","props","id","setValue","value","collectionSlug","path","getEntityConfig","collection","getPreference","displayedValue","setDisplayedValue","collectionConfig","fieldOptions","fields","length","prevDisplayedValue","map","field","match","find","option","label","doAsync","currentPreferences","columns","filter","a","active","b","accessor","admin","defaultColumns","onChange","options","updatedValue","div","className","disabled","readOnly","getOptionValue","String","inputId","replace","isClearable","isMulti","isSortable"],"mappings":"AAAA;;AAKA,SACEA,UAAU,EACVC,WAAW,EACXC,SAAS,EACTC,eAAe,EACfC,QAAQ,EACRC,cAAc,QACT,iBAAgB;AACvB,OAAOC,SAASC,SAAS,EAAEC,QAAQ,QAAQ,QAAO;AAElD,SAASC,eAAe,QAAQ,mCAAkC;AAClE,SAASC,YAAY,QAAQ,oBAAmB;AAEhD,MAAMC,YAAY;AAElB,OAAO,MAAMC,iBAA6C,CAACC;IACzD,MAAM,EAAEC,EAAE,EAAE,GAAGX;IACf,MAAM,EAAEY,QAAQ,EAAEC,KAAK,EAAE,GAAGZ;IAC5B,MAAM,EAAEY,OAAOC,cAAc,EAAE,GAAGb,SAAiB;QAAEc,MAAM;IAAiB;IAC5E,MAAM,EAAEC,eAAe,EAAE,GAAGjB;IAC5B,MAAM,EAAEkB,UAAU,EAAE,GAAGX;IACvB,MAAM,EAAEY,aAAa,EAAE,GAAGhB;IAC1B,MAAM,CAACiB,gBAAgBC,kBAAkB,GAAGf,SAE1C,EAAE;IAEJ,MAAMgB,mBAAmBL,gBAAgB;QAAEF,gBAAgBA,kBAAkBG;IAAW;IACxF,MAAMK,eAAef,aAAa;QAAEgB,QAAQF,kBAAkBE;IAAO;IAErEnB,UAAU;QACR,IAAIS,SAASA,MAAMW,MAAM,GAAG,GAAG;YAC7BJ,kBAAkB,CAACK;gBACjB,IAAIA,mBAAmBD,MAAM,GAAG,GAAG;oBACjC,OAAOC;gBACT,EAAE,8BAA8B;gBAEhC,OAAOZ,MAAMa,GAAG,CAAC,CAACC;oBAChB,MAAMC,QAAQN,aAAaO,IAAI,CAAC,CAACC,SAAWA,OAAOjB,KAAK,KAAKc;oBAC7D,OAAOC,QAAQ;wBAAE,GAAGA,KAAK;wBAAEjB,IAAIgB;oBAAM,IAAI;wBAAEhB,IAAIgB;wBAAOI,OAAOJ;wBAAOd,OAAOc;oBAAM;gBACnF;YACF;QACF;IACF,GAAG;QAACd;QAAOS;KAAa;IAExBlB,UAAU;QACR,IAAIO,MAAM,CAACG,gBAAgB;YACzB;QACF;QACA,MAAMkB,UAAU;YACd,MAAMC,qBAAqB,MAAMf,cAE9B,GAAGJ,eAAe,KAAK,CAAC;YAE3B,MAAMoB,UAAUD,oBAAoBC,SAASC,OAAO,CAACC,IAAMA,EAAEC,MAAM,EAAEX,IAAI,CAACY,IAAMA,EAAEC,QAAQ;YAC1F3B,SAASsB,WAAWb,kBAAkBmB,OAAOC,kBAAkB,EAAE;QACnE;QAEA,KAAKT;IACP,GAAG;QACDd;QACAD;QACAL;QACAE;QACAH;QACAU,kBAAkBmB,OAAOC;KAC1B;IACD,MAAMC,WAAW,CAACC;QAChB,IAAI,CAACA,SAAS;YACZ/B,SAAS,EAAE;YACX;QACF;QACA,MAAMgC,eAAeD,SAASjB,IAAI,CAACI,SACjC,OAAOA,WAAW,WAAWA,OAAOjB,KAAK,GAAGiB;QAE9ClB,SAASgC;QACTxB,kBAAkBuB;IACpB;IAEA,qBACE,MAACE;QAAIC,WAAWtC;;0BACd,KAACX;gBAAWkC,OAAOrB,MAAMiB,KAAK,CAACI,KAAK;gBAAEhB,MAAML,MAAMK,IAAI;;0BACtD,KAACjB;gBACCgD,WAAWtC;gBACXuC,UAAUrC,MAAMsC,QAAQ;gBACxBC,gBAAgB,CAACnB,SAAWoB,OAAOpB,OAAOjB,KAAK;gBAC/CsC,SAAS,CAAC,MAAM,EAAEzC,MAAMK,IAAI,CAACqC,OAAO,CAAC,OAAO,OAAO;gBACnDC,aAAa;gBACbC,SAAS;gBACTC,YAAY;gBACZ,uCAAuC;gBACvCb,UAAUA;gBACVC,SAASrB;gBACTT,OAAOM;;;;AAIf,EAAC"}
1
+ {"version":3,"sources":["../../../src/components/FieldsToExport/index.tsx"],"sourcesContent":["'use client'\n\nimport type { CollectionPreferences, SelectFieldClientComponent } from 'payload'\nimport type { ReactNode } from 'react'\n\nimport {\n FieldLabel,\n ReactSelect,\n useConfig,\n useDocumentInfo,\n useField,\n usePreferences,\n} from '@payloadcms/ui'\nimport React, { useEffect, useState } from 'react'\n\nimport { useImportExport } from '../ImportExportProvider/index.js'\nimport { reduceFields } from './reduceFields.js'\n\nconst baseClass = 'fields-to-export'\n\nexport const FieldsToExport: SelectFieldClientComponent = (props) => {\n const { id } = useDocumentInfo()\n const { setValue, value } = useField<string[]>()\n const { value: collectionSlug } = useField<string>({ path: 'collectionSlug' })\n const { getEntityConfig } = useConfig()\n const { collection } = useImportExport()\n const { getPreference } = usePreferences()\n const [displayedValue, setDisplayedValue] = useState<\n { id: string; label: ReactNode; value: string }[]\n >([])\n\n const collectionConfig = getEntityConfig({ collectionSlug: collectionSlug ?? collection })\n const fieldOptions = reduceFields({ fields: collectionConfig?.fields })\n\n useEffect(() => {\n if (value && value.length > 0) {\n setDisplayedValue((prevDisplayedValue) => {\n if (prevDisplayedValue.length > 0) {\n return prevDisplayedValue\n } // Prevent unnecessary updates\n\n return value.map((field) => {\n const match = fieldOptions.find((option) => option.value === field)\n return match ? { ...match, id: field } : { id: field, label: field, value: field }\n })\n })\n }\n }, [value, fieldOptions])\n\n useEffect(() => {\n if (id || !collectionSlug) {\n return\n }\n\n const doAsync = async () => {\n const currentPreferences = await getPreference<{\n columns: CollectionPreferences['columns']\n }>(`collection-${collectionSlug}`)\n\n const columns = currentPreferences?.columns?.filter((a) => a.active).map((b) => b.accessor)\n setValue(columns ?? collectionConfig?.admin?.defaultColumns ?? [])\n }\n\n void doAsync()\n }, [\n getPreference,\n collection,\n setValue,\n collectionSlug,\n id,\n collectionConfig?.admin?.defaultColumns,\n ])\n const onChange = (options: { id: string; label: ReactNode; value: string }[]) => {\n if (!options) {\n setValue([])\n return\n }\n const updatedValue = options?.map((option) =>\n typeof option === 'object' ? option.value : option,\n )\n setValue(updatedValue)\n setDisplayedValue(options)\n }\n\n return (\n <div className={baseClass}>\n <FieldLabel label={props.field.label} path={props.path} />\n <ReactSelect\n className={baseClass}\n disabled={props.readOnly}\n getOptionValue={(option) => String(option.value)}\n inputId={`field-${props.path.replace(/\\./g, '__')}`}\n isClearable={true}\n isMulti={true}\n isSortable={true}\n // @ts-expect-error react select option\n onChange={onChange}\n options={fieldOptions}\n value={displayedValue}\n />\n </div>\n )\n}\n"],"names":["FieldLabel","ReactSelect","useConfig","useDocumentInfo","useField","usePreferences","React","useEffect","useState","useImportExport","reduceFields","baseClass","FieldsToExport","props","id","setValue","value","collectionSlug","path","getEntityConfig","collection","getPreference","displayedValue","setDisplayedValue","collectionConfig","fieldOptions","fields","length","prevDisplayedValue","map","field","match","find","option","label","doAsync","currentPreferences","columns","filter","a","active","b","accessor","admin","defaultColumns","onChange","options","updatedValue","div","className","disabled","readOnly","getOptionValue","String","inputId","replace","isClearable","isMulti","isSortable"],"mappings":"AAAA;;AAKA,SACEA,UAAU,EACVC,WAAW,EACXC,SAAS,EACTC,eAAe,EACfC,QAAQ,EACRC,cAAc,QACT,iBAAgB;AACvB,OAAOC,SAASC,SAAS,EAAEC,QAAQ,QAAQ,QAAO;AAElD,SAASC,eAAe,QAAQ,mCAAkC;AAClE,SAASC,YAAY,QAAQ,oBAAmB;AAEhD,MAAMC,YAAY;AAElB,OAAO,MAAMC,iBAA6C,CAACC;IACzD,MAAM,EAAEC,EAAE,EAAE,GAAGX;IACf,MAAM,EAAEY,QAAQ,EAAEC,KAAK,EAAE,GAAGZ;IAC5B,MAAM,EAAEY,OAAOC,cAAc,EAAE,GAAGb,SAAiB;QAAEc,MAAM;IAAiB;IAC5E,MAAM,EAAEC,eAAe,EAAE,GAAGjB;IAC5B,MAAM,EAAEkB,UAAU,EAAE,GAAGX;IACvB,MAAM,EAAEY,aAAa,EAAE,GAAGhB;IAC1B,MAAM,CAACiB,gBAAgBC,kBAAkB,GAAGf,SAE1C,EAAE;IAEJ,MAAMgB,mBAAmBL,gBAAgB;QAAEF,gBAAgBA,kBAAkBG;IAAW;IACxF,MAAMK,eAAef,aAAa;QAAEgB,QAAQF,kBAAkBE;IAAO;IAErEnB,UAAU;QACR,IAAIS,SAASA,MAAMW,MAAM,GAAG,GAAG;YAC7BJ,kBAAkB,CAACK;gBACjB,IAAIA,mBAAmBD,MAAM,GAAG,GAAG;oBACjC,OAAOC;gBACT,EAAE,8BAA8B;gBAEhC,OAAOZ,MAAMa,GAAG,CAAC,CAACC;oBAChB,MAAMC,QAAQN,aAAaO,IAAI,CAAC,CAACC,SAAWA,OAAOjB,KAAK,KAAKc;oBAC7D,OAAOC,QAAQ;wBAAE,GAAGA,KAAK;wBAAEjB,IAAIgB;oBAAM,IAAI;wBAAEhB,IAAIgB;wBAAOI,OAAOJ;wBAAOd,OAAOc;oBAAM;gBACnF;YACF;QACF;IACF,GAAG;QAACd;QAAOS;KAAa;IAExBlB,UAAU;QACR,IAAIO,MAAM,CAACG,gBAAgB;YACzB;QACF;QAEA,MAAMkB,UAAU;YACd,MAAMC,qBAAqB,MAAMf,cAE9B,CAAC,WAAW,EAAEJ,gBAAgB;YAEjC,MAAMoB,UAAUD,oBAAoBC,SAASC,OAAO,CAACC,IAAMA,EAAEC,MAAM,EAAEX,IAAI,CAACY,IAAMA,EAAEC,QAAQ;YAC1F3B,SAASsB,WAAWb,kBAAkBmB,OAAOC,kBAAkB,EAAE;QACnE;QAEA,KAAKT;IACP,GAAG;QACDd;QACAD;QACAL;QACAE;QACAH;QACAU,kBAAkBmB,OAAOC;KAC1B;IACD,MAAMC,WAAW,CAACC;QAChB,IAAI,CAACA,SAAS;YACZ/B,SAAS,EAAE;YACX;QACF;QACA,MAAMgC,eAAeD,SAASjB,IAAI,CAACI,SACjC,OAAOA,WAAW,WAAWA,OAAOjB,KAAK,GAAGiB;QAE9ClB,SAASgC;QACTxB,kBAAkBuB;IACpB;IAEA,qBACE,MAACE;QAAIC,WAAWtC;;0BACd,KAACX;gBAAWkC,OAAOrB,MAAMiB,KAAK,CAACI,KAAK;gBAAEhB,MAAML,MAAMK,IAAI;;0BACtD,KAACjB;gBACCgD,WAAWtC;gBACXuC,UAAUrC,MAAMsC,QAAQ;gBACxBC,gBAAgB,CAACnB,SAAWoB,OAAOpB,OAAOjB,KAAK;gBAC/CsC,SAAS,CAAC,MAAM,EAAEzC,MAAMK,IAAI,CAACqC,OAAO,CAAC,OAAO,OAAO;gBACnDC,aAAa;gBACbC,SAAS;gBACTC,YAAY;gBACZ,uCAAuC;gBACvCb,UAAUA;gBACVC,SAASrB;gBACTT,OAAOM;;;;AAIf,EAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Preview/index.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,MAAM,OAAO,CAAA;AAOzB,OAAO,cAAc,CAAA;AAKrB,eAAO,MAAM,OAAO,yBA8GnB,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;AAIrB,eAAO,MAAM,OAAO,yBA+InB,CAAA"}
@@ -1,12 +1,10 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { getTranslation } from '@payloadcms/translations';
4
- import { Table, Translation, useConfig, useField, useTranslation } from '@payloadcms/ui';
5
- import { fieldAffectsData } from 'payload/shared';
6
- import * as qs from 'qs-esm';
4
+ import { CodeEditorLazy, Table, Translation, useConfig, useField, useTranslation } from '@payloadcms/ui';
7
5
  import React from 'react';
8
- import './index.scss';
9
6
  import { useImportExport } from '../ImportExportProvider/index.js';
7
+ import './index.scss';
10
8
  const baseClass = 'preview';
11
9
  export const Preview = ()=>{
12
10
  const { collection } = useImportExport();
@@ -24,7 +22,13 @@ export const Preview = ()=>{
24
22
  path: 'sort'
25
23
  });
26
24
  const { value: draft } = useField({
27
- path: 'draft'
25
+ path: 'drafts'
26
+ });
27
+ const { value: locale } = useField({
28
+ path: 'locale'
29
+ });
30
+ const { value: format } = useField({
31
+ path: 'format'
28
32
  });
29
33
  const [dataToRender, setDataToRender] = React.useState([]);
30
34
  const [resultCount, setResultCount] = React.useState('');
@@ -32,68 +36,98 @@ export const Preview = ()=>{
32
36
  const { i18n, t } = useTranslation();
33
37
  const collectionSlug = typeof collection === 'string' && collection;
34
38
  const collectionConfig = config.collections.find((collection)=>collection.slug === collectionSlug);
39
+ const isCSV = format === 'csv';
35
40
  React.useEffect(()=>{
36
41
  const fetchData = async ()=>{
37
- if (!collectionSlug) {
42
+ if (!collectionSlug || !collectionConfig) {
38
43
  return;
39
44
  }
40
45
  try {
41
- const whereQuery = qs.stringify({
42
- depth: 0,
43
- draft,
44
- limit: limit > 10 ? 10 : limit,
45
- sort,
46
- where
47
- }, {
48
- addQueryPrefix: true
49
- });
50
- const response = await fetch(`/api/${collectionSlug}${whereQuery}`, {
46
+ const res = await fetch('/api/preview-data', {
47
+ body: JSON.stringify({
48
+ collectionSlug,
49
+ draft,
50
+ fields,
51
+ limit,
52
+ locale,
53
+ sort,
54
+ where
55
+ }),
56
+ credentials: 'include',
51
57
  headers: {
52
58
  'Content-Type': 'application/json'
53
59
  },
54
- method: 'GET'
60
+ method: 'POST'
55
61
  });
56
- if (response.ok) {
57
- const data = await response.json();
58
- setResultCount(limit && limit < data.totalDocs ? limit : data.totalDocs);
59
- // TODO: check if this data is in the correct format for the table
60
- const filteredFields = collectionConfig?.fields?.filter((field)=>{
61
- if (!fieldAffectsData(field)) {
62
- return false;
63
- }
64
- if (fields?.length > 0) {
65
- return fields.includes(field.name);
66
- }
67
- return true;
68
- }) ?? [];
69
- setColumns(filteredFields.map((field)=>({
70
- accessor: field.name || '',
71
- active: true,
72
- field: field,
73
- Heading: getTranslation(field?.label || field.name, i18n),
74
- renderedCells: data.docs.map((doc)=>{
75
- if (!field.name || !doc[field.name]) {
76
- return null;
77
- }
78
- if (typeof doc[field.name] === 'object') {
79
- return JSON.stringify(doc[field.name]);
80
- }
81
- return String(doc[field.name]);
82
- })
83
- })));
84
- setDataToRender(data.docs);
62
+ if (!res.ok) {
63
+ return;
85
64
  }
65
+ const { docs, totalDocs } = await res.json();
66
+ setResultCount(limit && limit < totalDocs ? limit : totalDocs);
67
+ const allKeys = Object.keys(docs[0] || {});
68
+ const defaultMetaFields = [
69
+ 'createdAt',
70
+ 'updatedAt',
71
+ '_status',
72
+ 'id'
73
+ ];
74
+ // Match CSV column ordering by building keys based on fields and regex
75
+ const fieldToRegex = (field)=>{
76
+ const parts = field.split('.').map((part)=>`${part}(?:_\\d+)?`);
77
+ return new RegExp(`^${parts.join('_')}`);
78
+ };
79
+ // Construct final list of field keys to match field order + meta order
80
+ const selectedKeys = Array.isArray(fields) && fields.length > 0 ? fields.flatMap((field)=>{
81
+ const regex = fieldToRegex(field);
82
+ return allKeys.filter((key)=>regex.test(key));
83
+ }) : allKeys.filter((key)=>!defaultMetaFields.includes(key));
84
+ const includedMeta = new Set(selectedKeys);
85
+ const missingMetaFields = defaultMetaFields.flatMap((field)=>{
86
+ const regex = fieldToRegex(field);
87
+ return allKeys.filter((key)=>regex.test(key) && !includedMeta.has(key));
88
+ });
89
+ const fieldKeys = [
90
+ ...selectedKeys,
91
+ ...missingMetaFields
92
+ ];
93
+ // Build columns based on flattened keys
94
+ const newColumns = fieldKeys.map((key)=>({
95
+ accessor: key,
96
+ active: true,
97
+ field: {
98
+ name: key
99
+ },
100
+ Heading: getTranslation(key, i18n),
101
+ renderedCells: docs.map((doc)=>{
102
+ const val = doc[key];
103
+ if (val === undefined || val === null) {
104
+ return null;
105
+ }
106
+ // Avoid ESLint warning by type-checking before calling String()
107
+ if (typeof val === 'string' || typeof val === 'number' || typeof val === 'boolean') {
108
+ return String(val);
109
+ }
110
+ if (Array.isArray(val)) {
111
+ return val.map(String).join(', ');
112
+ }
113
+ return JSON.stringify(val);
114
+ })
115
+ }));
116
+ setColumns(newColumns);
117
+ setDataToRender(docs);
86
118
  } catch (error) {
87
- console.error('Error fetching data:', error);
119
+ console.error('Error fetching preview data:', error);
88
120
  }
89
121
  };
90
122
  void fetchData();
91
123
  }, [
92
- collectionConfig?.fields,
124
+ collectionConfig,
93
125
  collectionSlug,
94
126
  draft,
95
127
  fields,
128
+ i18n,
96
129
  limit,
130
+ locale,
97
131
  sort,
98
132
  where
99
133
  ]);
@@ -120,10 +154,14 @@ export const Preview = ()=>{
120
154
  })
121
155
  ]
122
156
  }),
123
- dataToRender && /*#__PURE__*/ _jsx(Table, {
157
+ dataToRender && (isCSV ? /*#__PURE__*/ _jsx(Table, {
124
158
  columns: columns,
125
159
  data: dataToRender
126
- })
160
+ }) : /*#__PURE__*/ _jsx(CodeEditorLazy, {
161
+ language: "json",
162
+ readOnly: true,
163
+ value: JSON.stringify(dataToRender, null, 2)
164
+ }))
127
165
  ]
128
166
  });
129
167
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/Preview/index.tsx"],"sourcesContent":["'use client'\nimport type { Column } from '@payloadcms/ui'\nimport type { ClientField, FieldAffectingDataClient } from 'payload'\n\nimport { getTranslation } from '@payloadcms/translations'\nimport { Table, Translation, useConfig, useField, useTranslation } from '@payloadcms/ui'\nimport { fieldAffectsData } from 'payload/shared'\nimport * as qs from 'qs-esm'\nimport React from 'react'\n\nimport type {\n PluginImportExportTranslationKeys,\n PluginImportExportTranslations,\n} from '../../translations/index.js'\n\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: 'draft' })\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 React.useEffect(() => {\n const fetchData = async () => {\n if (!collectionSlug) {\n return\n }\n\n try {\n const whereQuery = qs.stringify(\n {\n depth: 0,\n draft,\n limit: limit > 10 ? 10 : limit,\n sort,\n where,\n },\n {\n addQueryPrefix: true,\n },\n )\n const response = await fetch(`/api/${collectionSlug}${whereQuery}`, {\n headers: {\n 'Content-Type': 'application/json',\n },\n method: 'GET',\n })\n\n if (response.ok) {\n const data = await response.json()\n setResultCount(limit && limit < data.totalDocs ? limit : data.totalDocs)\n // TODO: check if this data is in the correct format for the table\n\n const filteredFields = (collectionConfig?.fields?.filter((field) => {\n if (!fieldAffectsData(field)) {\n return false\n }\n if (fields?.length > 0) {\n return fields.includes(field.name)\n }\n return true\n }) ?? []) as FieldAffectingDataClient[]\n\n setColumns(\n filteredFields.map((field) => ({\n accessor: field.name || '',\n active: true,\n field: field as ClientField,\n Heading: getTranslation(field?.label || (field.name as string), i18n),\n renderedCells: data.docs.map((doc: Record<string, unknown>) => {\n if (!field.name || !doc[field.name]) {\n return null\n }\n if (typeof doc[field.name] === 'object') {\n return JSON.stringify(doc[field.name])\n }\n return String(doc[field.name])\n }),\n })) as Column[],\n )\n setDataToRender(data.docs)\n }\n } catch (error) {\n console.error('Error fetching data:', error)\n }\n }\n\n void fetchData()\n }, [collectionConfig?.fields, collectionSlug, draft, fields, limit, 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 && <Table columns={columns} data={dataToRender} />}\n </div>\n )\n}\n"],"names":["getTranslation","Table","Translation","useConfig","useField","useTranslation","fieldAffectsData","qs","React","useImportExport","baseClass","Preview","collection","config","value","where","path","limit","fields","sort","draft","dataToRender","setDataToRender","useState","resultCount","setResultCount","columns","setColumns","i18n","t","collectionSlug","collectionConfig","collections","find","slug","useEffect","fetchData","whereQuery","stringify","depth","addQueryPrefix","response","fetch","headers","method","ok","data","json","totalDocs","filteredFields","filter","field","length","includes","name","map","accessor","active","Heading","label","renderedCells","docs","doc","JSON","String","error","console","div","className","h3","i18nKey","variables","count"],"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 } = 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 +1 @@
1
- {"version":3,"file":"createExport.d.ts","sourceRoot":"","sources":["../../src/export/createExport.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,cAAc,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAW/E,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,IAAI,CAAA;CACZ,CAAA;AAED,eAAO,MAAM,YAAY,SAAgB,gBAAgB,kCA8KxD,CAAA"}
1
+ {"version":3,"file":"createExport.d.ts","sourceRoot":"","sources":["../../src/export/createExport.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAWhE,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,IAAI,CAAA;CACZ,CAAA;AAED,eAAO,MAAM,YAAY,SAAgB,gBAAgB,kCAmMxD,CAAA"}
@@ -51,9 +51,6 @@ export const createExport = async (args)=>{
51
51
  findArgs
52
52
  });
53
53
  }
54
- let result = {
55
- hasNextPage: true
56
- };
57
54
  const toCSVFunctions = getCustomFieldFunctions({
58
55
  fields: collectionConfig.flattenedFields,
59
56
  select
@@ -63,35 +60,44 @@ export const createExport = async (args)=>{
63
60
  req.payload.logger.info('Starting download stream');
64
61
  }
65
62
  const encoder = new TextEncoder();
63
+ let isFirstBatch = true;
64
+ let columns;
65
+ let page = 1;
66
66
  const stream = new Readable({
67
67
  async read () {
68
- let result = await payload.find(findArgs);
69
- let isFirstBatch = true;
70
- while(result.docs.length > 0){
68
+ const result = await payload.find({
69
+ ...findArgs,
70
+ page
71
+ });
72
+ if (debug) {
73
+ req.payload.logger.info(`Processing batch ${page} with ${result.docs.length} documents`);
74
+ }
75
+ if (result.docs.length === 0) {
76
+ this.push(null);
77
+ return;
78
+ }
79
+ const csvInput = result.docs.map((doc)=>flattenObject({
80
+ doc,
81
+ fields,
82
+ toCSVFunctions
83
+ }));
84
+ if (isFirstBatch) {
85
+ columns = Object.keys(csvInput[0] ?? {});
86
+ }
87
+ const csvString = stringify(csvInput, {
88
+ header: isFirstBatch,
89
+ columns
90
+ });
91
+ this.push(encoder.encode(csvString));
92
+ isFirstBatch = false;
93
+ if (!result.hasNextPage) {
71
94
  if (debug) {
72
- req.payload.logger.info(`Processing batch ${findArgs.page + 1} with ${result.docs.length} documents`);
73
- }
74
- const csvInput = result.docs.map((doc)=>flattenObject({
75
- doc,
76
- fields,
77
- toCSVFunctions
78
- }));
79
- const csvString = stringify(csvInput, {
80
- header: isFirstBatch
81
- });
82
- this.push(encoder.encode(csvString));
83
- isFirstBatch = false;
84
- if (!result.hasNextPage) {
85
- if (debug) {
86
- req.payload.logger.info('Stream complete - no more pages');
87
- }
88
- this.push(null) // End the stream
89
- ;
90
- break;
95
+ req.payload.logger.info('Stream complete - no more pages');
91
96
  }
92
- findArgs.page += 1;
93
- result = await payload.find(findArgs);
97
+ this.push(null) // End the stream
98
+ ;
94
99
  }
100
+ page += 1;
95
101
  }
96
102
  });
97
103
  return new Response(stream, {
@@ -106,9 +112,13 @@ export const createExport = async (args)=>{
106
112
  }
107
113
  const outputData = [];
108
114
  let isFirstBatch = true;
109
- while(result.hasNextPage){
110
- findArgs.page += 1;
111
- result = await payload.find(findArgs);
115
+ let page = 1;
116
+ let hasNextPage = true;
117
+ while(hasNextPage){
118
+ const result = await payload.find({
119
+ ...findArgs,
120
+ page
121
+ });
112
122
  if (debug) {
113
123
  req.payload.logger.info(`Processing batch ${findArgs.page} with ${result.docs.length} documents`);
114
124
  }
@@ -126,6 +136,8 @@ export const createExport = async (args)=>{
126
136
  const jsonInput = result.docs.map((doc)=>JSON.stringify(doc));
127
137
  outputData.push(jsonInput.join(',\n'));
128
138
  }
139
+ hasNextPage = result.hasNextPage;
140
+ page += 1;
129
141
  }
130
142
  const buffer = Buffer.from(format === 'json' ? `[${outputData.join(',')}]` : outputData.join(''));
131
143
  if (debug) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/export/createExport.ts"],"sourcesContent":["/* eslint-disable perfectionist/sort-objects */\nimport type { PaginatedDocs, 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 let result: PaginatedDocs = { hasNextPage: true } as PaginatedDocs\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 const encoder = new TextEncoder()\n const stream = new Readable({\n async read() {\n let result = await payload.find(findArgs)\n let isFirstBatch = true\n\n while (result.docs.length > 0) {\n if (debug) {\n req.payload.logger.info(\n `Processing batch ${findArgs.page + 1} with ${result.docs.length} documents`,\n )\n }\n const csvInput = result.docs.map((doc) => flattenObject({ doc, fields, toCSVFunctions }))\n const csvString = stringify(csvInput, { header: isFirstBatch })\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 break\n }\n\n findArgs.page += 1\n result = await payload.find(findArgs)\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 if (debug) {\n req.payload.logger.info('Starting file generation')\n }\n const outputData: string[] = []\n let isFirstBatch = true\n\n while (result.hasNextPage) {\n findArgs.page += 1\n result = await payload.find(findArgs)\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\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","result","hasNextPage","toCSVFunctions","flattenedFields","encoder","TextEncoder","stream","read","isFirstBatch","docs","csvInput","map","doc","csvString","header","push","encode","Response","headers","outputData","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, 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":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAKrC,OAAO,KAAK,EAAE,wBAAwB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAMzE,eAAO,MAAM,kBAAkB,iBACd,wBAAwB,cAC9B,MAAM,KAAG,MAqEjB,CAAA;AAEH,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAiB,WAAW;QAC1B,sBAAsB,CAAC,EAAE;YACvB,KAAK,CAAC,EAAE,aAAa,CAAA;SACtB,CAAA;KACF;CACF"}
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;AASzE,eAAO,MAAM,kBAAkB,iBACd,wBAAwB,cAC9B,MAAM,KAAG,MAoIjB,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
@@ -1,5 +1,8 @@
1
- import { deepMergeSimple } from 'payload';
1
+ import { addDataAndFileToRequest, deepMergeSimple } from 'payload';
2
+ import { flattenObject } from './export/flattenObject.js';
2
3
  import { getCreateCollectionExportTask } from './export/getCreateExportCollectionTask.js';
4
+ import { getCustomFieldFunctions } from './export/getCustomFieldFunctions.js';
5
+ import { getSelect } from './export/getSelect.js';
3
6
  import { getExportCollection } from './getExportCollection.js';
4
7
  import { translations } from './translations/index.js';
5
8
  export const importExportPlugin = (pluginConfig)=>(config)=>{
@@ -51,6 +54,51 @@ export const importExportPlugin = (pluginConfig)=>(config)=>{
51
54
  config.i18n = {};
52
55
  }
53
56
  // config.i18n.translations = deepMergeSimple(translations, config.i18n?.translations ?? {})
57
+ // Inject custom REST endpoints into the config
58
+ config.endpoints = config.endpoints || [];
59
+ config.endpoints.push({
60
+ handler: async (req)=>{
61
+ await addDataAndFileToRequest(req);
62
+ const { collectionSlug, draft, fields, limit, locale, sort, where } = req.data;
63
+ const collection = req.payload.collections[collectionSlug];
64
+ if (!collection) {
65
+ return Response.json({
66
+ error: `Collection with slug ${collectionSlug} not found`
67
+ }, {
68
+ status: 400
69
+ });
70
+ }
71
+ const select = Array.isArray(fields) && fields.length > 0 ? getSelect(fields) : undefined;
72
+ const result = await req.payload.find({
73
+ collection: collectionSlug,
74
+ depth: 1,
75
+ draft: draft === 'yes',
76
+ limit: limit && limit > 10 ? 10 : limit,
77
+ locale,
78
+ overrideAccess: false,
79
+ req,
80
+ select,
81
+ sort,
82
+ where
83
+ });
84
+ const docs = result.docs;
85
+ const toCSVFunctions = getCustomFieldFunctions({
86
+ fields: collection.config.fields,
87
+ select
88
+ });
89
+ const transformed = docs.map((doc)=>flattenObject({
90
+ doc,
91
+ fields,
92
+ toCSVFunctions
93
+ }));
94
+ return Response.json({
95
+ docs: transformed,
96
+ totalDocs: result.totalDocs
97
+ });
98
+ },
99
+ method: 'post',
100
+ path: '/preview-data'
101
+ });
54
102
  /**
55
103
  * Merge plugin translations
56
104
  */ const simplifiedTranslations = Object.entries(translations).reduce((acc, [key, value])=>{
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { Config } from 'payload'\n\nimport { deepMergeSimple } from 'payload'\n\nimport type { PluginDefaultTranslationsObject } from './translations/types.js'\nimport type { ImportExportPluginConfig, ToCSVFunction } from './types.js'\n\nimport { getCreateCollectionExportTask } from './export/getCreateExportCollectionTask.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 /**\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":["deepMergeSimple","getCreateCollectionExportTask","getExportCollection","translations","importExportPlugin","pluginConfig","config","exportCollection","collections","push","admin","components","providers","jobs","tasks","collectionsToUpdate","usePluginCollections","length","filter","collection","includes","slug","forEach","listMenuItems","clientProps","exportCollectionSlug","path","i18n","simplifiedTranslations","Object","entries","reduce","acc","key","value"],"mappings":"AAEA,SAASA,eAAe,QAAQ,UAAS;AAKzC,SAASC,6BAA6B,QAAQ,4CAA2C;AACzF,SAASC,mBAAmB,QAAQ,2BAA0B;AAC9D,SAASC,YAAY,QAAQ,0BAAyB;AAEtD,OAAO,MAAMC,qBACX,CAACC,eACD,CAACC;QACC,MAAMC,mBAAmBL,oBAAoB;YAAEI;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,CAACR,8BAA8BK;QAExE,IAAIS,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;YACAP,WAAWT,KAAK,CAACC,UAAU,GAAGA;QAChC;QAEA,IAAI,CAACL,OAAOqB,IAAI,EAAE;YAChBrB,OAAOqB,IAAI,GAAG,CAAC;QACjB;QAEA,4FAA4F;QAE5F;;KAEC,GACD,MAAMC,yBAAyBC,OAAOC,OAAO,CAAC3B,cAAc4B,MAAM,CAChE,CAACC,KAAK,CAACC,KAAKC,MAAM;YAChBF,GAAG,CAACC,IAAI,GAAGC,MAAM/B,YAAY;YAC7B,OAAO6B;QACT,GACA,CAAC;QAGH1B,OAAOqB,IAAI,GAAG;YACZ,GAAGrB,OAAOqB,IAAI;YACdxB,cAAcH,gBAAgB4B,wBAAwBtB,OAAOqB,IAAI,EAAExB,gBAAgB,CAAC;QACtF;QAEA,OAAOG;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'\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) =>\n flattenObject({\n doc,\n fields,\n toCSVFunctions,\n }),\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","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","transformed","map","doc","totalDocs","method","simplifiedTranslations","Object","entries","reduce","acc","key","value"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payloadcms/plugin-import-export",
3
- "version": "3.44.0-canary.9",
3
+ "version": "3.44.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/translations": "3.44.0-canary.9",
68
- "@payloadcms/ui": "3.44.0-canary.9"
67
+ "@payloadcms/translations": "3.44.0",
68
+ "@payloadcms/ui": "3.44.0"
69
69
  },
70
70
  "devDependencies": {
71
- "@payloadcms/eslint-config": "3.28.0",
72
- "@payloadcms/ui": "3.44.0-canary.9",
73
- "payload": "3.44.0-canary.9"
71
+ "@payloadcms/ui": "3.44.0",
72
+ "payload": "3.44.0",
73
+ "@payloadcms/eslint-config": "3.28.0"
74
74
  },
75
75
  "peerDependencies": {
76
- "@payloadcms/ui": "3.44.0-canary.9",
77
- "payload": "3.44.0-canary.9"
76
+ "@payloadcms/ui": "3.44.0",
77
+ "payload": "3.44.0"
78
78
  },
79
79
  "homepage:": "https://payloadcms.com",
80
80
  "scripts": {