flow-upgrade 2.2.0 → 2.4.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 CHANGED
@@ -88,3 +88,13 @@ Part of the upgrade to 0.201
88
88
  Converts usages of the deprecated and unsafe `$Shape` utility type to its replacement, [`Partial`](https://flow.org/en/docs/types/utilities/#toc-partial).
89
89
 
90
90
  Run with `yarn run flow-codemod convertShapeToPartial`.
91
+
92
+ ### Migrate type casts `(x: T)` to `as` expressions `x as T`
93
+ Converts usages of the old casting syntax `(x: T)` to the new casting syntax `x as T`.
94
+
95
+ Run with `yarn run flow-codemod typeCastToAsExpression`.
96
+
97
+ ### Migrate internal Flow types for React to public-facing ones
98
+ Converts usages of the internal React types like `React$Node` to public facing ones like `React.Node`.
99
+
100
+ Run with `yarn run flow-codemod replaceReactDollarUtilityTypes`.
package/dist/Styled.js CHANGED
@@ -1,14 +1,5 @@
1
1
  "use strict";
2
2
 
3
- /**
4
- * Copyright (c) Meta Platforms, Inc. and affiliates.
5
- *
6
- * This source code is licensed under the MIT license found in the
7
- * LICENSE file in the root directory of this source tree.
8
- *
9
- * @format
10
- *
11
- */
12
3
  const chalk = require('chalk');
13
4
 
14
5
  exports.divider = function divider() {
@@ -24,16 +15,9 @@ exports.upgradeTitle = function upgradeTitle(title, n) {
24
15
  };
25
16
 
26
17
  exports.codeblock = function codeblock(code) {
27
- return code // Add indentation to the beginning of every line of code.
28
- .split('\n').map(line => ` ${line}`).join('\n') // Add highlighting for puncuation. We need to do this first otherwise it
29
- // breaks the other colors.
30
- .replace(/([={}()\[\];<>,:.*/])/g, chalk.grey('$1')) // Add highlighting for reserved keywords.
31
- .replace(/(import|from|typeof|type|class|extends|static|return|function)/g, chalk.magenta('$1')) // Add highlighting for strings.
32
- .replace(/('[^\n]*')/g, chalk.green('$1'));
18
+ return code.split('\n').map(line => ` ${line}`).join('\n').replace(/([={}()\[\];<>,:.*/])/g, chalk.grey('$1')).replace(/(import|from|typeof|type|class|extends|static|return|function)/g, chalk.magenta('$1')).replace(/('[^\n]*')/g, chalk.green('$1'));
33
19
  };
34
20
 
35
21
  exports.list = function list(items) {
36
- return items.map(item => // Indent every item and add a `- ` to the beginning of each line.
37
- item.split('\n').map((line, i) => `${i === 0 ? chalk.grey('- ') : ' '}${line}`).join('\n')) // Combine all of our items into one list string.
38
- .join('\n');
22
+ return items.map(item => item.split('\n').map((line, i) => `${i === 0 ? chalk.grey('- ') : ' '}${line}`).join('\n')).join('\n');
39
23
  };
package/dist/Types.js CHANGED
@@ -5,15 +5,6 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.codemod = codemod;
7
7
 
8
- /**
9
- * Copyright (c) Meta Platforms, Inc. and affiliates.
10
- *
11
- * This source code is licensed under the MIT license found in the
12
- * LICENSE file in the root directory of this source tree.
13
- *
14
- * @format
15
- *
16
- */
17
8
  function codemod(config) {
18
9
  return { ...config,
19
10
  kind: 'codemod'
@@ -1,14 +1,4 @@
1
1
  #!/usr/bin/env node
2
-
3
- /**
4
- * Copyright (c) Meta Platforms, Inc. and affiliates.
5
- *
6
- * This source code is licensed under the MIT license found in the
7
- * LICENSE file in the root directory of this source tree.
8
- *
9
- * @format
10
- *
11
- */
12
2
  "use strict";
13
3
 
14
4
  var _chalk = _interopRequireDefault(require("chalk"));
@@ -79,11 +69,10 @@ async function main(args) {
79
69
  const directory = process.cwd();
80
70
 
81
71
  try {
82
- const filePaths = await (0, _findFlowFiles.findFlowFilesWithSpinner)(directory, options); // $FlowExpectedError[unsupported-syntax]
83
-
72
+ const filePaths = await (0, _findFlowFiles.findFlowFilesWithSpinner)(directory, options);
84
73
  const {
85
74
  default: upgrade
86
- } = await Promise.resolve(`${CODEMOD_DIR}/${codemodName}.js`).then(s => _interopRequireWildcard(require(s))); // Tell the user what we are about to do.
75
+ } = await Promise.resolve(`${CODEMOD_DIR}/${codemodName}.js`).then(s => _interopRequireWildcard(require(s)));
87
76
 
88
77
  if (!options.silent) {
89
78
  console.log(_Styled.default.sectionHeader('Codemods'));
@@ -92,7 +81,7 @@ async function main(args) {
92
81
  console.log();
93
82
  console.log(_Styled.default.upgradeTitle(upgrade.title, 1));
94
83
  console.log();
95
- console.log(upgrade.description);
84
+ console.log(upgrade.describe);
96
85
  console.log();
97
86
  console.log(_Styled.default.divider());
98
87
  console.log();
@@ -104,7 +93,6 @@ async function main(args) {
104
93
  case 'codemod':
105
94
  await (0, _runCodemods.default)([upgrade], filePaths, options);
106
95
  break;
107
- // Throw an error for all other kinds of upgrades.
108
96
 
109
97
  default:
110
98
  throw new Error(`Unexpected upgrade kind: '${upgrade.kind}'`);
@@ -1,14 +1,4 @@
1
1
  #!/usr/bin/env node
2
-
3
- /**
4
- * Copyright (c) Meta Platforms, Inc. and affiliates.
5
- *
6
- * This source code is licensed under the MIT license found in the
7
- * LICENSE file in the root directory of this source tree.
8
- *
9
- * @format
10
- *
11
- */
12
2
  "use strict";
13
3
 
14
4
  var _chalk = _interopRequireDefault(require("chalk"));
@@ -57,11 +47,7 @@ async function main(args) {
57
47
  prettierOptions,
58
48
  silent: !!yargs.silent,
59
49
  yes: !!yargs.yes
60
- }; // For now we are asking for the version numbers out of convenience. When we add
61
- // upgrades for future versions we will need to check `.flowconfig` or
62
- // `flow-bin` for the current version and allow the new version to be
63
- // configurable. (But still default to the latest version.)
64
-
50
+ };
65
51
  const fromVersion = yargs._[0];
66
52
  const toVersion = yargs._[1];
67
53
 
@@ -5,15 +5,6 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.getClassMemberName = getClassMemberName;
7
7
 
8
- /**
9
- * Copyright (c) Meta Platforms, Inc. and affiliates.
10
- *
11
- * This source code is licensed under the MIT license found in the
12
- * LICENSE file in the root directory of this source tree.
13
- *
14
- * @format
15
- *
16
- */
17
8
  function getClassMemberName(member) {
18
9
  if (member.key.type === 'PrivateIdentifier') {
19
10
  return `#${member.key.name}`;
@@ -7,39 +7,12 @@ exports.replaceMethodWithArrowProp = replaceMethodWithArrowProp;
7
7
 
8
8
  var _hermesTransform = require("hermes-transform");
9
9
 
10
- /**
11
- * Copyright (c) Meta Platforms, Inc. and affiliates.
12
- *
13
- * This source code is licensed under the MIT license found in the
14
- * LICENSE file in the root directory of this source tree.
15
- *
16
- * @format
17
- *
18
- */
19
-
20
- /**
21
- * Converts method definition to an arrow function property
22
- * ```
23
- * method<T>(arg) { ... }
24
- * // to
25
- * +method = <T>(arg) => { ... };
26
- * ```
27
- */
28
10
  function replaceMethodWithArrowProp(context, method, name) {
29
11
  context.replaceNode(method, _hermesTransform.t.PropertyDefinition({
30
12
  computed: false,
31
13
  declare: false,
32
14
  key: _hermesTransform.t.Identifier({
33
15
  name,
34
- // for types-first compliance, this should ideally be filled out for
35
- // non-private members. However it's *super* complicated to correctly
36
- // handle these cases statically (type parameters and default args make
37
- // it hard).
38
- // So instead we just ignore it and they can be filled later using a
39
- // type-aware codemod like
40
- // ```
41
- // flow codemod annotate-exports --write --munge-underscore-members --max-type-size 25
42
- // ```
43
16
  typeAnnotation: null
44
17
  }),
45
18
  optional: false,
@@ -52,7 +25,6 @@ function replaceMethodWithArrowProp(context, method, name) {
52
25
  typeParameters: method.value.typeParameters,
53
26
  returnType: method.value.returnType
54
27
  }),
55
- // methods are readonly, so we mark the property as readonly as well
56
28
  variance: _hermesTransform.t.Variance({
57
29
  kind: 'plus'
58
30
  })
@@ -9,18 +9,9 @@ var _hermesTransform = require("hermes-transform");
9
9
 
10
10
  var _Types = require("../Types");
11
11
 
12
- /**
13
- * Copyright (c) Meta Platforms, Inc. and affiliates.
14
- *
15
- * This source code is licensed under the MIT license found in the
16
- * LICENSE file in the root directory of this source tree.
17
- *
18
- * @format
19
- *
20
- */
21
12
  var _default = (0, _Types.codemod)({
22
13
  title: 'Collapse Object Initialization',
23
- description: 'Converts static object assignments to inline properties',
14
+ describe: 'Converts static object assignments to inline properties',
24
15
  transform: context => {
25
16
  function getStatementContainerArray(stmtNode) {
26
17
  const parent = stmtNode.parent;
@@ -38,7 +29,6 @@ var _default = (0, _Types.codemod)({
38
29
 
39
30
  case 'Program':
40
31
  {
41
- // $FlowIgnore[incompatible-return]
42
32
  return parent.body;
43
33
  }
44
34
 
@@ -109,7 +99,7 @@ var _default = (0, _Types.codemod)({
109
99
  const memberPropertyNode = leftNode.property;
110
100
 
111
101
  if (memberObjectNode.type === 'Identifier' && memberObjectNode.name === idNode.name && memberPropertyNode.type === 'Identifier') {
112
- const shorthand = !leftNode.computed && exprRightNode.type === 'Identifier' && exprRightNode.name === memberPropertyNode.name; // $FlowIgnore[incompatible-type-arg] You gonna have to trust me
102
+ const shorthand = !leftNode.computed && exprRightNode.type === 'Identifier' && exprRightNode.name === memberPropertyNode.name;
113
103
 
114
104
  const property = _hermesTransform.t.Property({
115
105
  key: memberPropertyNode,
@@ -117,7 +107,6 @@ var _default = (0, _Types.codemod)({
117
107
  computed: leftNode.computed,
118
108
  kind: 'init',
119
109
  method: false,
120
- // $FlowIgnore[incompatible-call]
121
110
  shorthand
122
111
  });
123
112
 
@@ -211,8 +200,7 @@ var _default = (0, _Types.codemod)({
211
200
  }, 0);
212
201
 
213
202
  if (assignmentRefsCount !== objectProperties.length) {
214
- console.error(context.buildCodeFrame(stmtNode, 'Object had non inlinable and inlineable properties')); // If you don't wish to codemod these mixed objects return here.
215
- // return;
203
+ console.error(context.buildCodeFrame(stmtNode, 'Object had non inlinable and inlineable properties'));
216
204
  }
217
205
 
218
206
  const keyNames = new Set();
@@ -7,22 +7,12 @@ exports.default = void 0;
7
7
 
8
8
  var _Types = require("../Types");
9
9
 
10
- /**
11
- * Copyright (c) Meta Platforms, Inc. and affiliates.
12
- *
13
- * This source code is licensed under the MIT license found in the
14
- * LICENSE file in the root directory of this source tree.
15
- *
16
- * @format
17
- *
18
- */
19
10
  var _default = (0, _Types.codemod)({
20
11
  title: 'Make implicitly inexact object types explicitly inexact',
21
- description: 'Convert implicitly inexact object type syntax `{}` to explicitly inexact `{...}`',
12
+ describe: 'Convert implicitly inexact object type syntax `{}` to explicitly inexact `{...}`',
22
13
  transform: context => {
23
14
  return {
24
15
  ':not(InterfaceDeclaration, InterfaceTypeAnnotation, DeclareInterface, DeclareClass) > ObjectTypeAnnotation[inexact=false][exact=false]'(node) {
25
- // $FlowFixMe[incompatible-call] `inexact` can be true, as is the case with `{...}`
26
16
  context.modifyNodeInPlace(node, {
27
17
  inexact: true
28
18
  });
@@ -7,18 +7,9 @@ exports.default = void 0;
7
7
 
8
8
  var _Types = require("../Types");
9
9
 
10
- /**
11
- * Copyright (c) Meta Platforms, Inc. and affiliates.
12
- *
13
- * This source code is licensed under the MIT license found in the
14
- * LICENSE file in the root directory of this source tree.
15
- *
16
- * @format
17
- *
18
- */
19
10
  var _default = (0, _Types.codemod)({
20
11
  title: 'Convert `$Shape` to `Partial`',
21
- description: 'Converts usage of the `$Shape` utility type to `Partial`. It is possible that this will create type errors that you will have to resolve.',
12
+ describe: 'Converts usage of the `$Shape` utility type to `Partial`. It is possible that this will create type errors that you will have to resolve.',
22
13
  transform: context => {
23
14
  return {
24
15
  'GenericTypeAnnotation[id.name="$Shape"][typeParameters.params.length > 0]'(node) {
@@ -7,18 +7,9 @@ exports.default = void 0;
7
7
 
8
8
  var _Types = require("../Types");
9
9
 
10
- /**
11
- * Copyright (c) Meta Platforms, Inc. and affiliates.
12
- *
13
- * This source code is licensed under the MIT license found in the
14
- * LICENSE file in the root directory of this source tree.
15
- *
16
- * @format
17
- *
18
- */
19
10
  var _default = (0, _Types.codemod)({
20
11
  title: 'Remove Annotations In Destructuring',
21
- description: 'Remove annotations nested inside of destructuring. These are not valid Flow syntax.',
12
+ describe: 'Remove annotations nested inside of destructuring. These are not valid Flow syntax.',
22
13
  transform: context => {
23
14
  return {
24
15
  ':matches(ArrayPattern, ObjectPattern) > :matches(Identifier, ArrayPattern, ObjectPattern)[typeAnnotation!=null]'(node) {
@@ -11,15 +11,6 @@ var _replaceMethodWithArrowProp = require("../codemodUtils/replaceMethodWithArro
11
11
 
12
12
  var _Types = require("../Types");
13
13
 
14
- /**
15
- * Copyright (c) Meta Platforms, Inc. and affiliates.
16
- *
17
- * This source code is licensed under the MIT license found in the
18
- * LICENSE file in the root directory of this source tree.
19
- *
20
- * @format
21
- *
22
- */
23
14
  function getKind(member) {
24
15
  switch (member.type) {
25
16
  case 'MethodDefinition':
@@ -63,8 +54,7 @@ function findDuplicates(membersMap) {
63
54
  member
64
55
  };
65
56
  continue;
66
- } // handle the valid cases
67
-
57
+ }
68
58
 
69
59
  switch (lastMember.kind) {
70
60
  case 'GetterSetter':
@@ -105,8 +95,7 @@ function findDuplicates(membersMap) {
105
95
  }
106
96
 
107
97
  break;
108
- } // overwrite and delete the old member as it's incompatible
109
-
98
+ }
110
99
 
111
100
  if (lastMember.kind === 'GetterSetter') {
112
101
  toDelete.push(lastMember.getter);
@@ -127,11 +116,10 @@ function findDuplicates(membersMap) {
127
116
 
128
117
  var _default = (0, _Types.codemod)({
129
118
  title: 'Remove Duplicate Class Properties',
130
- description: 'Removes useless duplicate class properties and fixes bad constructor binding in those classes',
119
+ describe: 'Removes useless duplicate class properties and fixes bad constructor binding in those classes',
131
120
  transform: context => {
132
121
  let classStack = null;
133
122
  return {
134
- // find and delete duplicated members
135
123
  'ClassDeclaration, ClassExpression'(node) {
136
124
  const staticMembers = new Map();
137
125
  const instanceMembers = new Map();
@@ -141,7 +129,6 @@ var _default = (0, _Types.codemod)({
141
129
  const name = (0, _getClassMemberName.getClassMemberName)(member);
142
130
 
143
131
  if (name == null) {
144
- // unsupported computed member
145
132
  continue;
146
133
  }
147
134
 
@@ -158,8 +145,7 @@ var _default = (0, _Types.codemod)({
158
145
 
159
146
  if (toDelete.size === 0) {
160
147
  return;
161
- } // mark members for deletion
162
-
148
+ }
163
149
 
164
150
  for (const memberToDelete of toDelete) {
165
151
  var _memberToDelete$value;
@@ -169,9 +155,7 @@ var _default = (0, _Types.codemod)({
169
155
  }
170
156
 
171
157
  context.removeNode(memberToDelete);
172
- } // we need the final list of instance members so we can
173
- // fix up rebinding later
174
-
158
+ }
175
159
 
176
160
  const newInstanceMembers = new Map();
177
161
 
@@ -195,8 +179,7 @@ var _default = (0, _Types.codemod)({
195
179
  kind,
196
180
  member
197
181
  });
198
- } // push the stack
199
-
182
+ }
200
183
 
201
184
  classStack = {
202
185
  current: node,
@@ -205,7 +188,6 @@ var _default = (0, _Types.codemod)({
205
188
  };
206
189
  },
207
190
 
208
- // remove unnecessary .bind in constructor
209
191
  'MethodDefinition[kind = "constructor"] ExpressionStatement > AssignmentExpression[operator = "="] > MemberExpression[object.type = "ThisExpression"].left'(node) {
210
192
  if (!classStack) {
211
193
  return;
@@ -218,7 +200,7 @@ var _default = (0, _Types.codemod)({
218
200
  }
219
201
 
220
202
  const subjectName = node.property.name;
221
- const member = instanceMembers.get(subjectName); // the subject member must be a method
203
+ const member = instanceMembers.get(subjectName);
222
204
 
223
205
  if ((member === null || member === void 0 ? void 0 : member.kind) !== 'Method') {
224
206
  return;
@@ -231,26 +213,23 @@ var _default = (0, _Types.codemod)({
231
213
  throw new Error('this cannot happen');
232
214
  }
233
215
 
234
- const right = assignmentExpr.right; // we're looking for `this.thing = this.thing.bind(this)`
216
+ const right = assignmentExpr.right;
235
217
 
236
218
  if (right.type !== 'CallExpression' || right.arguments.length !== 1 || right.arguments[0].type !== 'ThisExpression' || right.callee.type !== 'MemberExpression' || right.callee.computed || right.callee.property.type !== 'Identifier' || right.callee.property.name !== 'bind' || right.callee.object.type !== 'MemberExpression' || right.callee.object.computed || right.callee.object.object.type !== 'ThisExpression' || right.callee.object.property.type !== 'Identifier' || right.callee.object.property.name !== subjectName) {
237
219
  console.log(context.buildCodeFrame(right, `${subjectName} was reassigned, but not to a bind. You can probably manually correct this.`));
238
220
  return;
239
- } // remove the bind assignment and...
240
-
221
+ }
241
222
 
242
223
  context.removeStatement(exprStatement);
243
224
  const method = member.member;
244
225
 
245
226
  if (method.type !== 'MethodDefinition') {
246
227
  throw new Error('this cannot happen');
247
- } // convert the method to an arrow function
248
-
228
+ }
249
229
 
250
230
  (0, _replaceMethodWithArrowProp.replaceMethodWithArrowProp)(context, method, subjectName);
251
231
  },
252
232
 
253
- // pop the stack
254
233
  'ClassDeclaration, ClassExpression:exit'(node) {
255
234
  var _classStack;
256
235
 
@@ -7,18 +7,9 @@ exports.default = void 0;
7
7
 
8
8
  var _Types = require("../Types");
9
9
 
10
- /**
11
- * Copyright (c) Meta Platforms, Inc. and affiliates.
12
- *
13
- * This source code is licensed under the MIT license found in the
14
- * LICENSE file in the root directory of this source tree.
15
- *
16
- * @format
17
- *
18
- */
19
10
  var _default = (0, _Types.codemod)({
20
11
  title: 'Remove explicitly exact object type syntax',
21
- description: 'Convert explicitly exact object type syntax `{| |}` to be just be `{ }`. To be done after you turn on `exact_by_default=true` in your `.flowconfig`.',
12
+ describe: 'Convert explicitly exact object type syntax `{| |}` to be just be `{ }`. To be done after you turn on `exact_by_default=true` in your `.flowconfig`.',
22
13
  transform: context => {
23
14
  return {
24
15
  'ObjectTypeAnnotation[exact=true]'(node) {
@@ -7,18 +7,9 @@ exports.default = void 0;
7
7
 
8
8
  var _Types = require("../Types");
9
9
 
10
- /**
11
- * Copyright (c) Meta Platforms, Inc. and affiliates.
12
- *
13
- * This source code is licensed under the MIT license found in the
14
- * LICENSE file in the root directory of this source tree.
15
- *
16
- * @format
17
- *
18
- */
19
10
  var _default = (0, _Types.codemod)({
20
11
  title: 'Rename `$Partial` to `Partial`',
21
- description: 'Renames the `$Partial` type utility to `Partial`.',
12
+ describe: 'Renames the `$Partial` type utility to `Partial`.',
22
13
  transform: context => {
23
14
  return {
24
15
  'GenericTypeAnnotation[id.name="$Partial"][typeParameters.params.length > 0]'(node) {
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _hermesTransform = require("hermes-transform");
9
+
10
+ var _Types = require("../Types");
11
+
12
+ const UTILITY_TYPES = new Set(['React$ComponentType', 'React$AbstractComponent', 'React$Element', 'React$MixedElement', 'React$ElementType', 'React$Key', 'React$Ref', 'React$RefSetter', 'React$Node', 'React$Context', 'React$Portal', 'React$ElementProps', 'React$ElementConfig', 'React$ElementRef', 'React$Config', 'React$Config', 'React$RefObject']);
13
+
14
+ var _default = (0, _Types.codemod)({
15
+ title: 'Replace React$SomeUtilityType with React.SomeUtilityType.',
16
+ transform: context => {
17
+ return {
18
+ GenericTypeAnnotation(node) {
19
+ if (typeof node.id.name !== 'string') {
20
+ return;
21
+ }
22
+
23
+ const utilTypeName = node.id.name;
24
+
25
+ if (!UTILITY_TYPES.has(utilTypeName)) {
26
+ return;
27
+ }
28
+
29
+ const newNode = _hermesTransform.t.GenericTypeAnnotation({
30
+ id: _hermesTransform.t.QualifiedTypeIdentifier({
31
+ id: _hermesTransform.t.Identifier({
32
+ name: utilTypeName.substring('React$'.length)
33
+ }),
34
+ qualification: _hermesTransform.t.Identifier({
35
+ name: 'React'
36
+ })
37
+ }),
38
+ typeParameters: node.typeParameters
39
+ });
40
+
41
+ context.replaceNode(node, newNode);
42
+ }
43
+
44
+ };
45
+ }
46
+ });
47
+
48
+ exports.default = _default;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _Types = require("../Types");
9
+
10
+ var _hermesTransform = require("hermes-transform");
11
+
12
+ function convertTypeCast(node) {
13
+ const {
14
+ expression,
15
+ typeAnnotation: {
16
+ typeAnnotation
17
+ }
18
+ } = node;
19
+ return _hermesTransform.t.AsExpression({
20
+ expression: expression.type === 'TypeCastExpression' ? convertTypeCast(expression) : expression,
21
+ typeAnnotation
22
+ });
23
+ }
24
+
25
+ var _default = (0, _Types.codemod)({
26
+ title: 'Update type casting syntax',
27
+ describe: 'Convert type cast expressions `(<expr>: <type>)` to as expressions `<expr> as <type>`',
28
+ transform: context => {
29
+ return {
30
+ TypeCastExpression(node) {
31
+ context.replaceNode(node, convertTypeCast(node), {
32
+ keepComments: true
33
+ });
34
+ context.skipTraversal();
35
+ }
36
+
37
+ };
38
+ }
39
+ });
40
+
41
+ exports.default = _default;
@@ -9,18 +9,9 @@ var _Types = require("../Types");
9
9
 
10
10
  var _hermesTransform = require("hermes-transform");
11
11
 
12
- /**
13
- * Copyright (c) Meta Platforms, Inc. and affiliates.
14
- *
15
- * This source code is licensed under the MIT license found in the
16
- * LICENSE file in the root directory of this source tree.
17
- *
18
- * @format
19
- *
20
- */
21
12
  var _default = (0, _Types.codemod)({
22
13
  title: 'Replace `T: {}` with `T: {...}` in type parameter bounds',
23
- description: 'Replace `T: {}` with `T: {...}` in type parameter bounds',
14
+ describe: 'Replace `T: {}` with `T: {...}` in type parameter bounds',
24
15
  transform: context => {
25
16
  return {
26
17
  TypeParameter(node) {
@@ -32,10 +23,6 @@ var _default = (0, _Types.codemod)({
32
23
  properties: [],
33
24
  callProperties: [],
34
25
  exact: false,
35
-
36
- /* $FlowExpectedError[incompatible-call]
37
- * TODO: hermes-transform mandates that inexact must be
38
- * `false`, which is wrong. */
39
26
  inexact: true,
40
27
  indexers: [],
41
28
  internalSlots: []
@@ -16,125 +16,70 @@ var _chalk = _interopRequireDefault(require("chalk"));
16
16
 
17
17
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18
18
 
19
- /**
20
- * Copyright (c) Meta Platforms, Inc. and affiliates.
21
- *
22
- * This source code is licensed under the MIT license found in the
23
- * LICENSE file in the root directory of this source tree.
24
- *
25
- * @format
26
- *
27
- */
28
-
29
- /**
30
- * How many bytes we should look at for the Flow pragma.
31
- */
32
19
  const PRAGMA_BYTES = 5000;
33
- /**
34
- * Finds all of the Flow files in the provided directory as efficiently as
35
- * possible.
36
- */
37
20
 
38
21
  async function findFlowFiles({
39
22
  includeNonAtFlow,
40
23
  rootDirectory
41
24
  }) {
42
- // All the valid file paths that we have found.
43
- const filePaths = []; // Begin the recursion!
44
-
25
+ const filePaths = [];
45
26
  await processDirectory(rootDirectory);
46
27
  return filePaths;
47
- /**
48
- * Process a directory by looking at all of its entries and recursing
49
- * through child directories as is appropriate.
50
- */
51
28
 
52
29
  async function processDirectory(directory) {
53
- // Read the directory...
54
- const fileNames = await _fsExtra.default.readdir(directory); // Process every file name that we got from reading the directory.
55
-
30
+ const fileNames = await _fsExtra.default.readdir(directory);
56
31
  await Promise.all(fileNames.map(fileName => processFilePath(directory, fileName)));
57
32
  }
58
- /**
59
- * Process a directory file path by seeing if it is a directory and either
60
- * recursing or adding it to filePaths.
61
- */
62
-
63
33
 
64
34
  async function processFilePath(directory, fileName) {
65
- // Get the file file path for this file.
66
- const filePath = _path.default.join(directory, fileName); // Get the stats for the file.
35
+ const filePath = _path.default.join(directory, fileName);
67
36
 
68
-
69
- const stats = await _fsExtra.default.lstat(filePath); // If this is a directory...
37
+ const stats = await _fsExtra.default.lstat(filePath);
70
38
 
71
39
  if (stats.isDirectory()) {
72
- // ...and it is not an ignored directory...
73
40
  if (fileName !== 'node_modules' && fileName !== 'flow-typed' && fileName !== '__flowtests__') {
74
- // ...then recursively process the directory.
75
41
  await processDirectory(filePath);
76
42
  }
77
43
  } else if (stats.isFile()) {
78
- // Otherwise if this is a JavaScript/JSX file and it is not an ignored
79
- // JavaScript file...
80
44
  const fileIsJsOrJsx = /\.jsx?$/.test(fileName);
81
45
  const fileIsIgnored = fileName.endsWith('-flowtest.js');
82
46
 
83
47
  if (fileIsJsOrJsx && !fileIsIgnored) {
84
- // Then process the file path as JavaScript.
85
48
  await processJavaScriptFilePath(filePath, stats.size);
86
- } // If this is a Flow file then we don't need to check the file pragma
87
- // and can add the file to our paths immediately.
88
-
49
+ }
89
50
 
90
51
  if (fileName.endsWith('.flow')) {
91
52
  filePaths.push(filePath);
92
53
  }
93
54
  }
94
55
  }
95
- /**
96
- * Check if a file path really is a Flow file by looking for the
97
- * header pragma.
98
- */
99
-
100
56
 
101
57
  async function processJavaScriptFilePath(filePath, fileByteSize) {
102
- // If `all` was configured then we don't need to check for the Flow
103
- // header pragma.
104
58
  if (includeNonAtFlow) {
105
59
  filePaths.push(filePath);
106
60
  return;
107
- } // Open the file path.
108
-
109
-
110
- const file = await _fsExtra.default.open(filePath, 'r'); // Get the smaller of our pragma chars constant and the file byte size.
111
-
112
- const bytes = Math.min(PRAGMA_BYTES, fileByteSize); // Create the buffer we will read to.
113
-
114
- const buffer = Buffer.alloc(bytes); // Read a set number of bytes from the file.
61
+ }
115
62
 
116
- await _fsExtra.default.read(file, buffer, 0, bytes, 0); // If the buffer has the pragma then add the file path to our
117
- // final file paths array.
63
+ const file = await _fsExtra.default.open(filePath, 'r');
64
+ const bytes = Math.min(PRAGMA_BYTES, fileByteSize);
65
+ const buffer = Buffer.alloc(bytes);
66
+ await _fsExtra.default.read(file, buffer, 0, bytes, 0);
118
67
 
119
68
  if (buffer.includes('@flow')) {
120
69
  filePaths.push(filePath);
121
- } // Close the file.
122
-
70
+ }
123
71
 
124
72
  await _fsExtra.default.close(file);
125
73
  }
126
74
  }
127
75
 
128
76
  async function findFlowFilesWithSpinner(rootDirectory, options) {
129
- // Create a new spinner.
130
77
  const spinner = (0, _ora.default)({
131
78
  text: _chalk.default.italic.cyan('Finding all the Flow files to be upgraded...'),
132
79
  color: 'cyan',
133
80
  isSilent: options.silent
134
- }); // Start the spinner.
135
-
136
- spinner.start(); // Find all of the Flow files in the directory we are upgrading.
137
-
81
+ });
82
+ spinner.start();
138
83
  const filePaths = await (() => {
139
84
  try {
140
85
  return findFlowFiles({
@@ -142,13 +87,11 @@ async function findFlowFilesWithSpinner(rootDirectory, options) {
142
87
  includeNonAtFlow: options.all
143
88
  });
144
89
  } catch (error) {
145
- // Stop the spinner if we get an error.
146
90
  spinner.stop();
147
91
  throw error;
148
92
  }
149
- })(); // Stop the spinner.
150
-
151
- spinner.stop(); // Log the number of Flow files that we found.
93
+ })();
94
+ spinner.stop();
152
95
 
153
96
  if (!options.silent) {
154
97
  console.log(`Found ${_chalk.default.bold.cyan(filePaths.length)} Flow files.`);
@@ -11,22 +11,13 @@ var _hermesTransform = require("hermes-transform");
11
11
 
12
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
13
 
14
- /**
15
- * Copyright (c) Meta Platforms, Inc. and affiliates.
16
- *
17
- * This source code is licensed under the MIT license found in the
18
- * LICENSE file in the root directory of this source tree.
19
- *
20
- * @format
21
- *
22
- */
23
14
  async function runCodemods(codemods, filePaths, options) {
24
15
  const results = await Promise.allSettled(filePaths.map(async filePath => {
25
16
  const originalContents = await _fsExtra.default.readFile(filePath, 'utf8');
26
17
  let contents = originalContents;
27
18
 
28
19
  for (const codemod of codemods) {
29
- contents = (0, _hermesTransform.transform)(contents, codemod.transform, options.prettierOptions);
20
+ contents = await (0, _hermesTransform.transform)(contents, codemod.transform, options.prettierOptions);
30
21
  }
31
22
 
32
23
  if (originalContents !== contents) {
package/dist/upgrade.js CHANGED
@@ -23,36 +23,19 @@ var _upgrades = require("./upgrades");
23
23
 
24
24
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
25
25
 
26
- /**
27
- * Copyright (c) Meta Platforms, Inc. and affiliates.
28
- *
29
- * This source code is licensed under the MIT license found in the
30
- * LICENSE file in the root directory of this source tree.
31
- *
32
- * @format
33
- *
34
- */
35
-
36
- /**
37
- * Decides all of the upgrades that will need to be run when moving from one
38
- * version to another and runs them asynchronously.
39
- */
40
26
  async function upgrade(directory, currentVersion, nextVersion, options) {
41
27
  const log = options.silent ? () => {} : (...messages) => console.log(...messages);
42
- const allUpgrades = []; // Collect all of the upgrades we will need to run.
28
+ const allUpgrades = [];
43
29
 
44
30
  for (let i = 0; i < _upgrades.VERSION_UPGRADES.length; i++) {
45
31
  const {
46
32
  version,
47
33
  upgrades
48
- } = _upgrades.VERSION_UPGRADES[i]; // If the version number is larger then the version we are upgrading to we
49
- // are done! Do not add any more upgrades,
34
+ } = _upgrades.VERSION_UPGRADES[i];
50
35
 
51
36
  if (_semver.default.cmp(version, '>', nextVersion)) {
52
37
  break;
53
- } // If the version number is larget then the current version, but not larger
54
- // then the next version then we want to run the upgrades for this version.
55
-
38
+ }
56
39
 
57
40
  if (_semver.default.cmp(version, '>', currentVersion)) {
58
41
  upgrades.forEach(upgrade => allUpgrades.push(upgrade));
@@ -63,8 +46,7 @@ async function upgrade(directory, currentVersion, nextVersion, options) {
63
46
  log(_Styled.default.sectionHeader('flow-upgrade'));
64
47
  log();
65
48
  {
66
- const titleStyled = _chalk.default.bold('flow-upgrade'); // Log the initial intro message for our user.
67
-
49
+ const titleStyled = _chalk.default.bold('flow-upgrade');
68
50
 
69
51
  const message = `
70
52
  Thank you for choosing to upgrade Flow. In every release the Flow community adds
@@ -100,40 +82,29 @@ Excluding any JavaScript files in node_modules directories, in flow-typed
100
82
  directories, in __flowtests__ directories, or files ending in -flowtest.js.
101
83
  `.slice(1);
102
84
  log(message);
103
- } // Find all of the Flow files in the directory we are upgrading.
104
-
105
- const filePaths = await (0, _findFlowFiles.findFlowFilesWithSpinner)(directory, options); // Make sure the user knows that they should review their information before
106
- // proceeding.
107
-
85
+ }
86
+ const filePaths = await (0, _findFlowFiles.findFlowFilesWithSpinner)(directory, options);
108
87
  log(_chalk.default.bold.red('Please review this information to make sure that it is correct before proceeding.'));
109
- log(); // Ask the user for confirmation.
110
-
111
- const answer = options.yes || (await new _promptConfirm.default('Are you ready to begin the upgrade?').run()); // If the user did not let us continue then log a new line and do not
112
- // continue.
88
+ log();
89
+ const answer = options.yes || (await new _promptConfirm.default('Are you ready to begin the upgrade?').run());
113
90
 
114
91
  if (!answer) {
115
92
  log();
116
93
  return;
117
- } // Run through all of our upgrades.
118
-
94
+ }
119
95
 
120
96
  while (allUpgrades.length) {
121
- // Put some space between us and the last upgrade.
122
- log(); // Get the next upgrade.
123
-
97
+ log();
124
98
  const upgrade = allUpgrades.shift();
125
99
 
126
100
  switch (upgrade.kind) {
127
- // If this is a codemod, collect all codemods after it as well and execute
128
- // those codemods together.
129
101
  case 'codemod':
130
102
  {
131
- const codemods = [upgrade]; // While the next upgrade is a codemod, add it to our `codemods` array.
103
+ const codemods = [upgrade];
132
104
 
133
105
  while (allUpgrades[0] && allUpgrades[0].kind === 'codemod') {
134
106
  codemods.push(allUpgrades.shift());
135
- } // Tell the user what we are about to do.
136
-
107
+ }
137
108
 
138
109
  log(_Styled.default.sectionHeader('Codemods'));
139
110
  log();
@@ -148,18 +119,16 @@ directories, in __flowtests__ directories, or files ending in -flowtest.js.
148
119
  codemods.forEach((u, i) => {
149
120
  log(_Styled.default.upgradeTitle(u.title, i + 1));
150
121
  log();
151
- log(u.description);
122
+ log(u.describe);
152
123
  log();
153
124
  log(_Styled.default.divider());
154
125
  log();
155
126
  });
156
127
  log(`Running ${_chalk.default.bold.cyan(codemods.length)} codemods...`);
157
- log(); // Run all of our codemods.
158
-
128
+ log();
159
129
  await (0, _runCodemods.default)(codemods, filePaths, options);
160
130
  break;
161
131
  }
162
- // Throw an error for all other kinds of upgrades.
163
132
 
164
133
  default:
165
134
  throw new Error(`Unexpected upgrade kind: '${upgrade.kind}'`);
@@ -9,15 +9,6 @@ var _removeDuplicateClassProperties = _interopRequireDefault(require("../../code
9
9
 
10
10
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
11
 
12
- /**
13
- * Copyright (c) Meta Platforms, Inc. and affiliates.
14
- *
15
- * This source code is licensed under the MIT license found in the
16
- * LICENSE file in the root directory of this source tree.
17
- *
18
- * @format
19
- *
20
- */
21
12
  var _default = {
22
13
  version: '0.170.0',
23
14
  upgrades: [_removeDuplicateClassProperties.default]
@@ -9,15 +9,6 @@ var _removeAnnotationsInDestructuring = _interopRequireDefault(require("../../co
9
9
 
10
10
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
11
 
12
- /**
13
- * Copyright (c) Meta Platforms, Inc. and affiliates.
14
- *
15
- * This source code is licensed under the MIT license found in the
16
- * LICENSE file in the root directory of this source tree.
17
- *
18
- * @format
19
- *
20
- */
21
12
  var _default = {
22
13
  version: '0.176.0',
23
14
  upgrades: [_removeAnnotationsInDestructuring.default]
@@ -9,15 +9,6 @@ var _renamePartial = _interopRequireDefault(require("../../codemods/renamePartia
9
9
 
10
10
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
11
 
12
- /**
13
- * Copyright (c) Meta Platforms, Inc. and affiliates.
14
- *
15
- * This source code is licensed under the MIT license found in the
16
- * LICENSE file in the root directory of this source tree.
17
- *
18
- * @format
19
- *
20
- */
21
12
  var _default = {
22
13
  version: '0.201.0',
23
14
  upgrades: [_renamePartial.default]
@@ -9,15 +9,6 @@ var _convertImplicitInexactObjectTypes = _interopRequireDefault(require("../../c
9
9
 
10
10
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
11
 
12
- /**
13
- * Copyright (c) Meta Platforms, Inc. and affiliates.
14
- *
15
- * This source code is licensed under the MIT license found in the
16
- * LICENSE file in the root directory of this source tree.
17
- *
18
- * @format
19
- *
20
- */
21
12
  var _default = {
22
13
  version: '0.84.0',
23
14
  upgrades: [_convertImplicitInexactObjectTypes.default]
@@ -15,19 +15,5 @@ var _4 = _interopRequireDefault(require("./0.201.0"));
15
15
 
16
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
17
 
18
- /**
19
- * Copyright (c) Meta Platforms, Inc. and affiliates.
20
- *
21
- * This source code is licensed under the MIT license found in the
22
- * LICENSE file in the root directory of this source tree.
23
- *
24
- * @format
25
- *
26
- */
27
-
28
- /**
29
- * Holds all of the upgrades that need to be run to upgrade to each version from
30
- * the last version of Flow.
31
- */
32
18
  const VERSION_UPGRADES = [_.default, _2.default, _3.default, _4.default];
33
19
  exports.VERSION_UPGRADES = VERSION_UPGRADES;
@@ -1,12 +1,3 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @format
8
- *
9
- */
10
1
  'use strict';
11
2
 
12
3
  Object.defineProperty(exports, "__esModule", {
@@ -29,22 +20,19 @@ const oldConsole = {
29
20
  };
30
21
 
31
22
  function redirectConsole(reporter_) {
32
- const reporter = typeof reporter_ === 'function' ? reporter_(oldConsole) : reporter_; // $FlowExpectedError[cannot-write]
23
+ const reporter = typeof reporter_ === 'function' ? reporter_(oldConsole) : reporter_;
33
24
 
34
25
  console.log = (...args) => {
35
26
  reporter.onStdout(util.format(...args));
36
- }; // $FlowExpectedError[cannot-write]
37
-
27
+ };
38
28
 
39
29
  console.info = (...args) => {
40
30
  reporter.onStdout(util.format(...args));
41
- }; // $FlowExpectedError[cannot-write]
42
-
31
+ };
43
32
 
44
33
  console.warn = (...args) => {
45
34
  reporter.onStdout('[WARN]' + util.format(...args));
46
- }; // $FlowExpectedError[cannot-write]
47
-
35
+ };
48
36
 
49
37
  console.error = (...args) => {
50
38
  reporter.onStderr(util.format(...args));
@@ -53,7 +41,6 @@ function redirectConsole(reporter_) {
53
41
 
54
42
  function restoreConsole() {
55
43
  for (const [name, fn] of Object.entries(oldConsole)) {
56
- // $FlowExpectedError
57
44
  console[name] = fn;
58
45
  }
59
46
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flow-upgrade",
3
- "version": "2.2.0",
3
+ "version": "2.4.0",
4
4
  "description": "A utility for upgrading your codebase to the latest version of Flow.",
5
5
  "engines": {
6
6
  "node": ">=14"
@@ -15,7 +15,8 @@
15
15
  },
16
16
  "scripts": {
17
17
  "build": "rm -rf dist && babel src --out-dir dist --ignore '**/__tests__'",
18
- "test": "jest --watch",
18
+ "test": "jest",
19
+ "flow": "flow",
19
20
  "prepublish": "yarn run build",
20
21
  "postpublish": "node ./scripts/postpublish.js"
21
22
  },
@@ -29,28 +30,30 @@
29
30
  "homepage": "https://github.com/facebook/flow/tree/master/packages/flow-upgrade#readme",
30
31
  "dependencies": {
31
32
  "@babel/highlight": "^7.18.6",
33
+ "babel-plugin-syntax-hermes-parser": "0.23.0",
32
34
  "chalk": "^2.0.1",
33
35
  "fs-extra": "10.1.0",
34
- "hermes-estree": "0.10.0",
35
- "hermes-parser": "0.10.0",
36
- "hermes-transform": "0.10.0",
36
+ "hermes-estree": "0.23.0",
37
+ "hermes-parser": "0.23.0",
38
+ "hermes-transform": "0.23.0",
37
39
  "klaw-sync": "^6.0.0",
38
40
  "ora": "^5.4.1",
41
+ "prettier-plugin-hermes-parser": "0.23.0",
39
42
  "prompt-confirm": "^1.2.0",
40
43
  "semver": "^7.3.7",
41
44
  "yargs": "^17.0.1"
42
45
  },
43
46
  "peerDependencies": {
44
- "prettier": "2.7.1"
47
+ "prettier": "2.8.8"
45
48
  },
46
49
  "devDependencies": {
47
50
  "@babel/cli": "^7.14.8",
48
51
  "@babel/core": "^7.14.8",
49
52
  "@babel/preset-env": "^7.14.8",
50
53
  "@babel/preset-flow": "^7.14.5",
51
- "flow-bin": "^0.178.0",
54
+ "flow-bin": "^0.227.0",
52
55
  "jest": "^27.5.1",
53
56
  "memfs": "^3.4.3",
54
- "prettier": "2.7.1"
57
+ "prettier": "2.8.8"
55
58
  }
56
59
  }