spex-parser 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +37 -0
- package/.github/workflows/publish.yml +35 -0
- package/.prettierrc +8 -0
- package/LICENSE +7 -0
- package/README.md +513 -0
- package/dist/ast.d.ts +48 -0
- package/dist/ast.d.ts.map +1 -0
- package/dist/ast.js +2 -0
- package/dist/ast.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/lexer.d.ts +30 -0
- package/dist/lexer.d.ts.map +1 -0
- package/dist/lexer.js +109 -0
- package/dist/lexer.js.map +1 -0
- package/dist/parser.d.ts +18 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +132 -0
- package/dist/parser.js.map +1 -0
- package/dist/visitor.d.ts +22 -0
- package/dist/visitor.d.ts.map +1 -0
- package/dist/visitor.js +154 -0
- package/dist/visitor.js.map +1 -0
- package/eslint.config.js +27 -0
- package/package.json +45 -0
- package/src/ast.ts +67 -0
- package/src/index.ts +13 -0
- package/src/lexer.ts +121 -0
- package/src/parser.ts +170 -0
- package/src/visitor.ts +179 -0
- package/tests/e2e.test.ts +17 -0
- package/tests/lexer.test.ts +123 -0
- package/tests/parser.test.ts +227 -0
- package/tests/props/todo.spex +83 -0
- package/tests/visitor.test.ts +463 -0
- package/tsconfig.json +47 -0
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { parseToAst } from '../src/visitor.js'
|
|
3
|
+
import type {
|
|
4
|
+
ObjectDeclaration,
|
|
5
|
+
ImportDeclaration,
|
|
6
|
+
ExportDeclaration,
|
|
7
|
+
GenerateDeclaration,
|
|
8
|
+
} from '../src/ast.js'
|
|
9
|
+
|
|
10
|
+
describe('SpexParserVisitor', () => {
|
|
11
|
+
describe('object declaration', () => {
|
|
12
|
+
it('should convert named object declaration to AST', () => {
|
|
13
|
+
const testCase = 'create MyObject as Number;'
|
|
14
|
+
const ast = parseToAst(testCase)
|
|
15
|
+
const decl = ast.declarations[0] as ObjectDeclaration
|
|
16
|
+
expect(decl).toEqual({
|
|
17
|
+
kind: 'ObjectDeclaration',
|
|
18
|
+
name: 'MyObject',
|
|
19
|
+
object: {
|
|
20
|
+
kind: 'NamedObject',
|
|
21
|
+
name: 'Number',
|
|
22
|
+
},
|
|
23
|
+
})
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('should convert product object declaration to AST', () => {
|
|
27
|
+
const testCase = 'create MyProduct as (n: Number, s: String);'
|
|
28
|
+
const ast = parseToAst(testCase)
|
|
29
|
+
const decl = ast.declarations[0] as ObjectDeclaration
|
|
30
|
+
expect(decl).toEqual({
|
|
31
|
+
kind: 'ObjectDeclaration',
|
|
32
|
+
name: 'MyProduct',
|
|
33
|
+
object: {
|
|
34
|
+
kind: 'ProductObject',
|
|
35
|
+
fields: {
|
|
36
|
+
n: { kind: 'NamedObject', name: 'Number' },
|
|
37
|
+
s: { kind: 'NamedObject', name: 'String' },
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
})
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it('should convert product object declaration with trailing commas to AST', () => {
|
|
44
|
+
const testCase = 'create MyProduct as (n: Number, s: String,);'
|
|
45
|
+
const ast = parseToAst(testCase)
|
|
46
|
+
const decl = ast.declarations[0] as ObjectDeclaration
|
|
47
|
+
expect(decl).toEqual({
|
|
48
|
+
kind: 'ObjectDeclaration',
|
|
49
|
+
name: 'MyProduct',
|
|
50
|
+
object: {
|
|
51
|
+
kind: 'ProductObject',
|
|
52
|
+
fields: {
|
|
53
|
+
n: { kind: 'NamedObject', name: 'Number' },
|
|
54
|
+
s: { kind: 'NamedObject', name: 'String' },
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
})
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it('should convert product object declaration with exponential objects to AST', () => {
|
|
61
|
+
const testCase = 'create MyProduct as (f: Number -> String, n: Number);'
|
|
62
|
+
const ast = parseToAst(testCase)
|
|
63
|
+
const decl = ast.declarations[0] as ObjectDeclaration
|
|
64
|
+
expect(decl).toEqual({
|
|
65
|
+
kind: 'ObjectDeclaration',
|
|
66
|
+
name: 'MyProduct',
|
|
67
|
+
object: {
|
|
68
|
+
kind: 'ProductObject',
|
|
69
|
+
fields: {
|
|
70
|
+
f: {
|
|
71
|
+
kind: 'ExponentialObject',
|
|
72
|
+
exponent: { kind: 'NamedObject', name: 'Number' },
|
|
73
|
+
base: { kind: 'NamedObject', name: 'String' },
|
|
74
|
+
},
|
|
75
|
+
n: { kind: 'NamedObject', name: 'Number' },
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
})
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
it('should convert product object declaration with subobjects to AST', () => {
|
|
82
|
+
const testCase =
|
|
83
|
+
'create MyProduct as (p: from Number select { value is positive }, n: Number);'
|
|
84
|
+
const ast = parseToAst(testCase)
|
|
85
|
+
const decl = ast.declarations[0] as ObjectDeclaration
|
|
86
|
+
expect(decl).toEqual({
|
|
87
|
+
kind: 'ObjectDeclaration',
|
|
88
|
+
name: 'MyProduct',
|
|
89
|
+
object: {
|
|
90
|
+
kind: 'ProductObject',
|
|
91
|
+
fields: {
|
|
92
|
+
p: {
|
|
93
|
+
kind: 'SubObject',
|
|
94
|
+
base: { kind: 'NamedObject', name: 'Number' },
|
|
95
|
+
constraint: 'value is positive',
|
|
96
|
+
},
|
|
97
|
+
n: { kind: 'NamedObject', name: 'Number' },
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
})
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
it('should convert exponential object declaration with named object to AST', () => {
|
|
104
|
+
const testCase = 'create MyExponential as Number -> Unit;'
|
|
105
|
+
const ast = parseToAst(testCase)
|
|
106
|
+
const decl = ast.declarations[0] as ObjectDeclaration
|
|
107
|
+
expect(decl).toEqual({
|
|
108
|
+
kind: 'ObjectDeclaration',
|
|
109
|
+
name: 'MyExponential',
|
|
110
|
+
object: {
|
|
111
|
+
kind: 'ExponentialObject',
|
|
112
|
+
exponent: { kind: 'NamedObject', name: 'Number' },
|
|
113
|
+
base: { kind: 'NamedObject', name: 'Unit' },
|
|
114
|
+
},
|
|
115
|
+
})
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
it('should convert exponential object declaration with product objects to AST', () => {
|
|
119
|
+
const testCase = 'create MyExponential as (n: Number) -> (s: String);'
|
|
120
|
+
const ast = parseToAst(testCase)
|
|
121
|
+
const decl = ast.declarations[0] as ObjectDeclaration
|
|
122
|
+
expect(decl).toEqual({
|
|
123
|
+
kind: 'ObjectDeclaration',
|
|
124
|
+
name: 'MyExponential',
|
|
125
|
+
object: {
|
|
126
|
+
kind: 'ExponentialObject',
|
|
127
|
+
exponent: {
|
|
128
|
+
kind: 'ProductObject',
|
|
129
|
+
fields: {
|
|
130
|
+
n: { kind: 'NamedObject', name: 'Number' },
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
base: {
|
|
134
|
+
kind: 'ProductObject',
|
|
135
|
+
fields: {
|
|
136
|
+
s: { kind: 'NamedObject', name: 'String' },
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
})
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
it('should convert exponential object declaration with exponential objects to AST', () => {
|
|
144
|
+
const testCase = 'create MyExponential as (f: Number -> String, n: Number) -> String;'
|
|
145
|
+
const ast = parseToAst(testCase)
|
|
146
|
+
const decl = ast.declarations[0] as ObjectDeclaration
|
|
147
|
+
expect(decl).toEqual({
|
|
148
|
+
kind: 'ObjectDeclaration',
|
|
149
|
+
name: 'MyExponential',
|
|
150
|
+
object: {
|
|
151
|
+
kind: 'ExponentialObject',
|
|
152
|
+
exponent: {
|
|
153
|
+
kind: 'ProductObject',
|
|
154
|
+
fields: {
|
|
155
|
+
f: {
|
|
156
|
+
kind: 'ExponentialObject',
|
|
157
|
+
exponent: { kind: 'NamedObject', name: 'Number' },
|
|
158
|
+
base: { kind: 'NamedObject', name: 'String' },
|
|
159
|
+
},
|
|
160
|
+
n: { kind: 'NamedObject', name: 'Number' },
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
base: { kind: 'NamedObject', name: 'String' },
|
|
164
|
+
},
|
|
165
|
+
})
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
it('should convert exponential object declaration with subobjects to AST', () => {
|
|
169
|
+
const testCase =
|
|
170
|
+
'create MyExponential as from Number select { value is positive } -> from Number select { value is positive };'
|
|
171
|
+
const ast = parseToAst(testCase)
|
|
172
|
+
const decl = ast.declarations[0] as ObjectDeclaration
|
|
173
|
+
expect(decl).toEqual({
|
|
174
|
+
kind: 'ObjectDeclaration',
|
|
175
|
+
name: 'MyExponential',
|
|
176
|
+
object: {
|
|
177
|
+
kind: 'ExponentialObject',
|
|
178
|
+
exponent: {
|
|
179
|
+
kind: 'SubObject',
|
|
180
|
+
base: { kind: 'NamedObject', name: 'Number' },
|
|
181
|
+
constraint: 'value is positive',
|
|
182
|
+
},
|
|
183
|
+
base: {
|
|
184
|
+
kind: 'SubObject',
|
|
185
|
+
base: { kind: 'NamedObject', name: 'Number' },
|
|
186
|
+
constraint: 'value is positive',
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
})
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
it('should convert subobject declaration with named objects to AST', () => {
|
|
193
|
+
const testCase = 'create PositiveNumber as from Number select { isPositive };'
|
|
194
|
+
const ast = parseToAst(testCase)
|
|
195
|
+
const decl = ast.declarations[0] as ObjectDeclaration
|
|
196
|
+
expect(decl).toEqual({
|
|
197
|
+
kind: 'ObjectDeclaration',
|
|
198
|
+
name: 'PositiveNumber',
|
|
199
|
+
object: {
|
|
200
|
+
kind: 'SubObject',
|
|
201
|
+
base: { kind: 'NamedObject', name: 'Number' },
|
|
202
|
+
constraint: 'isPositive',
|
|
203
|
+
},
|
|
204
|
+
})
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
it('should convert subobject declaration with text constraint to AST', () => {
|
|
208
|
+
const testCase = 'create PositiveNumber as from Number select { the number is positive };'
|
|
209
|
+
const ast = parseToAst(testCase)
|
|
210
|
+
const decl = ast.declarations[0] as ObjectDeclaration
|
|
211
|
+
expect(decl).toEqual({
|
|
212
|
+
kind: 'ObjectDeclaration',
|
|
213
|
+
name: 'PositiveNumber',
|
|
214
|
+
object: {
|
|
215
|
+
kind: 'SubObject',
|
|
216
|
+
base: { kind: 'NamedObject', name: 'Number' },
|
|
217
|
+
constraint: 'the number is positive',
|
|
218
|
+
},
|
|
219
|
+
})
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
it('should convert subobject declaration with product objects to AST', () => {
|
|
223
|
+
const testCase =
|
|
224
|
+
'create MySubobject as from (n: Number, s: String) select { @n is positive };'
|
|
225
|
+
const ast = parseToAst(testCase)
|
|
226
|
+
const decl = ast.declarations[0] as ObjectDeclaration
|
|
227
|
+
expect(decl).toEqual({
|
|
228
|
+
kind: 'ObjectDeclaration',
|
|
229
|
+
name: 'MySubobject',
|
|
230
|
+
object: {
|
|
231
|
+
kind: 'SubObject',
|
|
232
|
+
base: {
|
|
233
|
+
kind: 'ProductObject',
|
|
234
|
+
fields: {
|
|
235
|
+
n: { kind: 'NamedObject', name: 'Number' },
|
|
236
|
+
s: { kind: 'NamedObject', name: 'String' },
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
constraint: '@n is positive',
|
|
240
|
+
},
|
|
241
|
+
})
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
it('should convert subobject declaration with exponential objects to AST', () => {
|
|
245
|
+
const testCase =
|
|
246
|
+
'create MySubobject as from (n: Number, s: String) -> Bool select { logs the given input };'
|
|
247
|
+
const ast = parseToAst(testCase)
|
|
248
|
+
const decl = ast.declarations[0] as ObjectDeclaration
|
|
249
|
+
expect(decl).toEqual({
|
|
250
|
+
kind: 'ObjectDeclaration',
|
|
251
|
+
name: 'MySubobject',
|
|
252
|
+
object: {
|
|
253
|
+
kind: 'SubObject',
|
|
254
|
+
base: {
|
|
255
|
+
kind: 'ExponentialObject',
|
|
256
|
+
exponent: {
|
|
257
|
+
kind: 'ProductObject',
|
|
258
|
+
fields: {
|
|
259
|
+
n: { kind: 'NamedObject', name: 'Number' },
|
|
260
|
+
s: { kind: 'NamedObject', name: 'String' },
|
|
261
|
+
},
|
|
262
|
+
},
|
|
263
|
+
base: { kind: 'NamedObject', name: 'Bool' },
|
|
264
|
+
},
|
|
265
|
+
constraint: 'logs the given input',
|
|
266
|
+
},
|
|
267
|
+
})
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
it('should convert subobject declaration with subobjects to AST', () => {
|
|
271
|
+
const testCase =
|
|
272
|
+
'create MySubobject as from from Number select { value is positive } select { value is odd };'
|
|
273
|
+
const ast = parseToAst(testCase)
|
|
274
|
+
const decl = ast.declarations[0] as ObjectDeclaration
|
|
275
|
+
expect(decl).toEqual({
|
|
276
|
+
kind: 'ObjectDeclaration',
|
|
277
|
+
name: 'MySubobject',
|
|
278
|
+
object: {
|
|
279
|
+
kind: 'SubObject',
|
|
280
|
+
base: {
|
|
281
|
+
kind: 'SubObject',
|
|
282
|
+
base: { kind: 'NamedObject', name: 'Number' },
|
|
283
|
+
constraint: 'value is positive',
|
|
284
|
+
},
|
|
285
|
+
constraint: 'value is odd',
|
|
286
|
+
},
|
|
287
|
+
})
|
|
288
|
+
})
|
|
289
|
+
|
|
290
|
+
it('should convert basic object string to AST', () => {
|
|
291
|
+
const testCase = 'create MyObject as string;'
|
|
292
|
+
const ast = parseToAst(testCase)
|
|
293
|
+
const decl = ast.declarations[0] as ObjectDeclaration
|
|
294
|
+
expect(decl).toEqual({
|
|
295
|
+
kind: 'ObjectDeclaration',
|
|
296
|
+
name: 'MyObject',
|
|
297
|
+
object: {
|
|
298
|
+
kind: 'NamedObject',
|
|
299
|
+
name: 'string',
|
|
300
|
+
},
|
|
301
|
+
})
|
|
302
|
+
})
|
|
303
|
+
|
|
304
|
+
it('should convert basic object number to AST', () => {
|
|
305
|
+
const testCase = 'create MyObject as number;'
|
|
306
|
+
const ast = parseToAst(testCase)
|
|
307
|
+
const decl = ast.declarations[0] as ObjectDeclaration
|
|
308
|
+
expect(decl).toEqual({
|
|
309
|
+
kind: 'ObjectDeclaration',
|
|
310
|
+
name: 'MyObject',
|
|
311
|
+
object: {
|
|
312
|
+
kind: 'NamedObject',
|
|
313
|
+
name: 'number',
|
|
314
|
+
},
|
|
315
|
+
})
|
|
316
|
+
})
|
|
317
|
+
|
|
318
|
+
it('should convert basic object bool to AST', () => {
|
|
319
|
+
const testCase = 'create MyObject as bool;'
|
|
320
|
+
const ast = parseToAst(testCase)
|
|
321
|
+
const decl = ast.declarations[0] as ObjectDeclaration
|
|
322
|
+
expect(decl).toEqual({
|
|
323
|
+
kind: 'ObjectDeclaration',
|
|
324
|
+
name: 'MyObject',
|
|
325
|
+
object: {
|
|
326
|
+
kind: 'NamedObject',
|
|
327
|
+
name: 'bool',
|
|
328
|
+
},
|
|
329
|
+
})
|
|
330
|
+
})
|
|
331
|
+
|
|
332
|
+
it('should convert basic object unit to AST', () => {
|
|
333
|
+
const testCase = 'create MyObject as unit;'
|
|
334
|
+
const ast = parseToAst(testCase)
|
|
335
|
+
const decl = ast.declarations[0] as ObjectDeclaration
|
|
336
|
+
expect(decl).toEqual({
|
|
337
|
+
kind: 'ObjectDeclaration',
|
|
338
|
+
name: 'MyObject',
|
|
339
|
+
object: {
|
|
340
|
+
kind: 'NamedObject',
|
|
341
|
+
name: 'unit',
|
|
342
|
+
},
|
|
343
|
+
})
|
|
344
|
+
})
|
|
345
|
+
|
|
346
|
+
it('should convert array type declaration to AST', () => {
|
|
347
|
+
const testCase = 'create MyArray as string[];'
|
|
348
|
+
const ast = parseToAst(testCase)
|
|
349
|
+
const decl = ast.declarations[0] as ObjectDeclaration
|
|
350
|
+
expect(decl).toEqual({
|
|
351
|
+
kind: 'ObjectDeclaration',
|
|
352
|
+
name: 'MyArray',
|
|
353
|
+
object: {
|
|
354
|
+
kind: 'ArrayObject',
|
|
355
|
+
base: { kind: 'NamedObject', name: 'string' },
|
|
356
|
+
},
|
|
357
|
+
})
|
|
358
|
+
})
|
|
359
|
+
|
|
360
|
+
it('should convert array of product type to AST', () => {
|
|
361
|
+
const testCase = 'create MyArray as (n: Number)[];'
|
|
362
|
+
const ast = parseToAst(testCase)
|
|
363
|
+
const decl = ast.declarations[0] as ObjectDeclaration
|
|
364
|
+
expect(decl).toEqual({
|
|
365
|
+
kind: 'ObjectDeclaration',
|
|
366
|
+
name: 'MyArray',
|
|
367
|
+
object: {
|
|
368
|
+
kind: 'ArrayObject',
|
|
369
|
+
base: {
|
|
370
|
+
kind: 'ProductObject',
|
|
371
|
+
fields: {
|
|
372
|
+
n: { kind: 'NamedObject', name: 'Number' },
|
|
373
|
+
},
|
|
374
|
+
},
|
|
375
|
+
},
|
|
376
|
+
})
|
|
377
|
+
})
|
|
378
|
+
|
|
379
|
+
it('should convert dotted name to AST', () => {
|
|
380
|
+
const testCase =
|
|
381
|
+
'create SignUp as (user: types.EmailAddress, pass: types.Password) -> string;'
|
|
382
|
+
const ast = parseToAst(testCase)
|
|
383
|
+
const decl = ast.declarations[0] as ObjectDeclaration
|
|
384
|
+
expect(decl).toEqual({
|
|
385
|
+
kind: 'ObjectDeclaration',
|
|
386
|
+
name: 'SignUp',
|
|
387
|
+
object: {
|
|
388
|
+
kind: 'ExponentialObject',
|
|
389
|
+
exponent: {
|
|
390
|
+
kind: 'ProductObject',
|
|
391
|
+
fields: {
|
|
392
|
+
user: { kind: 'NamedObject', name: 'types.EmailAddress' },
|
|
393
|
+
pass: { kind: 'NamedObject', name: 'types.Password' },
|
|
394
|
+
},
|
|
395
|
+
},
|
|
396
|
+
base: { kind: 'NamedObject', name: 'string' },
|
|
397
|
+
},
|
|
398
|
+
})
|
|
399
|
+
})
|
|
400
|
+
})
|
|
401
|
+
|
|
402
|
+
describe('import declaration', () => {
|
|
403
|
+
it('should convert named import to AST', () => {
|
|
404
|
+
const testCase = 'import EmailAddress from "types.spex";'
|
|
405
|
+
const ast = parseToAst(testCase)
|
|
406
|
+
const decl = ast.declarations[0] as ImportDeclaration
|
|
407
|
+
expect(decl).toEqual({
|
|
408
|
+
kind: 'ImportDeclaration',
|
|
409
|
+
name: 'EmailAddress',
|
|
410
|
+
source: 'types.spex',
|
|
411
|
+
alias: null,
|
|
412
|
+
})
|
|
413
|
+
})
|
|
414
|
+
|
|
415
|
+
it('should convert named import with alias to AST', () => {
|
|
416
|
+
const testCase = 'import EmailAddress from "types.spex" as Username;'
|
|
417
|
+
const ast = parseToAst(testCase)
|
|
418
|
+
const decl = ast.declarations[0] as ImportDeclaration
|
|
419
|
+
expect(decl).toEqual({
|
|
420
|
+
kind: 'ImportDeclaration',
|
|
421
|
+
name: 'EmailAddress',
|
|
422
|
+
source: 'types.spex',
|
|
423
|
+
alias: 'Username',
|
|
424
|
+
})
|
|
425
|
+
})
|
|
426
|
+
|
|
427
|
+
it('should convert module import to AST', () => {
|
|
428
|
+
const testCase = 'import "types.spex" as types;'
|
|
429
|
+
const ast = parseToAst(testCase)
|
|
430
|
+
const decl = ast.declarations[0] as ImportDeclaration
|
|
431
|
+
expect(decl).toEqual({
|
|
432
|
+
kind: 'ImportDeclaration',
|
|
433
|
+
name: null,
|
|
434
|
+
source: 'types.spex',
|
|
435
|
+
alias: 'types',
|
|
436
|
+
})
|
|
437
|
+
})
|
|
438
|
+
})
|
|
439
|
+
|
|
440
|
+
describe('export declaration', () => {
|
|
441
|
+
it('should convert export declaration to AST', () => {
|
|
442
|
+
const testCase = 'export EmailAddress;'
|
|
443
|
+
const ast = parseToAst(testCase)
|
|
444
|
+
const decl = ast.declarations[0] as ExportDeclaration
|
|
445
|
+
expect(decl).toEqual({
|
|
446
|
+
kind: 'ExportDeclaration',
|
|
447
|
+
name: 'EmailAddress',
|
|
448
|
+
})
|
|
449
|
+
})
|
|
450
|
+
})
|
|
451
|
+
|
|
452
|
+
describe('generate declaration', () => {
|
|
453
|
+
it('should convert generate declaration to AST', () => {
|
|
454
|
+
const testCase = 'generate Main;'
|
|
455
|
+
const ast = parseToAst(testCase)
|
|
456
|
+
const decl = ast.declarations[0] as GenerateDeclaration
|
|
457
|
+
expect(decl).toEqual({
|
|
458
|
+
kind: 'GenerateDeclaration',
|
|
459
|
+
name: 'Main',
|
|
460
|
+
})
|
|
461
|
+
})
|
|
462
|
+
})
|
|
463
|
+
})
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Visit https://aka.ms/tsconfig to read more about this file
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
// File Layout
|
|
5
|
+
"rootDir": "./src",
|
|
6
|
+
"outDir": "./dist",
|
|
7
|
+
|
|
8
|
+
// Environment Settings
|
|
9
|
+
// See also https://aka.ms/tsconfig/module
|
|
10
|
+
"module": "nodenext",
|
|
11
|
+
"target": "es2022",
|
|
12
|
+
"types": ["node"],
|
|
13
|
+
"moduleResolution": "nodenext",
|
|
14
|
+
// For nodejs:
|
|
15
|
+
"lib": ["ES2022"],
|
|
16
|
+
// "types": ["node"],
|
|
17
|
+
// and npm install -D @types/node
|
|
18
|
+
|
|
19
|
+
// Other Outputs
|
|
20
|
+
"sourceMap": true,
|
|
21
|
+
"declaration": true,
|
|
22
|
+
"declarationMap": true,
|
|
23
|
+
|
|
24
|
+
// Stricter Typechecking Options
|
|
25
|
+
"noUncheckedIndexedAccess": true,
|
|
26
|
+
"exactOptionalPropertyTypes": true,
|
|
27
|
+
|
|
28
|
+
// Style Options
|
|
29
|
+
// "noImplicitReturns": true,
|
|
30
|
+
// "noImplicitOverride": true,
|
|
31
|
+
// "noUnusedLocals": true,
|
|
32
|
+
// "noUnusedParameters": true,
|
|
33
|
+
// "noFallthroughCasesInSwitch": true,
|
|
34
|
+
// "noPropertyAccessFromIndexSignature": true,
|
|
35
|
+
|
|
36
|
+
// Recommended Options
|
|
37
|
+
"strict": true,
|
|
38
|
+
"jsx": "react-jsx",
|
|
39
|
+
"verbatimModuleSyntax": true,
|
|
40
|
+
"isolatedModules": true,
|
|
41
|
+
"noUncheckedSideEffectImports": true,
|
|
42
|
+
"moduleDetection": "force",
|
|
43
|
+
"skipLibCheck": true,
|
|
44
|
+
},
|
|
45
|
+
"include": ["src/**/*"],
|
|
46
|
+
"exclude": ["dist/**/*"],
|
|
47
|
+
}
|