@player-tools/xlr-converters 0.0.2-next.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/README.md +7 -0
- package/dist/index.cjs.js +756 -0
- package/dist/index.d.ts +86 -0
- package/dist/index.esm.js +746 -0
- package/package.json +35 -0
- package/src/index.ts +5 -0
- package/src/ts-to-xlr.ts +725 -0
- package/src/types.ts +15 -0
- package/src/xlr-to-ts.ts +511 -0
package/src/types.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Specific error that can be caught to indicate an error in conversion
|
|
3
|
+
*/
|
|
4
|
+
export class ConversionError extends Error {
|
|
5
|
+
constructor(msg: string) {
|
|
6
|
+
super(msg);
|
|
7
|
+
|
|
8
|
+
// Set the prototype explicitly.
|
|
9
|
+
Object.setPrototypeOf(this, ConversionError.prototype);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
toString() {
|
|
13
|
+
return `Conversion Error: ${this.message}`;
|
|
14
|
+
}
|
|
15
|
+
}
|
package/src/xlr-to-ts.ts
ADDED
|
@@ -0,0 +1,511 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ConditionalType,
|
|
3
|
+
Annotations,
|
|
4
|
+
FunctionType,
|
|
5
|
+
NamedType,
|
|
6
|
+
NodeType,
|
|
7
|
+
NodeTypeWithGenerics,
|
|
8
|
+
ObjectType,
|
|
9
|
+
PrimitiveTypes,
|
|
10
|
+
RecordType,
|
|
11
|
+
RefType,
|
|
12
|
+
TemplateLiteralType,
|
|
13
|
+
TupleType,
|
|
14
|
+
} from '@player-tools/xlr';
|
|
15
|
+
import type { TopLevelDeclaration } from '@player-tools/xlr-utils';
|
|
16
|
+
import {
|
|
17
|
+
isGenericNamedType,
|
|
18
|
+
isPrimitiveTypeNode,
|
|
19
|
+
} from '@player-tools/xlr-utils';
|
|
20
|
+
import ts from 'typescript';
|
|
21
|
+
import { ConversionError } from './types';
|
|
22
|
+
|
|
23
|
+
const templateSplit = /(?=true\|false|\.\*|\[0-9]\*)/gm;
|
|
24
|
+
|
|
25
|
+
export interface ConvertedType {
|
|
26
|
+
/** Converted input type represented as in TS Nodes */
|
|
27
|
+
type: TopLevelDeclaration;
|
|
28
|
+
|
|
29
|
+
/** Types that may require import statements to be added */
|
|
30
|
+
referencedTypes?: Set<string>;
|
|
31
|
+
|
|
32
|
+
/** Any additionally referenced types that were deserialized that should be separate declarations */
|
|
33
|
+
additionalTypes?: Map<string, TopLevelDeclaration>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface TSWriterContext {
|
|
37
|
+
/** */
|
|
38
|
+
factory: ts.NodeFactory;
|
|
39
|
+
|
|
40
|
+
/** */
|
|
41
|
+
throwError: (message: string) => never;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** */
|
|
45
|
+
export class TSWriter {
|
|
46
|
+
private context: TSWriterContext;
|
|
47
|
+
private importSet: Set<string>;
|
|
48
|
+
private additionalTypes: Map<string, TopLevelDeclaration>;
|
|
49
|
+
|
|
50
|
+
constructor(factory?: ts.NodeFactory) {
|
|
51
|
+
this.context = {
|
|
52
|
+
factory: factory ?? ts.factory,
|
|
53
|
+
throwError: (message: string) => {
|
|
54
|
+
throw new ConversionError(message);
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
this.importSet = new Set();
|
|
58
|
+
this.additionalTypes = new Map();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public convertNamedType(type: NamedType): ConvertedType {
|
|
62
|
+
this.importSet.clear();
|
|
63
|
+
this.additionalTypes.clear();
|
|
64
|
+
|
|
65
|
+
const finalNode = this.convertNamedTypeNode(type);
|
|
66
|
+
|
|
67
|
+
const referencedTypes =
|
|
68
|
+
this.importSet.size > 0 ? this.importSet : undefined;
|
|
69
|
+
const additionalTypes =
|
|
70
|
+
this.additionalTypes.size > 0 ? this.additionalTypes : undefined;
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
type: this.makeAnnotations(finalNode, type),
|
|
74
|
+
referencedTypes,
|
|
75
|
+
additionalTypes,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private convertNamedTypeNode(type: NamedType): TopLevelDeclaration {
|
|
80
|
+
const typeName = type.name;
|
|
81
|
+
const tsNode = this.convertTypeNode(type);
|
|
82
|
+
|
|
83
|
+
let generics;
|
|
84
|
+
if (isGenericNamedType(type)) {
|
|
85
|
+
generics = this.createTypeParameters(type);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
let finalNode;
|
|
89
|
+
if (ts.isTypeLiteralNode(tsNode)) {
|
|
90
|
+
finalNode = this.makeInterfaceDeclaration(
|
|
91
|
+
typeName,
|
|
92
|
+
tsNode.members,
|
|
93
|
+
generics
|
|
94
|
+
);
|
|
95
|
+
} else {
|
|
96
|
+
finalNode = this.makeTypeDeclaration(typeName, tsNode, generics);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return finalNode;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private convertTypeNode(type: NodeType): ts.TypeNode {
|
|
103
|
+
if (type.type === 'object') {
|
|
104
|
+
return this.createObjectNode(type);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (type.type === 'and') {
|
|
108
|
+
return this.context.factory.createIntersectionTypeNode(
|
|
109
|
+
type.and.map((element) => {
|
|
110
|
+
return this.convertTypeNode(element);
|
|
111
|
+
})
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (type.type === 'or') {
|
|
116
|
+
return this.context.factory.createUnionTypeNode(
|
|
117
|
+
type.or.map((element) => {
|
|
118
|
+
return this.convertTypeNode(element);
|
|
119
|
+
})
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (type.type === 'array') {
|
|
124
|
+
return this.context.factory.createTypeReferenceNode(
|
|
125
|
+
this.context.factory.createIdentifier('Array'),
|
|
126
|
+
[this.convertTypeNode(type.elementType)]
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (isPrimitiveTypeNode(type)) {
|
|
131
|
+
return this.createPrimitiveNode(type);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (type.type === 'conditional') {
|
|
135
|
+
return this.createConditionalTypeNode(type);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (type.type === 'function') {
|
|
139
|
+
return this.createFunctionDeclarationNode(type);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (type.type === 'record') {
|
|
143
|
+
return this.createRecordNode(type);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (type.type === 'ref') {
|
|
147
|
+
return this.createRefNode(type);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (type.type === 'template') {
|
|
151
|
+
return this.createTemplateLiteral(type);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (type.type === 'tuple') {
|
|
155
|
+
return this.createTupleNode(type);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
this.context.throwError(
|
|
159
|
+
`Unable to convert node type: ${(type as any).type}`
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
private createRefNode(xlrNode: RefType): ts.TypeReferenceNode {
|
|
164
|
+
if (xlrNode.genericArguments) {
|
|
165
|
+
xlrNode.genericArguments.forEach((genericArg) => {
|
|
166
|
+
if (genericArg.name) {
|
|
167
|
+
const additionalType = this.convertNamedTypeNode(
|
|
168
|
+
genericArg as NamedType
|
|
169
|
+
);
|
|
170
|
+
this.additionalTypes.set(genericArg.name, additionalType);
|
|
171
|
+
} else if (genericArg.type === 'and') {
|
|
172
|
+
genericArg.and.forEach((type) => {
|
|
173
|
+
if (type.name) {
|
|
174
|
+
const additionalType = this.convertNamedTypeNode(
|
|
175
|
+
type as NamedType
|
|
176
|
+
);
|
|
177
|
+
this.additionalTypes.set(type.name, additionalType);
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
} else if (genericArg.type === 'or') {
|
|
181
|
+
genericArg.or.forEach((type) => {
|
|
182
|
+
if (type.name) {
|
|
183
|
+
const additionalType = this.convertNamedTypeNode(
|
|
184
|
+
type as NamedType
|
|
185
|
+
);
|
|
186
|
+
this.additionalTypes.set(type.name, additionalType);
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const importName = xlrNode.ref.split('<')[0];
|
|
194
|
+
this.importSet.add(importName);
|
|
195
|
+
return this.context.factory.createTypeReferenceNode(xlrNode.ref);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
private createPrimitiveNode(xlrNode: PrimitiveTypes): ts.TypeNode {
|
|
199
|
+
if (
|
|
200
|
+
((xlrNode.type === 'string' ||
|
|
201
|
+
xlrNode.type === 'boolean' ||
|
|
202
|
+
xlrNode.type === 'number') &&
|
|
203
|
+
xlrNode.const) ||
|
|
204
|
+
xlrNode.type === 'null'
|
|
205
|
+
) {
|
|
206
|
+
return this.context.factory.createLiteralTypeNode(
|
|
207
|
+
this.createLiteralTypeNode(xlrNode)
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
switch (xlrNode.type) {
|
|
212
|
+
case 'string':
|
|
213
|
+
return this.context.factory.createKeywordTypeNode(
|
|
214
|
+
ts.SyntaxKind.StringKeyword
|
|
215
|
+
);
|
|
216
|
+
case 'number':
|
|
217
|
+
return this.context.factory.createKeywordTypeNode(
|
|
218
|
+
ts.SyntaxKind.NumberKeyword
|
|
219
|
+
);
|
|
220
|
+
case 'boolean':
|
|
221
|
+
return this.context.factory.createKeywordTypeNode(
|
|
222
|
+
ts.SyntaxKind.BooleanKeyword
|
|
223
|
+
);
|
|
224
|
+
case 'any':
|
|
225
|
+
return this.context.factory.createKeywordTypeNode(
|
|
226
|
+
ts.SyntaxKind.AnyKeyword
|
|
227
|
+
);
|
|
228
|
+
case 'unknown':
|
|
229
|
+
return this.context.factory.createKeywordTypeNode(
|
|
230
|
+
ts.SyntaxKind.UnknownKeyword
|
|
231
|
+
);
|
|
232
|
+
case 'never':
|
|
233
|
+
return this.context.factory.createKeywordTypeNode(
|
|
234
|
+
ts.SyntaxKind.NeverKeyword
|
|
235
|
+
);
|
|
236
|
+
case 'undefined':
|
|
237
|
+
return this.context.factory.createKeywordTypeNode(
|
|
238
|
+
ts.SyntaxKind.UndefinedKeyword
|
|
239
|
+
);
|
|
240
|
+
default:
|
|
241
|
+
this.context.throwError(
|
|
242
|
+
`Unknown primitive type ${(xlrNode as any).type}`
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
private createLiteralTypeNode(
|
|
248
|
+
xlrNode: NodeType
|
|
249
|
+
): ts.NullLiteral | ts.BooleanLiteral | ts.LiteralExpression {
|
|
250
|
+
if (xlrNode.type === 'boolean') {
|
|
251
|
+
return xlrNode.const
|
|
252
|
+
? this.context.factory.createTrue()
|
|
253
|
+
: this.context.factory.createFalse();
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (xlrNode.type === 'number') {
|
|
257
|
+
return xlrNode.const
|
|
258
|
+
? this.context.factory.createNumericLiteral(xlrNode.const)
|
|
259
|
+
: this.context.throwError(
|
|
260
|
+
"Can't make literal type out of non constant number"
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (xlrNode.type === 'string') {
|
|
265
|
+
return xlrNode.const
|
|
266
|
+
? this.context.factory.createStringLiteral(xlrNode.const)
|
|
267
|
+
: this.context.throwError(
|
|
268
|
+
"Can't make literal type out of non constant string"
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (xlrNode.type === 'null') {
|
|
273
|
+
return this.context.factory.createNull();
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
this.context.throwError(`Can't make literal out of type ${xlrNode.type}`);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
private createTupleNode(xlrNode: TupleType): ts.TypeNode {
|
|
280
|
+
return this.context.factory.createTupleTypeNode(
|
|
281
|
+
xlrNode.elementTypes.map((e) => this.convertTypeNode(e))
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
private createFunctionDeclarationNode(xlrNode: FunctionType): ts.TypeNode {
|
|
286
|
+
return this.context.factory.createFunctionTypeNode(
|
|
287
|
+
undefined,
|
|
288
|
+
xlrNode.parameters.map((e) => {
|
|
289
|
+
return this.context.factory.createParameterDeclaration(
|
|
290
|
+
undefined,
|
|
291
|
+
undefined,
|
|
292
|
+
undefined,
|
|
293
|
+
e.name,
|
|
294
|
+
e.optional
|
|
295
|
+
? this.context.factory.createToken(ts.SyntaxKind.QuestionToken)
|
|
296
|
+
: undefined,
|
|
297
|
+
this.convertTypeNode(e.type),
|
|
298
|
+
e.default ? this.createLiteralTypeNode(e.default) : undefined
|
|
299
|
+
);
|
|
300
|
+
}),
|
|
301
|
+
xlrNode.returnType
|
|
302
|
+
? this.convertTypeNode(xlrNode.returnType)
|
|
303
|
+
: this.context.factory.createToken(ts.SyntaxKind.VoidKeyword)
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
private createRecordNode(xlrNode: RecordType): ts.TypeNode {
|
|
308
|
+
const keyType = this.convertTypeNode(xlrNode.keyType);
|
|
309
|
+
const valueType = this.convertTypeNode(xlrNode.valueType);
|
|
310
|
+
return this.context.factory.createTypeReferenceNode(
|
|
311
|
+
this.context.factory.createIdentifier('Record'),
|
|
312
|
+
[keyType, valueType]
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
private createConditionalTypeNode(xlrNode: ConditionalType): ts.TypeNode {
|
|
317
|
+
const leftCheck = this.convertTypeNode(xlrNode.check.left);
|
|
318
|
+
const rightCheck = this.convertTypeNode(xlrNode.check.right);
|
|
319
|
+
const trueValue = this.convertTypeNode(xlrNode.value.true);
|
|
320
|
+
const falseValue = this.convertTypeNode(xlrNode.value.false);
|
|
321
|
+
|
|
322
|
+
return this.context.factory.createConditionalTypeNode(
|
|
323
|
+
leftCheck,
|
|
324
|
+
rightCheck,
|
|
325
|
+
trueValue,
|
|
326
|
+
falseValue
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
private createObjectNode(xlrNode: ObjectType): ts.TypeLiteralNode {
|
|
331
|
+
const { properties, additionalProperties = false } = xlrNode;
|
|
332
|
+
|
|
333
|
+
const propertyNodes: Array<ts.TypeElement> = [
|
|
334
|
+
...Object.keys(properties)
|
|
335
|
+
.map((name) => ({ name, ...properties[name] }))
|
|
336
|
+
.map(({ name, node, required }) =>
|
|
337
|
+
this.makeAnnotations(
|
|
338
|
+
this.context.factory.createPropertySignature(
|
|
339
|
+
undefined, // modifiers
|
|
340
|
+
name,
|
|
341
|
+
required
|
|
342
|
+
? undefined
|
|
343
|
+
: this.context.factory.createToken(ts.SyntaxKind.QuestionToken),
|
|
344
|
+
this.convertTypeNode(node)
|
|
345
|
+
),
|
|
346
|
+
node
|
|
347
|
+
)
|
|
348
|
+
),
|
|
349
|
+
];
|
|
350
|
+
|
|
351
|
+
if (additionalProperties) {
|
|
352
|
+
propertyNodes.push(
|
|
353
|
+
this.context.factory.createIndexSignature(
|
|
354
|
+
undefined, // decorators
|
|
355
|
+
undefined, // modifiers
|
|
356
|
+
[
|
|
357
|
+
this.context.factory.createParameterDeclaration(
|
|
358
|
+
undefined, // decorators
|
|
359
|
+
undefined, // modifiers
|
|
360
|
+
undefined, // dotdotdot token
|
|
361
|
+
'key',
|
|
362
|
+
undefined, // question token
|
|
363
|
+
this.context.factory.createKeywordTypeNode(
|
|
364
|
+
ts.SyntaxKind.StringKeyword
|
|
365
|
+
)
|
|
366
|
+
),
|
|
367
|
+
],
|
|
368
|
+
this.convertTypeNode(additionalProperties)
|
|
369
|
+
)
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
return this.context.factory.createTypeLiteralNode(propertyNodes);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
private createTemplateLiteral(xlrNode: TemplateLiteralType) {
|
|
377
|
+
const templateSegments = xlrNode.format.split(templateSplit);
|
|
378
|
+
let templateHead;
|
|
379
|
+
|
|
380
|
+
if (templateSegments.length % 2) {
|
|
381
|
+
templateHead = this.context.factory.createTemplateHead(
|
|
382
|
+
templateSegments[0]
|
|
383
|
+
);
|
|
384
|
+
templateSegments.splice(0, 1);
|
|
385
|
+
} else {
|
|
386
|
+
templateHead = this.context.factory.createTemplateHead('');
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
return this.context.factory.createTemplateLiteralType(
|
|
390
|
+
templateHead,
|
|
391
|
+
templateSegments.map((segments, i) => {
|
|
392
|
+
const [regexSegment, stringSegment] = segments.split(' ', 1);
|
|
393
|
+
|
|
394
|
+
let regexTemplateType: ts.KeywordSyntaxKind;
|
|
395
|
+
if (regexSegment === '.*') {
|
|
396
|
+
regexTemplateType = ts.SyntaxKind.StringKeyword;
|
|
397
|
+
} else if (regexSegment === '[0-9]*') {
|
|
398
|
+
regexTemplateType = ts.SyntaxKind.NumberKeyword;
|
|
399
|
+
} else if (regexSegment === 'true|false') {
|
|
400
|
+
regexTemplateType = ts.SyntaxKind.BooleanKeyword;
|
|
401
|
+
} else {
|
|
402
|
+
this.context.throwError(
|
|
403
|
+
`Can't make template literal type from regex ${regexSegment}`
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
let stringTemplateType;
|
|
408
|
+
|
|
409
|
+
if (i === templateSegments.length - 1) {
|
|
410
|
+
stringTemplateType =
|
|
411
|
+
this.context.factory.createTemplateTail(stringSegment);
|
|
412
|
+
} else {
|
|
413
|
+
stringTemplateType =
|
|
414
|
+
this.context.factory.createTemplateMiddle(stringSegment);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
return this.context.factory.createTemplateLiteralTypeSpan(
|
|
418
|
+
this.context.factory.createKeywordTypeNode(regexTemplateType),
|
|
419
|
+
stringTemplateType
|
|
420
|
+
);
|
|
421
|
+
})
|
|
422
|
+
);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
private createGenericArgumentNode(node?: NodeType): ts.TypeNode | undefined {
|
|
426
|
+
if (node) {
|
|
427
|
+
if (node.type === 'object' && node.name) {
|
|
428
|
+
const additionalType = this.convertNamedTypeNode(
|
|
429
|
+
node as NamedType<ObjectType>
|
|
430
|
+
);
|
|
431
|
+
this.additionalTypes.set(node.name, additionalType);
|
|
432
|
+
return this.context.factory.createTypeReferenceNode(node.name);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
return this.convertTypeNode(node);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
return undefined;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
private makeAnnotations<T extends ts.Node>(
|
|
442
|
+
tsNode: T,
|
|
443
|
+
xlrAnnotations: Annotations
|
|
444
|
+
) {
|
|
445
|
+
let comment = xlrAnnotations.description;
|
|
446
|
+
if (!comment) {
|
|
447
|
+
return tsNode;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
if (comment.includes('\n')) {
|
|
451
|
+
comment = `*\n${comment
|
|
452
|
+
.split('\n')
|
|
453
|
+
.map((s) => ` * ${s}`)
|
|
454
|
+
.join('\n')}\n`;
|
|
455
|
+
} else {
|
|
456
|
+
comment = `* ${comment} `;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
return ts.addSyntheticLeadingComment(
|
|
460
|
+
tsNode,
|
|
461
|
+
ts.SyntaxKind.MultiLineCommentTrivia,
|
|
462
|
+
comment,
|
|
463
|
+
true
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
private createTypeParameters(
|
|
468
|
+
genericxlrNode: NodeTypeWithGenerics
|
|
469
|
+
): Array<ts.TypeParameterDeclaration> {
|
|
470
|
+
return genericxlrNode.genericTokens.map((generic) => {
|
|
471
|
+
return this.context.factory.createTypeParameterDeclaration(
|
|
472
|
+
generic.symbol,
|
|
473
|
+
this.createGenericArgumentNode(generic.constraints),
|
|
474
|
+
this.createGenericArgumentNode(generic.default)
|
|
475
|
+
);
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
private makeInterfaceDeclaration(
|
|
480
|
+
name: string,
|
|
481
|
+
node: ts.NodeArray<ts.TypeElement>,
|
|
482
|
+
generics: Array<ts.TypeParameterDeclaration> | undefined
|
|
483
|
+
) {
|
|
484
|
+
return this.context.factory.createInterfaceDeclaration(
|
|
485
|
+
undefined,
|
|
486
|
+
this.context.factory.createModifiersFromModifierFlags(
|
|
487
|
+
ts.ModifierFlags.Export
|
|
488
|
+
),
|
|
489
|
+
this.context.factory.createIdentifier(name),
|
|
490
|
+
generics, // type parameters
|
|
491
|
+
undefined, // heritage
|
|
492
|
+
node
|
|
493
|
+
);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
private makeTypeDeclaration(
|
|
497
|
+
name: string,
|
|
498
|
+
node: ts.TypeNode,
|
|
499
|
+
generics: Array<ts.TypeParameterDeclaration> | undefined
|
|
500
|
+
) {
|
|
501
|
+
return this.context.factory.createTypeAliasDeclaration(
|
|
502
|
+
undefined, // decorators
|
|
503
|
+
this.context.factory.createModifiersFromModifierFlags(
|
|
504
|
+
ts.ModifierFlags.Export
|
|
505
|
+
),
|
|
506
|
+
this.context.factory.createIdentifier(name),
|
|
507
|
+
generics, // type parameters
|
|
508
|
+
node
|
|
509
|
+
);
|
|
510
|
+
}
|
|
511
|
+
}
|