flow-api-translator 0.33.3 → 0.35.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.
@@ -525,7 +525,7 @@ const getTransforms = (originalCode, opts) => {
525
525
  }),
526
526
  importKind: // `import type React from 'react'` in TS means `import typeof React from react` in Flow
527
527
  specifiers.some(s => s.type === 'ImportDefaultSpecifier') && node.importKind === 'type' ? 'typeof' : node.importKind,
528
- assertions: [],
528
+ attributes: [],
529
529
  specifiers
530
530
  });
531
531
  }
@@ -606,7 +606,7 @@ const getTransforms = (originalCode: string, opts: TranslationOptions) => {
606
606
  node.importKind === 'type'
607
607
  ? 'typeof'
608
608
  : node.importKind,
609
- assertions: [],
609
+ attributes: [],
610
610
  specifiers,
611
611
  });
612
612
  }
@@ -734,6 +734,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
734
734
  }
735
735
  };
736
736
 
737
+ const wellKnownSymbols = new Set(['iterator', 'asyncIterator', 'dispose', 'asyncDispose']);
737
738
  const transform = {
738
739
  AnyTypeAnnotation(_node) {
739
740
  return {
@@ -899,7 +900,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
899
900
  if (_key.type === 'Identifier' && _key.name.startsWith('@@')) {
900
901
  const name = _key.name.slice(2);
901
902
 
902
- if (['iterator', 'asyncIterator'].includes(name)) {
903
+ if (wellKnownSymbols.has(name)) {
903
904
  return [{
904
905
  type: 'MemberExpression',
905
906
  computed: false,
@@ -1267,7 +1268,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1267
1268
  return {
1268
1269
  type: 'ExportNamedDeclaration',
1269
1270
  loc: DUMMY_LOC,
1270
- // flow does not currently support assertions
1271
+ // flow does not currently support attributes
1271
1272
  assertions: [],
1272
1273
  declaration: null,
1273
1274
  // flow does not support declared type exports with specifiers
@@ -1350,7 +1351,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1350
1351
  return [{
1351
1352
  type: 'ExportNamedDeclaration',
1352
1353
  loc: DUMMY_LOC,
1353
- // flow does not currently support assertions
1354
+ // flow does not currently support attributes
1354
1355
  assertions: [],
1355
1356
  declaration,
1356
1357
  exportKind,
@@ -1385,7 +1386,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1385
1386
  loc: DUMMY_LOC,
1386
1387
  specifiers: [],
1387
1388
  exportKind: 'type',
1388
- // flow does not currently support assertions
1389
+ // flow does not currently support attributes
1389
1390
  assertions: []
1390
1391
  }];
1391
1392
  }
@@ -1394,7 +1395,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1394
1395
  const exportNamedDeclaration = {
1395
1396
  type: 'ExportNamedDeclaration',
1396
1397
  loc: DUMMY_LOC,
1397
- // flow does not currently support assertions
1398
+ // flow does not currently support attributes
1398
1399
  assertions: [],
1399
1400
  declaration,
1400
1401
  exportKind,
@@ -1408,7 +1409,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1408
1409
  return {
1409
1410
  type: 'ExportNamedDeclaration',
1410
1411
  loc: DUMMY_LOC,
1411
- // flow does not currently support assertions
1412
+ // flow does not currently support attributes
1412
1413
  assertions: [],
1413
1414
  declaration: null,
1414
1415
  // flow does not support declared type exports with a source
@@ -1718,7 +1719,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1718
1719
  return {
1719
1720
  type: 'ExportAllDeclaration',
1720
1721
  loc: DUMMY_LOC,
1721
- // flow does not currently support import/export assertions
1722
+ // flow does not currently support import/export attributes
1722
1723
  assertions: [],
1723
1724
  exportKind: node.exportKind,
1724
1725
  source: transform.StringLiteral(node.source),
@@ -1732,7 +1733,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1732
1733
  return {
1733
1734
  type: 'ExportNamedDeclaration',
1734
1735
  loc: DUMMY_LOC,
1735
- // flow does not currently support import/export assertions
1736
+ // flow does not currently support import/export attributes
1736
1737
  assertions: [],
1737
1738
  declaration: null,
1738
1739
  exportKind: node.exportKind,
@@ -2981,7 +2982,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
2981
2982
  const out = specifiers.length ? [{
2982
2983
  type: 'ImportDeclaration',
2983
2984
  loc: DUMMY_LOC,
2984
- assertions: node.assertions.map(transform.ImportAttribute),
2985
+ assertions: node.attributes.map(transform.ImportAttribute),
2985
2986
  importKind: importKind === 'typeof' ? 'type' : importKind != null ? importKind : 'value',
2986
2987
  source: transform.StringLiteral(node.source),
2987
2988
  specifiers
@@ -3119,7 +3120,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
3119
3120
 
3120
3121
  ObjectTypeAnnotation(node) {
3121
3122
  if (node.properties.length === 1 && node.properties[0].type === 'ObjectTypeMappedTypeProperty') {
3122
- var _prop$variance;
3123
+ var _prop$variance, _prop$variance2;
3123
3124
 
3124
3125
  // Mapped Object Object types must not have other object properties.
3125
3126
  const prop = node.properties[0];
@@ -3144,7 +3145,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
3144
3145
  name: prop.keyTparam.name
3145
3146
  },
3146
3147
  constraint: transformTypeAnnotationType(prop.sourceType),
3147
- readonly: ((_prop$variance = prop.variance) == null ? void 0 : _prop$variance.kind) === 'plus',
3148
+ readonly: ((_prop$variance = prop.variance) == null ? void 0 : _prop$variance.kind) === 'plus' || ((_prop$variance2 = prop.variance) == null ? void 0 : _prop$variance2.kind) === 'readonly',
3148
3149
  optional: prop.optional === 'Optional',
3149
3150
  typeAnnotation: transformTypeAnnotationType(prop.propType),
3150
3151
  nameType: null
@@ -3365,10 +3366,10 @@ const getTransforms = (originalCode, scopeManager, opts) => {
3365
3366
  },
3366
3367
 
3367
3368
  ObjectTypeIndexer(node) {
3368
- var _node$variance2;
3369
+ var _node$variance3, _node$variance4;
3369
3370
 
3370
3371
  if (node.key.type === 'GenericTypeAnnotation') {
3371
- var _node$variance;
3372
+ var _node$variance, _node$variance2;
3372
3373
 
3373
3374
  const ident = node.key.id.type === 'Identifier' ? node.key.id : node.key.id.id;
3374
3375
  return {
@@ -3390,7 +3391,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
3390
3391
  loc: DUMMY_LOC
3391
3392
  }
3392
3393
  },
3393
- readonly: ((_node$variance = node.variance) == null ? void 0 : _node$variance.kind) === 'plus',
3394
+ readonly: ((_node$variance = node.variance) == null ? void 0 : _node$variance.kind) === 'plus' || ((_node$variance2 = node.variance) == null ? void 0 : _node$variance2.kind) === 'readonly',
3394
3395
  static: node.static,
3395
3396
  typeAnnotation: {
3396
3397
  type: 'TSTypeAnnotation',
@@ -3413,7 +3414,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
3413
3414
  typeAnnotation: transformTypeAnnotationType(node.key)
3414
3415
  }
3415
3416
  }],
3416
- readonly: ((_node$variance2 = node.variance) == null ? void 0 : _node$variance2.kind) === 'plus',
3417
+ readonly: ((_node$variance3 = node.variance) == null ? void 0 : _node$variance3.kind) === 'plus' || ((_node$variance4 = node.variance) == null ? void 0 : _node$variance4.kind) === 'readonly',
3417
3418
  static: node.static,
3418
3419
  typeAnnotation: {
3419
3420
  type: 'TSTypeAnnotation',
@@ -3424,22 +3425,52 @@ const getTransforms = (originalCode, scopeManager, opts) => {
3424
3425
  },
3425
3426
 
3426
3427
  ObjectTypeProperty(node) {
3427
- var _node$variance3;
3428
+ var _node$variance5, _node$variance6;
3428
3429
 
3429
- const key = node.key.type === 'Identifier' ? transform.Identifier(node.key) : node.key.literalType === 'string' ? transform.StringLiteral(node.key) : null;
3430
+ const [key, computed] = (() => {
3431
+ if (node.key.type === 'Identifier' && node.key.name.startsWith('@@')) {
3432
+ const name = node.key.name.slice(2);
3430
3433
 
3431
- if (key == null) {
3432
- throw unexpectedTranslationError(node, 'Unsupported key type');
3433
- }
3434
+ if (node.method === true && wellKnownSymbols.has(name)) {
3435
+ return [{
3436
+ type: 'MemberExpression',
3437
+ computed: false,
3438
+ object: {
3439
+ type: 'Identifier',
3440
+ name: 'Symbol',
3441
+ optional: false,
3442
+ loc: DUMMY_LOC
3443
+ },
3444
+ optional: false,
3445
+ property: {
3446
+ type: 'Identifier',
3447
+ name,
3448
+ optional: false,
3449
+ loc: DUMMY_LOC
3450
+ },
3451
+ loc: DUMMY_LOC
3452
+ }, true];
3453
+ }
3454
+ }
3455
+
3456
+ const key = node.key.type === 'Identifier' ? transform.Identifier(node.key) : node.key.literalType === 'string' ? transform.StringLiteral(node.key) : null;
3457
+
3458
+ if (key == null) {
3459
+ throw unexpectedTranslationError(node, 'Unsupported key type');
3460
+ }
3461
+
3462
+ return [key, false];
3463
+ })();
3434
3464
 
3435
3465
  if (node.method === true) {
3436
3466
  // flow has just one node for all object properties and relies upon the method flag
3437
3467
  // TS has separate nodes for methods and properties
3438
- const func = transform.FunctionTypeAnnotation(node.value);
3468
+ const func = transform.FunctionTypeAnnotation(node.value); // $FlowFixMe[incompatible-type] `computed` is set dynamically
3469
+
3439
3470
  return {
3440
3471
  type: 'TSMethodSignature',
3441
3472
  loc: DUMMY_LOC,
3442
- computed: false,
3473
+ computed,
3443
3474
  key,
3444
3475
  kind: node.kind === 'init' ? 'method' : node.kind,
3445
3476
  optional: node.optional,
@@ -3453,11 +3484,12 @@ const getTransforms = (originalCode, scopeManager, opts) => {
3453
3484
  if (node.kind === 'get' || node.kind === 'set') {
3454
3485
  // flow treats getters/setters as true property signatures (method === false)
3455
3486
  // TS treats them as method signatures
3456
- const func = transform.FunctionTypeAnnotation(node.value);
3487
+ const func = transform.FunctionTypeAnnotation(node.value); // $FlowFixMe[incompatible-type] `computed` is set dynamically
3488
+
3457
3489
  return {
3458
3490
  type: 'TSMethodSignature',
3459
3491
  loc: DUMMY_LOC,
3460
- computed: false,
3492
+ computed,
3461
3493
  key,
3462
3494
  kind: node.kind,
3463
3495
  optional: false,
@@ -3468,15 +3500,16 @@ const getTransforms = (originalCode, scopeManager, opts) => {
3468
3500
  // TS accessors cannot have type parameters
3469
3501
  typeParameters: undefined
3470
3502
  };
3471
- }
3503
+ } // $FlowFixMe[incompatible-type] `computed` is set dynamically
3504
+
3472
3505
 
3473
3506
  return {
3474
3507
  type: 'TSPropertySignature',
3475
3508
  loc: DUMMY_LOC,
3476
- computed: false,
3509
+ computed,
3477
3510
  key,
3478
3511
  optional: node.optional,
3479
- readonly: ((_node$variance3 = node.variance) == null ? void 0 : _node$variance3.kind) === 'plus',
3512
+ readonly: ((_node$variance5 = node.variance) == null ? void 0 : _node$variance5.kind) === 'plus' || ((_node$variance6 = node.variance) == null ? void 0 : _node$variance6.kind) === 'readonly',
3480
3513
  static: node.static,
3481
3514
  typeAnnotation: {
3482
3515
  type: 'TSTypeAnnotation',
@@ -3598,7 +3631,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
3598
3631
  },
3599
3632
 
3600
3633
  TupleTypeAnnotation(node) {
3601
- const allReadOnly = node.elementTypes.length > 0 && node.elementTypes.every(element => element.type === 'TupleTypeLabeledElement' && element.variance != null && element.variance.kind === 'plus');
3634
+ const allReadOnly = node.elementTypes.length > 0 && node.elementTypes.every(element => element.type === 'TupleTypeLabeledElement' && element.variance != null && (element.variance.kind === 'plus' || element.variance.kind === 'readonly'));
3602
3635
  const elems = node.elementTypes.map(element => {
3603
3636
  switch (element.type) {
3604
3637
  case 'TupleTypeLabeledElement':
@@ -766,6 +766,13 @@ const getTransforms = (
766
766
  }
767
767
  };
768
768
 
769
+ const wellKnownSymbols = new Set([
770
+ 'iterator',
771
+ 'asyncIterator',
772
+ 'dispose',
773
+ 'asyncDispose',
774
+ ]);
775
+
769
776
  const transform = {
770
777
  AnyTypeAnnotation(
771
778
  _node: FlowESTree.AnyTypeAnnotation,
@@ -944,7 +951,7 @@ const getTransforms = (
944
951
  const _key = member.key;
945
952
  if (_key.type === 'Identifier' && _key.name.startsWith('@@')) {
946
953
  const name = _key.name.slice(2);
947
- if (['iterator', 'asyncIterator'].includes(name)) {
954
+ if (wellKnownSymbols.has(name)) {
948
955
  return [
949
956
  {
950
957
  type: 'MemberExpression',
@@ -1373,7 +1380,7 @@ const getTransforms = (
1373
1380
  return ({
1374
1381
  type: 'ExportNamedDeclaration',
1375
1382
  loc: DUMMY_LOC,
1376
- // flow does not currently support assertions
1383
+ // flow does not currently support attributes
1377
1384
  assertions: [],
1378
1385
  declaration: null,
1379
1386
  // flow does not support declared type exports with specifiers
@@ -1470,7 +1477,7 @@ const getTransforms = (
1470
1477
  {
1471
1478
  type: 'ExportNamedDeclaration',
1472
1479
  loc: DUMMY_LOC,
1473
- // flow does not currently support assertions
1480
+ // flow does not currently support attributes
1474
1481
  assertions: [],
1475
1482
  declaration,
1476
1483
  exportKind,
@@ -1506,7 +1513,7 @@ const getTransforms = (
1506
1513
  loc: DUMMY_LOC,
1507
1514
  specifiers: [],
1508
1515
  exportKind: 'type',
1509
- // flow does not currently support assertions
1516
+ // flow does not currently support attributes
1510
1517
  assertions: [],
1511
1518
  },
1512
1519
  ];
@@ -1517,7 +1524,7 @@ const getTransforms = (
1517
1524
  {
1518
1525
  type: 'ExportNamedDeclaration',
1519
1526
  loc: DUMMY_LOC,
1520
- // flow does not currently support assertions
1527
+ // flow does not currently support attributes
1521
1528
  assertions: [],
1522
1529
  declaration,
1523
1530
  exportKind,
@@ -1532,7 +1539,7 @@ const getTransforms = (
1532
1539
  return ({
1533
1540
  type: 'ExportNamedDeclaration',
1534
1541
  loc: DUMMY_LOC,
1535
- // flow does not currently support assertions
1542
+ // flow does not currently support attributes
1536
1543
  assertions: [],
1537
1544
  declaration: null,
1538
1545
  // flow does not support declared type exports with a source
@@ -1905,7 +1912,7 @@ const getTransforms = (
1905
1912
  return {
1906
1913
  type: 'ExportAllDeclaration',
1907
1914
  loc: DUMMY_LOC,
1908
- // flow does not currently support import/export assertions
1915
+ // flow does not currently support import/export attributes
1909
1916
  assertions: [],
1910
1917
  exportKind: node.exportKind,
1911
1918
  source: transform.StringLiteral(node.source),
@@ -1923,7 +1930,7 @@ const getTransforms = (
1923
1930
  return {
1924
1931
  type: 'ExportNamedDeclaration',
1925
1932
  loc: DUMMY_LOC,
1926
- // flow does not currently support import/export assertions
1933
+ // flow does not currently support import/export attributes
1927
1934
  assertions: [],
1928
1935
  declaration: null,
1929
1936
  exportKind: node.exportKind,
@@ -3227,7 +3234,7 @@ const getTransforms = (
3227
3234
  {
3228
3235
  type: 'ImportDeclaration',
3229
3236
  loc: DUMMY_LOC,
3230
- assertions: node.assertions.map(transform.ImportAttribute),
3237
+ assertions: node.attributes.map(transform.ImportAttribute),
3231
3238
  importKind:
3232
3239
  importKind === 'typeof' ? 'type' : (importKind ?? 'value'),
3233
3240
  source: transform.StringLiteral(node.source),
@@ -3415,7 +3422,9 @@ const getTransforms = (
3415
3422
  name: prop.keyTparam.name,
3416
3423
  },
3417
3424
  constraint: transformTypeAnnotationType(prop.sourceType),
3418
- readonly: prop.variance?.kind === 'plus',
3425
+ readonly:
3426
+ prop.variance?.kind === 'plus' ||
3427
+ prop.variance?.kind === 'readonly',
3419
3428
  optional: prop.optional === 'Optional',
3420
3429
  typeAnnotation: transformTypeAnnotationType(prop.propType),
3421
3430
  nameType: null,
@@ -3692,7 +3701,9 @@ const getTransforms = (
3692
3701
  loc: DUMMY_LOC,
3693
3702
  },
3694
3703
  },
3695
- readonly: node.variance?.kind === 'plus',
3704
+ readonly:
3705
+ node.variance?.kind === 'plus' ||
3706
+ node.variance?.kind === 'readonly',
3696
3707
  static: node.static,
3697
3708
  typeAnnotation: {
3698
3709
  type: 'TSTypeAnnotation',
@@ -3716,7 +3727,8 @@ const getTransforms = (
3716
3727
  },
3717
3728
  },
3718
3729
  ],
3719
- readonly: node.variance?.kind === 'plus',
3730
+ readonly:
3731
+ node.variance?.kind === 'plus' || node.variance?.kind === 'readonly',
3720
3732
  static: node.static,
3721
3733
  typeAnnotation: {
3722
3734
  type: 'TSTypeAnnotation',
@@ -3728,25 +3740,57 @@ const getTransforms = (
3728
3740
  ObjectTypeProperty(
3729
3741
  node: FlowESTree.ObjectTypeProperty,
3730
3742
  ): TSESTree.TSPropertySignature | TSESTree.TSMethodSignature {
3731
- const key =
3732
- node.key.type === 'Identifier'
3733
- ? transform.Identifier(node.key)
3734
- : node.key.literalType === 'string'
3735
- ? transform.StringLiteral(node.key)
3736
- : null;
3737
-
3738
- if (key == null) {
3739
- throw unexpectedTranslationError(node, 'Unsupported key type');
3740
- }
3743
+ const [key, computed] = ((): [TSESTree.PropertyName, boolean] => {
3744
+ if (node.key.type === 'Identifier' && node.key.name.startsWith('@@')) {
3745
+ const name = node.key.name.slice(2);
3746
+ if (node.method === true && wellKnownSymbols.has(name)) {
3747
+ return [
3748
+ {
3749
+ type: 'MemberExpression',
3750
+ computed: false,
3751
+ object: {
3752
+ type: 'Identifier',
3753
+ name: 'Symbol',
3754
+ optional: false,
3755
+ loc: DUMMY_LOC,
3756
+ },
3757
+ optional: false,
3758
+ property: {
3759
+ type: 'Identifier',
3760
+ name,
3761
+ optional: false,
3762
+ loc: DUMMY_LOC,
3763
+ },
3764
+ loc: DUMMY_LOC,
3765
+ },
3766
+ true,
3767
+ ];
3768
+ }
3769
+ }
3770
+
3771
+ const key =
3772
+ node.key.type === 'Identifier'
3773
+ ? transform.Identifier(node.key)
3774
+ : node.key.literalType === 'string'
3775
+ ? transform.StringLiteral(node.key)
3776
+ : null;
3777
+
3778
+ if (key == null) {
3779
+ throw unexpectedTranslationError(node, 'Unsupported key type');
3780
+ }
3781
+
3782
+ return [key, false];
3783
+ })();
3741
3784
 
3742
3785
  if (node.method === true) {
3743
3786
  // flow has just one node for all object properties and relies upon the method flag
3744
3787
  // TS has separate nodes for methods and properties
3745
3788
  const func = transform.FunctionTypeAnnotation(node.value);
3789
+ // $FlowFixMe[incompatible-type] `computed` is set dynamically
3746
3790
  return {
3747
3791
  type: 'TSMethodSignature',
3748
3792
  loc: DUMMY_LOC,
3749
- computed: false,
3793
+ computed,
3750
3794
  key,
3751
3795
  kind: node.kind === 'init' ? 'method' : node.kind,
3752
3796
  optional: node.optional,
@@ -3761,10 +3805,11 @@ const getTransforms = (
3761
3805
  // flow treats getters/setters as true property signatures (method === false)
3762
3806
  // TS treats them as method signatures
3763
3807
  const func = transform.FunctionTypeAnnotation(node.value);
3808
+ // $FlowFixMe[incompatible-type] `computed` is set dynamically
3764
3809
  return {
3765
3810
  type: 'TSMethodSignature',
3766
3811
  loc: DUMMY_LOC,
3767
- computed: false,
3812
+ computed,
3768
3813
  key,
3769
3814
  kind: node.kind,
3770
3815
  optional: false,
@@ -3777,13 +3822,15 @@ const getTransforms = (
3777
3822
  };
3778
3823
  }
3779
3824
 
3825
+ // $FlowFixMe[incompatible-type] `computed` is set dynamically
3780
3826
  return {
3781
3827
  type: 'TSPropertySignature',
3782
3828
  loc: DUMMY_LOC,
3783
- computed: false,
3829
+ computed,
3784
3830
  key,
3785
3831
  optional: node.optional,
3786
- readonly: node.variance?.kind === 'plus',
3832
+ readonly:
3833
+ node.variance?.kind === 'plus' || node.variance?.kind === 'readonly',
3787
3834
  static: node.static,
3788
3835
  typeAnnotation: {
3789
3836
  type: 'TSTypeAnnotation',
@@ -3924,7 +3971,8 @@ const getTransforms = (
3924
3971
  element =>
3925
3972
  element.type === 'TupleTypeLabeledElement' &&
3926
3973
  element.variance != null &&
3927
- element.variance.kind === 'plus',
3974
+ (element.variance.kind === 'plus' ||
3975
+ element.variance.kind === 'readonly'),
3928
3976
  );
3929
3977
  const elems = node.elementTypes.map((element): TSESTree.TypeNode => {
3930
3978
  switch (element.type) {
@@ -249,7 +249,7 @@ function stripUnusedDefs(detachedStmt, usedDeps, context) {
249
249
  specifiers: resultSpecfiers,
250
250
  importKind: stmt.importKind,
251
251
  source: stmt.source,
252
- assertions: stmt.assertions
252
+ attributes: stmt.attributes
253
253
  });
254
254
  }
255
255
 
@@ -727,15 +727,15 @@ function convertVariableDeclaration(stmt, context) {
727
727
  }
728
728
 
729
729
  function convertImportDeclaration(stmt, context) {
730
- if (stmt.assertions.length > 0) {
731
- throw (0, _ErrorUtils.translationError)(stmt, 'ImportDeclaration: assertions not supported', context);
730
+ if (stmt.attributes.length > 0) {
731
+ throw (0, _ErrorUtils.translationError)(stmt, 'ImportDeclaration: attributes not supported', context);
732
732
  }
733
733
 
734
734
  return [_hermesTransform.t.ImportDeclaration({
735
735
  specifiers: stmt.specifiers,
736
736
  importKind: stmt.importKind,
737
737
  source: stmt.source,
738
- assertions: []
738
+ attributes: []
739
739
  }), []];
740
740
  }
741
741
 
@@ -1147,12 +1147,12 @@ function convertFunctionParameters(params, context) {
1147
1147
  }
1148
1148
 
1149
1149
  function convertBindingNameToFunctionTypeParam(pat, context, index, isAssignment) {
1150
- const name = pat.type === 'Identifier' ? pat.name : `$$PARAM_${index}$$`;
1150
+ const name = pat.type === 'Identifier' && pat.name != null ? pat.name : `$$PARAM_${index}$$`;
1151
1151
  const [resultParamTypeAnnotation, paramDeps] = convertTypeAnnotation(pat.typeAnnotation, pat, context);
1152
1152
  return [_hermesTransform.t.FunctionTypeParam({
1153
- name: name != null ? _hermesTransform.t.Identifier({
1153
+ name: _hermesTransform.t.Identifier({
1154
1154
  name
1155
- }) : null,
1155
+ }),
1156
1156
  typeAnnotation: resultParamTypeAnnotation,
1157
1157
  optional: isAssignment || (pat.type === 'Identifier' ? pat.optional : false)
1158
1158
  }), paramDeps];
@@ -357,7 +357,7 @@ function stripUnusedDefs(
357
357
  specifiers: resultSpecfiers,
358
358
  importKind: stmt.importKind,
359
359
  source: stmt.source,
360
- assertions: stmt.assertions,
360
+ attributes: stmt.attributes,
361
361
  });
362
362
  }
363
363
  return detachedStmt;
@@ -940,10 +940,10 @@ function convertImportDeclaration(
940
940
  stmt: ImportDeclaration,
941
941
  context: TranslationContext,
942
942
  ): TranslatedResult<ImportDeclaration> {
943
- if (stmt.assertions.length > 0) {
943
+ if (stmt.attributes.length > 0) {
944
944
  throw translationError(
945
945
  stmt,
946
- 'ImportDeclaration: assertions not supported',
946
+ 'ImportDeclaration: attributes not supported',
947
947
  context,
948
948
  );
949
949
  }
@@ -953,7 +953,7 @@ function convertImportDeclaration(
953
953
  specifiers: stmt.specifiers,
954
954
  importKind: stmt.importKind,
955
955
  source: stmt.source,
956
- assertions: [],
956
+ attributes: [],
957
957
  }),
958
958
  [],
959
959
  ];
@@ -1623,7 +1623,10 @@ function convertBindingNameToFunctionTypeParam(
1623
1623
  index: number,
1624
1624
  isAssignment: boolean,
1625
1625
  ): TranslatedResult<FunctionTypeParam> {
1626
- const name = pat.type === 'Identifier' ? pat.name : `$$PARAM_${index}$$`;
1626
+ const name =
1627
+ pat.type === 'Identifier' && pat.name != null
1628
+ ? pat.name
1629
+ : `$$PARAM_${index}$$`;
1627
1630
  const [resultParamTypeAnnotation, paramDeps] = convertTypeAnnotation(
1628
1631
  pat.typeAnnotation,
1629
1632
  pat,
@@ -1631,7 +1634,7 @@ function convertBindingNameToFunctionTypeParam(
1631
1634
  );
1632
1635
  return [
1633
1636
  t.FunctionTypeParam({
1634
- name: name != null ? t.Identifier({name}) : null,
1637
+ name: t.Identifier({name}),
1635
1638
  typeAnnotation: resultParamTypeAnnotation,
1636
1639
  optional:
1637
1640
  isAssignment || (pat.type === 'Identifier' ? pat.optional : false),
@@ -525,7 +525,7 @@ const getTransforms = (originalCode, opts) => {
525
525
  }),
526
526
  importKind: // `import type React from 'react'` in TS means `import typeof React from react` in Flow
527
527
  specifiers.some(s => s.type === 'ImportDefaultSpecifier') && node.importKind === 'type' ? 'typeof' : node.importKind,
528
- assertions: [],
528
+ attributes: [],
529
529
  specifiers
530
530
  });
531
531
  }
@@ -734,6 +734,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
734
734
  }
735
735
  };
736
736
 
737
+ const wellKnownSymbols = new Set(['iterator', 'asyncIterator', 'dispose', 'asyncDispose']);
737
738
  const transform = {
738
739
  AnyTypeAnnotation(_node) {
739
740
  return {
@@ -899,7 +900,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
899
900
  if (_key.type === 'Identifier' && _key.name.startsWith('@@')) {
900
901
  const name = _key.name.slice(2);
901
902
 
902
- if (['iterator', 'asyncIterator'].includes(name)) {
903
+ if (wellKnownSymbols.has(name)) {
903
904
  return [{
904
905
  type: 'MemberExpression',
905
906
  computed: false,
@@ -1267,7 +1268,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1267
1268
  return {
1268
1269
  type: 'ExportNamedDeclaration',
1269
1270
  loc: DUMMY_LOC,
1270
- // flow does not currently support assertions
1271
+ // flow does not currently support attributes
1271
1272
  assertions: [],
1272
1273
  declaration: null,
1273
1274
  // flow does not support declared type exports with specifiers
@@ -1350,7 +1351,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1350
1351
  return [{
1351
1352
  type: 'ExportNamedDeclaration',
1352
1353
  loc: DUMMY_LOC,
1353
- // flow does not currently support assertions
1354
+ // flow does not currently support attributes
1354
1355
  assertions: [],
1355
1356
  declaration,
1356
1357
  exportKind,
@@ -1385,7 +1386,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1385
1386
  loc: DUMMY_LOC,
1386
1387
  specifiers: [],
1387
1388
  exportKind: 'type',
1388
- // flow does not currently support assertions
1389
+ // flow does not currently support attributes
1389
1390
  assertions: []
1390
1391
  }];
1391
1392
  }
@@ -1394,7 +1395,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1394
1395
  const exportNamedDeclaration = {
1395
1396
  type: 'ExportNamedDeclaration',
1396
1397
  loc: DUMMY_LOC,
1397
- // flow does not currently support assertions
1398
+ // flow does not currently support attributes
1398
1399
  assertions: [],
1399
1400
  declaration,
1400
1401
  exportKind,
@@ -1408,7 +1409,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1408
1409
  return {
1409
1410
  type: 'ExportNamedDeclaration',
1410
1411
  loc: DUMMY_LOC,
1411
- // flow does not currently support assertions
1412
+ // flow does not currently support attributes
1412
1413
  assertions: [],
1413
1414
  declaration: null,
1414
1415
  // flow does not support declared type exports with a source
@@ -1718,7 +1719,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1718
1719
  return {
1719
1720
  type: 'ExportAllDeclaration',
1720
1721
  loc: DUMMY_LOC,
1721
- // flow does not currently support import/export assertions
1722
+ // flow does not currently support import/export attributes
1722
1723
  assertions: [],
1723
1724
  exportKind: node.exportKind,
1724
1725
  source: transform.StringLiteral(node.source),
@@ -1732,7 +1733,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1732
1733
  return {
1733
1734
  type: 'ExportNamedDeclaration',
1734
1735
  loc: DUMMY_LOC,
1735
- // flow does not currently support import/export assertions
1736
+ // flow does not currently support import/export attributes
1736
1737
  assertions: [],
1737
1738
  declaration: null,
1738
1739
  exportKind: node.exportKind,
@@ -2981,7 +2982,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
2981
2982
  const out = specifiers.length ? [{
2982
2983
  type: 'ImportDeclaration',
2983
2984
  loc: DUMMY_LOC,
2984
- assertions: node.assertions.map(transform.ImportAttribute),
2985
+ assertions: node.attributes.map(transform.ImportAttribute),
2985
2986
  importKind: importKind === 'typeof' ? 'type' : importKind != null ? importKind : 'value',
2986
2987
  source: transform.StringLiteral(node.source),
2987
2988
  specifiers
@@ -3119,7 +3120,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
3119
3120
 
3120
3121
  ObjectTypeAnnotation(node) {
3121
3122
  if (node.properties.length === 1 && node.properties[0].type === 'ObjectTypeMappedTypeProperty') {
3122
- var _prop$variance;
3123
+ var _prop$variance, _prop$variance2;
3123
3124
 
3124
3125
  // Mapped Object Object types must not have other object properties.
3125
3126
  const prop = node.properties[0];
@@ -3144,7 +3145,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
3144
3145
  name: prop.keyTparam.name
3145
3146
  },
3146
3147
  constraint: transformTypeAnnotationType(prop.sourceType),
3147
- readonly: ((_prop$variance = prop.variance) == null ? void 0 : _prop$variance.kind) === 'plus',
3148
+ readonly: ((_prop$variance = prop.variance) == null ? void 0 : _prop$variance.kind) === 'plus' || ((_prop$variance2 = prop.variance) == null ? void 0 : _prop$variance2.kind) === 'readonly',
3148
3149
  optional: prop.optional === 'Optional',
3149
3150
  typeAnnotation: transformTypeAnnotationType(prop.propType),
3150
3151
  nameType: null
@@ -3365,10 +3366,10 @@ const getTransforms = (originalCode, scopeManager, opts) => {
3365
3366
  },
3366
3367
 
3367
3368
  ObjectTypeIndexer(node) {
3368
- var _node$variance2;
3369
+ var _node$variance3, _node$variance4;
3369
3370
 
3370
3371
  if (node.key.type === 'GenericTypeAnnotation') {
3371
- var _node$variance;
3372
+ var _node$variance, _node$variance2;
3372
3373
 
3373
3374
  const ident = node.key.id.type === 'Identifier' ? node.key.id : node.key.id.id;
3374
3375
  return {
@@ -3390,7 +3391,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
3390
3391
  loc: DUMMY_LOC
3391
3392
  }
3392
3393
  },
3393
- readonly: ((_node$variance = node.variance) == null ? void 0 : _node$variance.kind) === 'plus',
3394
+ readonly: ((_node$variance = node.variance) == null ? void 0 : _node$variance.kind) === 'plus' || ((_node$variance2 = node.variance) == null ? void 0 : _node$variance2.kind) === 'readonly',
3394
3395
  static: node.static,
3395
3396
  typeAnnotation: {
3396
3397
  type: 'TSTypeAnnotation',
@@ -3413,7 +3414,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
3413
3414
  typeAnnotation: transformTypeAnnotationType(node.key)
3414
3415
  }
3415
3416
  }],
3416
- readonly: ((_node$variance2 = node.variance) == null ? void 0 : _node$variance2.kind) === 'plus',
3417
+ readonly: ((_node$variance3 = node.variance) == null ? void 0 : _node$variance3.kind) === 'plus' || ((_node$variance4 = node.variance) == null ? void 0 : _node$variance4.kind) === 'readonly',
3417
3418
  static: node.static,
3418
3419
  typeAnnotation: {
3419
3420
  type: 'TSTypeAnnotation',
@@ -3424,22 +3425,52 @@ const getTransforms = (originalCode, scopeManager, opts) => {
3424
3425
  },
3425
3426
 
3426
3427
  ObjectTypeProperty(node) {
3427
- var _node$variance3;
3428
+ var _node$variance5, _node$variance6;
3428
3429
 
3429
- const key = node.key.type === 'Identifier' ? transform.Identifier(node.key) : node.key.literalType === 'string' ? transform.StringLiteral(node.key) : null;
3430
+ const [key, computed] = (() => {
3431
+ if (node.key.type === 'Identifier' && node.key.name.startsWith('@@')) {
3432
+ const name = node.key.name.slice(2);
3430
3433
 
3431
- if (key == null) {
3432
- throw unexpectedTranslationError(node, 'Unsupported key type');
3433
- }
3434
+ if (node.method === true && wellKnownSymbols.has(name)) {
3435
+ return [{
3436
+ type: 'MemberExpression',
3437
+ computed: false,
3438
+ object: {
3439
+ type: 'Identifier',
3440
+ name: 'Symbol',
3441
+ optional: false,
3442
+ loc: DUMMY_LOC
3443
+ },
3444
+ optional: false,
3445
+ property: {
3446
+ type: 'Identifier',
3447
+ name,
3448
+ optional: false,
3449
+ loc: DUMMY_LOC
3450
+ },
3451
+ loc: DUMMY_LOC
3452
+ }, true];
3453
+ }
3454
+ }
3455
+
3456
+ const key = node.key.type === 'Identifier' ? transform.Identifier(node.key) : node.key.literalType === 'string' ? transform.StringLiteral(node.key) : null;
3457
+
3458
+ if (key == null) {
3459
+ throw unexpectedTranslationError(node, 'Unsupported key type');
3460
+ }
3461
+
3462
+ return [key, false];
3463
+ })();
3434
3464
 
3435
3465
  if (node.method === true) {
3436
3466
  // flow has just one node for all object properties and relies upon the method flag
3437
3467
  // TS has separate nodes for methods and properties
3438
- const func = transform.FunctionTypeAnnotation(node.value);
3468
+ const func = transform.FunctionTypeAnnotation(node.value); // $FlowFixMe[incompatible-type] `computed` is set dynamically
3469
+
3439
3470
  return {
3440
3471
  type: 'TSMethodSignature',
3441
3472
  loc: DUMMY_LOC,
3442
- computed: false,
3473
+ computed,
3443
3474
  key,
3444
3475
  kind: node.kind === 'init' ? 'method' : node.kind,
3445
3476
  optional: node.optional,
@@ -3453,11 +3484,12 @@ const getTransforms = (originalCode, scopeManager, opts) => {
3453
3484
  if (node.kind === 'get' || node.kind === 'set') {
3454
3485
  // flow treats getters/setters as true property signatures (method === false)
3455
3486
  // TS treats them as method signatures
3456
- const func = transform.FunctionTypeAnnotation(node.value);
3487
+ const func = transform.FunctionTypeAnnotation(node.value); // $FlowFixMe[incompatible-type] `computed` is set dynamically
3488
+
3457
3489
  return {
3458
3490
  type: 'TSMethodSignature',
3459
3491
  loc: DUMMY_LOC,
3460
- computed: false,
3492
+ computed,
3461
3493
  key,
3462
3494
  kind: node.kind,
3463
3495
  optional: false,
@@ -3468,15 +3500,16 @@ const getTransforms = (originalCode, scopeManager, opts) => {
3468
3500
  // TS accessors cannot have type parameters
3469
3501
  typeParameters: undefined
3470
3502
  };
3471
- }
3503
+ } // $FlowFixMe[incompatible-type] `computed` is set dynamically
3504
+
3472
3505
 
3473
3506
  return {
3474
3507
  type: 'TSPropertySignature',
3475
3508
  loc: DUMMY_LOC,
3476
- computed: false,
3509
+ computed,
3477
3510
  key,
3478
3511
  optional: node.optional,
3479
- readonly: ((_node$variance3 = node.variance) == null ? void 0 : _node$variance3.kind) === 'plus',
3512
+ readonly: ((_node$variance5 = node.variance) == null ? void 0 : _node$variance5.kind) === 'plus' || ((_node$variance6 = node.variance) == null ? void 0 : _node$variance6.kind) === 'readonly',
3480
3513
  static: node.static,
3481
3514
  typeAnnotation: {
3482
3515
  type: 'TSTypeAnnotation',
@@ -3598,7 +3631,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
3598
3631
  },
3599
3632
 
3600
3633
  TupleTypeAnnotation(node) {
3601
- const allReadOnly = node.elementTypes.length > 0 && node.elementTypes.every(element => element.type === 'TupleTypeLabeledElement' && element.variance != null && element.variance.kind === 'plus');
3634
+ const allReadOnly = node.elementTypes.length > 0 && node.elementTypes.every(element => element.type === 'TupleTypeLabeledElement' && element.variance != null && (element.variance.kind === 'plus' || element.variance.kind === 'readonly'));
3602
3635
  const elems = node.elementTypes.map(element => {
3603
3636
  switch (element.type) {
3604
3637
  case 'TupleTypeLabeledElement':
@@ -249,7 +249,7 @@ function stripUnusedDefs(detachedStmt, usedDeps, context) {
249
249
  specifiers: resultSpecfiers,
250
250
  importKind: stmt.importKind,
251
251
  source: stmt.source,
252
- assertions: stmt.assertions
252
+ attributes: stmt.attributes
253
253
  });
254
254
  }
255
255
 
@@ -727,15 +727,15 @@ function convertVariableDeclaration(stmt, context) {
727
727
  }
728
728
 
729
729
  function convertImportDeclaration(stmt, context) {
730
- if (stmt.assertions.length > 0) {
731
- throw (0, _ErrorUtils.translationError)(stmt, 'ImportDeclaration: assertions not supported', context);
730
+ if (stmt.attributes.length > 0) {
731
+ throw (0, _ErrorUtils.translationError)(stmt, 'ImportDeclaration: attributes not supported', context);
732
732
  }
733
733
 
734
734
  return [_hermesTransform.t.ImportDeclaration({
735
735
  specifiers: stmt.specifiers,
736
736
  importKind: stmt.importKind,
737
737
  source: stmt.source,
738
- assertions: []
738
+ attributes: []
739
739
  }), []];
740
740
  }
741
741
 
@@ -1147,12 +1147,12 @@ function convertFunctionParameters(params, context) {
1147
1147
  }
1148
1148
 
1149
1149
  function convertBindingNameToFunctionTypeParam(pat, context, index, isAssignment) {
1150
- const name = pat.type === 'Identifier' ? pat.name : `$$PARAM_${index}$$`;
1150
+ const name = pat.type === 'Identifier' && pat.name != null ? pat.name : `$$PARAM_${index}$$`;
1151
1151
  const [resultParamTypeAnnotation, paramDeps] = convertTypeAnnotation(pat.typeAnnotation, pat, context);
1152
1152
  return [_hermesTransform.t.FunctionTypeParam({
1153
- name: name != null ? _hermesTransform.t.Identifier({
1153
+ name: _hermesTransform.t.Identifier({
1154
1154
  name
1155
- }) : null,
1155
+ }),
1156
1156
  typeAnnotation: resultParamTypeAnnotation,
1157
1157
  optional: isAssignment || (pat.type === 'Identifier' ? pat.optional : false)
1158
1158
  }), paramDeps];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flow-api-translator",
3
- "version": "0.33.3",
3
+ "version": "0.35.0",
4
4
  "description": "Toolkit for creating Flow and TypeScript compatible libraries from Flow source code.",
5
5
  "main": "dist/index.js",
6
6
  "license": "MIT",
@@ -13,10 +13,10 @@
13
13
  "@typescript-eslint/parser": "8.38.0",
14
14
  "@typescript-eslint/visitor-keys": "8.38.0",
15
15
  "flow-enums-runtime": "^0.0.6",
16
- "hermes-eslint": "0.33.3",
17
- "hermes-estree": "0.33.3",
18
- "hermes-parser": "0.33.3",
19
- "hermes-transform": "0.33.3",
16
+ "hermes-eslint": "0.35.0",
17
+ "hermes-estree": "0.35.0",
18
+ "hermes-parser": "0.35.0",
19
+ "hermes-transform": "0.35.0",
20
20
  "typescript": "5.3.2"
21
21
  },
22
22
  "peerDependencies": {