Skip to content

Commit 4ac4764

Browse files
committed
fix: Enhance buildFieldSchema and buildSchemaTree functions to handle duplicate fields and improve UID checks
1 parent f4b9d57 commit 4ac4764

File tree

1 file changed

+45
-23
lines changed

1 file changed

+45
-23
lines changed

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

Lines changed: 45 additions & 23 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,
@@ -245,9 +245,9 @@ export function buildSchemaTree(fields: any[], parentUid = '', parentType = '',
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

@@ -260,12 +260,22 @@ export function buildSchemaTree(fields: any[], parentUid = '', parentType = '',
260260
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 (oldPrentUid && oldPrentUid !== parentUid && fieldUid.startsWith(oldPrentUid + '.')) {
272+
const remainder = fieldUid.substring(oldPrentUid.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.startsWith(parentUid) ? fieldUid.substring(parentUid.length + 1) : fieldUid.substring(oldPrentUid.length + 1);
268-
return remainder && !remainder.includes('.');
277+
// Not a direct child
278+
return false;
269279
});
270280

271281
return directChildren.map(field => {
@@ -282,13 +292,27 @@ export function buildSchemaTree(fields: any[], parentUid = '', parentType = '',
282292
// Determine if field should have nested schema
283293
const fieldUid = field.contentstackFieldUid;
284294
const fieldType = field.contentstackFieldType;
285-
const oldFieldtUid = field?.backupFieldUid || '';
286-
287-
// Check if this field has children
288-
const hasChildren = fields.some(f =>
289-
f.contentstackFieldUid &&
290-
(f.contentstackFieldUid.startsWith(fieldUid + '.') || f.contentstackFieldUid.startsWith(oldFieldtUid + '.'))
291-
);
295+
const oldFieldtUid = 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 (oldFieldtUid && fUid.startsWith(oldFieldtUid + '.')) {
310+
const remainder = fUid.substring(oldFieldtUid.length + 1);
311+
return remainder && !remainder.includes('.');
312+
}
313+
314+
return false;
315+
});
292316

293317
if (hasChildren) {
294318
if (fieldType === 'modular_blocks') {
@@ -308,14 +332,13 @@ export function buildSchemaTree(fields: any[], parentUid = '', parentType = '',
308332
...child,
309333
uid: childUid,
310334
display_name: childDisplay,
311-
schema: buildSchemaTree(fields, child.contentstackFieldUid, 'modular_blocks_child', field?.backupFieldUid || '')
335+
schema: buildSchemaTree(fields, child.contentstackFieldUid, 'modular_blocks_child', child?.backupFieldUid)
312336
};
313337
});
314338
} else if (fieldType === 'group' ||
315339
(fieldType === 'modular_blocks_child' && hasChildren)) {
316-
//console.info(`Building schema for group/modular_blocks_child: ${fieldUid}`);
317340
// Recursively build schema for groups and modular block children with nested content
318-
result.schema = buildSchemaTree(fields, fieldUid, fieldType, field?.backupFieldUid);
341+
result.schema = buildSchemaTree(fields, fieldUid, fieldType, oldFieldtUid);
319342
}
320343
}
321344

@@ -998,7 +1021,7 @@ const mergeTwoCts = async (ct: any, mergeCts: any) => {
9981021
group?.push(fieldGp);
9991022
}
10001023
}
1001-
field.schema = [...field?.schema ?? [], ...group];
1024+
field.schema = removeDuplicateFields([...field?.schema ?? [], ...group]);
10021025
}
10031026
}
10041027
ctData.schema = await mergeArrays(ctData?.schema, mergeCts?.schema) ?? [];
@@ -1024,11 +1047,11 @@ export const contenTypeMaker = async ({ contentType, destinationStackId, project
10241047

10251048
// Safe: ensures we never pass undefined to the builder
10261049
const ctData: any[] = buildSchemaTree(contentType?.fieldMapping || []);
1027-
1050+
10281051
// Use the deep converter that properly handles groups & modular blocks
10291052
for (const item of ctData) {
10301053
if (item?.isDeleted === true) continue;
1031-
//console.info("item --> ", item)
1054+
10321055
const fieldSchema = buildFieldSchema(item, marketPlacePath, '');
10331056
if (fieldSchema) {
10341057
ct?.schema.push(fieldSchema);
@@ -1039,7 +1062,6 @@ export const contenTypeMaker = async ({ contentType, destinationStackId, project
10391062
ct.schema = removeDuplicateFields(ct.schema || []);
10401063

10411064
if (currentCt?.uid) {
1042-
console.info('Merging with existing content type:', ctData);
10431065
ct = await mergeTwoCts(ct, currentCt);
10441066
}
10451067
if (ct?.uid && Array.isArray(ct?.schema) && ct?.schema.length) {

0 commit comments

Comments
 (0)