@payloadcms/plugin-import-export 4.0.0-internal.e55ccef → 4.0.0-internal.ea6e8f8
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/CollectionField/index.d.ts +3 -2
- package/dist/components/CollectionField/index.d.ts.map +1 -1
- package/dist/components/CollectionField/index.js.map +1 -1
- package/dist/components/ExportListMenuItem/index.d.ts.map +1 -1
- package/dist/components/ExportListMenuItem/index.js +14 -12
- package/dist/components/ExportListMenuItem/index.js.map +1 -1
- package/dist/components/ExportPreview/index.css +0 -3
- package/dist/components/ExportPreview/index.d.ts.map +1 -1
- package/dist/components/ExportPreview/index.js +11 -1
- package/dist/components/ExportPreview/index.js.map +1 -1
- package/dist/components/FieldsToExport/index.d.ts +3 -2
- package/dist/components/FieldsToExport/index.d.ts.map +1 -1
- package/dist/components/FieldsToExport/index.js +18 -15
- package/dist/components/FieldsToExport/index.js.map +1 -1
- package/dist/components/FieldsToExport/reduceFields.d.ts +6 -0
- package/dist/components/FieldsToExport/reduceFields.d.ts.map +1 -1
- package/dist/components/FieldsToExport/reduceFields.js +4 -0
- package/dist/components/FieldsToExport/reduceFields.js.map +1 -1
- package/dist/components/FormatField/index.d.ts +3 -2
- package/dist/components/FormatField/index.d.ts.map +1 -1
- package/dist/components/FormatField/index.js.map +1 -1
- package/dist/components/ImportListMenuItem/index.d.ts.map +1 -1
- package/dist/components/ImportListMenuItem/index.js +14 -12
- package/dist/components/ImportListMenuItem/index.js.map +1 -1
- package/dist/components/ImportPreview/index.css +0 -3
- package/dist/components/ImportPreview/index.d.ts.map +1 -1
- package/dist/components/ImportPreview/index.js +27 -8
- package/dist/components/ImportPreview/index.js.map +1 -1
- package/dist/components/LimitField/index.d.ts +3 -2
- package/dist/components/LimitField/index.d.ts.map +1 -1
- package/dist/components/LimitField/index.js.map +1 -1
- package/dist/components/LocaleField/index.d.ts +3 -2
- package/dist/components/LocaleField/index.d.ts.map +1 -1
- package/dist/components/LocaleField/index.js.map +1 -1
- package/dist/components/Page/index.d.ts +3 -2
- package/dist/components/Page/index.d.ts.map +1 -1
- package/dist/components/Page/index.js.map +1 -1
- package/dist/components/RelationshipCell/getRelationshipGroupKey.d.ts +7 -0
- package/dist/components/RelationshipCell/getRelationshipGroupKey.d.ts.map +1 -0
- package/dist/components/RelationshipCell/getRelationshipGroupKey.js +3 -0
- package/dist/components/RelationshipCell/getRelationshipGroupKey.js.map +1 -0
- package/dist/components/RelationshipCell/getRelationshipGroups.d.ts +43 -0
- package/dist/components/RelationshipCell/getRelationshipGroups.d.ts.map +1 -0
- package/dist/components/RelationshipCell/getRelationshipGroups.js +109 -0
- package/dist/components/RelationshipCell/getRelationshipGroups.js.map +1 -0
- package/dist/components/RelationshipCell/index.css +30 -0
- package/dist/components/RelationshipCell/index.d.ts +15 -0
- package/dist/components/RelationshipCell/index.d.ts.map +1 -0
- package/dist/components/RelationshipCell/index.js +57 -0
- package/dist/components/RelationshipCell/index.js.map +1 -0
- package/dist/components/SortBy/index.d.ts +3 -2
- package/dist/components/SortBy/index.d.ts.map +1 -1
- package/dist/components/SortBy/index.js.map +1 -1
- package/dist/components/SortOrder/index.d.ts +3 -2
- package/dist/components/SortOrder/index.d.ts.map +1 -1
- package/dist/components/SortOrder/index.js.map +1 -1
- package/dist/export/batchProcessor.d.ts +2 -1
- package/dist/export/batchProcessor.d.ts.map +1 -1
- package/dist/export/batchProcessor.js +6 -2
- package/dist/export/batchProcessor.js.map +1 -1
- package/dist/export/createExport.d.ts +2 -0
- package/dist/export/createExport.d.ts.map +1 -1
- package/dist/export/createExport.js +6 -1
- package/dist/export/createExport.js.map +1 -1
- package/dist/export/getCreateExportCollectionTask.d.ts.map +1 -1
- package/dist/export/getCreateExportCollectionTask.js +11 -0
- package/dist/export/getCreateExportCollectionTask.js.map +1 -1
- package/dist/export/getExportCollection.d.ts.map +1 -1
- package/dist/export/getExportCollection.js +5 -0
- package/dist/export/getExportCollection.js.map +1 -1
- package/dist/export/handleDownload.d.ts.map +1 -1
- package/dist/export/handleDownload.js +7 -3
- package/dist/export/handleDownload.js.map +1 -1
- package/dist/export/handlePreview.d.ts.map +1 -1
- package/dist/export/handlePreview.js +24 -5
- package/dist/export/handlePreview.js.map +1 -1
- package/dist/exports/types.d.ts +1 -1
- package/dist/exports/types.d.ts.map +1 -1
- package/dist/exports/types.js.map +1 -1
- package/dist/import/batchProcessor.d.ts +2 -1
- package/dist/import/batchProcessor.d.ts.map +1 -1
- package/dist/import/batchProcessor.js +15 -8
- package/dist/import/batchProcessor.js.map +1 -1
- package/dist/import/createImport.d.ts +3 -2
- package/dist/import/createImport.d.ts.map +1 -1
- package/dist/import/createImport.js +8 -1
- package/dist/import/createImport.js.map +1 -1
- package/dist/import/getCreateImportCollectionTask.d.ts.map +1 -1
- package/dist/import/getCreateImportCollectionTask.js +5 -2
- package/dist/import/getCreateImportCollectionTask.js.map +1 -1
- package/dist/import/getImportCollection.d.ts.map +1 -1
- package/dist/import/getImportCollection.js +2 -0
- package/dist/import/getImportCollection.js.map +1 -1
- package/dist/import/handlePreview.d.ts.map +1 -1
- package/dist/import/handlePreview.js +5 -1
- package/dist/import/handlePreview.js.map +1 -1
- package/dist/types.d.ts +17 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utilities/getExportFieldFunctions.js +64 -27
- package/dist/utilities/getExportFieldFunctions.js.map +1 -1
- package/dist/utilities/getFileFromDoc.js +3 -3
- package/dist/utilities/getFileFromDoc.js.map +1 -1
- package/dist/utilities/getSelect.d.ts.map +1 -1
- package/dist/utilities/getSelect.js +11 -3
- package/dist/utilities/getSelect.js.map +1 -1
- package/dist/utilities/getSubmittedFormValues.d.ts +12 -0
- package/dist/utilities/getSubmittedFormValues.d.ts.map +1 -0
- package/dist/utilities/getSubmittedFormValues.js +24 -0
- package/dist/utilities/getSubmittedFormValues.js.map +1 -0
- package/dist/utilities/setNestedValue.d.ts +2 -1
- package/dist/utilities/setNestedValue.d.ts.map +1 -1
- package/dist/utilities/setNestedValue.js +65 -34
- package/dist/utilities/setNestedValue.js.map +1 -1
- package/package.json +9 -9
- package/dist/components/FieldsToExport/reduceFields.spec.js +0 -239
- package/dist/components/FieldsToExport/reduceFields.spec.js.map +0 -1
- package/dist/utilities/applyFieldHooks.spec.js +0 -205
- package/dist/utilities/applyFieldHooks.spec.js.map +0 -1
- package/dist/utilities/buildDisabledFieldRegex.spec.js +0 -64
- package/dist/utilities/buildDisabledFieldRegex.spec.js.map +0 -1
- package/dist/utilities/fieldToRegex.spec.js +0 -151
- package/dist/utilities/fieldToRegex.spec.js.map +0 -1
- package/dist/utilities/filterToSelectedFields.spec.js +0 -204
- package/dist/utilities/filterToSelectedFields.spec.js.map +0 -1
- package/dist/utilities/flattenObject.spec.js +0 -158
- package/dist/utilities/flattenObject.spec.js.map +0 -1
- package/dist/utilities/getExportFieldFunctions.spec.js +0 -50
- package/dist/utilities/getExportFieldFunctions.spec.js.map +0 -1
- package/dist/utilities/getImportFieldFunctions.spec.js +0 -167
- package/dist/utilities/getImportFieldFunctions.spec.js.map +0 -1
- package/dist/utilities/getSchemaColumns.spec.js +0 -157
- package/dist/utilities/getSchemaColumns.spec.js.map +0 -1
- package/dist/utilities/parseCSV.spec.js +0 -195
- package/dist/utilities/parseCSV.spec.js.map +0 -1
- package/dist/utilities/processRichTextField.spec.js +0 -308
- package/dist/utilities/processRichTextField.spec.js.map +0 -1
- package/dist/utilities/siblingDoc.spec.js +0 -278
- package/dist/utilities/siblingDoc.spec.js.map +0 -1
- package/dist/utilities/unflattenObject.spec.js +0 -819
- package/dist/utilities/unflattenObject.spec.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/flattenObject.spec.ts"],"sourcesContent":["import { PayloadRequest } from 'payload'\n\nimport type { ExportFieldHookEntry } from '../types.js'\n\nimport { describe, expect, it, vi } from 'vitest'\n\nimport { flattenObject } from './flattenObject.js'\n\nconst mockReq = {\n payload: {\n logger: {\n error: vi.fn(),\n },\n },\n} as unknown as PayloadRequest\n\ndescribe('flattenObject parent + child traversal', () => {\n it('should run a parent group hook and still apply child field hooks against the transformed value', () => {\n const exportFieldHooks: Record<string, ExportFieldHookEntry> = {\n meta: {\n type: 'beforeExport',\n fn: ({ value }) => {\n const obj = (value ?? {}) as Record<string, unknown>\n return { ...obj, slug: `${obj.slug ?? ''}-from-parent` }\n },\n },\n meta_slug: {\n type: 'beforeExport',\n fn: ({ value }) => `${value}-from-child`,\n },\n }\n\n const row = flattenObject({\n data: { meta: { slug: 'raw' } },\n exportFieldHooks,\n format: 'csv',\n req: mockReq,\n })\n\n expect(row.meta_slug).toBe('raw-from-parent-from-child')\n })\n\n it('should still recurse into children when the parent group hook returns undefined', () => {\n const childCalls: unknown[] = []\n const exportFieldHooks: Record<string, ExportFieldHookEntry> = {\n meta: {\n type: 'beforeExport',\n fn: () => undefined,\n },\n meta_slug: {\n type: 'beforeExport',\n fn: ({ value }) => {\n childCalls.push(value)\n return `${value}-from-child`\n },\n },\n }\n\n const row = flattenObject({\n data: { meta: { slug: 'raw' } },\n exportFieldHooks,\n format: 'csv',\n req: mockReq,\n })\n\n expect(childCalls).toEqual(['raw'])\n expect(row.meta_slug).toBe('raw-from-child')\n })\n\n it('should not recurse into children when the parent hook returns a primitive', () => {\n const childFn = vi.fn(({ value }: { value: unknown }) => `${value}-from-child`)\n const exportFieldHooks: Record<string, ExportFieldHookEntry> = {\n meta: {\n type: 'beforeExport',\n fn: () => 'serialized',\n },\n meta_slug: {\n type: 'beforeExport',\n fn: childFn,\n },\n }\n\n const row = flattenObject({\n data: { meta: { slug: 'raw' } },\n exportFieldHooks,\n format: 'csv',\n req: mockReq,\n })\n\n expect(row.meta).toBe('serialized')\n expect(row.meta_slug).toBeUndefined()\n expect(childFn).not.toHaveBeenCalled()\n })\n\n it('should fall back to default array flattening when an undefined-returning hook did not write any keys, even if a sibling key with a matching prefix exists', () => {\n const exportFieldHooks: Record<string, ExportFieldHookEntry> = {\n tag: {\n type: 'beforeExport',\n fn: () => undefined,\n },\n }\n\n const row = flattenObject({\n data: { tag_meta: 'sibling-set-first', tag: ['a', 'b'] },\n exportFieldHooks,\n format: 'csv',\n req: mockReq,\n })\n\n expect(row.tag_meta).toBe('sibling-set-first')\n expect(row.tag_0).toBe('a')\n expect(row.tag_1).toBe('b')\n })\n\n it('should run a parent array hook then child hooks for each item', () => {\n const exportFieldHooks: Record<string, ExportFieldHookEntry> = {\n items: {\n type: 'beforeExport',\n fn: ({ value }) => {\n if (!Array.isArray(value)) {\n return value\n }\n return value.map((item) => ({\n ...(item as Record<string, unknown>),\n note: `${(item as Record<string, unknown>).note ?? ''}-parent`,\n }))\n },\n },\n items_note: {\n type: 'beforeExport',\n fn: ({ value }) => `${value}-child`,\n },\n }\n\n const row = flattenObject({\n data: { items: [{ note: 'a' }, { note: 'b' }] },\n exportFieldHooks,\n format: 'csv',\n req: mockReq,\n })\n\n expect(row.items_0_note).toBe('a-parent-child')\n expect(row.items_1_note).toBe('b-parent-child')\n })\n})\n"],"names":["describe","expect","it","vi","flattenObject","mockReq","payload","logger","error","fn","exportFieldHooks","meta","type","value","obj","slug","meta_slug","row","data","format","req","toBe","childCalls","undefined","push","toEqual","childFn","toBeUndefined","not","toHaveBeenCalled","tag","tag_meta","tag_0","tag_1","items","Array","isArray","map","item","note","items_note","items_0_note","items_1_note"],"mappings":"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"}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { getExportFieldFunctions } from './getExportFieldFunctions.js';
|
|
3
|
-
describe('getExportFieldFunctions registration', ()=>{
|
|
4
|
-
it('should not collide bare-key entries when two same-named fields with built-in handlers exist in different positions', ()=>{
|
|
5
|
-
const fields = [
|
|
6
|
-
{
|
|
7
|
-
name: 'groupA',
|
|
8
|
-
type: 'group',
|
|
9
|
-
flattenedFields: [
|
|
10
|
-
{
|
|
11
|
-
name: 'data',
|
|
12
|
-
type: 'json'
|
|
13
|
-
}
|
|
14
|
-
]
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
name: 'groupB',
|
|
18
|
-
type: 'group',
|
|
19
|
-
flattenedFields: [
|
|
20
|
-
{
|
|
21
|
-
name: 'data',
|
|
22
|
-
type: 'json'
|
|
23
|
-
}
|
|
24
|
-
]
|
|
25
|
-
}
|
|
26
|
-
];
|
|
27
|
-
const result = getExportFieldFunctions({
|
|
28
|
-
fields
|
|
29
|
-
});
|
|
30
|
-
// Both nested paths must be registered (not overwritten by collision)
|
|
31
|
-
expect(result['groupA_data']).toBeDefined();
|
|
32
|
-
expect(result['groupB_data']).toBeDefined();
|
|
33
|
-
// No bare-key fallback should exist for nested fields — that's the bug
|
|
34
|
-
expect(result['data']).toBeUndefined();
|
|
35
|
-
});
|
|
36
|
-
it('should still register a top-level field at its name', ()=>{
|
|
37
|
-
const fields = [
|
|
38
|
-
{
|
|
39
|
-
name: 'topLevelData',
|
|
40
|
-
type: 'json'
|
|
41
|
-
}
|
|
42
|
-
];
|
|
43
|
-
const result = getExportFieldFunctions({
|
|
44
|
-
fields
|
|
45
|
-
});
|
|
46
|
-
expect(result['topLevelData']).toBeDefined();
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
//# sourceMappingURL=getExportFieldFunctions.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/getExportFieldFunctions.spec.ts"],"sourcesContent":["import { FlattenedField } from 'payload'\n\nimport { describe, expect, it } from 'vitest'\n\nimport { getExportFieldFunctions } from './getExportFieldFunctions.js'\n\ndescribe('getExportFieldFunctions registration', () => {\n it('should not collide bare-key entries when two same-named fields with built-in handlers exist in different positions', () => {\n const fields: FlattenedField[] = [\n {\n name: 'groupA',\n type: 'group',\n flattenedFields: [{ name: 'data', type: 'json' } as FlattenedField],\n } as unknown as FlattenedField,\n {\n name: 'groupB',\n type: 'group',\n flattenedFields: [{ name: 'data', type: 'json' } as FlattenedField],\n } as unknown as FlattenedField,\n ]\n\n const result = getExportFieldFunctions({ fields })\n\n // Both nested paths must be registered (not overwritten by collision)\n expect(result['groupA_data']).toBeDefined()\n expect(result['groupB_data']).toBeDefined()\n\n // No bare-key fallback should exist for nested fields — that's the bug\n expect(result['data']).toBeUndefined()\n })\n\n it('should still register a top-level field at its name', () => {\n const fields: FlattenedField[] = [{ name: 'topLevelData', type: 'json' } as FlattenedField]\n\n const result = getExportFieldFunctions({ fields })\n\n expect(result['topLevelData']).toBeDefined()\n })\n})\n"],"names":["describe","expect","it","getExportFieldFunctions","fields","name","type","flattenedFields","result","toBeDefined","toBeUndefined"],"mappings":"AAEA,SAASA,QAAQ,EAAEC,MAAM,EAAEC,EAAE,QAAQ,SAAQ;AAE7C,SAASC,uBAAuB,QAAQ,+BAA8B;AAEtEH,SAAS,wCAAwC;IAC/CE,GAAG,sHAAsH;QACvH,MAAME,SAA2B;YAC/B;gBACEC,MAAM;gBACNC,MAAM;gBACNC,iBAAiB;oBAAC;wBAAEF,MAAM;wBAAQC,MAAM;oBAAO;iBAAoB;YACrE;YACA;gBACED,MAAM;gBACNC,MAAM;gBACNC,iBAAiB;oBAAC;wBAAEF,MAAM;wBAAQC,MAAM;oBAAO;iBAAoB;YACrE;SACD;QAED,MAAME,SAASL,wBAAwB;YAAEC;QAAO;QAEhD,sEAAsE;QACtEH,OAAOO,MAAM,CAAC,cAAc,EAAEC,WAAW;QACzCR,OAAOO,MAAM,CAAC,cAAc,EAAEC,WAAW;QAEzC,uEAAuE;QACvER,OAAOO,MAAM,CAAC,OAAO,EAAEE,aAAa;IACtC;IAEAR,GAAG,uDAAuD;QACxD,MAAME,SAA2B;YAAC;gBAAEC,MAAM;gBAAgBC,MAAM;YAAO;SAAoB;QAE3F,MAAME,SAASL,wBAAwB;YAAEC;QAAO;QAEhDH,OAAOO,MAAM,CAAC,eAAe,EAAEC,WAAW;IAC5C;AACF"}
|
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import { getImportFieldFunctions } from './getImportFieldFunctions.js';
|
|
3
|
-
const mockReq = {
|
|
4
|
-
payload: {
|
|
5
|
-
logger: {
|
|
6
|
-
error: vi.fn()
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
};
|
|
10
|
-
const callHook = (hooks, key, value)=>{
|
|
11
|
-
const entry = hooks[key];
|
|
12
|
-
if (!entry || entry.type !== 'beforeImport') {
|
|
13
|
-
throw new Error(`Expected beforeImport hook for ${key}`);
|
|
14
|
-
}
|
|
15
|
-
return entry.fn({
|
|
16
|
-
columnName: key,
|
|
17
|
-
data: {},
|
|
18
|
-
format: 'csv',
|
|
19
|
-
operation: 'create',
|
|
20
|
-
req: mockReq,
|
|
21
|
-
siblingData: {},
|
|
22
|
-
siblingDoc: {},
|
|
23
|
-
value
|
|
24
|
-
});
|
|
25
|
-
};
|
|
26
|
-
describe('getImportFieldFunctions empty-cell guards', ()=>{
|
|
27
|
-
describe('checkbox', ()=>{
|
|
28
|
-
const fields = [
|
|
29
|
-
{
|
|
30
|
-
name: 'flag',
|
|
31
|
-
type: 'checkbox'
|
|
32
|
-
}
|
|
33
|
-
];
|
|
34
|
-
it('should return undefined for empty string instead of false', ()=>{
|
|
35
|
-
const hooks = getImportFieldFunctions({
|
|
36
|
-
fields
|
|
37
|
-
});
|
|
38
|
-
expect(callHook(hooks, 'flag', '')).toBeUndefined();
|
|
39
|
-
});
|
|
40
|
-
it('should return undefined for null', ()=>{
|
|
41
|
-
const hooks = getImportFieldFunctions({
|
|
42
|
-
fields
|
|
43
|
-
});
|
|
44
|
-
expect(callHook(hooks, 'flag', null)).toBeUndefined();
|
|
45
|
-
});
|
|
46
|
-
it('should return undefined for undefined', ()=>{
|
|
47
|
-
const hooks = getImportFieldFunctions({
|
|
48
|
-
fields
|
|
49
|
-
});
|
|
50
|
-
expect(callHook(hooks, 'flag', undefined)).toBeUndefined();
|
|
51
|
-
});
|
|
52
|
-
it('should still parse "true" as true', ()=>{
|
|
53
|
-
const hooks = getImportFieldFunctions({
|
|
54
|
-
fields
|
|
55
|
-
});
|
|
56
|
-
expect(callHook(hooks, 'flag', 'true')).toBe(true);
|
|
57
|
-
});
|
|
58
|
-
it('should still parse "false" as false', ()=>{
|
|
59
|
-
const hooks = getImportFieldFunctions({
|
|
60
|
-
fields
|
|
61
|
-
});
|
|
62
|
-
expect(callHook(hooks, 'flag', 'false')).toBe(false);
|
|
63
|
-
});
|
|
64
|
-
it('should still pass through real booleans', ()=>{
|
|
65
|
-
const hooks = getImportFieldFunctions({
|
|
66
|
-
fields
|
|
67
|
-
});
|
|
68
|
-
expect(callHook(hooks, 'flag', true)).toBe(true);
|
|
69
|
-
expect(callHook(hooks, 'flag', false)).toBe(false);
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
describe('number (without hasMany)', ()=>{
|
|
73
|
-
const fields = [
|
|
74
|
-
{
|
|
75
|
-
name: 'count',
|
|
76
|
-
type: 'number'
|
|
77
|
-
}
|
|
78
|
-
];
|
|
79
|
-
it('should return undefined for empty string instead of 0', ()=>{
|
|
80
|
-
const hooks = getImportFieldFunctions({
|
|
81
|
-
fields
|
|
82
|
-
});
|
|
83
|
-
expect(callHook(hooks, 'count', '')).toBeUndefined();
|
|
84
|
-
});
|
|
85
|
-
it('should return undefined for null', ()=>{
|
|
86
|
-
const hooks = getImportFieldFunctions({
|
|
87
|
-
fields
|
|
88
|
-
});
|
|
89
|
-
expect(callHook(hooks, 'count', null)).toBeUndefined();
|
|
90
|
-
});
|
|
91
|
-
it('should return undefined for undefined', ()=>{
|
|
92
|
-
const hooks = getImportFieldFunctions({
|
|
93
|
-
fields
|
|
94
|
-
});
|
|
95
|
-
expect(callHook(hooks, 'count', undefined)).toBeUndefined();
|
|
96
|
-
});
|
|
97
|
-
it('should still parse a numeric string', ()=>{
|
|
98
|
-
const hooks = getImportFieldFunctions({
|
|
99
|
-
fields
|
|
100
|
-
});
|
|
101
|
-
expect(callHook(hooks, 'count', '42')).toBe(42);
|
|
102
|
-
});
|
|
103
|
-
it('should still pass through a real number', ()=>{
|
|
104
|
-
const hooks = getImportFieldFunctions({
|
|
105
|
-
fields
|
|
106
|
-
});
|
|
107
|
-
expect(callHook(hooks, 'count', 7)).toBe(7);
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
describe('date', ()=>{
|
|
111
|
-
const fields = [
|
|
112
|
-
{
|
|
113
|
-
name: 'when',
|
|
114
|
-
type: 'date'
|
|
115
|
-
}
|
|
116
|
-
];
|
|
117
|
-
it('should return undefined for empty string', ()=>{
|
|
118
|
-
const hooks = getImportFieldFunctions({
|
|
119
|
-
fields
|
|
120
|
-
});
|
|
121
|
-
expect(callHook(hooks, 'when', '')).toBeUndefined();
|
|
122
|
-
});
|
|
123
|
-
it('should return undefined for null', ()=>{
|
|
124
|
-
const hooks = getImportFieldFunctions({
|
|
125
|
-
fields
|
|
126
|
-
});
|
|
127
|
-
expect(callHook(hooks, 'when', null)).toBeUndefined();
|
|
128
|
-
});
|
|
129
|
-
it('should still parse a valid ISO date', ()=>{
|
|
130
|
-
const hooks = getImportFieldFunctions({
|
|
131
|
-
fields
|
|
132
|
-
});
|
|
133
|
-
const iso = '2026-05-06T00:00:00.000Z';
|
|
134
|
-
expect(callHook(hooks, 'when', iso)).toBe(iso);
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
describe('json', ()=>{
|
|
138
|
-
const fields = [
|
|
139
|
-
{
|
|
140
|
-
name: 'meta',
|
|
141
|
-
type: 'json'
|
|
142
|
-
}
|
|
143
|
-
];
|
|
144
|
-
it('should return undefined for empty string', ()=>{
|
|
145
|
-
const hooks = getImportFieldFunctions({
|
|
146
|
-
fields
|
|
147
|
-
});
|
|
148
|
-
expect(callHook(hooks, 'meta', '')).toBeUndefined();
|
|
149
|
-
});
|
|
150
|
-
it('should return undefined for null', ()=>{
|
|
151
|
-
const hooks = getImportFieldFunctions({
|
|
152
|
-
fields
|
|
153
|
-
});
|
|
154
|
-
expect(callHook(hooks, 'meta', null)).toBeUndefined();
|
|
155
|
-
});
|
|
156
|
-
it('should still parse a valid JSON string', ()=>{
|
|
157
|
-
const hooks = getImportFieldFunctions({
|
|
158
|
-
fields
|
|
159
|
-
});
|
|
160
|
-
expect(callHook(hooks, 'meta', '{"a":1}')).toEqual({
|
|
161
|
-
a: 1
|
|
162
|
-
});
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
//# sourceMappingURL=getImportFieldFunctions.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/getImportFieldFunctions.spec.ts"],"sourcesContent":["import { FlattenedField, PayloadRequest } from 'payload'\n\nimport { describe, expect, it, vi } from 'vitest'\n\nimport { getImportFieldFunctions } from './getImportFieldFunctions.js'\n\nconst mockReq = {\n payload: {\n logger: {\n error: vi.fn(),\n },\n },\n} as unknown as PayloadRequest\n\nconst callHook = (\n hooks: ReturnType<typeof getImportFieldFunctions>,\n key: string,\n value: unknown,\n) => {\n const entry = hooks[key]\n if (!entry || entry.type !== 'beforeImport') {\n throw new Error(`Expected beforeImport hook for ${key}`)\n }\n return entry.fn({\n columnName: key,\n data: {},\n format: 'csv',\n operation: 'create',\n req: mockReq,\n siblingData: {},\n siblingDoc: {},\n value,\n })\n}\n\ndescribe('getImportFieldFunctions empty-cell guards', () => {\n describe('checkbox', () => {\n const fields: FlattenedField[] = [{ name: 'flag', type: 'checkbox' } as FlattenedField]\n\n it('should return undefined for empty string instead of false', () => {\n const hooks = getImportFieldFunctions({ fields })\n expect(callHook(hooks, 'flag', '')).toBeUndefined()\n })\n\n it('should return undefined for null', () => {\n const hooks = getImportFieldFunctions({ fields })\n expect(callHook(hooks, 'flag', null)).toBeUndefined()\n })\n\n it('should return undefined for undefined', () => {\n const hooks = getImportFieldFunctions({ fields })\n expect(callHook(hooks, 'flag', undefined)).toBeUndefined()\n })\n\n it('should still parse \"true\" as true', () => {\n const hooks = getImportFieldFunctions({ fields })\n expect(callHook(hooks, 'flag', 'true')).toBe(true)\n })\n\n it('should still parse \"false\" as false', () => {\n const hooks = getImportFieldFunctions({ fields })\n expect(callHook(hooks, 'flag', 'false')).toBe(false)\n })\n\n it('should still pass through real booleans', () => {\n const hooks = getImportFieldFunctions({ fields })\n expect(callHook(hooks, 'flag', true)).toBe(true)\n expect(callHook(hooks, 'flag', false)).toBe(false)\n })\n })\n\n describe('number (without hasMany)', () => {\n const fields: FlattenedField[] = [{ name: 'count', type: 'number' } as FlattenedField]\n\n it('should return undefined for empty string instead of 0', () => {\n const hooks = getImportFieldFunctions({ fields })\n expect(callHook(hooks, 'count', '')).toBeUndefined()\n })\n\n it('should return undefined for null', () => {\n const hooks = getImportFieldFunctions({ fields })\n expect(callHook(hooks, 'count', null)).toBeUndefined()\n })\n\n it('should return undefined for undefined', () => {\n const hooks = getImportFieldFunctions({ fields })\n expect(callHook(hooks, 'count', undefined)).toBeUndefined()\n })\n\n it('should still parse a numeric string', () => {\n const hooks = getImportFieldFunctions({ fields })\n expect(callHook(hooks, 'count', '42')).toBe(42)\n })\n\n it('should still pass through a real number', () => {\n const hooks = getImportFieldFunctions({ fields })\n expect(callHook(hooks, 'count', 7)).toBe(7)\n })\n })\n\n describe('date', () => {\n const fields: FlattenedField[] = [{ name: 'when', type: 'date' } as FlattenedField]\n\n it('should return undefined for empty string', () => {\n const hooks = getImportFieldFunctions({ fields })\n expect(callHook(hooks, 'when', '')).toBeUndefined()\n })\n\n it('should return undefined for null', () => {\n const hooks = getImportFieldFunctions({ fields })\n expect(callHook(hooks, 'when', null)).toBeUndefined()\n })\n\n it('should still parse a valid ISO date', () => {\n const hooks = getImportFieldFunctions({ fields })\n const iso = '2026-05-06T00:00:00.000Z'\n expect(callHook(hooks, 'when', iso)).toBe(iso)\n })\n })\n\n describe('json', () => {\n const fields: FlattenedField[] = [{ name: 'meta', type: 'json' } as FlattenedField]\n\n it('should return undefined for empty string', () => {\n const hooks = getImportFieldFunctions({ fields })\n expect(callHook(hooks, 'meta', '')).toBeUndefined()\n })\n\n it('should return undefined for null', () => {\n const hooks = getImportFieldFunctions({ fields })\n expect(callHook(hooks, 'meta', null)).toBeUndefined()\n })\n\n it('should still parse a valid JSON string', () => {\n const hooks = getImportFieldFunctions({ fields })\n expect(callHook(hooks, 'meta', '{\"a\":1}')).toEqual({ a: 1 })\n })\n })\n})\n"],"names":["describe","expect","it","vi","getImportFieldFunctions","mockReq","payload","logger","error","fn","callHook","hooks","key","value","entry","type","Error","columnName","data","format","operation","req","siblingData","siblingDoc","fields","name","toBeUndefined","undefined","toBe","iso","toEqual","a"],"mappings":"AAEA,SAASA,QAAQ,EAAEC,MAAM,EAAEC,EAAE,EAAEC,EAAE,QAAQ,SAAQ;AAEjD,SAASC,uBAAuB,QAAQ,+BAA8B;AAEtE,MAAMC,UAAU;IACdC,SAAS;QACPC,QAAQ;YACNC,OAAOL,GAAGM,EAAE;QACd;IACF;AACF;AAEA,MAAMC,WAAW,CACfC,OACAC,KACAC;IAEA,MAAMC,QAAQH,KAAK,CAACC,IAAI;IACxB,IAAI,CAACE,SAASA,MAAMC,IAAI,KAAK,gBAAgB;QAC3C,MAAM,IAAIC,MAAM,CAAC,+BAA+B,EAAEJ,KAAK;IACzD;IACA,OAAOE,MAAML,EAAE,CAAC;QACdQ,YAAYL;QACZM,MAAM,CAAC;QACPC,QAAQ;QACRC,WAAW;QACXC,KAAKhB;QACLiB,aAAa,CAAC;QACdC,YAAY,CAAC;QACbV;IACF;AACF;AAEAb,SAAS,6CAA6C;IACpDA,SAAS,YAAY;QACnB,MAAMwB,SAA2B;YAAC;gBAAEC,MAAM;gBAAQV,MAAM;YAAW;SAAoB;QAEvFb,GAAG,6DAA6D;YAC9D,MAAMS,QAAQP,wBAAwB;gBAAEoB;YAAO;YAC/CvB,OAAOS,SAASC,OAAO,QAAQ,KAAKe,aAAa;QACnD;QAEAxB,GAAG,oCAAoC;YACrC,MAAMS,QAAQP,wBAAwB;gBAAEoB;YAAO;YAC/CvB,OAAOS,SAASC,OAAO,QAAQ,OAAOe,aAAa;QACrD;QAEAxB,GAAG,yCAAyC;YAC1C,MAAMS,QAAQP,wBAAwB;gBAAEoB;YAAO;YAC/CvB,OAAOS,SAASC,OAAO,QAAQgB,YAAYD,aAAa;QAC1D;QAEAxB,GAAG,qCAAqC;YACtC,MAAMS,QAAQP,wBAAwB;gBAAEoB;YAAO;YAC/CvB,OAAOS,SAASC,OAAO,QAAQ,SAASiB,IAAI,CAAC;QAC/C;QAEA1B,GAAG,uCAAuC;YACxC,MAAMS,QAAQP,wBAAwB;gBAAEoB;YAAO;YAC/CvB,OAAOS,SAASC,OAAO,QAAQ,UAAUiB,IAAI,CAAC;QAChD;QAEA1B,GAAG,2CAA2C;YAC5C,MAAMS,QAAQP,wBAAwB;gBAAEoB;YAAO;YAC/CvB,OAAOS,SAASC,OAAO,QAAQ,OAAOiB,IAAI,CAAC;YAC3C3B,OAAOS,SAASC,OAAO,QAAQ,QAAQiB,IAAI,CAAC;QAC9C;IACF;IAEA5B,SAAS,4BAA4B;QACnC,MAAMwB,SAA2B;YAAC;gBAAEC,MAAM;gBAASV,MAAM;YAAS;SAAoB;QAEtFb,GAAG,yDAAyD;YAC1D,MAAMS,QAAQP,wBAAwB;gBAAEoB;YAAO;YAC/CvB,OAAOS,SAASC,OAAO,SAAS,KAAKe,aAAa;QACpD;QAEAxB,GAAG,oCAAoC;YACrC,MAAMS,QAAQP,wBAAwB;gBAAEoB;YAAO;YAC/CvB,OAAOS,SAASC,OAAO,SAAS,OAAOe,aAAa;QACtD;QAEAxB,GAAG,yCAAyC;YAC1C,MAAMS,QAAQP,wBAAwB;gBAAEoB;YAAO;YAC/CvB,OAAOS,SAASC,OAAO,SAASgB,YAAYD,aAAa;QAC3D;QAEAxB,GAAG,uCAAuC;YACxC,MAAMS,QAAQP,wBAAwB;gBAAEoB;YAAO;YAC/CvB,OAAOS,SAASC,OAAO,SAAS,OAAOiB,IAAI,CAAC;QAC9C;QAEA1B,GAAG,2CAA2C;YAC5C,MAAMS,QAAQP,wBAAwB;gBAAEoB;YAAO;YAC/CvB,OAAOS,SAASC,OAAO,SAAS,IAAIiB,IAAI,CAAC;QAC3C;IACF;IAEA5B,SAAS,QAAQ;QACf,MAAMwB,SAA2B;YAAC;gBAAEC,MAAM;gBAAQV,MAAM;YAAO;SAAoB;QAEnFb,GAAG,4CAA4C;YAC7C,MAAMS,QAAQP,wBAAwB;gBAAEoB;YAAO;YAC/CvB,OAAOS,SAASC,OAAO,QAAQ,KAAKe,aAAa;QACnD;QAEAxB,GAAG,oCAAoC;YACrC,MAAMS,QAAQP,wBAAwB;gBAAEoB;YAAO;YAC/CvB,OAAOS,SAASC,OAAO,QAAQ,OAAOe,aAAa;QACrD;QAEAxB,GAAG,uCAAuC;YACxC,MAAMS,QAAQP,wBAAwB;gBAAEoB;YAAO;YAC/C,MAAMK,MAAM;YACZ5B,OAAOS,SAASC,OAAO,QAAQkB,MAAMD,IAAI,CAACC;QAC5C;IACF;IAEA7B,SAAS,QAAQ;QACf,MAAMwB,SAA2B;YAAC;gBAAEC,MAAM;gBAAQV,MAAM;YAAO;SAAoB;QAEnFb,GAAG,4CAA4C;YAC7C,MAAMS,QAAQP,wBAAwB;gBAAEoB;YAAO;YAC/CvB,OAAOS,SAASC,OAAO,QAAQ,KAAKe,aAAa;QACnD;QAEAxB,GAAG,oCAAoC;YACrC,MAAMS,QAAQP,wBAAwB;gBAAEoB;YAAO;YAC/CvB,OAAOS,SAASC,OAAO,QAAQ,OAAOe,aAAa;QACrD;QAEAxB,GAAG,0CAA0C;YAC3C,MAAMS,QAAQP,wBAAwB;gBAAEoB;YAAO;YAC/CvB,OAAOS,SAASC,OAAO,QAAQ,YAAYmB,OAAO,CAAC;gBAAEC,GAAG;YAAE;QAC5D;IACF;AACF"}
|
|
@@ -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,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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"}
|