1
1
import { parse , type Node } from "kdljs" ;
2
- import type { Enum , Event , Property } from "./types" ;
2
+ import type { Enum , Event , Property , Interface , WebIdl } from "./types" ;
3
3
import { readdir , readFile } from "fs/promises" ;
4
4
import { merge } from "./helpers.js" ;
5
- type Properties = Record < string , Partial < Property > > ;
5
+
6
+ type DeepPartial < T > = T extends object
7
+ ? { [ K in keyof T ] ?: DeepPartial < T [ K ] > }
8
+ : T ;
6
9
7
10
/**
8
11
* Converts patch files in KDL to match the [types](types.d.ts).
9
12
*/
10
- function parseKDL ( kdlText : string ) {
13
+ function parseKDL ( kdlText : string ) : DeepPartial < WebIdl > {
11
14
const { output, errors } = parse ( kdlText ) ;
12
15
13
16
if ( errors . length ) {
@@ -16,22 +19,26 @@ function parseKDL(kdlText: string) {
16
19
17
20
const nodes = output ! ;
18
21
const enums : Record < string , Enum > = { } ;
19
- const mixins : Record < string , any > = { } ;
22
+ const mixin : Record < string , DeepPartial < Interface > > = { } ;
20
23
21
24
for ( const node of nodes ) {
25
+ const name = node . values [ 0 ] ;
26
+ if ( typeof name !== "string" ) {
27
+ throw new Error ( `Missing name for ${ node . name } ` ) ;
28
+ }
22
29
switch ( node . name ) {
23
30
case "enum" :
24
- handleEnum ( node , enums ) ;
31
+ enums [ name ] = handleEnum ( node ) ;
25
32
break ;
26
33
case "interface-mixin" :
27
- handleMixin ( node , mixins ) ;
34
+ mixin [ name ] = handleMixin ( node ) ;
28
35
break ;
29
36
default :
30
37
throw new Error ( `Unknown node name: ${ node . name } ` ) ;
31
38
}
32
39
}
33
40
34
- return { enums : { enum : enums } , mixins : { mixin : mixins } } ;
41
+ return { enums : { enum : enums } , mixins : { mixin } } ;
35
42
}
36
43
37
44
/**
@@ -40,7 +47,7 @@ function parseKDL(kdlText: string) {
40
47
* @param node The enum node to handle.
41
48
* @param enums The record of enums to update.
42
49
*/
43
- function handleEnum ( node : Node , enums : Record < string , Enum > ) {
50
+ function handleEnum ( node : Node ) : Enum {
44
51
const name = node . values [ 0 ] ;
45
52
if ( typeof name !== "string" ) {
46
53
throw new Error ( "Missing enum name" ) ;
@@ -51,7 +58,7 @@ function handleEnum(node: Node, enums: Record<string, Enum>) {
51
58
values . push ( child . name ) ;
52
59
}
53
60
54
- enums [ name ] = { name, value : values } ;
61
+ return { name, value : values } ;
55
62
}
56
63
57
64
/**
@@ -61,14 +68,14 @@ function handleEnum(node: Node, enums: Record<string, Enum>) {
61
68
* @param node The mixin node to handle.
62
69
* @param mixins The record of mixins to update.
63
70
*/
64
- function handleMixin ( node : Node , mixins : Record < string , any > ) {
71
+ function handleMixin ( node : Node ) : DeepPartial < Interface > {
65
72
const name = node . values [ 0 ] ;
66
73
if ( typeof name !== "string" ) {
67
74
throw new Error ( "Missing mixin name" ) ;
68
75
}
69
76
70
77
const event : Event [ ] = [ ] ;
71
- const property : Properties = { } ;
78
+ const property : Record < string , Partial < Property > > = { } ;
72
79
73
80
for ( const child of node . children ) {
74
81
switch ( child . name ) {
@@ -85,14 +92,18 @@ function handleMixin(node: Node, mixins: Record<string, any>) {
85
92
}
86
93
}
87
94
88
- mixins [ name ] = { name, events : { event } , properties : { property } } ;
95
+ return {
96
+ name,
97
+ events : { event } ,
98
+ properties : { property } ,
99
+ } as DeepPartial < Interface > ;
89
100
}
90
101
91
102
/**
92
103
* Handles a child node of type "event" and adds it to the event array.
93
104
* @param child The child node to handle.
94
105
*/
95
- function handleEvent ( child : Node ) {
106
+ function handleEvent ( child : Node ) : Event {
96
107
return {
97
108
name : child . values [ 0 ] as string ,
98
109
type : child . properties . type as string ,
@@ -103,7 +114,7 @@ function handleEvent(child: Node) {
103
114
* Handles a child node of type "property" and adds it to the property object.
104
115
* @param child The child node to handle.
105
116
*/
106
- function handleProperty ( child : Node ) {
117
+ function handleProperty ( child : Node ) : Partial < Property > {
107
118
return {
108
119
name : child . values [ 0 ] as string ,
109
120
exposed : child . properties ?. exposed as string ,
0 commit comments