@payloadcms/plugin-import-export 3.91.0-internal.c1569dc → 4.0.0-beta.1
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/README.md +2 -2
- 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 +52 -0
- package/dist/components/ExportPreview/index.d.ts +1 -1
- package/dist/components/ExportPreview/index.d.ts.map +1 -1
- package/dist/components/ExportPreview/index.js +12 -2
- 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 +6 -3
- 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 +45 -0
- package/dist/components/ImportPreview/index.d.ts +1 -1
- package/dist/components/ImportPreview/index.d.ts.map +1 -1
- package/dist/components/ImportPreview/index.js +44 -11
- 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 +4 -3
- package/dist/components/Page/index.d.ts.map +1 -1
- package/dist/components/Page/index.js +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.css +9 -0
- package/dist/components/SortBy/index.d.ts +4 -3
- package/dist/components/SortBy/index.d.ts.map +1 -1
- package/dist/components/SortBy/index.js +1 -2
- package/dist/components/SortBy/index.js.map +1 -1
- package/dist/components/SortOrder/index.css +9 -0
- package/dist/components/SortOrder/index.d.ts +4 -3
- package/dist/components/SortOrder/index.d.ts.map +1 -1
- package/dist/components/SortOrder/index.js +1 -2
- package/dist/components/SortOrder/index.js.map +1 -1
- package/dist/export/batchProcessor.d.ts +4 -3
- 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 +4 -2
- package/dist/export/createExport.d.ts.map +1 -1
- package/dist/export/createExport.js +7 -2
- 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 +9 -4
- 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 +4 -3
- 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 +9 -2
- 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 +6 -4
- 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/index.d.ts +2 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -8
- package/dist/index.js.map +1 -1
- package/dist/translations/languages/en.d.ts.map +1 -1
- package/dist/types.d.ts +17 -33
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utilities/applyFieldHooks.d.ts +1 -2
- package/dist/utilities/applyFieldHooks.d.ts.map +1 -1
- package/dist/utilities/applyFieldHooks.js +2 -3
- package/dist/utilities/applyFieldHooks.js.map +1 -1
- package/dist/utilities/flattenObject.d.ts.map +1 -1
- package/dist/utilities/flattenObject.js +3 -13
- package/dist/utilities/flattenObject.js.map +1 -1
- package/dist/utilities/flattenedFields.d.ts.map +1 -1
- package/dist/utilities/flattenedFields.js +3 -0
- package/dist/utilities/flattenedFields.js.map +1 -1
- package/dist/utilities/getExportFieldFunctions.js +64 -35
- 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/getImportFieldFunctions.js +0 -8
- package/dist/utilities/getImportFieldFunctions.js.map +1 -1
- package/dist/utilities/getSchemaColumns.d.ts +1 -1
- package/dist/utilities/getSchemaColumns.js +2 -2
- package/dist/utilities/getSchemaColumns.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/sortHelpers.d.ts +1 -1
- package/dist/utilities/unflattenObject.d.ts.map +1 -1
- package/dist/utilities/unflattenObject.js +8 -16
- package/dist/utilities/unflattenObject.js.map +1 -1
- package/license.md +1 -1
- package/package.json +9 -9
- package/dist/components/ExportPreview/index.scss +0 -48
- package/dist/components/FieldsToExport/index.scss +0 -0
- package/dist/components/FieldsToExport/reduceFields.spec.js +0 -239
- package/dist/components/FieldsToExport/reduceFields.spec.js.map +0 -1
- package/dist/components/ImportPreview/index.scss +0 -41
- package/dist/components/SortBy/index.scss +0 -3
- package/dist/components/SortOrder/index.scss +0 -3
- 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/getSelect.spec.js +0 -57
- package/dist/utilities/getSelect.spec.js.map +0 -1
- package/dist/utilities/legacyHookDispatch.spec.js +0 -227
- package/dist/utilities/legacyHookDispatch.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/setNestedValue.spec.js +0 -214
- package/dist/utilities/setNestedValue.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
- /package/dist/components/Page/{index.scss → index.css} +0 -0
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
import { APIError } from 'payload';
|
|
2
|
-
import { describe, expect, it } from 'vitest';
|
|
3
|
-
import { setNestedValue } from './setNestedValue.js';
|
|
4
|
-
const unsupportedSegments = [
|
|
5
|
-
'__proto__'
|
|
6
|
-
];
|
|
7
|
-
const unsupportedPaths = unsupportedSegments.flatMap((segment)=>[
|
|
8
|
-
`${segment}.value`,
|
|
9
|
-
`group.${segment}.value`,
|
|
10
|
-
`group.${segment}`,
|
|
11
|
-
`items.${segment}.0.value`,
|
|
12
|
-
`items.0.${segment}.value`,
|
|
13
|
-
`items.0.${segment}`
|
|
14
|
-
]);
|
|
15
|
-
describe('setNestedValue', ()=>{
|
|
16
|
-
it.each(unsupportedPaths)('rejects invalid field path %s without changing the target', (path)=>{
|
|
17
|
-
const target = {
|
|
18
|
-
stable: {
|
|
19
|
-
value: true
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
const objectPrototypeBefore = Object.getOwnPropertyDescriptors(Object.prototype);
|
|
23
|
-
const targetPrototypeBefore = Object.getPrototypeOf(target);
|
|
24
|
-
try {
|
|
25
|
-
setNestedValue(target, path, true);
|
|
26
|
-
expect.fail('Expected setNestedValue to reject the invalid field path');
|
|
27
|
-
} catch (error) {
|
|
28
|
-
expect(error).toBeInstanceOf(APIError);
|
|
29
|
-
if (error instanceof APIError) {
|
|
30
|
-
expect(error.status).toBe(400);
|
|
31
|
-
expect(error.isPublic).toBe(true);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
expect(target).toEqual({
|
|
35
|
-
stable: {
|
|
36
|
-
value: true
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
expect(Object.getPrototypeOf(target)).toBe(targetPrototypeBefore);
|
|
40
|
-
expect(Object.getOwnPropertyDescriptors(Object.prototype)).toEqual(objectPrototypeBefore);
|
|
41
|
-
});
|
|
42
|
-
it('should build nested values from owned data', ()=>{
|
|
43
|
-
const inheritedContainer = 'constrainedNestedContainer';
|
|
44
|
-
const target = {};
|
|
45
|
-
const source = {};
|
|
46
|
-
const objectPrototypeBefore = Object.getOwnPropertyDescriptors(Object.prototype);
|
|
47
|
-
const originalContainerDescriptor = Object.getOwnPropertyDescriptor(Object.prototype, inheritedContainer);
|
|
48
|
-
let inheritedGetterCalls = 0;
|
|
49
|
-
let inheritedSetterCalls = 0;
|
|
50
|
-
try {
|
|
51
|
-
Object.defineProperty(Object.prototype, inheritedContainer, {
|
|
52
|
-
configurable: true,
|
|
53
|
-
get: ()=>{
|
|
54
|
-
inheritedGetterCalls += 1;
|
|
55
|
-
return {
|
|
56
|
-
value: 'inherited'
|
|
57
|
-
};
|
|
58
|
-
},
|
|
59
|
-
set: ()=>{
|
|
60
|
-
inheritedSetterCalls += 1;
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
setNestedValue(target, 'constructor.prototype.value', 'example');
|
|
64
|
-
setNestedValue(target, 'prototype.value', 'example');
|
|
65
|
-
setNestedValue(target, `${inheritedContainer}.value`, 'local', source);
|
|
66
|
-
} finally{
|
|
67
|
-
if (originalContainerDescriptor) {
|
|
68
|
-
Object.defineProperty(Object.prototype, inheritedContainer, originalContainerDescriptor);
|
|
69
|
-
} else {
|
|
70
|
-
delete Object.prototype[inheritedContainer];
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
expect(inheritedGetterCalls).toBe(0);
|
|
74
|
-
expect(inheritedSetterCalls).toBe(0);
|
|
75
|
-
expect(Object.hasOwn(target, 'constructor')).toBe(true);
|
|
76
|
-
expect(Object.hasOwn(target, 'prototype')).toBe(true);
|
|
77
|
-
expect(target).toEqual({
|
|
78
|
-
[inheritedContainer]: {
|
|
79
|
-
value: 'local'
|
|
80
|
-
},
|
|
81
|
-
constructor: {
|
|
82
|
-
prototype: {
|
|
83
|
-
value: 'example'
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
prototype: {
|
|
87
|
-
value: 'example'
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
expect(Object.getPrototypeOf(target.constructor)).toBeNull();
|
|
91
|
-
expect(Object.getPrototypeOf(target.prototype)).toBeNull();
|
|
92
|
-
expect(Object.getOwnPropertyDescriptors(Object.prototype)).toEqual(objectPrototypeBefore);
|
|
93
|
-
});
|
|
94
|
-
it('rejects field paths with out-of-range array indexes', ()=>{
|
|
95
|
-
const source = {
|
|
96
|
-
items: [
|
|
97
|
-
{
|
|
98
|
-
value: true
|
|
99
|
-
}
|
|
100
|
-
]
|
|
101
|
-
};
|
|
102
|
-
const target = {};
|
|
103
|
-
expect(()=>setNestedValue(target, 'items.4294967294.value', true, source)).toThrow(APIError);
|
|
104
|
-
expect(target).toEqual({
|
|
105
|
-
items: []
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
it('supports out-of-order array indexes that exist in the source document', ()=>{
|
|
109
|
-
const source = {
|
|
110
|
-
items: [
|
|
111
|
-
{
|
|
112
|
-
value: 'first'
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
value: 'second'
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
value: 'third'
|
|
119
|
-
}
|
|
120
|
-
]
|
|
121
|
-
};
|
|
122
|
-
const target = {};
|
|
123
|
-
setNestedValue(target, 'items.2.value', 'third', source);
|
|
124
|
-
expect(target).toEqual({
|
|
125
|
-
items: [
|
|
126
|
-
undefined,
|
|
127
|
-
undefined,
|
|
128
|
-
{
|
|
129
|
-
value: 'third'
|
|
130
|
-
}
|
|
131
|
-
]
|
|
132
|
-
});
|
|
133
|
-
});
|
|
134
|
-
it.each([
|
|
135
|
-
'-1',
|
|
136
|
-
'+1',
|
|
137
|
-
'01',
|
|
138
|
-
' 1',
|
|
139
|
-
'1 ',
|
|
140
|
-
'1e2',
|
|
141
|
-
'0x10',
|
|
142
|
-
'Infinity',
|
|
143
|
-
'9007199254740992'
|
|
144
|
-
])('treats noncanonical numeric segment %s as an object key', (segment)=>{
|
|
145
|
-
const target = {};
|
|
146
|
-
setNestedValue(target, `items.${segment}.value`, 'example');
|
|
147
|
-
expect(Array.isArray(target.items)).toBe(false);
|
|
148
|
-
expect(target).toEqual({
|
|
149
|
-
items: {
|
|
150
|
-
[segment]: {
|
|
151
|
-
value: 'example'
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
});
|
|
155
|
-
});
|
|
156
|
-
it('builds nested objects and arrays', ()=>{
|
|
157
|
-
const target = {};
|
|
158
|
-
setNestedValue(target, 'group.items.0.title', 'first');
|
|
159
|
-
setNestedValue(target, 'group.items.0.description', 'description');
|
|
160
|
-
setNestedValue(target, 'group.items.1.title', 'second');
|
|
161
|
-
expect(target).toEqual({
|
|
162
|
-
group: {
|
|
163
|
-
items: [
|
|
164
|
-
{
|
|
165
|
-
description: 'description',
|
|
166
|
-
title: 'first'
|
|
167
|
-
},
|
|
168
|
-
{
|
|
169
|
-
title: 'second'
|
|
170
|
-
}
|
|
171
|
-
]
|
|
172
|
-
}
|
|
173
|
-
});
|
|
174
|
-
const group = target.group;
|
|
175
|
-
const items = group.items;
|
|
176
|
-
expect(Object.getPrototypeOf(group)).toBeNull();
|
|
177
|
-
expect(Array.isArray(items)).toBe(true);
|
|
178
|
-
expect(Object.getPrototypeOf(items[0])).toBeNull();
|
|
179
|
-
expect(Object.getPrototypeOf(items[1])).toBeNull();
|
|
180
|
-
});
|
|
181
|
-
it('supports nested arrays using numeric lookahead', ()=>{
|
|
182
|
-
const target = {};
|
|
183
|
-
setNestedValue(target, 'matrix.0.1.value', 'nested');
|
|
184
|
-
expect(target).toEqual({
|
|
185
|
-
matrix: [
|
|
186
|
-
[
|
|
187
|
-
undefined,
|
|
188
|
-
{
|
|
189
|
-
value: 'nested'
|
|
190
|
-
}
|
|
191
|
-
]
|
|
192
|
-
]
|
|
193
|
-
});
|
|
194
|
-
});
|
|
195
|
-
it('creates own containers instead of traversing inherited properties', ()=>{
|
|
196
|
-
const inheritedGroup = {
|
|
197
|
-
inherited: true
|
|
198
|
-
};
|
|
199
|
-
const target = Object.create({
|
|
200
|
-
group: inheritedGroup
|
|
201
|
-
});
|
|
202
|
-
setNestedValue(target, 'group.value', 'own');
|
|
203
|
-
expect(Object.prototype.hasOwnProperty.call(target, 'group')).toBe(true);
|
|
204
|
-
expect(target.group).toEqual({
|
|
205
|
-
value: 'own'
|
|
206
|
-
});
|
|
207
|
-
expect(Object.getPrototypeOf(target.group)).toBeNull();
|
|
208
|
-
expect(inheritedGroup).toEqual({
|
|
209
|
-
inherited: true
|
|
210
|
-
});
|
|
211
|
-
});
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
//# sourceMappingURL=setNestedValue.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/setNestedValue.spec.ts"],"sourcesContent":["import { APIError } from 'payload'\nimport { describe, expect, it } from 'vitest'\n\nimport { setNestedValue } from './setNestedValue.js'\n\nconst unsupportedSegments = ['__proto__']\nconst unsupportedPaths = unsupportedSegments.flatMap((segment) => [\n `${segment}.value`,\n `group.${segment}.value`,\n `group.${segment}`,\n `items.${segment}.0.value`,\n `items.0.${segment}.value`,\n `items.0.${segment}`,\n])\n\ndescribe('setNestedValue', () => {\n it.each(unsupportedPaths)('rejects invalid field path %s without changing the target', (path) => {\n const target = { stable: { value: true } }\n const objectPrototypeBefore = Object.getOwnPropertyDescriptors(Object.prototype)\n const targetPrototypeBefore = Object.getPrototypeOf(target)\n\n try {\n setNestedValue(target, path, true)\n expect.fail('Expected setNestedValue 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 expect(target).toEqual({ stable: { value: true } })\n expect(Object.getPrototypeOf(target)).toBe(targetPrototypeBefore)\n expect(Object.getOwnPropertyDescriptors(Object.prototype)).toEqual(objectPrototypeBefore)\n })\n\n it('should build nested values from owned data', () => {\n const inheritedContainer = 'constrainedNestedContainer'\n const target: Record<string, unknown> = {}\n const source: Record<string, unknown> = {}\n const objectPrototypeBefore = Object.getOwnPropertyDescriptors(Object.prototype)\n const originalContainerDescriptor = Object.getOwnPropertyDescriptor(\n Object.prototype,\n inheritedContainer,\n )\n let inheritedGetterCalls = 0\n let inheritedSetterCalls = 0\n\n try {\n Object.defineProperty(Object.prototype, inheritedContainer, {\n configurable: true,\n get: () => {\n inheritedGetterCalls += 1\n return { value: 'inherited' }\n },\n set: () => {\n inheritedSetterCalls += 1\n },\n })\n\n setNestedValue(target, 'constructor.prototype.value', 'example')\n setNestedValue(target, 'prototype.value', 'example')\n setNestedValue(target, `${inheritedContainer}.value`, 'local', source)\n } finally {\n if (originalContainerDescriptor) {\n Object.defineProperty(Object.prototype, inheritedContainer, originalContainerDescriptor)\n } else {\n delete (Object.prototype as Record<string, unknown>)[inheritedContainer]\n }\n }\n\n expect(inheritedGetterCalls).toBe(0)\n expect(inheritedSetterCalls).toBe(0)\n expect(Object.hasOwn(target, 'constructor')).toBe(true)\n expect(Object.hasOwn(target, 'prototype')).toBe(true)\n expect(target).toEqual({\n [inheritedContainer]: {\n value: 'local',\n },\n constructor: {\n prototype: {\n value: 'example',\n },\n },\n prototype: {\n value: 'example',\n },\n })\n expect(Object.getPrototypeOf(target.constructor)).toBeNull()\n expect(Object.getPrototypeOf(target.prototype)).toBeNull()\n expect(Object.getOwnPropertyDescriptors(Object.prototype)).toEqual(objectPrototypeBefore)\n })\n\n it('rejects field paths with out-of-range array indexes', () => {\n const source = { items: [{ value: true }] }\n const target: Record<string, unknown> = {}\n\n expect(() => setNestedValue(target, 'items.4294967294.value', true, source)).toThrow(APIError)\n expect(target).toEqual({ items: [] })\n })\n\n it('supports out-of-order array indexes that exist in the source document', () => {\n const source = { items: [{ value: 'first' }, { value: 'second' }, { value: 'third' }] }\n const target: Record<string, unknown> = {}\n\n setNestedValue(target, 'items.2.value', 'third', source)\n\n expect(target).toEqual({ items: [undefined, undefined, { value: 'third' }] })\n })\n\n it.each(['-1', '+1', '01', ' 1', '1 ', '1e2', '0x10', 'Infinity', '9007199254740992'])(\n 'treats noncanonical numeric segment %s as an object key',\n (segment) => {\n const target: Record<string, unknown> = {}\n\n setNestedValue(target, `items.${segment}.value`, 'example')\n\n expect(Array.isArray(target.items)).toBe(false)\n expect(target).toEqual({ items: { [segment]: { value: 'example' } } })\n },\n )\n\n it('builds nested objects and arrays', () => {\n const target: Record<string, unknown> = {}\n\n setNestedValue(target, 'group.items.0.title', 'first')\n setNestedValue(target, 'group.items.0.description', 'description')\n setNestedValue(target, 'group.items.1.title', 'second')\n\n expect(target).toEqual({\n group: {\n items: [{ description: 'description', title: 'first' }, { title: 'second' }],\n },\n })\n\n const group = target.group as Record<string, unknown>\n const items = group.items as Record<string, unknown>[]\n\n expect(Object.getPrototypeOf(group)).toBeNull()\n expect(Array.isArray(items)).toBe(true)\n expect(Object.getPrototypeOf(items[0])).toBeNull()\n expect(Object.getPrototypeOf(items[1])).toBeNull()\n })\n\n it('supports nested arrays using numeric lookahead', () => {\n const target: Record<string, unknown> = {}\n\n setNestedValue(target, 'matrix.0.1.value', 'nested')\n\n expect(target).toEqual({\n matrix: [[undefined, { value: 'nested' }]],\n })\n })\n\n it('creates own containers instead of traversing inherited properties', () => {\n const inheritedGroup = { inherited: true }\n const target = Object.create({ group: inheritedGroup }) as Record<string, unknown>\n\n setNestedValue(target, 'group.value', 'own')\n\n expect(Object.prototype.hasOwnProperty.call(target, 'group')).toBe(true)\n expect(target.group).toEqual({ value: 'own' })\n expect(Object.getPrototypeOf(target.group)).toBeNull()\n expect(inheritedGroup).toEqual({ inherited: true })\n })\n})\n"],"names":["APIError","describe","expect","it","setNestedValue","unsupportedSegments","unsupportedPaths","flatMap","segment","each","path","target","stable","value","objectPrototypeBefore","Object","getOwnPropertyDescriptors","prototype","targetPrototypeBefore","getPrototypeOf","fail","error","toBeInstanceOf","status","toBe","isPublic","toEqual","inheritedContainer","source","originalContainerDescriptor","getOwnPropertyDescriptor","inheritedGetterCalls","inheritedSetterCalls","defineProperty","configurable","get","set","hasOwn","toBeNull","items","toThrow","undefined","Array","isArray","group","description","title","matrix","inheritedGroup","inherited","create","hasOwnProperty","call"],"mappings":"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"}
|
|
@@ -1,278 +0,0 @@
|
|
|
1
|
-
import { applyFieldHooks } from './applyFieldHooks.js';
|
|
2
|
-
import { flattenObject } from './flattenObject.js';
|
|
3
|
-
import { getExportFieldFunctions } from './getExportFieldFunctions.js';
|
|
4
|
-
import { getImportFieldFunctions } from './getImportFieldFunctions.js';
|
|
5
|
-
import { unflattenObject } from './unflattenObject.js';
|
|
6
|
-
import { describe, expect, it, vi } from 'vitest';
|
|
7
|
-
const mockReq = {
|
|
8
|
-
payload: {
|
|
9
|
-
logger: {
|
|
10
|
-
error: vi.fn()
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
describe('beforeExport / beforeImport siblingDoc arg', ()=>{
|
|
15
|
-
describe('CSV export (flattenObject)', ()=>{
|
|
16
|
-
it('passes the source doc at the current nesting level as siblingDoc', ()=>{
|
|
17
|
-
const received = [];
|
|
18
|
-
const fields = [
|
|
19
|
-
{
|
|
20
|
-
name: 'title',
|
|
21
|
-
type: 'text'
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
name: 'group',
|
|
25
|
-
type: 'group',
|
|
26
|
-
flattenedFields: [
|
|
27
|
-
{
|
|
28
|
-
name: 'inner',
|
|
29
|
-
type: 'text',
|
|
30
|
-
custom: {
|
|
31
|
-
'plugin-import-export': {
|
|
32
|
-
hooks: {
|
|
33
|
-
beforeExport: ({ columnName, siblingData, siblingDoc, value })=>{
|
|
34
|
-
received.push({
|
|
35
|
-
columnName,
|
|
36
|
-
isSiblingDocSource: siblingDoc && typeof siblingDoc === 'object' && siblingDoc.inner === value,
|
|
37
|
-
isSiblingDocRow: siblingDoc === siblingData
|
|
38
|
-
});
|
|
39
|
-
return value;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
]
|
|
46
|
-
}
|
|
47
|
-
];
|
|
48
|
-
const exportFieldHooks = getExportFieldFunctions({
|
|
49
|
-
fields
|
|
50
|
-
});
|
|
51
|
-
flattenObject({
|
|
52
|
-
data: {
|
|
53
|
-
group: {
|
|
54
|
-
inner: 'deep'
|
|
55
|
-
},
|
|
56
|
-
title: 'Top'
|
|
57
|
-
},
|
|
58
|
-
exportFieldHooks,
|
|
59
|
-
format: 'csv',
|
|
60
|
-
req: mockReq
|
|
61
|
-
});
|
|
62
|
-
expect(received).toEqual([
|
|
63
|
-
{
|
|
64
|
-
columnName: 'group_inner',
|
|
65
|
-
isSiblingDocSource: true,
|
|
66
|
-
isSiblingDocRow: false
|
|
67
|
-
}
|
|
68
|
-
]);
|
|
69
|
-
});
|
|
70
|
-
it('lets a hook read another sibling by reading siblingDoc', ()=>{
|
|
71
|
-
const fields = [
|
|
72
|
-
{
|
|
73
|
-
name: 'firstName',
|
|
74
|
-
type: 'text'
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
name: 'fullName',
|
|
78
|
-
type: 'text',
|
|
79
|
-
custom: {
|
|
80
|
-
'plugin-import-export': {
|
|
81
|
-
hooks: {
|
|
82
|
-
beforeExport: ({ siblingDoc, value })=>{
|
|
83
|
-
const last = siblingDoc.lastName;
|
|
84
|
-
const first = siblingDoc.firstName;
|
|
85
|
-
if (first && last) {
|
|
86
|
-
return `${first} ${last}`;
|
|
87
|
-
}
|
|
88
|
-
return value;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
name: 'lastName',
|
|
96
|
-
type: 'text'
|
|
97
|
-
}
|
|
98
|
-
];
|
|
99
|
-
const exportFieldHooks = getExportFieldFunctions({
|
|
100
|
-
fields
|
|
101
|
-
});
|
|
102
|
-
const result = flattenObject({
|
|
103
|
-
data: {
|
|
104
|
-
firstName: 'Ada',
|
|
105
|
-
fullName: '(computed)',
|
|
106
|
-
lastName: 'Lovelace'
|
|
107
|
-
},
|
|
108
|
-
exportFieldHooks,
|
|
109
|
-
format: 'csv',
|
|
110
|
-
req: mockReq
|
|
111
|
-
});
|
|
112
|
-
expect(result.fullName).toBe('Ada Lovelace');
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
describe('JSON export (applyFieldHooks)', ()=>{
|
|
116
|
-
it('passes the untouched source sibling as siblingDoc and the mutable output as siblingData', ()=>{
|
|
117
|
-
let capturedSiblingDoc = null;
|
|
118
|
-
let capturedSiblingData = null;
|
|
119
|
-
const fields = [
|
|
120
|
-
{
|
|
121
|
-
name: 'outer',
|
|
122
|
-
type: 'group',
|
|
123
|
-
flattenedFields: [
|
|
124
|
-
{
|
|
125
|
-
name: 'tracked',
|
|
126
|
-
type: 'text',
|
|
127
|
-
custom: {
|
|
128
|
-
'plugin-import-export': {
|
|
129
|
-
hooks: {
|
|
130
|
-
beforeExport: ({ siblingData, siblingDoc, value })=>{
|
|
131
|
-
capturedSiblingDoc = siblingDoc;
|
|
132
|
-
capturedSiblingData = siblingData;
|
|
133
|
-
siblingData.injected = 'written-into-output';
|
|
134
|
-
return String(value) + '_changed';
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
]
|
|
141
|
-
}
|
|
142
|
-
];
|
|
143
|
-
const exportFieldHooks = getExportFieldFunctions({
|
|
144
|
-
fields
|
|
145
|
-
});
|
|
146
|
-
const source = {
|
|
147
|
-
outer: {
|
|
148
|
-
tracked: 'original'
|
|
149
|
-
}
|
|
150
|
-
};
|
|
151
|
-
applyFieldHooks({
|
|
152
|
-
data: source,
|
|
153
|
-
fieldHooks: exportFieldHooks,
|
|
154
|
-
fields,
|
|
155
|
-
format: 'json',
|
|
156
|
-
operation: 'export',
|
|
157
|
-
req: mockReq,
|
|
158
|
-
type: 'beforeExport'
|
|
159
|
-
});
|
|
160
|
-
expect(capturedSiblingDoc).toEqual({
|
|
161
|
-
tracked: 'original'
|
|
162
|
-
});
|
|
163
|
-
// The hook's mutation lives on siblingData, not siblingDoc
|
|
164
|
-
expect(capturedSiblingData?.injected).toBe('written-into-output');
|
|
165
|
-
expect(capturedSiblingDoc?.injected).toBeUndefined();
|
|
166
|
-
// And the source object itself is not mutated
|
|
167
|
-
expect(source).toEqual({
|
|
168
|
-
outer: {
|
|
169
|
-
tracked: 'original'
|
|
170
|
-
}
|
|
171
|
-
});
|
|
172
|
-
});
|
|
173
|
-
});
|
|
174
|
-
describe('CSV import (unflattenObject)', ()=>{
|
|
175
|
-
it('passes the full flat row as siblingDoc (equal to data)', ()=>{
|
|
176
|
-
const received = [];
|
|
177
|
-
const fields = [
|
|
178
|
-
{
|
|
179
|
-
name: 'title',
|
|
180
|
-
type: 'text'
|
|
181
|
-
},
|
|
182
|
-
{
|
|
183
|
-
name: 'note',
|
|
184
|
-
type: 'text',
|
|
185
|
-
custom: {
|
|
186
|
-
'plugin-import-export': {
|
|
187
|
-
hooks: {
|
|
188
|
-
beforeImport: ({ data, siblingDoc, value })=>{
|
|
189
|
-
received.push({
|
|
190
|
-
siblingDocIsData: siblingDoc === data
|
|
191
|
-
});
|
|
192
|
-
return value;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
];
|
|
199
|
-
const importFieldHooks = getImportFieldFunctions({
|
|
200
|
-
fields
|
|
201
|
-
});
|
|
202
|
-
unflattenObject({
|
|
203
|
-
data: {
|
|
204
|
-
note: 'hello',
|
|
205
|
-
title: 'Top'
|
|
206
|
-
},
|
|
207
|
-
fields,
|
|
208
|
-
format: 'csv',
|
|
209
|
-
importFieldHooks,
|
|
210
|
-
req: mockReq
|
|
211
|
-
});
|
|
212
|
-
expect(received).toEqual([
|
|
213
|
-
{
|
|
214
|
-
siblingDocIsData: true
|
|
215
|
-
}
|
|
216
|
-
]);
|
|
217
|
-
});
|
|
218
|
-
});
|
|
219
|
-
describe('JSON import (applyFieldHooks)', ()=>{
|
|
220
|
-
it('passes the untouched source sibling as siblingDoc and the mutable output as siblingData', ()=>{
|
|
221
|
-
let capturedSiblingDoc = null;
|
|
222
|
-
let capturedSiblingData = null;
|
|
223
|
-
const fields = [
|
|
224
|
-
{
|
|
225
|
-
name: 'outer',
|
|
226
|
-
type: 'group',
|
|
227
|
-
flattenedFields: [
|
|
228
|
-
{
|
|
229
|
-
name: 'tracked',
|
|
230
|
-
type: 'text',
|
|
231
|
-
custom: {
|
|
232
|
-
'plugin-import-export': {
|
|
233
|
-
hooks: {
|
|
234
|
-
beforeImport: ({ siblingData, siblingDoc, value })=>{
|
|
235
|
-
capturedSiblingDoc = siblingDoc;
|
|
236
|
-
capturedSiblingData = siblingData;
|
|
237
|
-
siblingData.injected = 'written-into-output';
|
|
238
|
-
return value;
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
]
|
|
245
|
-
}
|
|
246
|
-
];
|
|
247
|
-
const importFieldHooks = getImportFieldFunctions({
|
|
248
|
-
fields
|
|
249
|
-
});
|
|
250
|
-
const source = {
|
|
251
|
-
outer: {
|
|
252
|
-
tracked: 'original'
|
|
253
|
-
}
|
|
254
|
-
};
|
|
255
|
-
applyFieldHooks({
|
|
256
|
-
data: source,
|
|
257
|
-
fieldHooks: importFieldHooks,
|
|
258
|
-
fields,
|
|
259
|
-
format: 'json',
|
|
260
|
-
operation: 'import',
|
|
261
|
-
req: mockReq,
|
|
262
|
-
type: 'beforeImport'
|
|
263
|
-
});
|
|
264
|
-
expect(capturedSiblingDoc).toEqual({
|
|
265
|
-
tracked: 'original'
|
|
266
|
-
});
|
|
267
|
-
expect(capturedSiblingData?.injected).toBe('written-into-output');
|
|
268
|
-
expect(capturedSiblingDoc?.injected).toBeUndefined();
|
|
269
|
-
expect(source).toEqual({
|
|
270
|
-
outer: {
|
|
271
|
-
tracked: 'original'
|
|
272
|
-
}
|
|
273
|
-
});
|
|
274
|
-
});
|
|
275
|
-
});
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
//# sourceMappingURL=siblingDoc.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/siblingDoc.spec.ts"],"sourcesContent":["import { FlattenedField, PayloadRequest } from 'payload'\n\nimport type { FieldBeforeExportHook, FieldBeforeImportHook } from '../types.js'\n\nimport { applyFieldHooks } from './applyFieldHooks.js'\nimport { flattenObject } from './flattenObject.js'\nimport { getExportFieldFunctions } from './getExportFieldFunctions.js'\nimport { getImportFieldFunctions } from './getImportFieldFunctions.js'\nimport { unflattenObject } from './unflattenObject.js'\n\nimport { describe, expect, it, vi } from 'vitest'\n\nconst mockReq = {\n payload: {\n logger: {\n error: vi.fn(),\n },\n },\n} as unknown as PayloadRequest\n\ndescribe('beforeExport / beforeImport siblingDoc arg', () => {\n describe('CSV export (flattenObject)', () => {\n it('passes the source doc at the current nesting level as siblingDoc', () => {\n const received: Array<{\n columnName: string\n isSiblingDocSource: boolean\n isSiblingDocRow: boolean\n }> = []\n\n const fields: FlattenedField[] = [\n { name: 'title', type: 'text' } as FlattenedField,\n {\n name: 'group',\n type: 'group',\n flattenedFields: [\n {\n name: 'inner',\n type: 'text',\n custom: {\n 'plugin-import-export': {\n hooks: {\n beforeExport: (({ columnName, siblingData, siblingDoc, value }) => {\n received.push({\n columnName,\n isSiblingDocSource:\n siblingDoc &&\n typeof siblingDoc === 'object' &&\n siblingDoc.inner === value,\n isSiblingDocRow: siblingDoc === siblingData,\n })\n return value\n }) satisfies FieldBeforeExportHook,\n },\n },\n },\n },\n ],\n } as unknown as FlattenedField,\n ]\n\n const exportFieldHooks = getExportFieldFunctions({ fields })\n\n flattenObject({\n data: { group: { inner: 'deep' }, title: 'Top' },\n exportFieldHooks,\n format: 'csv',\n req: mockReq,\n })\n\n expect(received).toEqual([\n {\n columnName: 'group_inner',\n isSiblingDocSource: true,\n isSiblingDocRow: false,\n },\n ])\n })\n\n it('lets a hook read another sibling by reading siblingDoc', () => {\n const fields: FlattenedField[] = [\n { name: 'firstName', type: 'text' } as FlattenedField,\n {\n name: 'fullName',\n type: 'text',\n custom: {\n 'plugin-import-export': {\n hooks: {\n beforeExport: (({ siblingDoc, value }) => {\n const last = siblingDoc.lastName as string | undefined\n const first = siblingDoc.firstName as string | undefined\n if (first && last) {\n return `${first} ${last}`\n }\n return value\n }) satisfies FieldBeforeExportHook,\n },\n },\n },\n } as FlattenedField,\n { name: 'lastName', type: 'text' } as FlattenedField,\n ]\n\n const exportFieldHooks = getExportFieldFunctions({ fields })\n\n const result = flattenObject({\n data: { firstName: 'Ada', fullName: '(computed)', lastName: 'Lovelace' },\n exportFieldHooks,\n format: 'csv',\n req: mockReq,\n })\n\n expect(result.fullName).toBe('Ada Lovelace')\n })\n })\n\n describe('JSON export (applyFieldHooks)', () => {\n it('passes the untouched source sibling as siblingDoc and the mutable output as siblingData', () => {\n let capturedSiblingDoc: Record<string, unknown> | null = null\n let capturedSiblingData: Record<string, unknown> | null = null\n\n const fields: FlattenedField[] = [\n {\n name: 'outer',\n type: 'group',\n flattenedFields: [\n {\n name: 'tracked',\n type: 'text',\n custom: {\n 'plugin-import-export': {\n hooks: {\n beforeExport: (({ siblingData, siblingDoc, value }) => {\n capturedSiblingDoc = siblingDoc\n capturedSiblingData = siblingData\n siblingData.injected = 'written-into-output'\n return String(value) + '_changed'\n }) satisfies FieldBeforeExportHook,\n },\n },\n },\n },\n ],\n } as unknown as FlattenedField,\n ]\n\n const exportFieldHooks = getExportFieldFunctions({ fields })\n\n const source = { outer: { tracked: 'original' } }\n\n applyFieldHooks({\n data: source,\n fieldHooks: exportFieldHooks,\n fields,\n format: 'json',\n operation: 'export',\n req: mockReq,\n type: 'beforeExport',\n })\n\n expect(capturedSiblingDoc).toEqual({ tracked: 'original' })\n // The hook's mutation lives on siblingData, not siblingDoc\n expect((capturedSiblingData as unknown as Record<string, unknown>)?.injected).toBe(\n 'written-into-output',\n )\n expect((capturedSiblingDoc as unknown as Record<string, unknown>)?.injected).toBeUndefined()\n // And the source object itself is not mutated\n expect(source).toEqual({ outer: { tracked: 'original' } })\n })\n })\n\n describe('CSV import (unflattenObject)', () => {\n it('passes the full flat row as siblingDoc (equal to data)', () => {\n const received: Array<{ siblingDocIsData: boolean }> = []\n\n const fields: FlattenedField[] = [\n { name: 'title', type: 'text' } as FlattenedField,\n {\n name: 'note',\n type: 'text',\n custom: {\n 'plugin-import-export': {\n hooks: {\n beforeImport: (({ data, siblingDoc, value }) => {\n received.push({ siblingDocIsData: siblingDoc === data })\n return value\n }) satisfies FieldBeforeImportHook,\n },\n },\n },\n } as FlattenedField,\n ]\n\n const importFieldHooks = getImportFieldFunctions({ fields })\n\n unflattenObject({\n data: { note: 'hello', title: 'Top' },\n fields,\n format: 'csv',\n importFieldHooks,\n req: mockReq,\n })\n\n expect(received).toEqual([{ siblingDocIsData: true }])\n })\n })\n\n describe('JSON import (applyFieldHooks)', () => {\n it('passes the untouched source sibling as siblingDoc and the mutable output as siblingData', () => {\n let capturedSiblingDoc: Record<string, unknown> | null = null\n let capturedSiblingData: Record<string, unknown> | null = null\n\n const fields: FlattenedField[] = [\n {\n name: 'outer',\n type: 'group',\n flattenedFields: [\n {\n name: 'tracked',\n type: 'text',\n custom: {\n 'plugin-import-export': {\n hooks: {\n beforeImport: (({ siblingData, siblingDoc, value }) => {\n capturedSiblingDoc = siblingDoc\n capturedSiblingData = siblingData\n siblingData.injected = 'written-into-output'\n return value\n }) satisfies FieldBeforeImportHook,\n },\n },\n },\n },\n ],\n } as unknown as FlattenedField,\n ]\n\n const importFieldHooks = getImportFieldFunctions({ fields })\n\n const source = { outer: { tracked: 'original' } }\n\n applyFieldHooks({\n data: source,\n fieldHooks: importFieldHooks,\n fields,\n format: 'json',\n operation: 'import',\n req: mockReq,\n type: 'beforeImport',\n })\n\n expect(capturedSiblingDoc).toEqual({ tracked: 'original' })\n expect((capturedSiblingData as unknown as Record<string, unknown>)?.injected).toBe(\n 'written-into-output',\n )\n expect((capturedSiblingDoc as unknown as Record<string, unknown>)?.injected).toBeUndefined()\n expect(source).toEqual({ outer: { tracked: 'original' } })\n })\n })\n})\n"],"names":["applyFieldHooks","flattenObject","getExportFieldFunctions","getImportFieldFunctions","unflattenObject","describe","expect","it","vi","mockReq","payload","logger","error","fn","received","fields","name","type","flattenedFields","custom","hooks","beforeExport","columnName","siblingData","siblingDoc","value","push","isSiblingDocSource","inner","isSiblingDocRow","exportFieldHooks","data","group","title","format","req","toEqual","last","lastName","first","firstName","result","fullName","toBe","capturedSiblingDoc","capturedSiblingData","injected","String","source","outer","tracked","fieldHooks","operation","toBeUndefined","beforeImport","siblingDocIsData","importFieldHooks","note"],"mappings":"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"}
|