Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .talismanrc
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ fileignoreconfig:
checksum: 7c3993212b359b175c3665b4efb22dd35163518e4240031c4269427cbef36b93
- filename: .husky/pre-commit
checksum: 5baabd7d2c391648163f9371f0e5e9484f8fb90fa2284cfc378732ec3192c193
- filename: src/generateTS/factory.ts
checksum: 4be7b31934d36cbc6275a9155b3414293f6b9a1083ccfbd80d979ecf4ce8a0ac
version: "1.0"
55 changes: 34 additions & 21 deletions src/generateTS/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export default function (userOptions: TSGenOptions) {
const cachedModularBlocks: ModularBlockCache = {};
const modularBlockInterfaces = new Set<string>();
const uniqueBlockInterfaces = new Set<string>();
const blockInterfacesKeyToName: { [key: string]: string } = {};
let counter = 1;

const typeMap: TypeMap = {
Expand Down Expand Up @@ -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) {
Expand Down