@payloadcms/plugin-import-export 4.0.0-internal.5b1e7cd → 4.0.0-internal.5e065b3
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 +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 +12 -3
- package/dist/export/batchProcessor.d.ts.map +1 -1
- package/dist/export/batchProcessor.js +61 -15
- 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 +105 -22
- 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 +60 -16
- 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 +17 -4
- package/dist/import/batchProcessor.d.ts.map +1 -1
- package/dist/import/batchProcessor.js +63 -34
- package/dist/import/batchProcessor.js.map +1 -1
- package/dist/import/createImport.d.ts +3 -11
- package/dist/import/createImport.d.ts.map +1 -1
- package/dist/import/createImport.js +42 -54
- 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 +37 -7
- package/dist/import/handlePreview.js.map +1 -1
- package/dist/index.d.ts +51 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +36 -8
- package/dist/index.js.map +1 -1
- package/dist/translations/languages/en.d.ts.map +1 -1
- package/dist/types.d.ts +205 -42
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utilities/applyFieldHooks.d.ts +22 -0
- package/dist/utilities/applyFieldHooks.d.ts.map +1 -0
- package/dist/utilities/applyFieldHooks.js +117 -0
- package/dist/utilities/applyFieldHooks.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 +85 -75
- package/dist/utilities/flattenObject.js.map +1 -1
- package/dist/utilities/flattenedFields.d.ts +21 -0
- package/dist/utilities/flattenedFields.d.ts.map +1 -0
- package/dist/utilities/flattenedFields.js +37 -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 +122 -99
- 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.d.ts +5 -5
- package/dist/utilities/getImportFieldFunctions.d.ts.map +1 -1
- package/dist/utilities/getImportFieldFunctions.js +95 -103
- 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/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/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/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.d.ts.map +1 -1
- package/dist/utilities/processRichTextField.js +7 -0
- package/dist/utilities/processRichTextField.js.map +1 -1
- package/dist/utilities/removeDisabledFields.js.map +1 -1
- package/dist/utilities/setNestedValue.d.ts +2 -1
- package/dist/utilities/setNestedValue.d.ts.map +1 -1
- package/dist/utilities/setNestedValue.js +65 -32
- package/dist/utilities/setNestedValue.js.map +1 -1
- package/dist/utilities/sortHelpers.d.ts +1 -1
- package/dist/utilities/unflattenObject.d.ts +4 -3
- package/dist/utilities/unflattenObject.d.ts.map +1 -1
- package/dist/utilities/unflattenObject.js +69 -170
- package/dist/utilities/unflattenObject.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 +174 -0
- package/dist/utilities/unflattenPostProcess.js.map +1 -0
- 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/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/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/unflattenObject.spec.js +0 -680
- package/dist/utilities/unflattenObject.spec.js.map +0 -1
- /package/dist/components/Page/{index.scss → index.css} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isPlainObject.d.ts","sourceRoot":"","sources":["../../src/utilities/isPlainObject.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,UAAW,OAAO,KAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CACR,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/isPlainObject.ts"],"sourcesContent":["export const isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n"],"names":["isPlainObject","value","Array","isArray"],"mappings":"AAAA,OAAO,MAAMA,gBAAgB,CAACC,QAC5B,OAAOA,UAAU,YAAYA,UAAU,QAAQ,CAACC,MAAMC,OAAO,CAACF,OAAM"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type PolymorphicRelValue = {
|
|
2
|
+
relationTo: string;
|
|
3
|
+
value: {
|
|
4
|
+
id: number | string;
|
|
5
|
+
} | number | string;
|
|
6
|
+
};
|
|
7
|
+
export declare const isPolymorphicRelValue: (v: unknown) => v is PolymorphicRelValue;
|
|
8
|
+
/**
|
|
9
|
+
* Returns the id of a populated polymorphic relationship value, or `undefined`
|
|
10
|
+
* if the inner value is missing. Handles both depth=0 (`value` is the bare id)
|
|
11
|
+
* and depth>=1 (`value` is the populated doc).
|
|
12
|
+
*/
|
|
13
|
+
export declare const getPolymorphicRelId: (v: PolymorphicRelValue) => number | string | undefined;
|
|
14
|
+
//# sourceMappingURL=polymorphicRel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"polymorphicRel.d.ts","sourceRoot":"","sources":["../../src/utilities/polymorphicRel.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,mBAAmB,GAAG;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,MAAM,GAAG,MAAM,CAAA;CACjD,CAAA;AAED,eAAO,MAAM,qBAAqB,MAAO,OAAO,KAAG,CAAC,IAAI,mBACkB,CAAA;AAE1E;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,MAAO,mBAAmB,KAAG,MAAM,GAAG,MAAM,GAAG,SAS9E,CAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const isPolymorphicRelValue = (v)=>typeof v === 'object' && v !== null && 'relationTo' in v && 'value' in v;
|
|
2
|
+
/**
|
|
3
|
+
* Returns the id of a populated polymorphic relationship value, or `undefined`
|
|
4
|
+
* if the inner value is missing. Handles both depth=0 (`value` is the bare id)
|
|
5
|
+
* and depth>=1 (`value` is the populated doc).
|
|
6
|
+
*/ export const getPolymorphicRelId = (v)=>{
|
|
7
|
+
const inner = v.value;
|
|
8
|
+
if (inner == null) {
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
if (typeof inner === 'object') {
|
|
12
|
+
return inner.id;
|
|
13
|
+
}
|
|
14
|
+
return inner;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=polymorphicRel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/polymorphicRel.ts"],"sourcesContent":["export type PolymorphicRelValue = {\n relationTo: string\n value: { id: number | string } | number | string\n}\n\nexport const isPolymorphicRelValue = (v: unknown): v is PolymorphicRelValue =>\n typeof v === 'object' && v !== null && 'relationTo' in v && 'value' in v\n\n/**\n * Returns the id of a populated polymorphic relationship value, or `undefined`\n * if the inner value is missing. Handles both depth=0 (`value` is the bare id)\n * and depth>=1 (`value` is the populated doc).\n */\nexport const getPolymorphicRelId = (v: PolymorphicRelValue): number | string | undefined => {\n const inner = v.value\n if (inner == null) {\n return undefined\n }\n if (typeof inner === 'object') {\n return (inner as { id?: number | string }).id\n }\n return inner\n}\n"],"names":["isPolymorphicRelValue","v","getPolymorphicRelId","inner","value","undefined","id"],"mappings":"AAKA,OAAO,MAAMA,wBAAwB,CAACC,IACpC,OAAOA,MAAM,YAAYA,MAAM,QAAQ,gBAAgBA,KAAK,WAAWA,EAAC;AAE1E;;;;CAIC,GACD,OAAO,MAAMC,sBAAsB,CAACD;IAClC,MAAME,QAAQF,EAAEG,KAAK;IACrB,IAAID,SAAS,MAAM;QACjB,OAAOE;IACT;IACA,IAAI,OAAOF,UAAU,UAAU;QAC7B,OAAO,AAACA,MAAmCG,EAAE;IAC/C;IACA,OAAOH;AACT,EAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"processRichTextField.d.ts","sourceRoot":"","sources":["../../src/utilities/processRichTextField.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,oBAAoB,UAAW,OAAO,KAAG,
|
|
1
|
+
{"version":3,"file":"processRichTextField.d.ts","sourceRoot":"","sources":["../../src/utilities/processRichTextField.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,oBAAoB,UAAW,OAAO,KAAG,OAoDrD,CAAA"}
|
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
* Process rich text fields to ensure proper data types for Lexical editor.
|
|
3
3
|
* Lexical expects certain properties to be numbers, not strings.
|
|
4
4
|
*/ export const processRichTextField = (value)=>{
|
|
5
|
+
if (typeof value === 'string') {
|
|
6
|
+
try {
|
|
7
|
+
value = JSON.parse(value);
|
|
8
|
+
} catch {
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
5
12
|
if (!value || typeof value !== 'object') {
|
|
6
13
|
return value;
|
|
7
14
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/processRichTextField.ts"],"sourcesContent":["/**\n * Process rich text fields to ensure proper data types for Lexical editor.\n * Lexical expects certain properties to be numbers, not strings.\n */\nexport const processRichTextField = (value: unknown): unknown => {\n if (!value || typeof value !== 'object') {\n return value\n }\n\n // Properties that should be numbers in Lexical\n const numericProperties = [\n 'detail',\n 'format',\n 'indent',\n 'version',\n 'value',\n 'start',\n 'textFormat',\n 'textStyle',\n ]\n\n const processNode = (node:
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/processRichTextField.ts"],"sourcesContent":["/**\n * Process rich text fields to ensure proper data types for Lexical editor.\n * Lexical expects certain properties to be numbers, not strings.\n */\nexport const processRichTextField = (value: unknown): unknown => {\n if (typeof value === 'string') {\n try {\n value = JSON.parse(value)\n } catch {\n return value\n }\n }\n\n if (!value || typeof value !== 'object') {\n return value\n }\n\n // Properties that should be numbers in Lexical\n const numericProperties = [\n 'detail',\n 'format',\n 'indent',\n 'version',\n 'value',\n 'start',\n 'textFormat',\n 'textStyle',\n ]\n\n const processNode = (node: unknown): unknown => {\n if (!node || typeof node !== 'object') {\n return node\n }\n\n // Process current node's properties\n const processed: Record<string, unknown> = {}\n for (const [key, val] of Object.entries(node as Record<string, unknown>)) {\n if (numericProperties.includes(key) && typeof val === 'string') {\n // Convert string numbers to actual numbers\n const num = parseFloat(val)\n processed[key] = isNaN(num) ? val : num\n } else if (key === 'children' && Array.isArray(val)) {\n // Recursively process children\n processed[key] = val.map((child) => processNode(child))\n } else if (typeof val === 'object' && val !== null) {\n // Recursively process nested objects\n processed[key] = processNode(val)\n } else {\n processed[key] = val\n }\n }\n\n return processed\n }\n\n return processNode(value)\n}\n"],"names":["processRichTextField","value","JSON","parse","numericProperties","processNode","node","processed","key","val","Object","entries","includes","num","parseFloat","isNaN","Array","isArray","map","child"],"mappings":"AAAA;;;CAGC,GACD,OAAO,MAAMA,uBAAuB,CAACC;IACnC,IAAI,OAAOA,UAAU,UAAU;QAC7B,IAAI;YACFA,QAAQC,KAAKC,KAAK,CAACF;QACrB,EAAE,OAAM;YACN,OAAOA;QACT;IACF;IAEA,IAAI,CAACA,SAAS,OAAOA,UAAU,UAAU;QACvC,OAAOA;IACT;IAEA,+CAA+C;IAC/C,MAAMG,oBAAoB;QACxB;QACA;QACA;QACA;QACA;QACA;QACA;QACA;KACD;IAED,MAAMC,cAAc,CAACC;QACnB,IAAI,CAACA,QAAQ,OAAOA,SAAS,UAAU;YACrC,OAAOA;QACT;QAEA,oCAAoC;QACpC,MAAMC,YAAqC,CAAC;QAC5C,KAAK,MAAM,CAACC,KAAKC,IAAI,IAAIC,OAAOC,OAAO,CAACL,MAAkC;YACxE,IAAIF,kBAAkBQ,QAAQ,CAACJ,QAAQ,OAAOC,QAAQ,UAAU;gBAC9D,2CAA2C;gBAC3C,MAAMI,MAAMC,WAAWL;gBACvBF,SAAS,CAACC,IAAI,GAAGO,MAAMF,OAAOJ,MAAMI;YACtC,OAAO,IAAIL,QAAQ,cAAcQ,MAAMC,OAAO,CAACR,MAAM;gBACnD,+BAA+B;gBAC/BF,SAAS,CAACC,IAAI,GAAGC,IAAIS,GAAG,CAAC,CAACC,QAAUd,YAAYc;YAClD,OAAO,IAAI,OAAOV,QAAQ,YAAYA,QAAQ,MAAM;gBAClD,qCAAqC;gBACrCF,SAAS,CAACC,IAAI,GAAGH,YAAYI;YAC/B,OAAO;gBACLF,SAAS,CAACC,IAAI,GAAGC;YACnB;QACF;QAEA,OAAOF;IACT;IAEA,OAAOF,YAAYJ;AACrB,EAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/removeDisabledFields.ts"],"sourcesContent":["/**\n * Recursively removes fields from a deeply nested object based on dot-notation paths.\n *\n * This utility supports removing:\n * - Nested fields in plain objects (e.g., \"group.value\")\n * - Fields inside arrays of objects (e.g., \"group.array.field1\")\n *\n * It safely traverses both object and array structures and avoids mutating the original input.\n *\n * @param obj - The original object to clean.\n * @param disabled - An array of dot-separated paths indicating which fields to remove.\n * @returns A deep clone of the original object with specified fields removed.\n */\n\nexport const removeDisabledFields = (\n obj: Record<string, unknown>,\n disabled: string[] = [],\n): Record<string, unknown> => {\n if (!disabled.length) {\n return obj\n }\n\n const clone = structuredClone(obj)\n\n // Process each disabled path independently\n for (const path of disabled) {\n const parts = path.split('.')\n\n /**\n * Recursively walks the object tree according to the dot path,\n * and deletes the field once the full path is reached.\n *\n * @param target - The current object or array being traversed\n * @param i - The index of the current path part\n */\n const removeRecursively = (target:
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/removeDisabledFields.ts"],"sourcesContent":["/**\n * Recursively removes fields from a deeply nested object based on dot-notation paths.\n *\n * This utility supports removing:\n * - Nested fields in plain objects (e.g., \"group.value\")\n * - Fields inside arrays of objects (e.g., \"group.array.field1\")\n *\n * It safely traverses both object and array structures and avoids mutating the original input.\n *\n * @param obj - The original object to clean.\n * @param disabled - An array of dot-separated paths indicating which fields to remove.\n * @returns A deep clone of the original object with specified fields removed.\n */\n\nexport const removeDisabledFields = (\n obj: Record<string, unknown>,\n disabled: string[] = [],\n): Record<string, unknown> => {\n if (!disabled.length) {\n return obj\n }\n\n const clone = structuredClone(obj)\n\n // Process each disabled path independently\n for (const path of disabled) {\n const parts = path.split('.')\n\n /**\n * Recursively walks the object tree according to the dot path,\n * and deletes the field once the full path is reached.\n *\n * @param target - The current object or array being traversed\n * @param i - The index of the current path part\n */\n const removeRecursively = (target: unknown, i = 0): void => {\n if (target == null) {\n return\n }\n\n const key = parts[i]\n\n // If at the final part of the path, perform the deletion\n if (i === parts.length - 1) {\n // If the current level is an array, delete the key from each item\n if (Array.isArray(target)) {\n for (const item of target) {\n if (item && typeof item === 'object' && key !== undefined) {\n delete (item as Record<string, unknown>)[key]\n }\n }\n } else if (typeof target === 'object' && key !== undefined) {\n delete (target as Record<string, unknown>)[key]\n }\n return\n }\n\n if (key === undefined) {\n return\n }\n\n // Traverse to the next level in the path\n const next = (target as Record<string, unknown>)[key]\n\n if (Array.isArray(next)) {\n // If the next value is an array, recurse into each item\n for (const item of next) {\n removeRecursively(item, i + 1)\n }\n } else {\n // Otherwise, continue down the object path\n removeRecursively(next, i + 1)\n }\n }\n\n removeRecursively(clone)\n }\n\n return clone\n}\n"],"names":["removeDisabledFields","obj","disabled","length","clone","structuredClone","path","parts","split","removeRecursively","target","i","key","Array","isArray","item","undefined","next"],"mappings":"AAAA;;;;;;;;;;;;CAYC,GAED,OAAO,MAAMA,uBAAuB,CAClCC,KACAC,WAAqB,EAAE;IAEvB,IAAI,CAACA,SAASC,MAAM,EAAE;QACpB,OAAOF;IACT;IAEA,MAAMG,QAAQC,gBAAgBJ;IAE9B,2CAA2C;IAC3C,KAAK,MAAMK,QAAQJ,SAAU;QAC3B,MAAMK,QAAQD,KAAKE,KAAK,CAAC;QAEzB;;;;;;KAMC,GACD,MAAMC,oBAAoB,CAACC,QAAiBC,IAAI,CAAC;YAC/C,IAAID,UAAU,MAAM;gBAClB;YACF;YAEA,MAAME,MAAML,KAAK,CAACI,EAAE;YAEpB,yDAAyD;YACzD,IAAIA,MAAMJ,MAAMJ,MAAM,GAAG,GAAG;gBAC1B,kEAAkE;gBAClE,IAAIU,MAAMC,OAAO,CAACJ,SAAS;oBACzB,KAAK,MAAMK,QAAQL,OAAQ;wBACzB,IAAIK,QAAQ,OAAOA,SAAS,YAAYH,QAAQI,WAAW;4BACzD,OAAO,AAACD,IAAgC,CAACH,IAAI;wBAC/C;oBACF;gBACF,OAAO,IAAI,OAAOF,WAAW,YAAYE,QAAQI,WAAW;oBAC1D,OAAO,AAACN,MAAkC,CAACE,IAAI;gBACjD;gBACA;YACF;YAEA,IAAIA,QAAQI,WAAW;gBACrB;YACF;YAEA,yCAAyC;YACzC,MAAMC,OAAO,AAACP,MAAkC,CAACE,IAAI;YAErD,IAAIC,MAAMC,OAAO,CAACG,OAAO;gBACvB,wDAAwD;gBACxD,KAAK,MAAMF,QAAQE,KAAM;oBACvBR,kBAAkBM,MAAMJ,IAAI;gBAC9B;YACF,OAAO;gBACL,2CAA2C;gBAC3CF,kBAAkBQ,MAAMN,IAAI;YAC9B;QACF;QAEAF,kBAAkBL;IACpB;IAEA,OAAOA;AACT,EAAC"}
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* @param obj - The target object to mutate.
|
|
15
15
|
* @param path - A dot-separated string path indicating where to assign the value.
|
|
16
16
|
* @param value - The value to set at the specified path.
|
|
17
|
+
* @param source - The source object used to validate array boundaries.
|
|
17
18
|
*/
|
|
18
|
-
export declare const setNestedValue: (obj: Record<string, unknown>, path: string, value: unknown) => void;
|
|
19
|
+
export declare const setNestedValue: (obj: Record<string, unknown>, path: string, value: unknown, source?: Record<string, unknown>) => void;
|
|
19
20
|
//# sourceMappingURL=setNestedValue.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setNestedValue.d.ts","sourceRoot":"","sources":["../../src/utilities/setNestedValue.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"setNestedValue.d.ts","sourceRoot":"","sources":["../../src/utilities/setNestedValue.ts"],"names":[],"mappings":"AAoDA;;;;;;;;;;;;;;;;;GAiBG;AAEH,eAAO,MAAM,cAAc,QACpB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QACtB,MAAM,SACL,OAAO,WACL,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC/B,IAyCF,CAAA"}
|
|
@@ -1,3 +1,34 @@
|
|
|
1
|
+
import { APIError } from 'payload';
|
|
2
|
+
import { hasUnsupportedFieldPathSegment, setOwnProperty } from 'payload/shared';
|
|
3
|
+
const MAX_UNVERIFIED_SPARSE_ARRAY_GAP = 1;
|
|
4
|
+
const createObject = ()=>Object.create(null);
|
|
5
|
+
const isArrayIndex = (part)=>{
|
|
6
|
+
if (!/^(?:0|[1-9]\d*)$/.test(part)) {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
const index = Number(part);
|
|
10
|
+
return Number.isSafeInteger(index) && index >= 0;
|
|
11
|
+
};
|
|
12
|
+
const getPathKey = (target, part, source)=>{
|
|
13
|
+
if (!Array.isArray(target) || !isArrayIndex(part)) {
|
|
14
|
+
return part;
|
|
15
|
+
}
|
|
16
|
+
const index = Number(part);
|
|
17
|
+
if (Array.isArray(source) && index >= source.length || !Array.isArray(source) && index > target.length + MAX_UNVERIFIED_SPARSE_ARRAY_GAP) {
|
|
18
|
+
throw new APIError('Invalid field path.', 400, null, true);
|
|
19
|
+
}
|
|
20
|
+
return index;
|
|
21
|
+
};
|
|
22
|
+
const getSourceValue = (source, part)=>{
|
|
23
|
+
if (source === null || typeof source !== 'object') {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
const key = Array.isArray(source) && isArrayIndex(part) ? Number(part) : part;
|
|
27
|
+
if (!Object.hasOwn(source, key)) {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
return source[key];
|
|
31
|
+
};
|
|
1
32
|
/**
|
|
2
33
|
* Sets a value deeply into a nested object or array, based on a dot-notation path.
|
|
3
34
|
*
|
|
@@ -14,42 +45,44 @@
|
|
|
14
45
|
* @param obj - The target object to mutate.
|
|
15
46
|
* @param path - A dot-separated string path indicating where to assign the value.
|
|
16
47
|
* @param value - The value to set at the specified path.
|
|
17
|
-
|
|
48
|
+
* @param source - The source object used to validate array boundaries.
|
|
49
|
+
*/ export const setNestedValue = (obj, path, value, source)=>{
|
|
18
50
|
const parts = path.split('.');
|
|
51
|
+
if (hasUnsupportedFieldPathSegment({
|
|
52
|
+
segments: parts
|
|
53
|
+
})) {
|
|
54
|
+
throw new APIError('Invalid field path.', 400, null, true);
|
|
55
|
+
}
|
|
56
|
+
const lastPart = parts.pop();
|
|
57
|
+
if (lastPart === undefined) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
19
60
|
let current = obj;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
if (isLast) {
|
|
35
|
-
current[index] = value;
|
|
36
|
-
} else {
|
|
37
|
-
current = current[index];
|
|
38
|
-
}
|
|
39
|
-
} else {
|
|
40
|
-
// Ensure the object key exists
|
|
41
|
-
if (isLast) {
|
|
42
|
-
if (typeof part === 'string') {
|
|
43
|
-
current[part] = value;
|
|
44
|
-
}
|
|
45
|
-
} else {
|
|
46
|
-
if (typeof current[part] !== 'object' || current[part] === null) {
|
|
47
|
-
current[part] = {};
|
|
48
|
-
}
|
|
49
|
-
current = current[part];
|
|
50
|
-
}
|
|
61
|
+
let sourceCurrent = source;
|
|
62
|
+
for (const [i, part] of parts.entries()){
|
|
63
|
+
const key = getPathKey(current, part, sourceCurrent);
|
|
64
|
+
const currentRecord = current;
|
|
65
|
+
const nextPart = parts[i + 1] ?? lastPart;
|
|
66
|
+
const nextSource = getSourceValue(sourceCurrent, part);
|
|
67
|
+
const hasOwnNextValue = Object.hasOwn(currentRecord, key);
|
|
68
|
+
const nextValue = hasOwnNextValue ? currentRecord[key] : undefined;
|
|
69
|
+
if (!hasOwnNextValue || typeof nextValue !== 'object' || nextValue === null) {
|
|
70
|
+
setOwnProperty({
|
|
71
|
+
key,
|
|
72
|
+
target: currentRecord,
|
|
73
|
+
value: isArrayIndex(nextPart) ? [] : createObject()
|
|
74
|
+
});
|
|
51
75
|
}
|
|
76
|
+
current = currentRecord[key];
|
|
77
|
+
sourceCurrent = nextSource;
|
|
52
78
|
}
|
|
79
|
+
const lastKey = getPathKey(current, lastPart, sourceCurrent);
|
|
80
|
+
const finalRecord = current;
|
|
81
|
+
setOwnProperty({
|
|
82
|
+
key: lastKey,
|
|
83
|
+
target: finalRecord,
|
|
84
|
+
value
|
|
85
|
+
});
|
|
53
86
|
};
|
|
54
87
|
|
|
55
88
|
//# sourceMappingURL=setNestedValue.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/setNestedValue.ts"],"sourcesContent":["/**\n * Sets a value deeply into a nested object or array, based on a dot-notation path.\n *\n * This function:\n * - Supports array indexing (e.g., \"array.0.field1\")\n * - Creates intermediate arrays/objects as needed\n * - Mutates the target object directly\n *\n * @example\n * const obj = {}\n * setNestedValue(obj, 'group.array.0.field1', 'hello')\n * // Result: { group: { array: [ { field1: 'hello' } ] } }\n *\n * @param obj - The target object to mutate.\n * @param path - A dot-separated string path indicating where to assign the value.\n * @param value - The value to set at the specified path.\n */\n\nexport const setNestedValue = (\n obj: Record<string, unknown>,\n path: string,\n value: unknown,\n): void => {\n const parts = path.split('.')\n
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/setNestedValue.ts"],"sourcesContent":["import { APIError } from 'payload'\nimport { hasUnsupportedFieldPathSegment, setOwnProperty } from 'payload/shared'\n\nconst MAX_UNVERIFIED_SPARSE_ARRAY_GAP = 1\n\nconst createObject = (): Record<string, unknown> => Object.create(null) as Record<string, unknown>\n\nconst isArrayIndex = (part: string): boolean => {\n if (!/^(?:0|[1-9]\\d*)$/.test(part)) {\n return false\n }\n\n const index = Number(part)\n\n return Number.isSafeInteger(index) && index >= 0\n}\n\nconst getPathKey = (\n target: Record<string, unknown> | unknown[],\n part: string,\n source: unknown,\n): number | string => {\n if (!Array.isArray(target) || !isArrayIndex(part)) {\n return part\n }\n\n const index = Number(part)\n\n if (\n (Array.isArray(source) && index >= source.length) ||\n (!Array.isArray(source) && index > target.length + MAX_UNVERIFIED_SPARSE_ARRAY_GAP)\n ) {\n throw new APIError('Invalid field path.', 400, null, true)\n }\n\n return index\n}\n\nconst getSourceValue = (source: unknown, part: string): unknown => {\n if (source === null || typeof source !== 'object') {\n return undefined\n }\n\n const key = Array.isArray(source) && isArrayIndex(part) ? Number(part) : part\n\n if (!Object.hasOwn(source, key)) {\n return undefined\n }\n\n return (source as Record<number | string, unknown>)[key]\n}\n\n/**\n * Sets a value deeply into a nested object or array, based on a dot-notation path.\n *\n * This function:\n * - Supports array indexing (e.g., \"array.0.field1\")\n * - Creates intermediate arrays/objects as needed\n * - Mutates the target object directly\n *\n * @example\n * const obj = {}\n * setNestedValue(obj, 'group.array.0.field1', 'hello')\n * // Result: { group: { array: [ { field1: 'hello' } ] } }\n *\n * @param obj - The target object to mutate.\n * @param path - A dot-separated string path indicating where to assign the value.\n * @param value - The value to set at the specified path.\n * @param source - The source object used to validate array boundaries.\n */\n\nexport const setNestedValue = (\n obj: Record<string, unknown>,\n path: string,\n value: unknown,\n source?: Record<string, unknown>,\n): void => {\n const parts = path.split('.')\n\n if (hasUnsupportedFieldPathSegment({ segments: parts })) {\n throw new APIError('Invalid field path.', 400, null, true)\n }\n\n const lastPart = parts.pop()\n\n if (lastPart === undefined) {\n return\n }\n\n let current: Record<string, unknown> | unknown[] = obj\n let sourceCurrent: unknown = source\n\n for (const [i, part] of parts.entries()) {\n const key = getPathKey(current, part, sourceCurrent)\n const currentRecord = current as Record<number | string, unknown>\n const nextPart = parts[i + 1] ?? lastPart\n const nextSource = getSourceValue(sourceCurrent, part)\n\n const hasOwnNextValue = Object.hasOwn(currentRecord, key)\n const nextValue = hasOwnNextValue ? currentRecord[key] : undefined\n\n if (!hasOwnNextValue || typeof nextValue !== 'object' || nextValue === null) {\n setOwnProperty({\n key,\n target: currentRecord,\n value: isArrayIndex(nextPart) ? [] : createObject(),\n })\n }\n\n current = currentRecord[key] as Record<string, unknown> | unknown[]\n sourceCurrent = nextSource\n }\n\n const lastKey = getPathKey(current, lastPart, sourceCurrent)\n const finalRecord = current as Record<number | string, unknown>\n\n setOwnProperty({ key: lastKey, target: finalRecord, value })\n}\n"],"names":["APIError","hasUnsupportedFieldPathSegment","setOwnProperty","MAX_UNVERIFIED_SPARSE_ARRAY_GAP","createObject","Object","create","isArrayIndex","part","test","index","Number","isSafeInteger","getPathKey","target","source","Array","isArray","length","getSourceValue","undefined","key","hasOwn","setNestedValue","obj","path","value","parts","split","segments","lastPart","pop","current","sourceCurrent","i","entries","currentRecord","nextPart","nextSource","hasOwnNextValue","nextValue","lastKey","finalRecord"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,UAAS;AAClC,SAASC,8BAA8B,EAAEC,cAAc,QAAQ,iBAAgB;AAE/E,MAAMC,kCAAkC;AAExC,MAAMC,eAAe,IAA+BC,OAAOC,MAAM,CAAC;AAElE,MAAMC,eAAe,CAACC;IACpB,IAAI,CAAC,mBAAmBC,IAAI,CAACD,OAAO;QAClC,OAAO;IACT;IAEA,MAAME,QAAQC,OAAOH;IAErB,OAAOG,OAAOC,aAAa,CAACF,UAAUA,SAAS;AACjD;AAEA,MAAMG,aAAa,CACjBC,QACAN,MACAO;IAEA,IAAI,CAACC,MAAMC,OAAO,CAACH,WAAW,CAACP,aAAaC,OAAO;QACjD,OAAOA;IACT;IAEA,MAAME,QAAQC,OAAOH;IAErB,IACE,AAACQ,MAAMC,OAAO,CAACF,WAAWL,SAASK,OAAOG,MAAM,IAC/C,CAACF,MAAMC,OAAO,CAACF,WAAWL,QAAQI,OAAOI,MAAM,GAAGf,iCACnD;QACA,MAAM,IAAIH,SAAS,uBAAuB,KAAK,MAAM;IACvD;IAEA,OAAOU;AACT;AAEA,MAAMS,iBAAiB,CAACJ,QAAiBP;IACvC,IAAIO,WAAW,QAAQ,OAAOA,WAAW,UAAU;QACjD,OAAOK;IACT;IAEA,MAAMC,MAAML,MAAMC,OAAO,CAACF,WAAWR,aAAaC,QAAQG,OAAOH,QAAQA;IAEzE,IAAI,CAACH,OAAOiB,MAAM,CAACP,QAAQM,MAAM;QAC/B,OAAOD;IACT;IAEA,OAAO,AAACL,MAA2C,CAACM,IAAI;AAC1D;AAEA;;;;;;;;;;;;;;;;;CAiBC,GAED,OAAO,MAAME,iBAAiB,CAC5BC,KACAC,MACAC,OACAX;IAEA,MAAMY,QAAQF,KAAKG,KAAK,CAAC;IAEzB,IAAI3B,+BAA+B;QAAE4B,UAAUF;IAAM,IAAI;QACvD,MAAM,IAAI3B,SAAS,uBAAuB,KAAK,MAAM;IACvD;IAEA,MAAM8B,WAAWH,MAAMI,GAAG;IAE1B,IAAID,aAAaV,WAAW;QAC1B;IACF;IAEA,IAAIY,UAA+CR;IACnD,IAAIS,gBAAyBlB;IAE7B,KAAK,MAAM,CAACmB,GAAG1B,KAAK,IAAImB,MAAMQ,OAAO,GAAI;QACvC,MAAMd,MAAMR,WAAWmB,SAASxB,MAAMyB;QACtC,MAAMG,gBAAgBJ;QACtB,MAAMK,WAAWV,KAAK,CAACO,IAAI,EAAE,IAAIJ;QACjC,MAAMQ,aAAanB,eAAec,eAAezB;QAEjD,MAAM+B,kBAAkBlC,OAAOiB,MAAM,CAACc,eAAef;QACrD,MAAMmB,YAAYD,kBAAkBH,aAAa,CAACf,IAAI,GAAGD;QAEzD,IAAI,CAACmB,mBAAmB,OAAOC,cAAc,YAAYA,cAAc,MAAM;YAC3EtC,eAAe;gBACbmB;gBACAP,QAAQsB;gBACRV,OAAOnB,aAAa8B,YAAY,EAAE,GAAGjC;YACvC;QACF;QAEA4B,UAAUI,aAAa,CAACf,IAAI;QAC5BY,gBAAgBK;IAClB;IAEA,MAAMG,UAAU5B,WAAWmB,SAASF,UAAUG;IAC9C,MAAMS,cAAcV;IAEpB9B,eAAe;QAAEmB,KAAKoB;QAAS3B,QAAQ4B;QAAahB;IAAM;AAC5D,EAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Remove a leading '-' from a sort value (e.g. "-title" -> "title") */
|
|
2
2
|
export declare const stripSortDash: (v?: null | string) => string;
|
|
3
3
|
/** Apply order to a base field (("title","desc") -> "-title") */
|
|
4
|
-
export declare const applySortOrder: (field: string, order:
|
|
4
|
+
export declare const applySortOrder: (field: string, order: 'asc' | 'desc') => string;
|
|
5
5
|
export declare const normalizeQueryParam: (v: unknown) => string | undefined;
|
|
6
6
|
//# sourceMappingURL=sortHelpers.d.ts.map
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { FlattenedField, PayloadRequest } from 'payload';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ImportFieldHookEntry } from '../types.js';
|
|
3
3
|
type UnflattenArgs = {
|
|
4
4
|
data: Record<string, unknown>;
|
|
5
5
|
fields: FlattenedField[];
|
|
6
|
-
|
|
6
|
+
format?: 'csv' | 'json' | ({} & string);
|
|
7
|
+
importFieldHooks?: Record<string, ImportFieldHookEntry>;
|
|
7
8
|
req: PayloadRequest;
|
|
8
9
|
};
|
|
9
10
|
/**
|
|
@@ -19,6 +20,6 @@ type UnflattenArgs = {
|
|
|
19
20
|
* - Regular nested objects
|
|
20
21
|
* 4. Post-processes to handle localized fields, hasMany conversions, and relationship transforms
|
|
21
22
|
*/
|
|
22
|
-
export declare const unflattenObject: ({ data, fields,
|
|
23
|
+
export declare const unflattenObject: ({ data, fields, format, importFieldHooks, req, }: UnflattenArgs) => Record<string, unknown>;
|
|
23
24
|
export {};
|
|
24
25
|
//# sourceMappingURL=unflattenObject.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unflattenObject.d.ts","sourceRoot":"","sources":["../../src/utilities/unflattenObject.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAE7D,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"unflattenObject.d.ts","sourceRoot":"","sources":["../../src/utilities/unflattenObject.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAE7D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAKvD,KAAK,aAAa,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7B,MAAM,EAAE,cAAc,EAAE,CAAA;IACxB,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,CAAC,EAAE,GAAG,MAAM,CAAC,CAAA;IACvC,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAA;IACvD,GAAG,EAAE,cAAc,CAAA;CACpB,CAAA;AAuCD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe,qDAMzB,aAAa,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAyUxC,CAAA"}
|
|
@@ -1,4 +1,35 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getBlockFlattenedFields, getNestedFlattenedFields } from './flattenedFields.js';
|
|
2
|
+
import { postProcessDocument } from './unflattenPostProcess.js';
|
|
3
|
+
const indexSegment = /^\d+$/;
|
|
4
|
+
const collectArrayLikeNames = (fields, into)=>{
|
|
5
|
+
for (const field of fields){
|
|
6
|
+
if (!('name' in field) || !field.name) {
|
|
7
|
+
continue;
|
|
8
|
+
}
|
|
9
|
+
if (field.type === 'array' || field.type === 'blocks') {
|
|
10
|
+
into.add(field.name);
|
|
11
|
+
}
|
|
12
|
+
if (field.type === 'blocks') {
|
|
13
|
+
for (const block of field.blocks ?? []){
|
|
14
|
+
collectArrayLikeNames(getBlockFlattenedFields(block), into);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const nested = getNestedFlattenedFields(field);
|
|
18
|
+
if (nested) {
|
|
19
|
+
collectArrayLikeNames(nested, into);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Drops numeric array-index segments from a flat key so a runtime key like
|
|
25
|
+
* `items_0_note` matches the static, index-free key a user hook is registered
|
|
26
|
+
* under. A digit-only segment is only stripped when the segment immediately
|
|
27
|
+
* before it names an array or blocks field, so a literal field name like
|
|
28
|
+
* `2024` is preserved.
|
|
29
|
+
*/ const toLogicalKey = (flatKey, arrayLikeNames)=>{
|
|
30
|
+
const segments = flatKey.split('_');
|
|
31
|
+
return segments.filter((seg, i)=>!indexSegment.test(seg) || !arrayLikeNames.has(segments[i - 1] ?? '')).join('_');
|
|
32
|
+
};
|
|
2
33
|
/**
|
|
3
34
|
* Converts flattened CSV data back into a nested document structure.
|
|
4
35
|
*
|
|
@@ -11,11 +42,13 @@ import { processRichTextField } from './processRichTextField.js';
|
|
|
11
42
|
* - Polymorphic relationships (_relationTo and _id suffix pairs)
|
|
12
43
|
* - Regular nested objects
|
|
13
44
|
* 4. Post-processes to handle localized fields, hasMany conversions, and relationship transforms
|
|
14
|
-
*/ export const unflattenObject = ({ data, fields,
|
|
45
|
+
*/ export const unflattenObject = ({ data, fields, format = 'csv', importFieldHooks = {}, req })=>{
|
|
15
46
|
if (!data || typeof data !== 'object') {
|
|
16
47
|
return {};
|
|
17
48
|
}
|
|
18
49
|
const result = {};
|
|
50
|
+
const arrayLikeNames = new Set();
|
|
51
|
+
collectArrayLikeNames(fields, arrayLikeNames);
|
|
19
52
|
// Sort keys to ensure array indices are processed in order
|
|
20
53
|
const sortedKeys = Object.keys(data).sort((a, b)=>{
|
|
21
54
|
// Extract array indices from flattened keys (e.g., "field_0_subfield" -> "0")
|
|
@@ -72,13 +105,25 @@ import { processRichTextField } from './processRichTextField.js';
|
|
|
72
105
|
}
|
|
73
106
|
}
|
|
74
107
|
}
|
|
75
|
-
|
|
76
|
-
if (
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
108
|
+
const importHookEntry = importFieldHooks[flatKey] ?? importFieldHooks[toLogicalKey(flatKey, arrayLikeNames)];
|
|
109
|
+
if (importHookEntry) {
|
|
110
|
+
try {
|
|
111
|
+
value = importHookEntry.fn({
|
|
112
|
+
columnName: flatKey,
|
|
113
|
+
data,
|
|
114
|
+
format,
|
|
115
|
+
siblingData: data,
|
|
116
|
+
siblingDoc: data,
|
|
117
|
+
value
|
|
118
|
+
});
|
|
119
|
+
} catch (error) {
|
|
120
|
+
req.payload.logger.error({
|
|
121
|
+
err: error,
|
|
122
|
+
msg: `[plugin-import-export] Field-level beforeImport hook for "${flatKey}" threw — falling back to original value`
|
|
123
|
+
});
|
|
124
|
+
// Keep the original value so the row is not dropped — downstream
|
|
125
|
+
// validation will surface any deeper issue per-row.
|
|
126
|
+
}
|
|
82
127
|
}
|
|
83
128
|
// Example: "blocks_0_content_text" -> ["blocks", "0", "content", "text"]
|
|
84
129
|
const pathSegments = flatKey.split('_');
|
|
@@ -190,7 +235,9 @@ import { processRichTextField } from './processRichTextField.js';
|
|
|
190
235
|
blockObject[blockFieldName] = value;
|
|
191
236
|
} else {
|
|
192
237
|
if (!blockObject[blockFieldName] || typeof blockObject[blockFieldName] !== 'object') {
|
|
193
|
-
|
|
238
|
+
const segmentAfterBlockField = pathSegments[i + 4];
|
|
239
|
+
const blockFieldIsArray = segmentAfterBlockField !== undefined && indexSegment.test(segmentAfterBlockField);
|
|
240
|
+
blockObject[blockFieldName] = blockFieldIsArray ? [] : {};
|
|
194
241
|
}
|
|
195
242
|
currentObject = blockObject[blockFieldName];
|
|
196
243
|
i = i + 3;
|
|
@@ -214,6 +261,18 @@ import { processRichTextField } from './processRichTextField.js';
|
|
|
214
261
|
currentObject = arr[arrayIndex];
|
|
215
262
|
i++;
|
|
216
263
|
}
|
|
264
|
+
} else if (Array.isArray(currentObject) && indexSegment.test(segment)) {
|
|
265
|
+
// currentObject is an array we arrived at via block field traversal — treat the
|
|
266
|
+
// segment as a numeric index rather than a plain property name.
|
|
267
|
+
const idx = parseInt(segment, 10);
|
|
268
|
+
const arr = currentObject;
|
|
269
|
+
while(arr.length <= idx){
|
|
270
|
+
arr.push(null);
|
|
271
|
+
}
|
|
272
|
+
if (arr[idx] === null || arr[idx] === undefined) {
|
|
273
|
+
arr[idx] = {};
|
|
274
|
+
}
|
|
275
|
+
currentObject = arr[idx];
|
|
217
276
|
} else {
|
|
218
277
|
// Skip if already set to null (polymorphic relationship already processed)
|
|
219
278
|
if (currentObject[segment] === null && isLast && segment === 'relationTo') {
|
|
@@ -271,165 +330,5 @@ const getParentObject = (obj, segments)=>{
|
|
|
271
330
|
}
|
|
272
331
|
return current;
|
|
273
332
|
};
|
|
274
|
-
/**
|
|
275
|
-
* Post-processes the unflattened document to handle special field types:
|
|
276
|
-
* - Localized fields: transforms field_locale keys to nested { field: { locale: value } }
|
|
277
|
-
* - Number hasMany: converts comma-separated strings or arrays to number arrays
|
|
278
|
-
* - Relationship hasMany: converts comma-separated IDs to arrays
|
|
279
|
-
* - Polymorphic relationships: transforms flat {relationTo, id} to {relationTo, value}
|
|
280
|
-
* - Rich text fields: ensures proper data structure
|
|
281
|
-
*/ const postProcessDocument = (doc, fields)=>{
|
|
282
|
-
const localizedFields = fields.filter((field)=>field.localized);
|
|
283
|
-
const processedLocalizedFields = new Set();
|
|
284
|
-
for (const field of localizedFields){
|
|
285
|
-
if (processedLocalizedFields.has(field.name)) {
|
|
286
|
-
continue;
|
|
287
|
-
}
|
|
288
|
-
// Look for all locale-specific keys for this field
|
|
289
|
-
const localePattern = new RegExp(`^${field.name}_([a-z]{2}(?:_[A-Z]{2})?)$`);
|
|
290
|
-
const localeData = {};
|
|
291
|
-
const keysToDelete = [];
|
|
292
|
-
for (const [key, value] of Object.entries(doc)){
|
|
293
|
-
const match = key.match(localePattern);
|
|
294
|
-
if (match && match[1]) {
|
|
295
|
-
const locale = match[1];
|
|
296
|
-
localeData[locale] = value;
|
|
297
|
-
keysToDelete.push(key);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
// If we found locale-specific data, restructure it as Payload expects
|
|
301
|
-
if (Object.keys(localeData).length > 0) {
|
|
302
|
-
// Payload stores localized fields as nested objects: { field: { en: 'value', es: 'value' } }
|
|
303
|
-
doc[field.name] = localeData;
|
|
304
|
-
keysToDelete.forEach((key)=>delete doc[key]);
|
|
305
|
-
processedLocalizedFields.add(field.name);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
// Handle number fields with hasMany - convert string arrays to number arrays
|
|
309
|
-
const numberFields = fields.filter((field)=>field.type === 'number' && field.hasMany);
|
|
310
|
-
for (const field of numberFields){
|
|
311
|
-
const value = doc[field.name];
|
|
312
|
-
// Skip if field doesn't exist in document
|
|
313
|
-
if (!(field.name in doc)) {
|
|
314
|
-
continue;
|
|
315
|
-
}
|
|
316
|
-
// Handle comma-separated string (e.g., "1,2,3,4,5")
|
|
317
|
-
if (typeof value === 'string' && value.includes(',')) {
|
|
318
|
-
doc[field.name] = value.split(',').map((v)=>v.trim()).filter((v)=>v !== '').map((v)=>{
|
|
319
|
-
const num = parseFloat(v);
|
|
320
|
-
return isNaN(num) ? 0 : num;
|
|
321
|
-
});
|
|
322
|
-
} else if (Array.isArray(value)) {
|
|
323
|
-
// Filter out null, undefined, and empty string values, then convert to numbers
|
|
324
|
-
doc[field.name] = value.filter((v)=>v !== null && v !== undefined && v !== '').map((v)=>{
|
|
325
|
-
if (typeof v === 'string') {
|
|
326
|
-
const num = parseFloat(v);
|
|
327
|
-
return isNaN(num) ? 0 : num;
|
|
328
|
-
}
|
|
329
|
-
return v;
|
|
330
|
-
});
|
|
331
|
-
} else if (value !== null && value !== undefined && value !== '') {
|
|
332
|
-
const num = typeof value === 'string' ? parseFloat(value) : value;
|
|
333
|
-
doc[field.name] = isNaN(num) ? [] : [
|
|
334
|
-
num
|
|
335
|
-
];
|
|
336
|
-
} else {
|
|
337
|
-
doc[field.name] = [];
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
// Handle relationship fields with hasMany - convert comma-separated IDs to arrays
|
|
341
|
-
const relationshipFields = fields.filter((field)=>(field.type === 'relationship' || field.type === 'upload') && field.hasMany === true && !Array.isArray(field.relationTo));
|
|
342
|
-
for (const field of relationshipFields){
|
|
343
|
-
const value = doc[field.name];
|
|
344
|
-
// Handle comma-separated string of IDs (e.g., "id1,id2,id3")
|
|
345
|
-
if (typeof value === 'string' && value.includes(',')) {
|
|
346
|
-
doc[field.name] = value.split(',').map((v)=>v.trim()).filter((v)=>v !== '');
|
|
347
|
-
} else if (Array.isArray(value)) {
|
|
348
|
-
doc[field.name] = value.filter((v)=>v !== null && v !== undefined && v !== '');
|
|
349
|
-
} else if (value !== null && value !== undefined && value !== '') {
|
|
350
|
-
doc[field.name] = [
|
|
351
|
-
value
|
|
352
|
-
];
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
// Handle polymorphic relationships - transform from flat structure to proper format
|
|
356
|
-
for (const [key, value] of Object.entries(doc)){
|
|
357
|
-
// Handle arrays of polymorphic relationships
|
|
358
|
-
if (Array.isArray(value)) {
|
|
359
|
-
// Check if this array contains polymorphic relationship objects
|
|
360
|
-
const hasPolymorphicItems = value.some((item)=>typeof item === 'object' && item !== null && 'relationTo' in item);
|
|
361
|
-
if (hasPolymorphicItems) {
|
|
362
|
-
// Filter out null/invalid polymorphic items and transform valid ones
|
|
363
|
-
const processedArray = [];
|
|
364
|
-
for(let i = 0; i < value.length; i++){
|
|
365
|
-
const item = value[i];
|
|
366
|
-
if (typeof item === 'object' && item !== null && 'relationTo' in item) {
|
|
367
|
-
const typedItem = item;
|
|
368
|
-
// Skip if both relationTo and value/id are null/empty
|
|
369
|
-
if (!typedItem.relationTo || !typedItem.id && !typedItem.value) {
|
|
370
|
-
continue;
|
|
371
|
-
}
|
|
372
|
-
// Transform from {relationTo: 'collection', id: '123'} to {relationTo: 'collection', value: '123'}
|
|
373
|
-
if ('id' in typedItem) {
|
|
374
|
-
typedItem.value = typedItem.id;
|
|
375
|
-
delete typedItem.id;
|
|
376
|
-
}
|
|
377
|
-
processedArray.push(typedItem);
|
|
378
|
-
} else if (item !== null && item !== undefined) {
|
|
379
|
-
processedArray.push(item);
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
// Update the array with filtered results
|
|
383
|
-
if (value.length !== processedArray.length) {
|
|
384
|
-
doc[key] = processedArray.length > 0 ? processedArray : [];
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
// For non-polymorphic arrays, preserve null placeholders for sparse arrays
|
|
388
|
-
} else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
|
389
|
-
// Check if this is a single polymorphic relationship
|
|
390
|
-
if ('relationTo' in value && ('id' in value || 'value' in value)) {
|
|
391
|
-
const typedValue = value;
|
|
392
|
-
// If both relationTo and value are null/empty, set the whole field to null
|
|
393
|
-
if (!typedValue.relationTo || !typedValue.id && !typedValue.value) {
|
|
394
|
-
doc[key] = null;
|
|
395
|
-
} else {
|
|
396
|
-
// If it has 'id', transform to 'value'
|
|
397
|
-
if ('id' in typedValue && !('value' in typedValue)) {
|
|
398
|
-
typedValue.value = typedValue.id;
|
|
399
|
-
delete typedValue.id;
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
} else {
|
|
403
|
-
// Recursively process nested objects
|
|
404
|
-
postProcessDocument(value, fields);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
// Process rich text fields to ensure proper data types
|
|
409
|
-
const richTextFields = fields.filter((field)=>field.type === 'richText');
|
|
410
|
-
for (const field of richTextFields){
|
|
411
|
-
if (field.name in doc && doc[field.name]) {
|
|
412
|
-
doc[field.name] = processRichTextField(doc[field.name]);
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
// Also process rich text fields in blocks
|
|
416
|
-
const blockFields = fields.filter((field)=>field.type === 'blocks');
|
|
417
|
-
for (const field of blockFields){
|
|
418
|
-
if (field.name in doc && Array.isArray(doc[field.name])) {
|
|
419
|
-
const blocks = doc[field.name];
|
|
420
|
-
for (const block of blocks){
|
|
421
|
-
if (!block || typeof block !== 'object') {
|
|
422
|
-
continue;
|
|
423
|
-
}
|
|
424
|
-
// Look for richText fields directly in the block
|
|
425
|
-
for (const [key, value] of Object.entries(block)){
|
|
426
|
-
if (key === 'richText' || typeof key === 'string' && key.includes('richText')) {
|
|
427
|
-
block[key] = processRichTextField(value);
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
};
|
|
434
333
|
|
|
435
334
|
//# sourceMappingURL=unflattenObject.js.map
|