@zyno-io/ts-reflection 26.803.2224

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.
Files changed (61) hide show
  1. package/README.md +13 -0
  2. package/dist/index.cjs +1 -0
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +966 -0
  6. package/dist/reflection/annotations.d.ts +15 -0
  7. package/dist/reflection/annotations.d.ts.map +1 -0
  8. package/dist/reflection/compact-metadata.d.ts +18 -0
  9. package/dist/reflection/compact-metadata.d.ts.map +1 -0
  10. package/dist/reflection/conversion.d.ts +15 -0
  11. package/dist/reflection/conversion.d.ts.map +1 -0
  12. package/dist/reflection/deserializer.d.ts +15 -0
  13. package/dist/reflection/deserializer.d.ts.map +1 -0
  14. package/dist/reflection/errors.d.ts +8 -0
  15. package/dist/reflection/errors.d.ts.map +1 -0
  16. package/dist/reflection/index.d.ts +10 -0
  17. package/dist/reflection/index.d.ts.map +1 -0
  18. package/dist/reflection/metadata-store.d.ts +20 -0
  19. package/dist/reflection/metadata-store.d.ts.map +1 -0
  20. package/dist/reflection/model.d.ts +273 -0
  21. package/dist/reflection/model.d.ts.map +1 -0
  22. package/dist/reflection/primitive-conversion.d.ts +2 -0
  23. package/dist/reflection/primitive-conversion.d.ts.map +1 -0
  24. package/dist/reflection/reflection-class.d.ts +60 -0
  25. package/dist/reflection/reflection-class.d.ts.map +1 -0
  26. package/dist/reflection/type-utils.d.ts +34 -0
  27. package/dist/reflection/type-utils.d.ts.map +1 -0
  28. package/dist/type-compiler/download-prebuilt.cjs +114 -0
  29. package/dist/type-compiler/go/ast_expression.go +187 -0
  30. package/dist/type-compiler/go/ast_metadata.go +388 -0
  31. package/dist/type-compiler/go/collect.go +963 -0
  32. package/dist/type-compiler/go/compact_metadata.go +553 -0
  33. package/dist/type-compiler/go/emission_plan.go +340 -0
  34. package/dist/type-compiler/go/emit_ast.go +557 -0
  35. package/dist/type-compiler/go/emit_ast_test.go +558 -0
  36. package/dist/type-compiler/go/go.mod +10 -0
  37. package/dist/type-compiler/go/plugin.go +359 -0
  38. package/dist/type-compiler/go/plugin_test.go +1206 -0
  39. package/dist/type-compiler/go/precompute.go +86 -0
  40. package/dist/type-compiler/go/receive_type.go +912 -0
  41. package/dist/type-compiler/go/resolve.go +265 -0
  42. package/dist/type-compiler/go/source_scan.go +51 -0
  43. package/dist/type-compiler/go/text_parse.go +734 -0
  44. package/dist/type-compiler/go/type_expr.go +1291 -0
  45. package/dist/type-compiler/go/typia_expr.go +2316 -0
  46. package/dist/type-compiler/index.cjs +43 -0
  47. package/dist/type-compiler/pnp.cjs +474 -0
  48. package/dist/type-compiler/prebuilt.cjs +324 -0
  49. package/dist/type-metadata-runtime.cjs +1 -0
  50. package/dist/type-metadata-runtime.d.ts +2 -0
  51. package/dist/type-metadata-runtime.d.ts.map +1 -0
  52. package/dist/type-metadata-runtime.js +107 -0
  53. package/dist/types/index.d.ts +4 -0
  54. package/dist/types/index.d.ts.map +1 -0
  55. package/dist/types/primitives.d.ts +33 -0
  56. package/dist/types/primitives.d.ts.map +1 -0
  57. package/dist/types/runtime.d.ts +2 -0
  58. package/dist/types/runtime.d.ts.map +1 -0
  59. package/dist/types/type-annotations.d.ts +28 -0
  60. package/dist/types/type-annotations.d.ts.map +1 -0
  61. package/package.json +47 -0
@@ -0,0 +1,553 @@
1
+ package main
2
+
3
+ import (
4
+ "bytes"
5
+ "encoding/json"
6
+ "strconv"
7
+ "strings"
8
+
9
+ shimast "github.com/microsoft/typescript-go/shim/ast"
10
+ shimprinter "github.com/microsoft/typescript-go/shim/printer"
11
+ )
12
+
13
+ const (
14
+ compactMetadataRuntimeSpec = "@zyno-io/ts-reflection/type-metadata-runtime"
15
+ compactMetadataDecoderName = "decodeCompactMetadataV1"
16
+ compactMetadataRegistryName = "createCompactMetadataRegistryV1"
17
+ compactMetadataAliasResolverName = "resolveCompactMetadataAliasV1"
18
+ compactMetadataReferenceKey = "$tsf"
19
+ compactMetadataImportKey = "$tsfImport"
20
+ compactMetadataAliasKey = "$tsfAlias"
21
+ compactMetadataTypeKey = "$tsfType"
22
+ )
23
+
24
+ type compactMetadataEncoding struct {
25
+ serialized string
26
+ references []*shimast.Node
27
+ }
28
+
29
+ type compactMetadataEncoder struct {
30
+ buffer bytes.Buffer
31
+ references []*shimast.Node
32
+ referenceIndexes map[string]int
33
+ referenceKey func(*shimast.Node) (string, bool)
34
+ runtimeRecipe func(*compactMetadataEncoder, *shimast.Node) bool
35
+ }
36
+
37
+ type compactMetadataRuntimeInterner struct {
38
+ sourceFile *shimast.SourceFile
39
+ printer *shimprinter.Printer
40
+ }
41
+
42
+ func newCompactMetadataRuntimeInterner(
43
+ ec *shimprinter.EmitContext,
44
+ sourceFile *shimast.SourceFile,
45
+ ) *compactMetadataRuntimeInterner {
46
+ return &compactMetadataRuntimeInterner{
47
+ sourceFile: sourceFile,
48
+ printer: shimprinter.NewPrinter(shimprinter.PrinterOptions{}, shimprinter.PrintHandlers{}, ec),
49
+ }
50
+ }
51
+
52
+ func isCompactMetadataAliasResolverCall(expression *shimast.Node) bool {
53
+ if expression == nil || expression.Kind != shimast.KindCallExpression {
54
+ return false
55
+ }
56
+ call := expression.AsCallExpression()
57
+ if call == nil || call.Expression == nil || call.Expression.Kind != shimast.KindPropertyAccessExpression {
58
+ return false
59
+ }
60
+ name := call.Expression.AsPropertyAccessExpression().Name()
61
+ return name != nil && name.Text() == compactMetadataAliasResolverName
62
+ }
63
+
64
+ // deduplicationKey identifies generated runtime expressions whose value may be
65
+ // shared inside one decoded metadata graph. Class/validator thunks and primitive
66
+ // non-JSON values are immutable. Imported alias lookups clone compiler-owned
67
+ // metadata only to attach the same type name, so sharing that clone is also
68
+ // equivalent and avoids emitting hundreds of repeated factory calls for large
69
+ // DTO graphs. Arbitrary call expressions and escaped application objects remain
70
+ // distinct.
71
+ func (interner *compactMetadataRuntimeInterner) deduplicationKey(expression *shimast.Node) (string, bool) {
72
+ if expression == nil {
73
+ return "", false
74
+ }
75
+ switch expression.Kind {
76
+ case shimast.KindArrowFunction, shimast.KindBigIntLiteral:
77
+ return interner.emit(expression), true
78
+ case shimast.KindIdentifier:
79
+ if expression.Text() == "undefined" {
80
+ return "undefined", true
81
+ }
82
+ case shimast.KindCallExpression:
83
+ if isCompactMetadataAliasResolverCall(expression) {
84
+ return interner.emit(expression), true
85
+ }
86
+ source := interner.emit(expression)
87
+ if strings.Contains(source, "__tsf_module") && strings.Contains(source, "__tsf_alias") {
88
+ return source, true
89
+ }
90
+ }
91
+ return "", false
92
+ }
93
+
94
+ func (interner *compactMetadataRuntimeInterner) emit(expression *shimast.Node) string {
95
+ sourceFile := shimast.GetSourceFileOfNode(expression)
96
+ if sourceFile == nil {
97
+ sourceFile = interner.sourceFile
98
+ }
99
+ return interner.printer.Emit(expression, sourceFile)
100
+ }
101
+
102
+ func encodeCompactMetadata(root *shimast.Node) compactMetadataEncoding {
103
+ return encodeCompactMetadataWithReferenceKeys(root, nil)
104
+ }
105
+
106
+ func encodeCompactMetadataWithReferenceKeys(
107
+ root *shimast.Node,
108
+ referenceKey func(*shimast.Node) (string, bool),
109
+ ) compactMetadataEncoding {
110
+ return encodeCompactMetadataWithRuntimeRecipes(root, referenceKey, nil)
111
+ }
112
+
113
+ func encodeCompactMetadataWithRuntimeRecipes(
114
+ root *shimast.Node,
115
+ referenceKey func(*shimast.Node) (string, bool),
116
+ runtimeRecipe func(*compactMetadataEncoder, *shimast.Node) bool,
117
+ ) compactMetadataEncoding {
118
+ encoder := &compactMetadataEncoder{
119
+ referenceIndexes: map[string]int{},
120
+ referenceKey: referenceKey,
121
+ runtimeRecipe: runtimeRecipe,
122
+ }
123
+ encoder.buffer.WriteString("[1,")
124
+ encoder.writeValue(root)
125
+ encoder.buffer.WriteByte(']')
126
+ return compactMetadataEncoding{
127
+ serialized: encoder.buffer.String(),
128
+ references: encoder.references,
129
+ }
130
+ }
131
+
132
+ func (encoder *compactMetadataEncoder) writeValue(node *shimast.Node) {
133
+ start := encoder.buffer.Len()
134
+ referenceStart := len(encoder.references)
135
+ if encoder.writeJSONValue(node) {
136
+ return
137
+ }
138
+ encoder.buffer.Truncate(start)
139
+ encoder.references = encoder.references[:referenceStart]
140
+ encoder.writeReference(node)
141
+ }
142
+
143
+ func (encoder *compactMetadataEncoder) writeJSONValue(node *shimast.Node) bool {
144
+ if node == nil {
145
+ return false
146
+ }
147
+ if encoder.runtimeRecipe != nil && encoder.runtimeRecipe(encoder, node) {
148
+ return true
149
+ }
150
+ switch node.Kind {
151
+ case shimast.KindParenthesizedExpression:
152
+ encoder.writeValue(node.AsParenthesizedExpression().Expression)
153
+ return true
154
+ case shimast.KindObjectLiteralExpression:
155
+ return encoder.writeObject(node.AsObjectLiteralExpression())
156
+ case shimast.KindArrayLiteralExpression:
157
+ return encoder.writeArray(node.AsArrayLiteralExpression())
158
+ case shimast.KindStringLiteral, shimast.KindNoSubstitutionTemplateLiteral:
159
+ encoder.writeJSONString(node.Text())
160
+ return true
161
+ case shimast.KindNumericLiteral:
162
+ return encoder.writeJSONNumber(node.Text())
163
+ case shimast.KindTrueKeyword:
164
+ encoder.buffer.WriteString("true")
165
+ return true
166
+ case shimast.KindFalseKeyword:
167
+ encoder.buffer.WriteString("false")
168
+ return true
169
+ case shimast.KindNullKeyword:
170
+ encoder.buffer.WriteString("null")
171
+ return true
172
+ case shimast.KindPrefixUnaryExpression:
173
+ unary := node.AsPrefixUnaryExpression()
174
+ if unary.Operator != shimast.KindMinusToken || unary.Operand == nil || unary.Operand.Kind != shimast.KindNumericLiteral {
175
+ return false
176
+ }
177
+ return encoder.writeJSONNumber("-" + unary.Operand.Text())
178
+ default:
179
+ return false
180
+ }
181
+ }
182
+
183
+ func (encoder *compactMetadataEncoder) writeObject(object *shimast.ObjectLiteralExpression) bool {
184
+ if object == nil || object.Properties == nil {
185
+ encoder.buffer.WriteString("{}")
186
+ return true
187
+ }
188
+ for _, property := range object.Properties.Nodes {
189
+ name, ok := compactMetadataPropertyName(property)
190
+ if !ok || name == "__proto__" {
191
+ return false
192
+ }
193
+ }
194
+ // An application-provided object with the same exact shape as a wire-format
195
+ // reference must remain ordinary data. Escaping the small object through the
196
+ // side table makes marker recognition unambiguous without reserving a user key.
197
+ if len(object.Properties.Nodes) == 1 {
198
+ if name, ok := compactMetadataPropertyName(object.Properties.Nodes[0]); ok && isCompactMetadataReservedKey(name) {
199
+ return false
200
+ }
201
+ }
202
+ encoder.buffer.WriteByte('{')
203
+ for index, property := range object.Properties.Nodes {
204
+ assignment := property.AsPropertyAssignment()
205
+ name, _ := compactMetadataPropertyName(property)
206
+ if index != 0 {
207
+ encoder.buffer.WriteByte(',')
208
+ }
209
+ encoder.writeJSONString(name)
210
+ encoder.buffer.WriteByte(':')
211
+ encoder.writeValue(assignment.Initializer)
212
+ }
213
+ encoder.buffer.WriteByte('}')
214
+ return true
215
+ }
216
+
217
+ func isCompactMetadataReservedKey(name string) bool {
218
+ return name == compactMetadataReferenceKey || name == compactMetadataImportKey || name == compactMetadataAliasKey || name == compactMetadataTypeKey
219
+ }
220
+
221
+ func compactMetadataPropertyName(property *shimast.Node) (string, bool) {
222
+ if property == nil || property.Kind != shimast.KindPropertyAssignment {
223
+ return "", false
224
+ }
225
+ name := property.AsPropertyAssignment().Name()
226
+ if name == nil {
227
+ return "", false
228
+ }
229
+ switch name.Kind {
230
+ case shimast.KindIdentifier, shimast.KindStringLiteral, shimast.KindNumericLiteral:
231
+ return name.Text(), true
232
+ default:
233
+ return "", false
234
+ }
235
+ }
236
+
237
+ func (encoder *compactMetadataEncoder) writeArray(array *shimast.ArrayLiteralExpression) bool {
238
+ if array == nil || array.Elements == nil {
239
+ encoder.buffer.WriteString("[]")
240
+ return true
241
+ }
242
+ for _, element := range array.Elements.Nodes {
243
+ if element == nil || element.Kind == shimast.KindOmittedExpression || element.Kind == shimast.KindSpreadElement {
244
+ return false
245
+ }
246
+ }
247
+ encoder.buffer.WriteByte('[')
248
+ for index, element := range array.Elements.Nodes {
249
+ if index != 0 {
250
+ encoder.buffer.WriteByte(',')
251
+ }
252
+ encoder.writeValue(element)
253
+ }
254
+ encoder.buffer.WriteByte(']')
255
+ return true
256
+ }
257
+
258
+ func (encoder *compactMetadataEncoder) writeJSONNumber(value string) bool {
259
+ if value == "" || !json.Valid([]byte(value)) {
260
+ return false
261
+ }
262
+ if _, err := strconv.ParseFloat(value, 64); err != nil {
263
+ return false
264
+ }
265
+ encoder.buffer.WriteString(value)
266
+ return true
267
+ }
268
+
269
+ func (encoder *compactMetadataEncoder) writeJSONString(value string) {
270
+ encoded, _ := json.Marshal(value)
271
+ encoder.buffer.Write(encoded)
272
+ }
273
+
274
+ func (encoder *compactMetadataEncoder) writeReference(node *shimast.Node) {
275
+ key := ""
276
+ if encoder.referenceKey != nil {
277
+ if deduplicationKey, ok := encoder.referenceKey(node); ok {
278
+ key = "runtime:" + deduplicationKey
279
+ }
280
+ }
281
+ index := encoder.referenceIndex(node, key)
282
+ encoder.writeReferenceMarker(index)
283
+ }
284
+
285
+ func (encoder *compactMetadataEncoder) referenceIndex(node *shimast.Node, key string) int {
286
+ if key != "" {
287
+ if existing, found := encoder.referenceIndexes[key]; found {
288
+ return existing
289
+ }
290
+ }
291
+ index := len(encoder.references)
292
+ encoder.references = append(encoder.references, node)
293
+ if key != "" {
294
+ encoder.referenceIndexes[key] = index
295
+ }
296
+ return index
297
+ }
298
+
299
+ func (encoder *compactMetadataEncoder) writeReferenceMarker(index int) {
300
+ encoder.buffer.WriteString(`{"` + compactMetadataReferenceKey + `":`)
301
+ encoder.buffer.WriteString(strconv.Itoa(index))
302
+ encoder.buffer.WriteByte('}')
303
+ }
304
+
305
+ func materializeCompactMetadataExpression(
306
+ ec *shimprinter.EmitContext,
307
+ imports *astImportRegistry,
308
+ runtimeReferences *compactMetadataRuntimeInterner,
309
+ template expressionTemplate,
310
+ metadataTypeResolver string,
311
+ ) *shimast.Node {
312
+ metadata := template.materialize(ec, imports)
313
+ if _, ok := compactMetadataTypeRecipe(metadata, metadataTypeResolver); ok {
314
+ return metadata
315
+ }
316
+ return materializeCompactMetadataNode(ec, imports, runtimeReferences, metadata, metadataTypeResolver, false, false)
317
+ }
318
+
319
+ func materializeCompactAliasMetadataExpression(
320
+ ec *shimprinter.EmitContext,
321
+ imports *astImportRegistry,
322
+ runtimeReferences *compactMetadataRuntimeInterner,
323
+ template expressionTemplate,
324
+ metadataTypeResolver string,
325
+ ) *shimast.Node {
326
+ metadata := template.materialize(ec, imports)
327
+ return materializeCompactMetadataNode(ec, imports, runtimeReferences, metadata, metadataTypeResolver, false, true)
328
+ }
329
+
330
+ func materializeCompactMetadataRegistry(
331
+ ec *shimprinter.EmitContext,
332
+ imports *astImportRegistry,
333
+ runtimeReferences *compactMetadataRuntimeInterner,
334
+ templates []expressionTemplate,
335
+ metadataTypeResolver string,
336
+ ) *shimast.Node {
337
+ elements := make([]*shimast.Node, 0, len(templates))
338
+ for _, template := range templates {
339
+ elements = append(elements, template.materialize(ec, imports))
340
+ }
341
+ metadata := ec.Factory.NewArrayLiteralExpression(ec.Factory.NewNodeList(elements), false)
342
+ return materializeCompactMetadataNode(ec, imports, runtimeReferences, metadata, metadataTypeResolver, true, false)
343
+ }
344
+
345
+ func materializeCompactMetadataNode(
346
+ ec *shimprinter.EmitContext,
347
+ imports *astImportRegistry,
348
+ runtimeReferences *compactMetadataRuntimeInterner,
349
+ metadata *shimast.Node,
350
+ metadataTypeResolver string,
351
+ registry bool,
352
+ inlinePureJSON bool,
353
+ ) *shimast.Node {
354
+ encoding := encodeCompactMetadataWithRuntimeRecipes(
355
+ metadata,
356
+ runtimeReferences.deduplicationKey,
357
+ func(encoder *compactMetadataEncoder, expression *shimast.Node) bool {
358
+ return writeCompactMetadataRuntimeRecipe(encoder, expression, imports, metadataTypeResolver)
359
+ },
360
+ )
361
+ references := make([]*shimast.Node, 0, len(encoding.references))
362
+ for _, reference := range encoding.references {
363
+ // Runtime values must stay beside the metadata expression that produced
364
+ // them. Hoisting a thunk can move it outside the lexical scope of local
365
+ // classes and validators, leaving the generated closure unable to resolve
366
+ // its original binding.
367
+ references = append(references, ec.Factory.DeepCloneNode(reference))
368
+ }
369
+ if inlinePureJSON && len(references) == 0 && !strings.Contains(encoding.serialized, `"$tsf`) {
370
+ parsed := ec.Factory.NewCallExpression(
371
+ ec.Factory.NewPropertyAccessExpression(
372
+ ec.Factory.NewIdentifier("JSON"),
373
+ nil,
374
+ ec.Factory.NewIdentifier("parse"),
375
+ shimast.NodeFlagsNone,
376
+ ),
377
+ nil,
378
+ nil,
379
+ ec.Factory.NewNodeList([]*shimast.Node{ec.Factory.NewStringLiteral(encoding.serialized, shimast.TokenFlagsNone)}),
380
+ shimast.NodeFlagsNone,
381
+ )
382
+ return ec.Factory.NewElementAccessExpression(
383
+ parsed,
384
+ nil,
385
+ ec.Factory.NewNumericLiteral("1", shimast.TokenFlagsNone),
386
+ shimast.NodeFlagsNone,
387
+ )
388
+ }
389
+ helperName := compactMetadataDecoderName
390
+ if registry {
391
+ helperName = compactMetadataRegistryName
392
+ }
393
+ arguments := []*shimast.Node{
394
+ ec.Factory.NewStringLiteral(encoding.serialized, shimast.TokenFlagsNone),
395
+ ec.Factory.NewArrayLiteralExpression(ec.Factory.NewNodeList(references), false),
396
+ }
397
+ if !registry && metadataTypeResolver != "" {
398
+ arguments = append(arguments, ec.Factory.NewIdentifier(metadataTypeResolver))
399
+ }
400
+ return ec.Factory.NewCallExpression(
401
+ imports.staticMember(compactMetadataRuntimeSpec, helperName),
402
+ nil,
403
+ nil,
404
+ ec.Factory.NewNodeList(arguments),
405
+ shimast.NodeFlagsNone,
406
+ )
407
+ }
408
+
409
+ func writeCompactMetadataRuntimeRecipe(
410
+ encoder *compactMetadataEncoder,
411
+ expression *shimast.Node,
412
+ imports *astImportRegistry,
413
+ metadataTypeResolver string,
414
+ ) bool {
415
+ if index, ok := compactMetadataTypeRecipe(expression, metadataTypeResolver); ok {
416
+ encoder.buffer.WriteString(`{"` + compactMetadataTypeKey + `":`)
417
+ encoder.buffer.WriteString(strconv.Itoa(index))
418
+ encoder.buffer.WriteByte('}')
419
+ return true
420
+ }
421
+ if loader, spec, exportName, typeName, ok := compactMetadataAliasRecipe(expression, imports); ok {
422
+ index := encoder.referenceIndex(loader, compactMetadataModuleReferenceKey(loader, imports))
423
+ encoder.buffer.WriteString(`{"` + compactMetadataAliasKey + `":[`)
424
+ encoder.buffer.WriteString(strconv.Itoa(index))
425
+ encoder.buffer.WriteByte(',')
426
+ if spec != "" {
427
+ encoder.writeJSONString(spec)
428
+ encoder.buffer.WriteByte(',')
429
+ }
430
+ encoder.writeJSONString(exportName)
431
+ encoder.buffer.WriteByte(',')
432
+ encoder.writeJSONString(typeName)
433
+ encoder.buffer.WriteString("]}")
434
+ return true
435
+ }
436
+ if spec, exportName, ok := compactMetadataCommonJSImportRecipe(expression); ok {
437
+ loader := imports.ec.Factory.NewIdentifier("require")
438
+ index := encoder.referenceIndex(loader, compactMetadataModuleReferenceKey(loader, imports))
439
+ encoder.buffer.WriteString(`{"` + compactMetadataImportKey + `":[`)
440
+ encoder.buffer.WriteString(strconv.Itoa(index))
441
+ encoder.buffer.WriteByte(',')
442
+ encoder.writeJSONString(spec)
443
+ encoder.buffer.WriteByte(',')
444
+ encoder.writeJSONString(exportName)
445
+ encoder.buffer.WriteString("]}")
446
+ return true
447
+ }
448
+ return false
449
+ }
450
+
451
+ func compactMetadataTypeRecipe(expression *shimast.Node, resolverName string) (int, bool) {
452
+ for expression != nil && expression.Kind == shimast.KindParenthesizedExpression {
453
+ expression = expression.AsParenthesizedExpression().Expression
454
+ }
455
+ if resolverName == "" || expression == nil || expression.Kind != shimast.KindCallExpression {
456
+ return 0, false
457
+ }
458
+ call := expression.AsCallExpression()
459
+ if call.Expression == nil || call.Expression.Kind != shimast.KindIdentifier || call.Expression.Text() != resolverName ||
460
+ call.Arguments == nil || len(call.Arguments.Nodes) != 1 || call.Arguments.Nodes[0].Kind != shimast.KindNumericLiteral {
461
+ return 0, false
462
+ }
463
+ index, err := strconv.Atoi(call.Arguments.Nodes[0].Text())
464
+ return index, err == nil && index >= 0
465
+ }
466
+
467
+ func compactMetadataAliasRecipe(
468
+ expression *shimast.Node,
469
+ imports *astImportRegistry,
470
+ ) (*shimast.Node, string, string, string, bool) {
471
+ if !isCompactMetadataAliasResolverCall(expression) {
472
+ return nil, "", "", "", false
473
+ }
474
+ call := expression.AsCallExpression()
475
+ if call.Arguments == nil {
476
+ return nil, "", "", "", false
477
+ }
478
+ arguments := call.Arguments.Nodes
479
+ if len(arguments) == 3 && imports.isOptionalModuleLoader(arguments[0]) && shimast.IsStringLiteral(arguments[1]) && shimast.IsStringLiteral(arguments[2]) {
480
+ return arguments[0], "", arguments[1].Text(), arguments[2].Text(), true
481
+ }
482
+ if len(arguments) == 4 && isCompactMetadataCommonJSRequire(arguments[0], imports) &&
483
+ shimast.IsStringLiteral(arguments[1]) && shimast.IsStringLiteral(arguments[2]) && shimast.IsStringLiteral(arguments[3]) {
484
+ return arguments[0], arguments[1].Text(), arguments[2].Text(), arguments[3].Text(), true
485
+ }
486
+ return nil, "", "", "", false
487
+ }
488
+
489
+ func isCompactMetadataCommonJSRequire(expression *shimast.Node, imports *astImportRegistry) bool {
490
+ return imports.commonJS && expression != nil && expression.Kind == shimast.KindIdentifier && expression.Text() == "require"
491
+ }
492
+
493
+ func compactMetadataModuleReferenceKey(expression *shimast.Node, imports *astImportRegistry) string {
494
+ if isCompactMetadataCommonJSRequire(expression, imports) {
495
+ return "module:require"
496
+ }
497
+ return "loader:" + expression.Text()
498
+ }
499
+
500
+ func compactMetadataCommonJSImportRecipe(expression *shimast.Node) (string, string, bool) {
501
+ if expression == nil || expression.Kind != shimast.KindArrowFunction {
502
+ return "", "", false
503
+ }
504
+ body := expression.AsArrowFunction().Body
505
+ for body != nil && body.Kind == shimast.KindParenthesizedExpression {
506
+ body = body.AsParenthesizedExpression().Expression
507
+ }
508
+ if body == nil || body.Kind != shimast.KindConditionalExpression {
509
+ return "", "", false
510
+ }
511
+ conditional := body.AsConditionalExpression()
512
+ whenFalse := conditional.WhenFalse
513
+ if whenFalse == nil || whenFalse.Kind != shimast.KindIdentifier || whenFalse.Text() != "undefined" {
514
+ return "", "", false
515
+ }
516
+ whenTrue := conditional.WhenTrue
517
+ if whenTrue == nil || whenTrue.Kind != shimast.KindPropertyAccessExpression {
518
+ return "", "", false
519
+ }
520
+ property := whenTrue.AsPropertyAccessExpression()
521
+ if property.Expression == nil || property.Expression.Kind != shimast.KindCallExpression || property.Name() == nil {
522
+ return "", "", false
523
+ }
524
+ call := property.Expression.AsCallExpression()
525
+ if call.Expression == nil || call.Expression.Kind != shimast.KindIdentifier || call.Expression.Text() != "require" ||
526
+ call.Arguments == nil || len(call.Arguments.Nodes) != 1 || !shimast.IsStringLiteral(call.Arguments.Nodes[0]) {
527
+ return "", "", false
528
+ }
529
+ return call.Arguments.Nodes[0].Text(), property.Name().Text(), true
530
+ }
531
+
532
+ func expressionFactoryDeclaration(ec *shimprinter.EmitContext, name string, expression *shimast.Node) *shimast.Node {
533
+ return ec.Factory.NewVariableStatement(
534
+ nil,
535
+ ec.Factory.NewVariableDeclarationList(
536
+ ec.Factory.NewNodeList([]*shimast.Node{ec.Factory.NewVariableDeclaration(
537
+ ec.Factory.NewIdentifier(name),
538
+ nil,
539
+ nil,
540
+ ec.Factory.NewArrowFunction(
541
+ nil,
542
+ nil,
543
+ ec.Factory.NewNodeList(nil),
544
+ nil,
545
+ nil,
546
+ ec.Factory.NewToken(shimast.KindEqualsGreaterThanToken),
547
+ expression,
548
+ ),
549
+ )}),
550
+ shimast.NodeFlagsConst,
551
+ ),
552
+ )
553
+ }