@payloadcms/plugin-import-export 3.84.1 → 3.85.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/export/batchProcessor.d.ts +9 -1
- package/dist/export/batchProcessor.d.ts.map +1 -1
- package/dist/export/batchProcessor.js +57 -15
- package/dist/export/batchProcessor.js.map +1 -1
- package/dist/export/createExport.d.ts.map +1 -1
- package/dist/export/createExport.js +98 -20
- package/dist/export/createExport.js.map +1 -1
- package/dist/export/handlePreview.d.ts.map +1 -1
- package/dist/export/handlePreview.js +38 -13
- 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 +14 -2
- package/dist/import/batchProcessor.d.ts.map +1 -1
- package/dist/import/batchProcessor.js +49 -27
- package/dist/import/batchProcessor.js.map +1 -1
- package/dist/import/createImport.d.ts +1 -10
- package/dist/import/createImport.d.ts.map +1 -1
- package/dist/import/createImport.js +33 -52
- package/dist/import/createImport.js.map +1 -1
- package/dist/import/handlePreview.d.ts.map +1 -1
- package/dist/import/handlePreview.js +32 -6
- package/dist/import/handlePreview.js.map +1 -1
- package/dist/index.d.ts +58 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -1
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +218 -39
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utilities/applyFieldHooks.d.ts +23 -0
- package/dist/utilities/applyFieldHooks.d.ts.map +1 -0
- package/dist/utilities/applyFieldHooks.js +118 -0
- package/dist/utilities/applyFieldHooks.js.map +1 -0
- package/dist/utilities/applyFieldHooks.spec.js +205 -0
- package/dist/utilities/applyFieldHooks.spec.js.map +1 -0
- package/dist/utilities/collectDisabledFieldPaths.d.ts.map +1 -1
- package/dist/utilities/collectDisabledFieldPaths.js +1 -1
- package/dist/utilities/collectDisabledFieldPaths.js.map +1 -1
- package/dist/utilities/flattenObject.d.ts +8 -6
- package/dist/utilities/flattenObject.d.ts.map +1 -1
- package/dist/utilities/flattenObject.js +95 -75
- package/dist/utilities/flattenObject.js.map +1 -1
- package/dist/utilities/flattenObject.spec.js +158 -0
- package/dist/utilities/flattenObject.spec.js.map +1 -0
- package/dist/utilities/flattenedFields.d.ts +21 -0
- package/dist/utilities/flattenedFields.d.ts.map +1 -0
- package/dist/utilities/flattenedFields.js +34 -0
- package/dist/utilities/flattenedFields.js.map +1 -0
- package/dist/utilities/getExportFieldFunctions.d.ts +5 -5
- package/dist/utilities/getExportFieldFunctions.d.ts.map +1 -1
- package/dist/utilities/getExportFieldFunctions.js +92 -98
- package/dist/utilities/getExportFieldFunctions.js.map +1 -1
- package/dist/utilities/getExportFieldFunctions.spec.js +50 -0
- package/dist/utilities/getExportFieldFunctions.spec.js.map +1 -0
- package/dist/utilities/getImportFieldFunctions.d.ts +5 -5
- package/dist/utilities/getImportFieldFunctions.d.ts.map +1 -1
- package/dist/utilities/getImportFieldFunctions.js +103 -103
- package/dist/utilities/getImportFieldFunctions.js.map +1 -1
- package/dist/utilities/getImportFieldFunctions.spec.js +167 -0
- package/dist/utilities/getImportFieldFunctions.spec.js.map +1 -0
- package/dist/utilities/isPlainObject.d.ts +2 -0
- package/dist/utilities/isPlainObject.d.ts.map +1 -0
- package/dist/utilities/isPlainObject.js +3 -0
- package/dist/utilities/isPlainObject.js.map +1 -0
- package/dist/utilities/legacyHookDispatch.spec.js +227 -0
- package/dist/utilities/legacyHookDispatch.spec.js.map +1 -0
- package/dist/utilities/polymorphicRel.d.ts +14 -0
- package/dist/utilities/polymorphicRel.d.ts.map +1 -0
- package/dist/utilities/polymorphicRel.js +17 -0
- package/dist/utilities/polymorphicRel.js.map +1 -0
- package/dist/utilities/processRichTextField.js.map +1 -1
- package/dist/utilities/removeDisabledFields.js.map +1 -1
- package/dist/utilities/setNestedValue.d.ts.map +1 -1
- package/dist/utilities/setNestedValue.js +10 -8
- package/dist/utilities/setNestedValue.js.map +1 -1
- package/dist/utilities/siblingDoc.spec.js +278 -0
- package/dist/utilities/siblingDoc.spec.js.map +1 -0
- package/dist/utilities/unflattenObject.d.ts +4 -3
- package/dist/utilities/unflattenObject.d.ts.map +1 -1
- package/dist/utilities/unflattenObject.js +57 -169
- package/dist/utilities/unflattenObject.js.map +1 -1
- package/dist/utilities/unflattenObject.spec.js +33 -0
- package/dist/utilities/unflattenObject.spec.js.map +1 -1
- package/dist/utilities/unflattenPostProcess.d.ts +11 -0
- package/dist/utilities/unflattenPostProcess.d.ts.map +1 -0
- package/dist/utilities/unflattenPostProcess.js +148 -0
- package/dist/utilities/unflattenPostProcess.js.map +1 -0
- package/package.json +7 -7
|
@@ -1,109 +1,103 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { registerFieldHooks } from './flattenedFields.js';
|
|
2
|
+
import { getPolymorphicRelId, isPolymorphicRelValue } from './polymorphicRel.js';
|
|
2
3
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
4
|
+
* Builds a map from logical field path (e.g. `content_textBlock_body`) to
|
|
5
|
+
* the export hook entry. Paths include block slugs but never array indices.
|
|
5
6
|
*/ export const getExportFieldFunctions = ({ fields })=>{
|
|
6
7
|
const result = {};
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
8
|
+
registerFieldHooks(fields, '', result, registerExportHandler);
|
|
9
|
+
return result;
|
|
10
|
+
};
|
|
11
|
+
const registerExportHandler = (field, fullKey, result)=>{
|
|
12
|
+
const beforeExport = field.custom?.['plugin-import-export']?.hooks?.beforeExport;
|
|
13
|
+
const toCSV = field.custom?.['plugin-import-export']?.toCSV;
|
|
14
|
+
if (typeof beforeExport === 'function') {
|
|
15
|
+
result[fullKey] = {
|
|
16
|
+
type: 'beforeExport',
|
|
17
|
+
fn: beforeExport
|
|
18
|
+
};
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (typeof toCSV === 'function') {
|
|
22
|
+
result[fullKey] = {
|
|
23
|
+
type: 'toCSV',
|
|
24
|
+
fn: toCSV
|
|
25
|
+
};
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const registerHandler = (handler)=>{
|
|
29
|
+
result[fullKey] = {
|
|
30
|
+
type: 'beforeExport',
|
|
31
|
+
fn: handler
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
if (field.type === 'json' || field.type === 'richText') {
|
|
35
|
+
registerHandler(({ format, value })=>{
|
|
36
|
+
if (format === 'json') {
|
|
30
37
|
return value;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
;
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
} else {
|
|
64
|
-
if (!Array.isArray(field.relationTo)) {
|
|
65
|
-
// monomorphic many
|
|
66
|
-
// @ts-expect-error ref is untyped
|
|
67
|
-
result[`${ref.prefix}${field.name}`] = ({ data, value })=>{
|
|
68
|
-
if (Array.isArray(value)) {
|
|
69
|
-
value.forEach((val, i)=>{
|
|
70
|
-
const id = typeof val === 'object' && val ? val.id : val;
|
|
71
|
-
// @ts-expect-error ref is untyped
|
|
72
|
-
data[`${ref.prefix}${field.name}_${i}_id`] = id;
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
return undefined // prevents further flattening
|
|
76
|
-
;
|
|
77
|
-
};
|
|
78
|
-
} else {
|
|
79
|
-
// polymorphic many
|
|
80
|
-
// @ts-expect-error ref is untyped
|
|
81
|
-
result[`${ref.prefix}${field.name}`] = ({ data, value })=>{
|
|
82
|
-
if (Array.isArray(value)) {
|
|
83
|
-
value.forEach((val, i)=>{
|
|
84
|
-
if (val && typeof val === 'object') {
|
|
85
|
-
const relationTo = val.relationTo;
|
|
86
|
-
const relatedDoc = val.value;
|
|
87
|
-
if (relationTo && relatedDoc && typeof relatedDoc === 'object') {
|
|
88
|
-
// @ts-expect-error ref is untyped
|
|
89
|
-
data[`${ref.prefix}${field.name}_${i}_id`] = relatedDoc.id;
|
|
90
|
-
// @ts-expect-error ref is untyped
|
|
91
|
-
data[`${ref.prefix}${field.name}_${i}_relationTo`] = relationTo;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
return undefined;
|
|
97
|
-
};
|
|
38
|
+
}
|
|
39
|
+
if (value === null || value === undefined) {
|
|
40
|
+
return value;
|
|
41
|
+
}
|
|
42
|
+
if (typeof value === 'object') {
|
|
43
|
+
return JSON.stringify(value);
|
|
44
|
+
}
|
|
45
|
+
return value;
|
|
46
|
+
});
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (field.type === 'date') {
|
|
50
|
+
registerHandler(({ value })=>value);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (field.type !== 'relationship' && field.type !== 'upload') {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (field.hasMany !== true) {
|
|
57
|
+
if (!Array.isArray(field.relationTo)) {
|
|
58
|
+
registerHandler(({ value })=>typeof value === 'object' && value && 'id' in value ? value.id : value);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
registerHandler(({ siblingData, value })=>{
|
|
62
|
+
if (isPolymorphicRelValue(value)) {
|
|
63
|
+
const id = getPolymorphicRelId(value);
|
|
64
|
+
if (id !== undefined) {
|
|
65
|
+
siblingData[`${fullKey}_id`] = id;
|
|
66
|
+
siblingData[`${fullKey}_relationTo`] = value.relationTo;
|
|
98
67
|
}
|
|
99
68
|
}
|
|
69
|
+
return null;
|
|
70
|
+
});
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (!Array.isArray(field.relationTo)) {
|
|
74
|
+
registerHandler(({ siblingData, value })=>{
|
|
75
|
+
if (Array.isArray(value)) {
|
|
76
|
+
value.forEach((val, i)=>{
|
|
77
|
+
const id = typeof val === 'object' && val ? val.id : val;
|
|
78
|
+
siblingData[`${fullKey}_${i}_id`] = id;
|
|
79
|
+
});
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
return undefined;
|
|
83
|
+
});
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
registerHandler(({ siblingData, value })=>{
|
|
87
|
+
if (Array.isArray(value)) {
|
|
88
|
+
value.forEach((val, i)=>{
|
|
89
|
+
if (isPolymorphicRelValue(val)) {
|
|
90
|
+
const id = getPolymorphicRelId(val);
|
|
91
|
+
if (id !== undefined) {
|
|
92
|
+
siblingData[`${fullKey}_${i}_id`] = id;
|
|
93
|
+
siblingData[`${fullKey}_${i}_relationTo`] = val.relationTo;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
return null;
|
|
100
98
|
}
|
|
101
|
-
|
|
102
|
-
traverseFields({
|
|
103
|
-
callback: buildCustomFunctions,
|
|
104
|
-
fields
|
|
99
|
+
return undefined;
|
|
105
100
|
});
|
|
106
|
-
return result;
|
|
107
101
|
};
|
|
108
102
|
|
|
109
103
|
//# sourceMappingURL=getExportFieldFunctions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/getExportFieldFunctions.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/getExportFieldFunctions.ts"],"sourcesContent":["import type { FlattenedField } from 'payload'\n\nimport type { ExportFieldHookEntry, FieldBeforeExportHook } from '../types.js'\n\nimport { registerFieldHooks } from './flattenedFields.js'\nimport { getPolymorphicRelId, isPolymorphicRelValue } from './polymorphicRel.js'\n\ntype Args = {\n fields: FlattenedField[]\n}\n\n/**\n * Builds a map from logical field path (e.g. `content_textBlock_body`) to\n * the export hook entry. Paths include block slugs but never array indices.\n */\nexport const getExportFieldFunctions = ({ fields }: Args): Record<string, ExportFieldHookEntry> => {\n const result: Record<string, ExportFieldHookEntry> = {}\n registerFieldHooks(fields, '', result, registerExportHandler)\n return result\n}\n\nconst registerExportHandler = (\n field: FlattenedField,\n fullKey: string,\n result: Record<string, ExportFieldHookEntry>,\n): void => {\n const beforeExport = field.custom?.['plugin-import-export']?.hooks?.beforeExport\n\n const toCSV = field.custom?.['plugin-import-export']?.toCSV\n\n if (typeof beforeExport === 'function') {\n result[fullKey] = { type: 'beforeExport', fn: beforeExport }\n return\n }\n\n if (typeof toCSV === 'function') {\n result[fullKey] = { type: 'toCSV', fn: toCSV }\n return\n }\n\n const registerHandler = (handler: FieldBeforeExportHook) => {\n result[fullKey] = { type: 'beforeExport', fn: handler }\n }\n\n if (field.type === 'json' || field.type === 'richText') {\n registerHandler(({ format, value }) => {\n if (format === 'json') {\n return value\n }\n if (value === null || value === undefined) {\n return value\n }\n if (typeof value === 'object') {\n return JSON.stringify(value)\n }\n return value\n })\n return\n }\n\n if (field.type === 'date') {\n registerHandler(({ value }) => value)\n return\n }\n\n if (field.type !== 'relationship' && field.type !== 'upload') {\n return\n }\n\n if (field.hasMany !== true) {\n if (!Array.isArray(field.relationTo)) {\n registerHandler(({ value }) =>\n typeof value === 'object' && value && 'id' in value ? value.id : value,\n )\n return\n }\n\n registerHandler(({ siblingData, value }) => {\n if (isPolymorphicRelValue(value)) {\n const id = getPolymorphicRelId(value)\n if (id !== undefined) {\n siblingData[`${fullKey}_id`] = id\n siblingData[`${fullKey}_relationTo`] = value.relationTo\n }\n }\n return null\n })\n return\n }\n\n if (!Array.isArray(field.relationTo)) {\n registerHandler(({ siblingData, value }) => {\n if (Array.isArray(value)) {\n value.forEach((val, i) => {\n const id = typeof val === 'object' && val ? (val as { id: unknown }).id : val\n siblingData[`${fullKey}_${i}_id`] = id\n })\n return null\n }\n return undefined\n })\n return\n }\n\n registerHandler(({ siblingData, value }) => {\n if (Array.isArray(value)) {\n value.forEach((val, i) => {\n if (isPolymorphicRelValue(val)) {\n const id = getPolymorphicRelId(val)\n if (id !== undefined) {\n siblingData[`${fullKey}_${i}_id`] = id\n siblingData[`${fullKey}_${i}_relationTo`] = val.relationTo\n }\n }\n })\n return null\n }\n return undefined\n })\n}\n"],"names":["registerFieldHooks","getPolymorphicRelId","isPolymorphicRelValue","getExportFieldFunctions","fields","result","registerExportHandler","field","fullKey","beforeExport","custom","hooks","toCSV","type","fn","registerHandler","handler","format","value","undefined","JSON","stringify","hasMany","Array","isArray","relationTo","id","siblingData","forEach","val","i"],"mappings":"AAIA,SAASA,kBAAkB,QAAQ,uBAAsB;AACzD,SAASC,mBAAmB,EAAEC,qBAAqB,QAAQ,sBAAqB;AAMhF;;;CAGC,GACD,OAAO,MAAMC,0BAA0B,CAAC,EAAEC,MAAM,EAAQ;IACtD,MAAMC,SAA+C,CAAC;IACtDL,mBAAmBI,QAAQ,IAAIC,QAAQC;IACvC,OAAOD;AACT,EAAC;AAED,MAAMC,wBAAwB,CAC5BC,OACAC,SACAH;IAEA,MAAMI,eAAeF,MAAMG,MAAM,EAAE,CAAC,uBAAuB,EAAEC,OAAOF;IAEpE,MAAMG,QAAQL,MAAMG,MAAM,EAAE,CAAC,uBAAuB,EAAEE;IAEtD,IAAI,OAAOH,iBAAiB,YAAY;QACtCJ,MAAM,CAACG,QAAQ,GAAG;YAAEK,MAAM;YAAgBC,IAAIL;QAAa;QAC3D;IACF;IAEA,IAAI,OAAOG,UAAU,YAAY;QAC/BP,MAAM,CAACG,QAAQ,GAAG;YAAEK,MAAM;YAASC,IAAIF;QAAM;QAC7C;IACF;IAEA,MAAMG,kBAAkB,CAACC;QACvBX,MAAM,CAACG,QAAQ,GAAG;YAAEK,MAAM;YAAgBC,IAAIE;QAAQ;IACxD;IAEA,IAAIT,MAAMM,IAAI,KAAK,UAAUN,MAAMM,IAAI,KAAK,YAAY;QACtDE,gBAAgB,CAAC,EAAEE,MAAM,EAAEC,KAAK,EAAE;YAChC,IAAID,WAAW,QAAQ;gBACrB,OAAOC;YACT;YACA,IAAIA,UAAU,QAAQA,UAAUC,WAAW;gBACzC,OAAOD;YACT;YACA,IAAI,OAAOA,UAAU,UAAU;gBAC7B,OAAOE,KAAKC,SAAS,CAACH;YACxB;YACA,OAAOA;QACT;QACA;IACF;IAEA,IAAIX,MAAMM,IAAI,KAAK,QAAQ;QACzBE,gBAAgB,CAAC,EAAEG,KAAK,EAAE,GAAKA;QAC/B;IACF;IAEA,IAAIX,MAAMM,IAAI,KAAK,kBAAkBN,MAAMM,IAAI,KAAK,UAAU;QAC5D;IACF;IAEA,IAAIN,MAAMe,OAAO,KAAK,MAAM;QAC1B,IAAI,CAACC,MAAMC,OAAO,CAACjB,MAAMkB,UAAU,GAAG;YACpCV,gBAAgB,CAAC,EAAEG,KAAK,EAAE,GACxB,OAAOA,UAAU,YAAYA,SAAS,QAAQA,QAAQA,MAAMQ,EAAE,GAAGR;YAEnE;QACF;QAEAH,gBAAgB,CAAC,EAAEY,WAAW,EAAET,KAAK,EAAE;YACrC,IAAIhB,sBAAsBgB,QAAQ;gBAChC,MAAMQ,KAAKzB,oBAAoBiB;gBAC/B,IAAIQ,OAAOP,WAAW;oBACpBQ,WAAW,CAAC,GAAGnB,QAAQ,GAAG,CAAC,CAAC,GAAGkB;oBAC/BC,WAAW,CAAC,GAAGnB,QAAQ,WAAW,CAAC,CAAC,GAAGU,MAAMO,UAAU;gBACzD;YACF;YACA,OAAO;QACT;QACA;IACF;IAEA,IAAI,CAACF,MAAMC,OAAO,CAACjB,MAAMkB,UAAU,GAAG;QACpCV,gBAAgB,CAAC,EAAEY,WAAW,EAAET,KAAK,EAAE;YACrC,IAAIK,MAAMC,OAAO,CAACN,QAAQ;gBACxBA,MAAMU,OAAO,CAAC,CAACC,KAAKC;oBAClB,MAAMJ,KAAK,OAAOG,QAAQ,YAAYA,MAAM,AAACA,IAAwBH,EAAE,GAAGG;oBAC1EF,WAAW,CAAC,GAAGnB,QAAQ,CAAC,EAAEsB,EAAE,GAAG,CAAC,CAAC,GAAGJ;gBACtC;gBACA,OAAO;YACT;YACA,OAAOP;QACT;QACA;IACF;IAEAJ,gBAAgB,CAAC,EAAEY,WAAW,EAAET,KAAK,EAAE;QACrC,IAAIK,MAAMC,OAAO,CAACN,QAAQ;YACxBA,MAAMU,OAAO,CAAC,CAACC,KAAKC;gBAClB,IAAI5B,sBAAsB2B,MAAM;oBAC9B,MAAMH,KAAKzB,oBAAoB4B;oBAC/B,IAAIH,OAAOP,WAAW;wBACpBQ,WAAW,CAAC,GAAGnB,QAAQ,CAAC,EAAEsB,EAAE,GAAG,CAAC,CAAC,GAAGJ;wBACpCC,WAAW,CAAC,GAAGnB,QAAQ,CAAC,EAAEsB,EAAE,WAAW,CAAC,CAAC,GAAGD,IAAIJ,UAAU;oBAC5D;gBACF;YACF;YACA,OAAO;QACT;QACA,OAAON;IACT;AACF"}
|
|
@@ -0,0 +1,50 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type {
|
|
1
|
+
import type { FlattenedField } from 'payload';
|
|
2
|
+
import type { ImportFieldHookEntry } from '../types.js';
|
|
3
3
|
type Args = {
|
|
4
4
|
fields: FlattenedField[];
|
|
5
5
|
};
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Builds a map from logical field path (e.g. `content_textBlock_body`) to
|
|
8
|
+
* the import hook entry. Paths include block slugs but never array indices.
|
|
9
9
|
*/
|
|
10
|
-
export declare const getImportFieldFunctions: ({ fields }: Args) => Record<string,
|
|
10
|
+
export declare const getImportFieldFunctions: ({ fields }: Args) => Record<string, ImportFieldHookEntry>;
|
|
11
11
|
export {};
|
|
12
12
|
//# sourceMappingURL=getImportFieldFunctions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getImportFieldFunctions.d.ts","sourceRoot":"","sources":["../../src/utilities/getImportFieldFunctions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"getImportFieldFunctions.d.ts","sourceRoot":"","sources":["../../src/utilities/getImportFieldFunctions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAE7C,OAAO,KAAK,EAAyB,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAI9E,KAAK,IAAI,GAAG;IACV,MAAM,EAAE,cAAc,EAAE,CAAA;CACzB,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,uBAAuB,eAAgB,IAAI,KAAG,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAI7F,CAAA"}
|
|
@@ -1,116 +1,116 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { registerFieldHooks } from './flattenedFields.js';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Builds a map from logical field path (e.g. `content_textBlock_body`) to
|
|
4
|
+
* the import hook entry. Paths include block slugs but never array indices.
|
|
5
5
|
*/ export const getImportFieldFunctions = ({ fields })=>{
|
|
6
6
|
const result = {};
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
registerFieldHooks(fields, '', result, registerImportHandler);
|
|
8
|
+
return result;
|
|
9
|
+
};
|
|
10
|
+
const registerImportHandler = (field, fullKey, result)=>{
|
|
11
|
+
const beforeImport = field.custom?.['plugin-import-export']?.hooks?.beforeImport;
|
|
12
|
+
const fromCSV = field.custom?.['plugin-import-export']?.fromCSV;
|
|
13
|
+
if (typeof beforeImport === 'function') {
|
|
14
|
+
result[fullKey] = {
|
|
15
|
+
type: 'beforeImport',
|
|
16
|
+
fn: beforeImport
|
|
17
|
+
};
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (typeof fromCSV === 'function') {
|
|
21
|
+
result[fullKey] = {
|
|
22
|
+
type: 'fromCSV',
|
|
23
|
+
fn: fromCSV
|
|
24
|
+
};
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const registerBeforeImport = (fn)=>{
|
|
28
|
+
result[fullKey] = {
|
|
29
|
+
type: 'beforeImport',
|
|
30
|
+
fn
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
if (field.type === 'relationship' || field.type === 'upload') {
|
|
34
|
+
if (field.hasMany !== true) {
|
|
35
|
+
if (!Array.isArray(field.relationTo)) {
|
|
36
|
+
registerBeforeImport(({ value })=>value);
|
|
37
|
+
}
|
|
38
|
+
} else if (!Array.isArray(field.relationTo)) {
|
|
39
|
+
registerBeforeImport(({ value })=>value);
|
|
15
40
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (typeof value === 'object' && value !== null) {
|
|
27
|
-
return value;
|
|
28
|
-
}
|
|
29
|
-
// Convert string/number ID to relationship value
|
|
30
|
-
return value;
|
|
31
|
-
};
|
|
32
|
-
} else {
|
|
33
|
-
// Polymorphic single: handled in unflattenObject via _id/_relationTo columns
|
|
34
|
-
}
|
|
35
|
-
} else {
|
|
36
|
-
if (!Array.isArray(field.relationTo)) {
|
|
37
|
-
// @ts-expect-error ref is untyped
|
|
38
|
-
result[`${ref.prefix}${field.name}`] = ({ value })=>{
|
|
39
|
-
if (Array.isArray(value)) {
|
|
40
|
-
return value;
|
|
41
|
-
}
|
|
42
|
-
return value;
|
|
43
|
-
};
|
|
44
|
-
} else {
|
|
45
|
-
// Polymorphic many: handled in unflattenObject
|
|
46
|
-
}
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (field.type === 'number') {
|
|
44
|
+
if (field.hasMany) {
|
|
45
|
+
registerBeforeImport(({ value })=>value);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
registerBeforeImport(({ value })=>{
|
|
49
|
+
if (isEmptyImportValue(value)) {
|
|
50
|
+
return undefined;
|
|
47
51
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
// @ts-expect-error ref is untyped
|
|
51
|
-
result[`${ref.prefix}${field.name}`] = ({ value })=>value;
|
|
52
|
-
} else {
|
|
53
|
-
// @ts-expect-error ref is untyped
|
|
54
|
-
result[`${ref.prefix}${field.name}`] = ({ value })=>{
|
|
55
|
-
if (typeof value === 'number') {
|
|
56
|
-
return value;
|
|
57
|
-
}
|
|
58
|
-
if (typeof value === 'string') {
|
|
59
|
-
const parsed = parseFloat(value);
|
|
60
|
-
return isNaN(parsed) ? 0 : parsed;
|
|
61
|
-
}
|
|
62
|
-
return value;
|
|
63
|
-
};
|
|
52
|
+
if (typeof value === 'number') {
|
|
53
|
+
return value;
|
|
64
54
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
55
|
+
if (typeof value === 'string') {
|
|
56
|
+
const parsed = parseFloat(value);
|
|
57
|
+
return isNaN(parsed) ? undefined : parsed;
|
|
58
|
+
}
|
|
59
|
+
return value;
|
|
60
|
+
});
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (field.type === 'checkbox') {
|
|
64
|
+
registerBeforeImport(({ value })=>{
|
|
65
|
+
if (isEmptyImportValue(value)) {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
if (typeof value === 'boolean') {
|
|
69
|
+
return value;
|
|
70
|
+
}
|
|
71
|
+
if (typeof value === 'string') {
|
|
72
|
+
return value.toLowerCase() === 'true' || value === '1';
|
|
73
|
+
}
|
|
74
|
+
return Boolean(value);
|
|
75
|
+
});
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (field.type === 'date') {
|
|
79
|
+
registerBeforeImport(({ value })=>{
|
|
80
|
+
if (isEmptyImportValue(value)) {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
if (typeof value === 'string' && !isNaN(Date.parse(value))) {
|
|
84
|
+
return value;
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
const date = new Date(value);
|
|
88
|
+
return isNaN(date.getTime()) ? value : date.toISOString();
|
|
89
|
+
} catch {
|
|
90
|
+
return value;
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (field.type === 'json' || field.type === 'richText') {
|
|
96
|
+
registerBeforeImport(({ value })=>{
|
|
97
|
+
if (isEmptyImportValue(value)) {
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
if (typeof value === 'object') {
|
|
101
|
+
return value;
|
|
102
|
+
}
|
|
103
|
+
if (typeof value === 'string') {
|
|
85
104
|
try {
|
|
86
|
-
|
|
87
|
-
return isNaN(date.getTime()) ? value : date.toISOString();
|
|
105
|
+
return JSON.parse(value);
|
|
88
106
|
} catch {
|
|
89
107
|
return value;
|
|
90
108
|
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (typeof value === 'object') {
|
|
96
|
-
return value;
|
|
97
|
-
}
|
|
98
|
-
if (typeof value === 'string') {
|
|
99
|
-
try {
|
|
100
|
-
return JSON.parse(value);
|
|
101
|
-
} catch {
|
|
102
|
-
return value;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
return value;
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
traverseFields({
|
|
110
|
-
callback: buildCustomFunctions,
|
|
111
|
-
fields
|
|
112
|
-
});
|
|
113
|
-
return result;
|
|
109
|
+
}
|
|
110
|
+
return value;
|
|
111
|
+
});
|
|
112
|
+
}
|
|
114
113
|
};
|
|
114
|
+
const isEmptyImportValue = (value)=>value === '' || value === null || value === undefined;
|
|
115
115
|
|
|
116
116
|
//# sourceMappingURL=getImportFieldFunctions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/getImportFieldFunctions.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/getImportFieldFunctions.ts"],"sourcesContent":["import type { FlattenedField } from 'payload'\n\nimport type { FieldBeforeImportHook, ImportFieldHookEntry } from '../types.js'\n\nimport { registerFieldHooks } from './flattenedFields.js'\n\ntype Args = {\n fields: FlattenedField[]\n}\n\n/**\n * Builds a map from logical field path (e.g. `content_textBlock_body`) to\n * the import hook entry. Paths include block slugs but never array indices.\n */\nexport const getImportFieldFunctions = ({ fields }: Args): Record<string, ImportFieldHookEntry> => {\n const result: Record<string, ImportFieldHookEntry> = {}\n registerFieldHooks(fields, '', result, registerImportHandler)\n return result\n}\n\nconst registerImportHandler = (\n field: FlattenedField,\n fullKey: string,\n result: Record<string, ImportFieldHookEntry>,\n): void => {\n const beforeImport = field.custom?.['plugin-import-export']?.hooks?.beforeImport\n\n const fromCSV = field.custom?.['plugin-import-export']?.fromCSV\n\n if (typeof beforeImport === 'function') {\n result[fullKey] = { type: 'beforeImport', fn: beforeImport }\n return\n }\n\n if (typeof fromCSV === 'function') {\n result[fullKey] = { type: 'fromCSV', fn: fromCSV }\n return\n }\n\n const registerBeforeImport = (fn: FieldBeforeImportHook) => {\n result[fullKey] = { type: 'beforeImport', fn }\n }\n\n if (field.type === 'relationship' || field.type === 'upload') {\n if (field.hasMany !== true) {\n if (!Array.isArray(field.relationTo)) {\n registerBeforeImport(({ value }) => value)\n }\n } else if (!Array.isArray(field.relationTo)) {\n registerBeforeImport(({ value }) => value)\n }\n return\n }\n\n if (field.type === 'number') {\n if (field.hasMany) {\n registerBeforeImport(({ value }) => value)\n return\n }\n registerBeforeImport(({ value }) => {\n if (isEmptyImportValue(value)) {\n return undefined\n }\n if (typeof value === 'number') {\n return value\n }\n if (typeof value === 'string') {\n const parsed = parseFloat(value)\n return isNaN(parsed) ? undefined : parsed\n }\n return value\n })\n return\n }\n\n if (field.type === 'checkbox') {\n registerBeforeImport(({ value }) => {\n if (isEmptyImportValue(value)) {\n return undefined\n }\n if (typeof value === 'boolean') {\n return value\n }\n if (typeof value === 'string') {\n return value.toLowerCase() === 'true' || value === '1'\n }\n return Boolean(value)\n })\n return\n }\n\n if (field.type === 'date') {\n registerBeforeImport(({ value }) => {\n if (isEmptyImportValue(value)) {\n return undefined\n }\n if (typeof value === 'string' && !isNaN(Date.parse(value))) {\n return value\n }\n try {\n const date = new Date(value as string)\n return isNaN(date.getTime()) ? value : date.toISOString()\n } catch {\n return value\n }\n })\n return\n }\n\n if (field.type === 'json' || field.type === 'richText') {\n registerBeforeImport(({ value }) => {\n if (isEmptyImportValue(value)) {\n return undefined\n }\n if (typeof value === 'object') {\n return value\n }\n if (typeof value === 'string') {\n try {\n return JSON.parse(value)\n } catch {\n return value\n }\n }\n return value\n })\n }\n}\n\nconst isEmptyImportValue = (value: unknown): boolean =>\n value === '' || value === null || value === undefined\n"],"names":["registerFieldHooks","getImportFieldFunctions","fields","result","registerImportHandler","field","fullKey","beforeImport","custom","hooks","fromCSV","type","fn","registerBeforeImport","hasMany","Array","isArray","relationTo","value","isEmptyImportValue","undefined","parsed","parseFloat","isNaN","toLowerCase","Boolean","Date","parse","date","getTime","toISOString","JSON"],"mappings":"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"}
|