diff --git a/.talismanrc b/.talismanrc index bd60885..3a30eed 100644 --- a/.talismanrc +++ b/.talismanrc @@ -6,4 +6,6 @@ fileignoreconfig: checksum: 7c3993212b359b175c3665b4efb22dd35163518e4240031c4269427cbef36b93 - filename: .husky/pre-commit checksum: 5baabd7d2c391648163f9371f0e5e9484f8fb90fa2284cfc378732ec3192c193 + - filename: src/generateTS/factory.ts + checksum: 4be7b31934d36cbc6275a9155b3414293f6b9a1083ccfbd80d979ecf4ce8a0ac version: "1.0" diff --git a/src/generateTS/factory.ts b/src/generateTS/factory.ts index 9ebb647..16c9d32 100644 --- a/src/generateTS/factory.ts +++ b/src/generateTS/factory.ts @@ -72,6 +72,7 @@ export default function (userOptions: TSGenOptions) { const cachedModularBlocks: ModularBlockCache = {}; const modularBlockInterfaces = new Set(); const uniqueBlockInterfaces = new Set(); + const blockInterfacesKeyToName: { [key: string]: string } = {}; let counter = 1; const typeMap: TypeMap = { @@ -280,39 +281,51 @@ export default function (userOptions: TSGenOptions) { } function type_modular_blocks(field: ContentstackTypes.Field): string { - let blockInterfaceName = name_type(field.uid); + let modularBlockInterfaceName = name_type(field.uid); - const blockInterfaces = field.blocks.map((block) => { - const fieldType = block.reference_to + const modularBlockDefinitions = field.blocks.map((block) => { + const blockFieldType = block.reference_to ? name_type(block.reference_to) : visit_fields(block.schema || []); - const schema = block.reference_to - ? `${fieldType};` - : `{\n ${fieldType} }`; - return `${block.uid}: ${schema}`; + const blockSchemaDefinition = block.reference_to + ? `${blockFieldType};` + : `{\n ${blockFieldType} }`; + return `${block.uid}: ${blockSchemaDefinition}`; }); - const blockInterfacesKey = blockInterfaces.join(";"); - - if (!uniqueBlockInterfaces.has(blockInterfacesKey)) { - uniqueBlockInterfaces.add(blockInterfacesKey); - // Keep appending a counter until a unique name is found - while (cachedModularBlocks[blockInterfaceName]) { - blockInterfaceName = `${blockInterfaceName}${counter}`; - counter++; + const modularBlockSignature = JSON.stringify(modularBlockDefinitions); + + if (uniqueBlockInterfaces.has(modularBlockSignature)) { + // Find the existing interface name for this structure using O(1) lookup + const existingInterfaceName = + blockInterfacesKeyToName[modularBlockSignature]; + if (existingInterfaceName) { + return field.multiple + ? `${existingInterfaceName}[]` + : existingInterfaceName; } } - const modularInterface = [ - `export interface ${blockInterfaceName} {`, - blockInterfaces.join("\n"), + uniqueBlockInterfaces.add(modularBlockSignature); + + while (cachedModularBlocks[modularBlockInterfaceName]) { + modularBlockInterfaceName = `${modularBlockInterfaceName}${counter}`; + counter++; + } + + const modularBlockInterfaceDefinition = [ + `export interface ${modularBlockInterfaceName} {`, + modularBlockDefinitions.join("\n"), "}", ].join("\n"); // Store or track the generated block interface for later use - modularBlockInterfaces.add(modularInterface); - cachedModularBlocks[blockInterfaceName] = blockInterfaceName; - return field.multiple ? `${blockInterfaceName}[]` : blockInterfaceName; + modularBlockInterfaces.add(modularBlockInterfaceDefinition); + cachedModularBlocks[modularBlockInterfaceName] = modularBlockSignature; + blockInterfacesKeyToName[modularBlockSignature] = modularBlockInterfaceName; + return field.multiple + ? `${modularBlockInterfaceName}[]` + : modularBlockInterfaceName; } function type_group(field: ContentstackTypes.Field) {