Skip to content

Commit bda3c24

Browse files
authored
Merge pull request #125 from contentstack/development
DX | 09-09-2024 | Release
2 parents 012fe6f + f85dd83 commit bda3c24

File tree

6 files changed

+135
-60
lines changed

6 files changed

+135
-60
lines changed

MIGRATION.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
## Migrating from v2 to v3
2+
This document outlines the necessary changes to separate nested modular blocks into distinct interfaces. This update will affect how modular blocks are structured and used throughout the codebase.
3+
4+
## Before
5+
```typescript
6+
export interface Test {
7+
/** Version */
8+
_version?: 2;
9+
/** Title */
10+
title: string;
11+
/** Modular Blocks */
12+
modular_blocks?: {
13+
test: {
14+
/** Multi Line Textbox */
15+
multi_line?: string;
16+
/** Rich Text Editor */
17+
rich_text_editor?: string;
18+
/** Modular Blocks1 */
19+
modular_blocks1?: {
20+
test1: {
21+
/** Multi Line Textbox */
22+
multi_line?: string;
23+
};
24+
}[];
25+
};
26+
}[];
27+
}
28+
```
29+
30+
31+
## After
32+
```typescript
33+
export interface Test {
34+
/** Version */
35+
_version: 2;
36+
/** Title */
37+
title: string;
38+
/** Modular Blocks */
39+
modular_blocks?: ModularBlocks[];
40+
}
41+
42+
43+
export interface ModularBlocks {
44+
/** Multi Line Textbox */
45+
multi_line?: string;
46+
/** Rich Text Editor */
47+
rich_text_editor?: string;
48+
/** Modular Blocks1 */
49+
modular_blocks1?: ModularBlocks1[];
50+
}
51+
52+
export interface ModularBlocks1 {
53+
/** Multi Line Textbox */
54+
multi_line?: string;
55+
}
56+
```

README.md

Lines changed: 25 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ This plugin generates TypeScript typings from Content Types. Interfaces and fiel
1111
$ csdx plugins:install contentstack-cli-tsgen
1212
```
1313

14+
## Migration
15+
Refer to the [Migration Guide](https://github.com/contentstack/contentstack-cli-tsgen/blob/master/MIGRATION.md) version 3 if you are migrating from version 2 or older.
16+
1417
## How to use this plugin
1518

1619
`$ csdx tsgen`
@@ -92,38 +95,7 @@ interface BuiltinExample {
9295
/** Single Choice */
9396
single_choice: "Choice 1" | "Choice 2" | "Choice 3";
9497
/** Modular Blocks */
95-
modular_blocks?: (
96-
| {
97-
block_1: {
98-
/** Number */
99-
number?: number;
100-
/** Single line textbox */
101-
single_line?: string;
102-
};
103-
block_2: undefined;
104-
seo_gf: undefined;
105-
}
106-
| {
107-
block_2: {
108-
/** Boolean */
109-
boolean?: boolean;
110-
/** Date */
111-
date?: string;
112-
};
113-
block_1: undefined;
114-
seo_gf: undefined;
115-
}
116-
| {
117-
seo_gf: {
118-
/** Keywords */
119-
keywords?: string;
120-
/** Description */
121-
description?: string;
122-
};
123-
block_1: undefined;
124-
block_2: undefined;
125-
}
126-
)[];
98+
modular_blocks?:ModularBlocks[];
12799
/** Number */
128100
number?: number;
129101
/** Link */
@@ -135,4 +107,25 @@ interface BuiltinExample {
135107
/** Date */
136108
date?: string;
137109
}
110+
111+
interface ModularBlocks {
112+
block_1: {
113+
/** Number */
114+
number?: number;
115+
/** Single line textbox */
116+
single_line?: string;
117+
};
118+
block_2: {
119+
/** Boolean */
120+
boolean?: boolean;
121+
/** Date */
122+
date?: string;
123+
};
124+
seo_gf: {
125+
/** Keywords */
126+
keywords?: string;
127+
/** Description */
128+
description?: string;
129+
};
130+
}
138131
```

package-lock.json

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

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "contentstack-cli-tsgen",
33
"description": "Generate TypeScript typings from a Stack.",
4-
"version": "2.3.4",
4+
"version": "3.0.0",
55
"author": "Michael Davis",
66
"bugs": "https://github.com/Contentstack-Solutions/contentstack-cli-tsgen/issues",
77
"dependencies": {

src/lib/tsgen/factory.ts

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ type GlobalFieldCache = {
3131
[prop: string]: { definition: string };
3232
};
3333

34+
type ModularBlockCache = {
35+
[prop: string]: string;
36+
};
37+
3438
enum TypeFlags {
3539
BuiltinJS = 1 << 0,
3640
BuiltinCS = 1 << 1,
@@ -65,6 +69,8 @@ export default function (userOptions: TSGenOptions) {
6569
const visitedGlobalFields = new Set<string>()
6670
const visitedContentTypes = new Set<string>()
6771
const cachedGlobalFields: GlobalFieldCache = {}
72+
const cachedModularBlocks: ModularBlockCache = {}
73+
const modularBlockInterfaces = new Set<string>()
6874

6975
const typeMap: TypeMap = {
7076
text: {func: type_text, track: true, flag: TypeFlags.BuiltinJS},
@@ -215,6 +221,8 @@ export default function (userOptions: TSGenOptions) {
215221
if (field.multiple) {
216222
fieldType += "[]";
217223
}
224+
}else if (field.data_type === 'blocks') {
225+
fieldType = type_modular_blocks(field);
218226
}
219227
return [
220228
field.uid + op_required(field.mandatory) + ':',
@@ -235,7 +243,8 @@ export default function (userOptions: TSGenOptions) {
235243
function visit_content_type(
236244
contentType: ContentstackTypes.ContentType | ContentstackTypes.GlobalField
237245
) {
238-
return [
246+
modularBlockInterfaces.clear();
247+
const contentTypeInterface = [
239248
options.docgen.interface(contentType.description),
240249
define_interface(contentType, options.systemFields),
241250
'{',
@@ -246,25 +255,36 @@ export default function (userOptions: TSGenOptions) {
246255
]
247256
.filter(v => v)
248257
.join('\n')
249-
}
250258

251-
function visit_modular_block(
252-
field: ContentstackTypes.Field,
253-
block: ContentstackTypes.Block
254-
) {
255-
return (
256-
'{' +
257-
[block.uid + ':', block.reference_to ? name_type(block.reference_to as string) + ';' : '{' + visit_fields(block.schema || []) + '};'].join(' ') +
258-
visit_block_names(field, block) +
259-
'}'
260-
)
259+
return [...modularBlockInterfaces, contentTypeInterface].join('\n\n');
261260
}
262261

263-
function type_modular_blocks(field: ContentstackTypes.Field) {
264-
return op_paren(
265-
field.blocks.map(block => visit_modular_block(field, block)).join(' | ')
266-
)
262+
function type_modular_blocks(field: ContentstackTypes.Field): string {
263+
const blockInterfaceName = name_type(field.uid);
264+
if(!cachedModularBlocks[blockInterfaceName]){
265+
const blockInterfaces = field.blocks.map((block) => {
266+
const fieldType = block.reference_to && cachedGlobalFields[name_type(block.reference_to)]
267+
? name_type(block.reference_to)
268+
: visit_fields(block.schema || []);
269+
270+
const schema = block.reference_to ? `${fieldType};` : `{\n ${fieldType} }`;
271+
return `${block.uid}: ${schema}`;
272+
});
273+
274+
const modularInterface = [
275+
`export interface ${blockInterfaceName} {`,
276+
blockInterfaces.join('\n'),
277+
'}',
278+
].join('\n');
279+
280+
// Store or track the generated block interface for later use
281+
modularBlockInterfaces.add(modularInterface);
282+
cachedModularBlocks[blockInterfaceName] = blockInterfaceName;
283+
}
284+
285+
return field.multiple ? `${blockInterfaceName}[]` : blockInterfaceName;
267286
}
287+
268288

269289
function type_group(field: ContentstackTypes.Field) {
270290
return ['{', visit_fields(field.schema), '}'].filter(v => v).join('\n')

tests/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)