@payloadcms/plugin-import-export 4.0.0-internal.af6aad0 → 4.0.0-internal.b8a92d2

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.
Files changed (43) hide show
  1. package/dist/utilities/getFileFromDoc.js +3 -3
  2. package/dist/utilities/getFileFromDoc.js.map +1 -1
  3. package/dist/utilities/getSelect.d.ts.map +1 -1
  4. package/dist/utilities/getSelect.js +4 -2
  5. package/dist/utilities/getSelect.js.map +1 -1
  6. package/dist/utilities/setNestedValue.d.ts.map +1 -1
  7. package/dist/utilities/setNestedValue.js +20 -6
  8. package/dist/utilities/setNestedValue.js.map +1 -1
  9. package/package.json +8 -8
  10. package/dist/components/FieldsToExport/reduceFields.spec.js +0 -239
  11. package/dist/components/FieldsToExport/reduceFields.spec.js.map +0 -1
  12. package/dist/utilities/applyFieldHooks.spec.js +0 -205
  13. package/dist/utilities/applyFieldHooks.spec.js.map +0 -1
  14. package/dist/utilities/buildDisabledFieldRegex.spec.js +0 -64
  15. package/dist/utilities/buildDisabledFieldRegex.spec.js.map +0 -1
  16. package/dist/utilities/fieldPath.d.ts +0 -2
  17. package/dist/utilities/fieldPath.d.ts.map +0 -1
  18. package/dist/utilities/fieldPath.js +0 -8
  19. package/dist/utilities/fieldPath.js.map +0 -1
  20. package/dist/utilities/fieldToRegex.spec.js +0 -151
  21. package/dist/utilities/fieldToRegex.spec.js.map +0 -1
  22. package/dist/utilities/filterToSelectedFields.spec.js +0 -204
  23. package/dist/utilities/filterToSelectedFields.spec.js.map +0 -1
  24. package/dist/utilities/flattenObject.spec.js +0 -158
  25. package/dist/utilities/flattenObject.spec.js.map +0 -1
  26. package/dist/utilities/getExportFieldFunctions.spec.js +0 -50
  27. package/dist/utilities/getExportFieldFunctions.spec.js.map +0 -1
  28. package/dist/utilities/getImportFieldFunctions.spec.js +0 -167
  29. package/dist/utilities/getImportFieldFunctions.spec.js.map +0 -1
  30. package/dist/utilities/getSchemaColumns.spec.js +0 -157
  31. package/dist/utilities/getSchemaColumns.spec.js.map +0 -1
  32. package/dist/utilities/getSelect.spec.js +0 -70
  33. package/dist/utilities/getSelect.spec.js.map +0 -1
  34. package/dist/utilities/parseCSV.spec.js +0 -195
  35. package/dist/utilities/parseCSV.spec.js.map +0 -1
  36. package/dist/utilities/processRichTextField.spec.js +0 -308
  37. package/dist/utilities/processRichTextField.spec.js.map +0 -1
  38. package/dist/utilities/setNestedValue.spec.js +0 -164
  39. package/dist/utilities/setNestedValue.spec.js.map +0 -1
  40. package/dist/utilities/siblingDoc.spec.js +0 -278
  41. package/dist/utilities/siblingDoc.spec.js.map +0 -1
  42. package/dist/utilities/unflattenObject.spec.js +0 -819
  43. package/dist/utilities/unflattenObject.spec.js.map +0 -1
@@ -1,157 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { getSchemaColumns } from './getSchemaColumns.js';
3
- function createCollectionConfig(flattenedFields, options) {
4
- return {
5
- flattenedFields,
6
- timestamps: options?.timestamps ?? true,
7
- trash: options?.trash ?? false,
8
- versions: options?.versions
9
- };
10
- }
11
- describe('getSchemaColumns', ()=>{
12
- describe('fields from flattenedFields', ()=>{
13
- it('should include all fields present in flattenedFields in their natural order', ()=>{
14
- const flattenedFields = [
15
- {
16
- name: 'id',
17
- type: 'number'
18
- },
19
- {
20
- name: 'title',
21
- type: 'text'
22
- },
23
- {
24
- name: 'createdAt',
25
- type: 'date'
26
- },
27
- {
28
- name: 'updatedAt',
29
- type: 'date'
30
- }
31
- ];
32
- const collectionConfig = createCollectionConfig(flattenedFields);
33
- const result = getSchemaColumns({
34
- collectionConfig
35
- });
36
- expect(result).toEqual([
37
- 'id',
38
- 'title',
39
- 'createdAt',
40
- 'updatedAt'
41
- ]);
42
- });
43
- it('should include custom id field when defined in flattenedFields', ()=>{
44
- const flattenedFields = [
45
- {
46
- name: 'id',
47
- type: 'text'
48
- },
49
- {
50
- name: 'title',
51
- type: 'text'
52
- },
53
- {
54
- name: 'createdAt',
55
- type: 'date'
56
- },
57
- {
58
- name: 'updatedAt',
59
- type: 'date'
60
- }
61
- ];
62
- const collectionConfig = createCollectionConfig(flattenedFields);
63
- const result = getSchemaColumns({
64
- collectionConfig
65
- });
66
- expect(result).toContain('id');
67
- });
68
- it('should not include createdAt or updatedAt when timestamps disabled (not in flattenedFields)', ()=>{
69
- const flattenedFields = [
70
- {
71
- name: 'id',
72
- type: 'number'
73
- },
74
- {
75
- name: 'title',
76
- type: 'text'
77
- }
78
- ];
79
- const collectionConfig = createCollectionConfig(flattenedFields, {
80
- timestamps: false
81
- });
82
- const result = getSchemaColumns({
83
- collectionConfig
84
- });
85
- expect(result).toContain('id');
86
- expect(result).toContain('title');
87
- expect(result).not.toContain('createdAt');
88
- expect(result).not.toContain('updatedAt');
89
- });
90
- it('should include deletedAt when present in flattenedFields (trash enabled)', ()=>{
91
- const flattenedFields = [
92
- {
93
- name: 'id',
94
- type: 'number'
95
- },
96
- {
97
- name: 'title',
98
- type: 'text'
99
- },
100
- {
101
- name: 'createdAt',
102
- type: 'date'
103
- },
104
- {
105
- name: 'updatedAt',
106
- type: 'date'
107
- },
108
- {
109
- name: 'deletedAt',
110
- type: 'date'
111
- }
112
- ];
113
- const collectionConfig = createCollectionConfig(flattenedFields);
114
- const result = getSchemaColumns({
115
- collectionConfig
116
- });
117
- expect(result).toContain('deletedAt');
118
- });
119
- it('should add id when missing from flattenedFields (Payload core limitation)', ()=>{
120
- const flattenedFields = [
121
- {
122
- name: 'title',
123
- type: 'text'
124
- },
125
- {
126
- name: 'excerpt',
127
- type: 'textarea'
128
- },
129
- {
130
- name: 'createdAt',
131
- type: 'date'
132
- },
133
- {
134
- name: 'updatedAt',
135
- type: 'date'
136
- }
137
- ];
138
- const collectionConfig = createCollectionConfig(flattenedFields);
139
- const result = getSchemaColumns({
140
- collectionConfig
141
- });
142
- // id is added because Payload core doesn't add it to flattenedFields
143
- // but it exists on every document
144
- expect(result).toContain('id');
145
- expect(result[0]).toBe('id');
146
- expect(result).toEqual([
147
- 'id',
148
- 'title',
149
- 'excerpt',
150
- 'createdAt',
151
- 'updatedAt'
152
- ]);
153
- });
154
- });
155
- });
156
-
157
- //# sourceMappingURL=getSchemaColumns.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/utilities/getSchemaColumns.spec.ts"],"sourcesContent":["import type { FlattenedField, SanitizedCollectionConfig } from 'payload'\n\nimport { describe, expect, it } from 'vitest'\n\nimport { getSchemaColumns } from './getSchemaColumns.js'\n\nfunction createCollectionConfig(\n flattenedFields: FlattenedField[],\n options?: { timestamps?: boolean; trash?: boolean; versions?: unknown },\n): SanitizedCollectionConfig {\n return {\n flattenedFields,\n timestamps: options?.timestamps ?? true,\n trash: options?.trash ?? false,\n versions: options?.versions,\n } as SanitizedCollectionConfig\n}\n\ndescribe('getSchemaColumns', () => {\n describe('fields from flattenedFields', () => {\n it('should include all fields present in flattenedFields in their natural order', () => {\n const flattenedFields: FlattenedField[] = [\n { name: 'id', type: 'number' },\n { name: 'title', type: 'text' },\n { name: 'createdAt', type: 'date' },\n { name: 'updatedAt', type: 'date' },\n ]\n\n const collectionConfig = createCollectionConfig(flattenedFields)\n const result = getSchemaColumns({ collectionConfig })\n\n expect(result).toEqual(['id', 'title', 'createdAt', 'updatedAt'])\n })\n\n it('should include custom id field when defined in flattenedFields', () => {\n const flattenedFields: FlattenedField[] = [\n { name: 'id', type: 'text' },\n { name: 'title', type: 'text' },\n { name: 'createdAt', type: 'date' },\n { name: 'updatedAt', type: 'date' },\n ]\n\n const collectionConfig = createCollectionConfig(flattenedFields)\n const result = getSchemaColumns({ collectionConfig })\n\n expect(result).toContain('id')\n })\n\n it('should not include createdAt or updatedAt when timestamps disabled (not in flattenedFields)', () => {\n const flattenedFields: FlattenedField[] = [\n { name: 'id', type: 'number' },\n { name: 'title', type: 'text' },\n ]\n\n const collectionConfig = createCollectionConfig(flattenedFields, { timestamps: false })\n const result = getSchemaColumns({ collectionConfig })\n\n expect(result).toContain('id')\n expect(result).toContain('title')\n expect(result).not.toContain('createdAt')\n expect(result).not.toContain('updatedAt')\n })\n\n it('should include deletedAt when present in flattenedFields (trash enabled)', () => {\n const flattenedFields: FlattenedField[] = [\n { name: 'id', type: 'number' },\n { name: 'title', type: 'text' },\n { name: 'createdAt', type: 'date' },\n { name: 'updatedAt', type: 'date' },\n { name: 'deletedAt', type: 'date' },\n ]\n\n const collectionConfig = createCollectionConfig(flattenedFields)\n const result = getSchemaColumns({ collectionConfig })\n\n expect(result).toContain('deletedAt')\n })\n\n it('should add id when missing from flattenedFields (Payload core limitation)', () => {\n const flattenedFields: FlattenedField[] = [\n { name: 'title', type: 'text' },\n { name: 'excerpt', type: 'textarea' },\n { name: 'createdAt', type: 'date' },\n { name: 'updatedAt', type: 'date' },\n ]\n\n const collectionConfig = createCollectionConfig(flattenedFields)\n const result = getSchemaColumns({ collectionConfig })\n\n // id is added because Payload core doesn't add it to flattenedFields\n // but it exists on every document\n expect(result).toContain('id')\n expect(result[0]).toBe('id')\n expect(result).toEqual(['id', 'title', 'excerpt', 'createdAt', 'updatedAt'])\n })\n })\n})\n"],"names":["describe","expect","it","getSchemaColumns","createCollectionConfig","flattenedFields","options","timestamps","trash","versions","name","type","collectionConfig","result","toEqual","toContain","not","toBe"],"mappings":"AAEA,SAASA,QAAQ,EAAEC,MAAM,EAAEC,EAAE,QAAQ,SAAQ;AAE7C,SAASC,gBAAgB,QAAQ,wBAAuB;AAExD,SAASC,uBACPC,eAAiC,EACjCC,OAAuE;IAEvE,OAAO;QACLD;QACAE,YAAYD,SAASC,cAAc;QACnCC,OAAOF,SAASE,SAAS;QACzBC,UAAUH,SAASG;IACrB;AACF;AAEAT,SAAS,oBAAoB;IAC3BA,SAAS,+BAA+B;QACtCE,GAAG,+EAA+E;YAChF,MAAMG,kBAAoC;gBACxC;oBAAEK,MAAM;oBAAMC,MAAM;gBAAS;gBAC7B;oBAAED,MAAM;oBAASC,MAAM;gBAAO;gBAC9B;oBAAED,MAAM;oBAAaC,MAAM;gBAAO;gBAClC;oBAAED,MAAM;oBAAaC,MAAM;gBAAO;aACnC;YAED,MAAMC,mBAAmBR,uBAAuBC;YAChD,MAAMQ,SAASV,iBAAiB;gBAAES;YAAiB;YAEnDX,OAAOY,QAAQC,OAAO,CAAC;gBAAC;gBAAM;gBAAS;gBAAa;aAAY;QAClE;QAEAZ,GAAG,kEAAkE;YACnE,MAAMG,kBAAoC;gBACxC;oBAAEK,MAAM;oBAAMC,MAAM;gBAAO;gBAC3B;oBAAED,MAAM;oBAASC,MAAM;gBAAO;gBAC9B;oBAAED,MAAM;oBAAaC,MAAM;gBAAO;gBAClC;oBAAED,MAAM;oBAAaC,MAAM;gBAAO;aACnC;YAED,MAAMC,mBAAmBR,uBAAuBC;YAChD,MAAMQ,SAASV,iBAAiB;gBAAES;YAAiB;YAEnDX,OAAOY,QAAQE,SAAS,CAAC;QAC3B;QAEAb,GAAG,+FAA+F;YAChG,MAAMG,kBAAoC;gBACxC;oBAAEK,MAAM;oBAAMC,MAAM;gBAAS;gBAC7B;oBAAED,MAAM;oBAASC,MAAM;gBAAO;aAC/B;YAED,MAAMC,mBAAmBR,uBAAuBC,iBAAiB;gBAAEE,YAAY;YAAM;YACrF,MAAMM,SAASV,iBAAiB;gBAAES;YAAiB;YAEnDX,OAAOY,QAAQE,SAAS,CAAC;YACzBd,OAAOY,QAAQE,SAAS,CAAC;YACzBd,OAAOY,QAAQG,GAAG,CAACD,SAAS,CAAC;YAC7Bd,OAAOY,QAAQG,GAAG,CAACD,SAAS,CAAC;QAC/B;QAEAb,GAAG,4EAA4E;YAC7E,MAAMG,kBAAoC;gBACxC;oBAAEK,MAAM;oBAAMC,MAAM;gBAAS;gBAC7B;oBAAED,MAAM;oBAASC,MAAM;gBAAO;gBAC9B;oBAAED,MAAM;oBAAaC,MAAM;gBAAO;gBAClC;oBAAED,MAAM;oBAAaC,MAAM;gBAAO;gBAClC;oBAAED,MAAM;oBAAaC,MAAM;gBAAO;aACnC;YAED,MAAMC,mBAAmBR,uBAAuBC;YAChD,MAAMQ,SAASV,iBAAiB;gBAAES;YAAiB;YAEnDX,OAAOY,QAAQE,SAAS,CAAC;QAC3B;QAEAb,GAAG,6EAA6E;YAC9E,MAAMG,kBAAoC;gBACxC;oBAAEK,MAAM;oBAASC,MAAM;gBAAO;gBAC9B;oBAAED,MAAM;oBAAWC,MAAM;gBAAW;gBACpC;oBAAED,MAAM;oBAAaC,MAAM;gBAAO;gBAClC;oBAAED,MAAM;oBAAaC,MAAM;gBAAO;aACnC;YAED,MAAMC,mBAAmBR,uBAAuBC;YAChD,MAAMQ,SAASV,iBAAiB;gBAAES;YAAiB;YAEnD,qEAAqE;YACrE,kCAAkC;YAClCX,OAAOY,QAAQE,SAAS,CAAC;YACzBd,OAAOY,MAAM,CAAC,EAAE,EAAEI,IAAI,CAAC;YACvBhB,OAAOY,QAAQC,OAAO,CAAC;gBAAC;gBAAM;gBAAS;gBAAW;gBAAa;aAAY;QAC7E;IACF;AACF"}
@@ -1,70 +0,0 @@
1
- import { APIError } from 'payload';
2
- import { describe, expect, it } from 'vitest';
3
- import { getSelect } from './getSelect.js';
4
- const unsupportedSegments = [
5
- '__proto__',
6
- 'constructor',
7
- 'prototype'
8
- ];
9
- describe('getSelect', ()=>{
10
- it.each(unsupportedSegments.flatMap((segment)=>[
11
- [
12
- `${segment}.field`,
13
- segment,
14
- 'root'
15
- ],
16
- [
17
- `group.${segment}.field`,
18
- segment,
19
- 'middle'
20
- ],
21
- [
22
- `group.${segment}`,
23
- segment,
24
- 'leaf'
25
- ]
26
- ]))('rejects invalid field path %s', (path)=>{
27
- try {
28
- getSelect([
29
- path
30
- ]);
31
- expect.fail('Expected getSelect to reject the invalid field path');
32
- } catch (error) {
33
- expect(error).toBeInstanceOf(APIError);
34
- if (error instanceof APIError) {
35
- expect(error.status).toBe(400);
36
- expect(error.isPublic).toBe(true);
37
- }
38
- }
39
- });
40
- it('leaves global object state unchanged when rejecting invalid paths', ()=>{
41
- expect(Object.prototype).not.toHaveProperty('syntheticMarker');
42
- for (const path of [
43
- '__proto__.syntheticMarker',
44
- 'constructor.prototype.syntheticMarker'
45
- ]){
46
- expect(()=>getSelect([
47
- path
48
- ])).toThrow(APIError);
49
- }
50
- expect(Object.prototype).not.toHaveProperty('syntheticMarker');
51
- });
52
- it('builds select objects and merges nested siblings', ()=>{
53
- const select = getSelect([
54
- 'id',
55
- 'group.title',
56
- 'group.description'
57
- ]);
58
- expect(select).toEqual({
59
- group: {
60
- description: true,
61
- title: true
62
- },
63
- id: true
64
- });
65
- expect(Object.getPrototypeOf(select)).toBeNull();
66
- expect(Object.getPrototypeOf(select.group)).toBeNull();
67
- });
68
- });
69
-
70
- //# sourceMappingURL=getSelect.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/utilities/getSelect.spec.ts"],"sourcesContent":["import { APIError } from 'payload'\nimport { describe, expect, it } from 'vitest'\n\nimport { getSelect } from './getSelect.js'\n\nconst unsupportedSegments = ['__proto__', 'constructor', 'prototype']\n\ndescribe('getSelect', () => {\n it.each(\n unsupportedSegments.flatMap((segment) => [\n [`${segment}.field`, segment, 'root'],\n [`group.${segment}.field`, segment, 'middle'],\n [`group.${segment}`, segment, 'leaf'],\n ]),\n )('rejects invalid field path %s', (path) => {\n try {\n getSelect([path])\n expect.fail('Expected getSelect to reject the invalid field path')\n } catch (error) {\n expect(error).toBeInstanceOf(APIError)\n\n if (error instanceof APIError) {\n expect(error.status).toBe(400)\n expect(error.isPublic).toBe(true)\n }\n }\n })\n\n it('leaves global object state unchanged when rejecting invalid paths', () => {\n expect(Object.prototype).not.toHaveProperty('syntheticMarker')\n\n for (const path of ['__proto__.syntheticMarker', 'constructor.prototype.syntheticMarker']) {\n expect(() => getSelect([path])).toThrow(APIError)\n }\n\n expect(Object.prototype).not.toHaveProperty('syntheticMarker')\n })\n\n it('builds select objects and merges nested siblings', () => {\n const select = getSelect(['id', 'group.title', 'group.description'])\n\n expect(select).toEqual({\n group: {\n description: true,\n title: true,\n },\n id: true,\n })\n expect(Object.getPrototypeOf(select)).toBeNull()\n expect(Object.getPrototypeOf(select.group)).toBeNull()\n })\n})\n"],"names":["APIError","describe","expect","it","getSelect","unsupportedSegments","each","flatMap","segment","path","fail","error","toBeInstanceOf","status","toBe","isPublic","Object","prototype","not","toHaveProperty","toThrow","select","toEqual","group","description","title","id","getPrototypeOf","toBeNull"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,UAAS;AAClC,SAASC,QAAQ,EAAEC,MAAM,EAAEC,EAAE,QAAQ,SAAQ;AAE7C,SAASC,SAAS,QAAQ,iBAAgB;AAE1C,MAAMC,sBAAsB;IAAC;IAAa;IAAe;CAAY;AAErEJ,SAAS,aAAa;IACpBE,GAAGG,IAAI,CACLD,oBAAoBE,OAAO,CAAC,CAACC,UAAY;YACvC;gBAAC,GAAGA,QAAQ,MAAM,CAAC;gBAAEA;gBAAS;aAAO;YACrC;gBAAC,CAAC,MAAM,EAAEA,QAAQ,MAAM,CAAC;gBAAEA;gBAAS;aAAS;YAC7C;gBAAC,CAAC,MAAM,EAAEA,SAAS;gBAAEA;gBAAS;aAAO;SACtC,GACD,iCAAiC,CAACC;QAClC,IAAI;YACFL,UAAU;gBAACK;aAAK;YAChBP,OAAOQ,IAAI,CAAC;QACd,EAAE,OAAOC,OAAO;YACdT,OAAOS,OAAOC,cAAc,CAACZ;YAE7B,IAAIW,iBAAiBX,UAAU;gBAC7BE,OAAOS,MAAME,MAAM,EAAEC,IAAI,CAAC;gBAC1BZ,OAAOS,MAAMI,QAAQ,EAAED,IAAI,CAAC;YAC9B;QACF;IACF;IAEAX,GAAG,qEAAqE;QACtED,OAAOc,OAAOC,SAAS,EAAEC,GAAG,CAACC,cAAc,CAAC;QAE5C,KAAK,MAAMV,QAAQ;YAAC;YAA6B;SAAwC,CAAE;YACzFP,OAAO,IAAME,UAAU;oBAACK;iBAAK,GAAGW,OAAO,CAACpB;QAC1C;QAEAE,OAAOc,OAAOC,SAAS,EAAEC,GAAG,CAACC,cAAc,CAAC;IAC9C;IAEAhB,GAAG,oDAAoD;QACrD,MAAMkB,SAASjB,UAAU;YAAC;YAAM;YAAe;SAAoB;QAEnEF,OAAOmB,QAAQC,OAAO,CAAC;YACrBC,OAAO;gBACLC,aAAa;gBACbC,OAAO;YACT;YACAC,IAAI;QACN;QACAxB,OAAOc,OAAOW,cAAc,CAACN,SAASO,QAAQ;QAC9C1B,OAAOc,OAAOW,cAAc,CAACN,OAAOE,KAAK,GAAGK,QAAQ;IACtD;AACF"}
@@ -1,195 +0,0 @@
1
- import { parseCSV } from './parseCSV.js';
2
- import { describe, it, expect, vi } from 'vitest';
3
- describe('parseCSV', ()=>{
4
- const mockReq = {
5
- payload: {
6
- logger: {
7
- error: vi.fn()
8
- }
9
- }
10
- };
11
- describe('cast function behavior', ()=>{
12
- it('should preserve comma-separated values as strings', async ()=>{
13
- const csvData = Buffer.from('numbers,ids\n"1,2,3,5,8","id1,id2,id3"');
14
- const result = await parseCSV({
15
- data: csvData,
16
- req: mockReq
17
- });
18
- expect(result).toEqual([
19
- {
20
- numbers: '1,2,3,5,8',
21
- ids: 'id1,id2,id3'
22
- }
23
- ]);
24
- });
25
- it('should convert single numbers to numbers', async ()=>{
26
- const csvData = Buffer.from('single,decimal\n"42","3.14"');
27
- const result = await parseCSV({
28
- data: csvData,
29
- req: mockReq
30
- });
31
- expect(result).toEqual([
32
- {
33
- single: 42,
34
- decimal: 3.14
35
- }
36
- ]);
37
- });
38
- it('should handle booleans correctly', async ()=>{
39
- const csvData = Buffer.from('bool1,bool2,notBool\n"true","false","True"');
40
- const result = await parseCSV({
41
- data: csvData,
42
- req: mockReq
43
- });
44
- expect(result).toEqual([
45
- {
46
- bool1: true,
47
- bool2: false,
48
- notBool: 'True'
49
- }
50
- ]);
51
- });
52
- it('should convert empty strings to undefined', async ()=>{
53
- const csvData = Buffer.from('field1,field2\n"","value"');
54
- const result = await parseCSV({
55
- data: csvData,
56
- req: mockReq
57
- });
58
- expect(result).toEqual([
59
- {
60
- // field1 is undefined (not present) - empty cells don't update fields
61
- field2: 'value'
62
- }
63
- ]);
64
- });
65
- it('should handle null strings', async ()=>{
66
- const csvData = Buffer.from('field1,field2,field3\n"null","NULL","Null"');
67
- const result = await parseCSV({
68
- data: csvData,
69
- req: mockReq
70
- });
71
- expect(result).toEqual([
72
- {
73
- field1: null,
74
- field2: null,
75
- field3: 'Null'
76
- }
77
- ]);
78
- });
79
- it('should preserve spaces in comma-separated values', async ()=>{
80
- const csvData = Buffer.from('numbers\n" 10 , 20 , 30 "');
81
- const result = await parseCSV({
82
- data: csvData,
83
- req: mockReq
84
- });
85
- expect(result).toEqual([
86
- {
87
- numbers: ' 10 , 20 , 30 '
88
- }
89
- ]);
90
- });
91
- it('should handle mixed comma-separated values with empty entries', async ()=>{
92
- const csvData = Buffer.from('mixed\n"1,,3,,5"');
93
- const result = await parseCSV({
94
- data: csvData,
95
- req: mockReq
96
- });
97
- expect(result).toEqual([
98
- {
99
- mixed: '1,,3,,5'
100
- }
101
- ]);
102
- });
103
- it('should handle MongoDB ObjectIds as strings', async ()=>{
104
- const csvData = Buffer.from('id\n"507f1f77bcf86cd799439011"');
105
- const result = await parseCSV({
106
- data: csvData,
107
- req: mockReq
108
- });
109
- expect(result).toEqual([
110
- {
111
- id: '507f1f77bcf86cd799439011'
112
- }
113
- ]);
114
- });
115
- it('should handle multiple rows with various data types', async ()=>{
116
- const csvData = Buffer.from('title,count,tags,active\n' + '"Item 1","5","tag1,tag2,tag3","true"\n' + '"Item 2","","","false"\n' + '"Item 3","10","single",""\n');
117
- const result = await parseCSV({
118
- data: csvData,
119
- req: mockReq
120
- });
121
- expect(result).toEqual([
122
- {
123
- title: 'Item 1',
124
- count: 5,
125
- tags: 'tag1,tag2,tag3',
126
- active: true
127
- },
128
- {
129
- title: 'Item 2',
130
- // count is undefined (empty cell - field not updated)
131
- // tags is undefined (empty cell - field not updated)
132
- active: false
133
- },
134
- {
135
- title: 'Item 3',
136
- count: 10,
137
- tags: 'single'
138
- }
139
- ]);
140
- });
141
- it('should skip empty lines', async ()=>{
142
- const csvData = Buffer.from('field\n"value1"\n\n"value2"\n\n');
143
- const result = await parseCSV({
144
- data: csvData,
145
- req: mockReq
146
- });
147
- expect(result).toEqual([
148
- {
149
- field: 'value1'
150
- },
151
- {
152
- field: 'value2'
153
- }
154
- ]);
155
- });
156
- it('should strip UTF-8 BOM from column names', async ()=>{
157
- // UTF-8 BOM is 0xEF 0xBB 0xBF
158
- const bomBytes = Buffer.from([
159
- 0xef,
160
- 0xbb,
161
- 0xbf
162
- ]);
163
- const csvContent = Buffer.from('id,title,createdAt\ntesssst,test,2026-02-11T21:03:39.020Z');
164
- const csvWithBOM = Buffer.concat([
165
- bomBytes,
166
- csvContent
167
- ]);
168
- const result = await parseCSV({
169
- data: csvWithBOM,
170
- req: mockReq
171
- });
172
- expect(result).toEqual([
173
- {
174
- id: 'tesssst',
175
- title: 'test',
176
- createdAt: '2026-02-11T21:03:39.020Z'
177
- }
178
- ]);
179
- // Verify the column name is exactly "id" without BOM character
180
- expect(Object.keys(result[0])[0]).toBe('id');
181
- });
182
- });
183
- describe('error handling', ()=>{
184
- it('should handle parsing errors', async ()=>{
185
- const invalidCsv = Buffer.from('field1,field2\n"value1');
186
- await expect(parseCSV({
187
- data: invalidCsv,
188
- req: mockReq
189
- })).rejects.toThrow();
190
- expect(mockReq.payload.logger.error).toHaveBeenCalled();
191
- });
192
- });
193
- });
194
-
195
- //# sourceMappingURL=parseCSV.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/utilities/parseCSV.spec.ts"],"sourcesContent":["import { PayloadRequest } from 'payload'\n\nimport { parseCSV } from './parseCSV.js'\nimport { describe, it, expect, vi } from 'vitest'\n\ndescribe('parseCSV', () => {\n const mockReq = {\n payload: {\n logger: {\n error: vi.fn(),\n },\n },\n } as unknown as PayloadRequest\n\n describe('cast function behavior', () => {\n it('should preserve comma-separated values as strings', async () => {\n const csvData = Buffer.from('numbers,ids\\n\"1,2,3,5,8\",\"id1,id2,id3\"')\n const result = await parseCSV({ data: csvData, req: mockReq })\n\n expect(result).toEqual([\n {\n numbers: '1,2,3,5,8',\n ids: 'id1,id2,id3',\n },\n ])\n })\n\n it('should convert single numbers to numbers', async () => {\n const csvData = Buffer.from('single,decimal\\n\"42\",\"3.14\"')\n const result = await parseCSV({ data: csvData, req: mockReq })\n\n expect(result).toEqual([\n {\n single: 42,\n decimal: 3.14,\n },\n ])\n })\n\n it('should handle booleans correctly', async () => {\n const csvData = Buffer.from('bool1,bool2,notBool\\n\"true\",\"false\",\"True\"')\n const result = await parseCSV({ data: csvData, req: mockReq })\n\n expect(result).toEqual([\n {\n bool1: true,\n bool2: false,\n notBool: 'True', // Case-sensitive\n },\n ])\n })\n\n it('should convert empty strings to undefined', async () => {\n const csvData = Buffer.from('field1,field2\\n\"\",\"value\"')\n const result = await parseCSV({ data: csvData, req: mockReq })\n\n expect(result).toEqual([\n {\n // field1 is undefined (not present) - empty cells don't update fields\n field2: 'value',\n },\n ])\n })\n\n it('should handle null strings', async () => {\n const csvData = Buffer.from('field1,field2,field3\\n\"null\",\"NULL\",\"Null\"')\n const result = await parseCSV({ data: csvData, req: mockReq })\n\n expect(result).toEqual([\n {\n field1: null,\n field2: null,\n field3: 'Null', // Case-sensitive for mixed case\n },\n ])\n })\n\n it('should preserve spaces in comma-separated values', async () => {\n const csvData = Buffer.from('numbers\\n\" 10 , 20 , 30 \"')\n const result = await parseCSV({ data: csvData, req: mockReq })\n\n expect(result).toEqual([\n {\n numbers: ' 10 , 20 , 30 ', // CSV parser trims outer quotes but preserves the content\n },\n ])\n })\n\n it('should handle mixed comma-separated values with empty entries', async () => {\n const csvData = Buffer.from('mixed\\n\"1,,3,,5\"')\n const result = await parseCSV({ data: csvData, req: mockReq })\n\n expect(result).toEqual([\n {\n mixed: '1,,3,,5',\n },\n ])\n })\n\n it('should handle MongoDB ObjectIds as strings', async () => {\n const csvData = Buffer.from('id\\n\"507f1f77bcf86cd799439011\"')\n const result = await parseCSV({ data: csvData, req: mockReq })\n\n expect(result).toEqual([\n {\n id: '507f1f77bcf86cd799439011',\n },\n ])\n })\n\n it('should handle multiple rows with various data types', async () => {\n const csvData = Buffer.from(\n 'title,count,tags,active\\n' +\n '\"Item 1\",\"5\",\"tag1,tag2,tag3\",\"true\"\\n' +\n '\"Item 2\",\"\",\"\",\"false\"\\n' +\n '\"Item 3\",\"10\",\"single\",\"\"\\n',\n )\n const result = await parseCSV({ data: csvData, req: mockReq })\n\n expect(result).toEqual([\n {\n title: 'Item 1',\n count: 5,\n tags: 'tag1,tag2,tag3',\n active: true,\n },\n {\n title: 'Item 2',\n // count is undefined (empty cell - field not updated)\n // tags is undefined (empty cell - field not updated)\n active: false,\n },\n {\n title: 'Item 3',\n count: 10,\n tags: 'single',\n // active is undefined (empty cell - field not updated)\n },\n ])\n })\n\n it('should skip empty lines', async () => {\n const csvData = Buffer.from('field\\n\"value1\"\\n\\n\"value2\"\\n\\n')\n const result = await parseCSV({ data: csvData, req: mockReq })\n\n expect(result).toEqual([{ field: 'value1' }, { field: 'value2' }])\n })\n\n it('should strip UTF-8 BOM from column names', async () => {\n // UTF-8 BOM is 0xEF 0xBB 0xBF\n const bomBytes = Buffer.from([0xef, 0xbb, 0xbf])\n const csvContent = Buffer.from('id,title,createdAt\\ntesssst,test,2026-02-11T21:03:39.020Z')\n const csvWithBOM = Buffer.concat([bomBytes, csvContent])\n\n const result = await parseCSV({ data: csvWithBOM, req: mockReq })\n\n expect(result).toEqual([\n {\n id: 'tesssst',\n title: 'test',\n createdAt: '2026-02-11T21:03:39.020Z',\n },\n ])\n\n // Verify the column name is exactly \"id\" without BOM character\n expect(Object.keys(result[0])[0]).toBe('id')\n })\n })\n\n describe('error handling', () => {\n it('should handle parsing errors', async () => {\n const invalidCsv = Buffer.from('field1,field2\\n\"value1')\n\n await expect(parseCSV({ data: invalidCsv, req: mockReq })).rejects.toThrow()\n expect(mockReq.payload.logger.error).toHaveBeenCalled()\n })\n })\n})\n"],"names":["parseCSV","describe","it","expect","vi","mockReq","payload","logger","error","fn","csvData","Buffer","from","result","data","req","toEqual","numbers","ids","single","decimal","bool1","bool2","notBool","field2","field1","field3","mixed","id","title","count","tags","active","field","bomBytes","csvContent","csvWithBOM","concat","createdAt","Object","keys","toBe","invalidCsv","rejects","toThrow","toHaveBeenCalled"],"mappings":"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"}