diff --git a/api/src/services/drupal/entries.service.ts b/api/src/services/drupal/entries.service.ts index 84b4b5587..3368226e6 100644 --- a/api/src/services/drupal/entries.service.ts +++ b/api/src/services/drupal/entries.service.ts @@ -441,11 +441,18 @@ const processFieldByType = ( case 'file': { // File/Asset processing with proper validation and cleanup + // Note: earlier processing (processFieldData) may have already resolved + // the raw target_id into an asset reference object - pass those through + // as-is instead of re-deriving `assets_${value}` from the object. if (fieldMapping.advanced?.multiple) { // Multiple files if (Array.isArray(value)) { const validAssets = value ?.map((assetRef) => { + if (assetRef && typeof assetRef === 'object' && assetRef?.uid) { + return assetRef; // Already resolved + } + const assetKey = `assets_${assetRef}`; const assetReference = assetId?.[assetKey]; @@ -462,8 +469,29 @@ const processFieldByType = ( return validAssets?.length > 0 ? validAssets : undefined; // Return undefined if no valid assets } + + // processFieldData resolves asset target_ids to a single reference + // object even for multiple-value fields - normalize into an array + // instead of returning a bare object where Contentstack expects one. + if (value && typeof value === 'object' && value?.uid) { + return [value]; + } + + const assetKey = `assets_${value}`; + const assetReference = assetId?.[assetKey]; + + if (assetReference && typeof assetReference === 'object') { + return [assetReference]; + } + + console.error(`Asset ${assetKey} not found or invalid, removing field`); + return undefined; } else { // Single file + if (value && typeof value === 'object' && value?.uid) { + return value; // Already resolved + } + const assetKey = `assets_${value}`; const assetReference = assetId?.[assetKey]; @@ -479,16 +507,36 @@ const processFieldByType = ( case 'reference': { // Reference processing + // Note: earlier processing (processFieldData) may have already resolved + // reference ids into reference objects - pass those through as-is. if (fieldMapping.advanced?.multiple) { // Multiple references if (Array.isArray(value)) { - return value?.map( - (refId) => - referenceId?.[`content_type_entries_title_${refId}`] || refId, - ); + return value?.map((refId) => { + if (refId && typeof refId === 'object' && refId?.uid) { + return refId; // Already resolved + } + return referenceId?.[`content_type_entries_title_${refId}`] || refId; + }); } } else { // Single reference + if (Array.isArray(value)) { + // processFieldData normalizes reference target_ids into an array of + // resolved reference objects even for single-value fields - return + // as-is instead of wrapping again into a nested array [[{uid,...}]]. + // Mirror the `multiple` branch above and resolve any raw (unresolved) + // IDs still present, e.g. from _tid fields built in the ctValue loop. + return value.map((refId) => { + if (refId && typeof refId === 'object' && refId?.uid) { + return refId; // Already resolved + } + return referenceId?.[`content_type_entries_title_${refId}`] || refId; + }); + } + if (value && typeof value === 'object' && value?.uid) { + return [value]; // Already resolved + } return [referenceId?.[`content_type_entries_title_${value}`] || value]; } return value; @@ -671,8 +719,11 @@ const processFieldData = async ( const assetReference = assetId?.[assetKey]; if (assetReference && typeof assetReference === 'object') { processedData[dataKey] = assetReference; + } else { + console.error(`Asset ${assetKey} not found or invalid, removing field`); } - // If asset reference is not properly structured, skip the field + } else { + console.error(`Asset ${assetKey} not found or invalid, removing field`); } // If asset not found in assets index, mark field as skipped skippedFields?.add(dataKey);