Skip to content

Commit d4b65c3

Browse files
Merge pull request #27 from contentstack/modular-block-enhancement
Enhanced modular blocks to generate separate interface
2 parents d78a415 + 69ac0ac commit d4b65c3

File tree

5 files changed

+88
-83
lines changed

5 files changed

+88
-83
lines changed

README.md

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -123,38 +123,7 @@ interface BuiltinExample {
123123
/** Single Choice */
124124
single_choice: "Choice 1" | "Choice 2" | "Choice 3";
125125
/** Modular Blocks */
126-
modular_blocks?: (
127-
| {
128-
block_1: {
129-
/** Number */
130-
number?: number;
131-
/** Single line textbox */
132-
single_line?: string;
133-
};
134-
block_2: undefined;
135-
seo_gf: undefined;
136-
}
137-
| {
138-
block_2: {
139-
/** Boolean */
140-
boolean?: boolean;
141-
/** Date */
142-
date?: string;
143-
};
144-
block_1: undefined;
145-
seo_gf: undefined;
146-
}
147-
| {
148-
seo_gf: {
149-
/** Keywords */
150-
keywords?: string;
151-
/** Description */
152-
description?: string;
153-
};
154-
block_1: undefined;
155-
block_2: undefined;
156-
}
157-
)[];
126+
modular_blocks?: ModularBlocks[];
158127
/** Number */
159128
number?: number;
160129
/** Link */
@@ -166,6 +135,27 @@ interface BuiltinExample {
166135
/** Date */
167136
date?: string;
168137
}
138+
139+
interface ModularBlocks {
140+
block_1: {
141+
/** Number */
142+
number?: number;
143+
/** Single line textbox */
144+
single_line?: string;
145+
};
146+
block_2: {
147+
/** Boolean */
148+
boolean?: boolean;
149+
/** Date */
150+
date?: string;
151+
};
152+
seo_gf: {
153+
/** Keywords */
154+
keywords?: string;
155+
/** Description */
156+
description?: string;
157+
};
158+
}
169159
```
170160

171161
#### 2. `graphqlTS()` (Available only for NodeJS)

package-lock.json

Lines changed: 19 additions & 19 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@contentstack/types-generator",
3-
"version": "1.0.4",
3+
"version": "2.0.0",
44
"description": "Contentstack type definition generation library",
55
"private": false,
66
"author": "Contentstack",
@@ -42,7 +42,7 @@
4242
"typescript": "^5.4.5"
4343
},
4444
"dependencies": {
45-
"@contentstack/delivery-sdk": "^4.0.5",
45+
"@contentstack/delivery-sdk": "^4.1.0",
4646
"@gql2ts/from-schema": "^2.0.0-4",
4747
"axios": "^1.7.4",
4848
"lodash": "^4.17.21",

src/generateTS/factory.ts

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export default function (userOptions: TSGenOptions) {
6565
const visitedGlobalFields = new Set<string>();
6666
const visitedContentTypes = new Set<string>();
6767
const cachedGlobalFields: GlobalFieldCache = {};
68+
const modularBlockInterfaces = new Set<string>();
6869

6970
const typeMap: TypeMap = {
7071
text: { func: type_text, track: true, flag: TypeFlags.BuiltinJS },
@@ -233,6 +234,8 @@ export default function (userOptions: TSGenOptions) {
233234
if (field.multiple) {
234235
fieldType += "[]";
235236
}
237+
} else if (field.data_type === "blocks") {
238+
fieldType = type_modular_blocks(field);
236239
}
237240
return [
238241
field.uid + op_required(field.mandatory) + ":",
@@ -260,7 +263,8 @@ export default function (userOptions: TSGenOptions) {
260263
function visit_content_type(
261264
contentType: ContentstackTypes.ContentType | ContentstackTypes.GlobalField
262265
) {
263-
return [
266+
modularBlockInterfaces.clear();
267+
const contentTypeInterface = [
264268
options.docgen.interface(contentType.description),
265269
define_interface(contentType, options.systemFields),
266270
"{",
@@ -271,29 +275,34 @@ export default function (userOptions: TSGenOptions) {
271275
]
272276
.filter((v) => v)
273277
.join("\n");
274-
}
275278

276-
function visit_modular_block(
277-
field: ContentstackTypes.Field,
278-
block: ContentstackTypes.Block
279-
) {
280-
return (
281-
"{" +
282-
[
283-
block.uid + ":",
284-
block.reference_to
285-
? name_type(block.reference_to as string) + ";"
286-
: "{" + visit_fields(block.schema || []) + "};",
287-
].join(" ") +
288-
visit_block_names(field, block) +
289-
"}"
290-
);
279+
return [...modularBlockInterfaces, contentTypeInterface].join("\n\n");
291280
}
292281

293-
function type_modular_blocks(field: ContentstackTypes.Field) {
294-
return op_paren(
295-
field.blocks.map((block) => visit_modular_block(field, block)).join(" | ")
296-
);
282+
function type_modular_blocks(field: ContentstackTypes.Field): string {
283+
const blockInterfaceName = name_type(field.uid);
284+
const blockInterfaces = field.blocks.map((block) => {
285+
const fieldType =
286+
block.reference_to && cachedGlobalFields[name_type(block.reference_to)]
287+
? name_type(block.reference_to)
288+
: visit_fields(block.schema || []);
289+
290+
const schema = block.reference_to
291+
? `${fieldType};`
292+
: `{\n ${fieldType} }`;
293+
return `${block.uid}: ${schema}`;
294+
});
295+
296+
const modularInterface = [
297+
`export interface ${blockInterfaceName} {`,
298+
blockInterfaces.join("\n"),
299+
"}",
300+
].join("\n");
301+
302+
// Store or track the generated block interface for later use
303+
modularBlockInterfaces.add(modularInterface);
304+
305+
return field.multiple ? `${blockInterfaceName}[]` : blockInterfaceName;
297306
}
298307

299308
function type_group(field: ContentstackTypes.Field) {

tests/unit/tsgen/modular.blocks.test.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,26 @@ describe("modular blocks", () => {
1818

1919
test("definition", () => {
2020
expect(result.definition).toMatchInlineSnapshot(`
21-
"export interface ModularBlocks
21+
"export interface ModularBlocks {
22+
string_block: {
23+
single_line?: string ;
24+
multi_line?: string ;
25+
markdown?: string ;
26+
rich_text_editor?: string ; }
27+
string_block_with_options: {
28+
single_line_textbox_required: string ;
29+
single_line_textbox_multiple?: string[] ; }
30+
boolean_block: {
31+
boolean?: boolean ; }
32+
}
33+
34+
export interface ModularBlocks
2235
{
2336
/** Version */
2437
_version: 2 ;
2538
title: string ;
2639
url: string ;
27-
modular_blocks?: ({string_block: {single_line?: string ;
28-
multi_line?: string ;
29-
markdown?: string ;
30-
rich_text_editor?: string ;};string_block_with_options: undefined;
31-
boolean_block: undefined;} | {string_block_with_options: {single_line_textbox_required: string ;
32-
single_line_textbox_multiple?: string[] ;};string_block: undefined;
33-
boolean_block: undefined;} | {boolean_block: {boolean?: boolean ;};string_block: undefined;
34-
string_block_with_options: undefined;})[] ;
40+
modular_blocks?: ModularBlocks[] ;
3541
}"
3642
`);
3743
});

0 commit comments

Comments
 (0)