Skip to content

Commit 1dbf2d7

Browse files
Merge pull request #877 from contentstack/bugfix/sitecore-bugs/cmg-785
fix: Update buildSchemaTree to handle old parent UID and improve fiel…
2 parents 387859d + 47f7a3e commit 1dbf2d7

File tree

1 file changed

+51
-26
lines changed

1 file changed

+51
-26
lines changed

api/src/utils/content-type-creator.utils.ts

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ function buildFieldSchema(item: any, marketPlacePath: string, parentUid = ''): a
200200
data_type: "group",
201201
display_name: item?.display_name || rawUid, // Keep original for display
202202
field_metadata: {},
203-
schema: groupSchema,
203+
schema: removeDuplicateFields(groupSchema),
204204
uid: itemUid, // Snake case uid
205205
multiple: item?.advanced?.multiple || false,
206206
mandatory: item?.advanced?.mandatory || false,
@@ -237,40 +237,50 @@ function getLastSegmentNew(str: string, separator: string): string {
237237
return segments[segments.length - 1].trim();
238238
}
239239

240-
export function buildSchemaTree(fields: any[], parentUid = '', parentType = ''): any[] {
240+
export function buildSchemaTree(fields: any[], parentUid = '', parentType = '', oldParentUid = ''): any[] {
241241

242242
if (!Array.isArray(fields)) {
243243
console.warn('buildSchemaTree called with invalid fields:', fields);
244244
return [];
245245
}
246246
// Build a lookup map for O(1) access
247247
const fieldMap = new Map<string, any>();
248-
fields.forEach(f => {
249-
if (f.contentstackFieldUid) {
250-
fieldMap.set(f.contentstackFieldUid, f);
248+
fields?.forEach(f => {
249+
if (f?.contentstackFieldUid) {
250+
fieldMap?.set(f?.contentstackFieldUid, f);
251251
}
252252
});
253253

254254
// Filter direct children of current parent
255255
const directChildren = fields.filter(field => {
256-
const fieldUid = field.contentstackFieldUid || '';
256+
const fieldUid = field?.contentstackFieldUid || '';
257257

258258
if (!parentUid) {
259259
// Root level - only fields without dots
260-
return fieldUid && !fieldUid.includes('.');
260+
return fieldUid && !fieldUid?.includes('.');
261261
}
262262

263-
// Check if direct child of parent
264-
if (!fieldUid.startsWith(parentUid + '.')) return false;
263+
// Check if field is a direct child of parentUid
264+
if (fieldUid?.startsWith(parentUid + '.')) {
265+
const remainder = fieldUid?.substring(parentUid.length + 1);
266+
// Verify it's exactly one level deeper (no more dots in remainder)
267+
return remainder && !remainder?.includes('.');
268+
}
269+
270+
// Fallback: check if field is a direct child of oldPrentUid (if provided and different)
271+
if (oldParentUid && oldParentUid !== parentUid && fieldUid?.startsWith(oldParentUid + '.')) {
272+
const remainder = fieldUid?.substring(oldParentUid.length + 1);
273+
// Verify it's exactly one level deeper (no more dots in remainder)
274+
return remainder && !remainder?.includes('.');
275+
}
265276

266-
// Verify it's exactly one level deeper
267-
const remainder = fieldUid.substring(parentUid.length + 1);
268-
return remainder && !remainder.includes('.');
277+
// Not a direct child
278+
return false;
269279
});
270280

271281
return directChildren.map(field => {
272-
const uid = getLastSegmentNew(field.contentstackFieldUid, '.');
273-
const displayName = field.display_name || getLastSegmentNew(field.contentstackField || '', '>').trim();
282+
const uid = getLastSegmentNew(field?.contentstackFieldUid, '.');
283+
const displayName = field?.display_name || getLastSegmentNew(field?.contentstackField || '', '>').trim();
274284

275285
// Base field structure
276286
const result: any = {
@@ -280,14 +290,29 @@ export function buildSchemaTree(fields: any[], parentUid = '', parentType = ''):
280290
};
281291

282292
// Determine if field should have nested schema
283-
const fieldUid = field.contentstackFieldUid;
284-
const fieldType = field.contentstackFieldType;
285-
286-
// Check if this field has children
287-
const hasChildren = fields.some(f =>
288-
f.contentstackFieldUid &&
289-
f.contentstackFieldUid.startsWith(fieldUid + '.')
290-
);
293+
const fieldUid = field?.contentstackFieldUid;
294+
const fieldType = field?.contentstackFieldType;
295+
const oldFieldUid = field?.backupFieldUid;
296+
297+
// Check if this field has direct children (exactly one level deeper)
298+
const hasChildren = fields.some(f => {
299+
const fUid = f?.contentstackFieldUid || '';
300+
if (!fUid) return false;
301+
302+
// Check if field starts with current fieldUid and is exactly one level deeper
303+
if (fieldUid && fUid?.startsWith(fieldUid + '.')) {
304+
const remainder = fUid?.substring(fieldUid.length + 1);
305+
return remainder && !remainder?.includes('.');
306+
}
307+
308+
// Check if field starts with oldFieldtUid and is exactly one level deeper
309+
if (oldFieldUid && fUid?.startsWith(oldFieldUid + '.')) {
310+
const remainder = fUid?.substring(oldFieldUid.length + 1);
311+
return remainder && !remainder?.includes('.');
312+
}
313+
314+
return false;
315+
});
291316

292317
if (hasChildren) {
293318
if (fieldType === 'modular_blocks') {
@@ -307,13 +332,13 @@ export function buildSchemaTree(fields: any[], parentUid = '', parentType = ''):
307332
...child,
308333
uid: childUid,
309334
display_name: childDisplay,
310-
schema: buildSchemaTree(fields, child.contentstackFieldUid, 'modular_blocks_child')
335+
schema: buildSchemaTree(fields, child.contentstackFieldUid, 'modular_blocks_child', child?.backupFieldUid)
311336
};
312337
});
313338
} else if (fieldType === 'group' ||
314339
(fieldType === 'modular_blocks_child' && hasChildren)) {
315340
// Recursively build schema for groups and modular block children with nested content
316-
result.schema = buildSchemaTree(fields, fieldUid, fieldType);
341+
result.schema = buildSchemaTree(fields, fieldUid, fieldType, oldFieldUid);
317342
}
318343
}
319344

@@ -996,7 +1021,7 @@ const mergeTwoCts = async (ct: any, mergeCts: any) => {
9961021
group?.push(fieldGp);
9971022
}
9981023
}
999-
field.schema = [...field?.schema ?? [], ...group];
1024+
field.schema = removeDuplicateFields([...field?.schema ?? [], ...group]);
10001025
}
10011026
}
10021027
ctData.schema = await mergeArrays(ctData?.schema, mergeCts?.schema) ?? [];
@@ -1022,7 +1047,7 @@ export const contenTypeMaker = async ({ contentType, destinationStackId, project
10221047

10231048
// Safe: ensures we never pass undefined to the builder
10241049
const ctData: any[] = buildSchemaTree(contentType?.fieldMapping || []);
1025-
1050+
10261051
// Use the deep converter that properly handles groups & modular blocks
10271052
for (const item of ctData) {
10281053
if (item?.isDeleted === true) continue;

0 commit comments

Comments
 (0)