• Stars
    star
    675
  • Rank 66,879 (Top 2 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created over 2 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Codemod Stripe used to migrate 6.5m+ lines of code from Flow to TypeScript
TypeScript Llama

Flow to TypeScript Codemod


This project is provided as-is and is not actively maintained.

For more background on Stripe's TypeScript migration, check out our blog post!

This is the codemod Stripe used to migrate 4m+ lines of Flow to TypeScript. It has a few commands to automate the separate steps of a migration:

  • setup - Tools for installing TypeScript and type declarations in a project.
  • convert - The main codemod, which uses Babel to convert files from Flow to TypeScript.
  • fix - A second codemod that uses ts-morph to find, fix, suppress, and report TypeScript errors after initial conversion.

Every codebase and migration will be slightly different, so we recommend forking this repository and modifying it as needed for your use case. Our applications are written in React, so other frameworks will need additional work to support.

Note: We also recommend being on a version of Flow higher than v0.92.1, for best support retrieving missing types from Flow. Newer versions of Flow will work better.

πŸš€ Quick start

To try out this codemod on your codebase, you'll want to clone this repository and build the tool. We used yarn for package management but others should work as long as the patch packages are applied.

# Clone the repository
git clone https://github.com/stripe-archive/flow-to-typescript-codemod.git
cd flow-to-typescript-codemod/

# Install dependencies
yarn

# Run on a folder
yarn typescriptify convert -p ../path/to/your/codebase # Run in 'dry-run' without writing files
yarn typescriptify convert -p ../path/to/your/codebase --write --delete # Write converted files and delete Flow source

# Suppress errors
yarn typescriptify fix --autoSuppressErrors -p ../path/to/your/codebase --config ../path/to/your/codebase/tsconfig.json

Note: You can publish this package or link it using a workspace management tool to install it into multiple projects.

πŸ”¨ Basic usage

The main command for the project is typescriptify, and there are three sub-commands:

typescriptify [command]

Commands:
  typescriptify setup    Set your project up to support TypeScript.
  typescriptify convert  Convert Flow-typed files to TypeScript.                              
  typescriptify fix      Use the TypeScript compiler to identify and fix errors.             

Options:
  --version  Show version number                                                                                                                           
  --help     Show help                                                                                                                                     

Examples:
  typescriptify <setup,convert,fix> --help                                         Show usage instructions for a specific command.
  typescriptify convert --path .                                                   Run the codemod in dry-run mode.
  typescriptify convert --path src/ test/                                          Run the codemod on multiple paths.
  typescriptify convert --path . --ignore flow_typed/                              Ignore files from conversion.
  typescriptify convert --path ./src --format csv --output ./migration-report.csv  Generate a CSV migration report.
  typescriptify convert --path . --write --delete                                  Fully convert a project to TypeScript, 
                                                                                   writing files and deleting Flow files.
  typescriptify convert --path . --write --target=./dist                           Specify a directory to output the TypeScript files.
  typescriptify fix --autoSuppressErrors --removeUnused                            Remove unused ts-expect-errors, and add any for current errors.
  typescriptify fix --autoSuppressErrors --jiraSlug JIRA-722                       Suppress errors but add a JIRA slug to the comments.
  typescriptify fix --generateReport --output ./migration-report.csv               Generate a CSV file of categorized TS errors.

πŸƒ Running conversions from Flow to TypeScript

Dry run

By default, the codemod will run a dry run against your codebase. This mode will not actually write any TypeScript files, but will collect any potential problems in the Flow code that you may want to investigate prior to doing the actual conversion:

yarn typescriptify convert --path <path to source directory>

Running the conversion

Once you are ready to generate the actual TypeScript files, add the --write argument. This will generate new .ts and .tsx files from existing Flow files, and will leave the Flow files intact. In order to remove the Flow files as well, add the --delete argument.

# By default, this will leave your Flow files intact:
yarn typescriptify convert --write --path <path to source directory>

# If you want to delete the Flow files, and leave only the TypeScript files, add --delete
yarn typescriptify convert --write --delete --path <path to source directory>

# If you want to specify a different directory to emit the TS files add --target
yarn typescriptify convert --write --path <path to source directory> --target <where the source files should go>

Utility types

In cases where the conversion requires a complicated type, the codemod will insert an import for utility types:

import {Flow} from 'flow-to-typescript-codemod';
Flow.Diff<A, B>;

These types are defined in ./flow.d.ts, and you'll need to do some setup to make the import work. At Stripe, we published a version of this package internally so it could be installed in each codebase and the types would be available. You could also copy flow.d.ts into your project and use paths to resolve the import.

πŸ“Œ Advanced usage

Click to expand!

Automatically suppressing TypeScript errors

After conversion, there will likely be a number of errors in the converted TypeScript files. These errors can be the result of pre-existing issues in the Flow code, issues with the installed types, or issues with the codemod. For many conversions, the number of errors may be challenging to fix before merging. The auto suppression feature will run the TypeScript compiler against your converted code, and add ts-expect-error annotations that suppress errors. This allows you to suppress the errors to get a passing type check, and then fix the errors in future changes. If you fix an error that fixes other errors, you can use the removeUnused flag to automatically remove unused suppressions.

yarn typescriptify fix --autoSuppressErrors --jiraSlug <slug i.e JIRA-722>

Auto-generating declarations

If you want to continue writing Flow, but generate additional TypeScript versions, you can use the watermarking flag. Adding the --watermark argument will add a watermark to every file:

yarn typescriptify convert --watermark --path <path to source directory>

You can configure the codemod to skip files without a watermark when doing future conversions. Remove the watermark from a file to make manual edits to the type.

Supporting prop spreads

If your codebase follows the pattern of accepting any prop, and then forwarding them to another component like this:

const MyComponent = (props: Props) => {
  const { myProp, ...rest } = props;
  return <AnotherComponent test={myProp} {...rest} />
}

Flow was likely typing your extra parameters as any, and those will be type failures in TypeScript. We have experimental support for updating prop types to include the props of the underlying HTML element or component. Add the --handleSpreadReactProps to turn on this transformation.

πŸ’» Developing

# Install dependencies
yarn
# Run on a folder
yarn typescriptify convert -p ../path/to/your/codebase
# Build
yarn build
# Run tests
yarn test
# Type-check
yarn types
# Lint
yarn lint

πŸ“ Notes

We've compiled our notes documenting the complex type conversions.

🎨 Prior art

This project was built on top of Airtable's TypeScript Codemod. We're thankful for the Airtable team (Caleb Meredith and Andrew Wang) for open-sourcing their work, and hope others can similarly benefit from our project.

πŸ“Ž License

This project uses the MIT license.

✨ Contributing

This project is not being actively maintained. Please feel free to fork this repository to add changes as needed. Every migration will have some different patterns that need special logic, so it would be hard to maintain any general purpose tool for this task.

If you have questions about this code or our migration, you can reach out to members of our team:


Tyler Krupicka


Ken Deland


Russill Glover


Ben Bayard


Andrew Lunny

More Repositories

1

jquery.payment

[DEPRECATED] A general purpose library for building credit card forms, validating inputs and formatting numbers.
CoffeeScript
3,538
star
2

react-stripe-elements

Moved to stripe/react-stripe-js.
JavaScript
3,026
star
3

mosql

MongoDB β†’ PostgreSQL streaming replication
Ruby
1,629
star
4

stripe-payments-demo

Sample store accepting universal payments on the web with Stripe Elements, Payment Request, Apple Pay, Google Pay, Microsoft Pay, and the PaymentIntents API. πŸ’³πŸŒβœ¨
JavaScript
1,471
star
5

shop

Single-page shop
CSS
1,126
star
6

safesql

Static analysis tool for Golang that protects against SQL injections
Go
563
star
7

PaymentKit

Easily accept payments on iOS
Objective-C
470
star
8

brushfire

Distributed decision tree ensemble learning in Scala
Scala
391
star
9

stripe-webhook-monitor

Stripe Webhook Monitor provides a real-time feed and graph of Stripe events received via webhooks. πŸ“ˆβœ¨
JavaScript
366
star
10

accept-a-card-payment

Learn how to accept a basic card payment on web, iOS, Android
Java
351
star
11

jquery.mobilePhoneNumber

[DEPRECATED] A general purpose library for validating and formatting mobile phone numbers.
CoffeeScript
331
star
12

nextjs-typescript-react-stripe-js

Full-stack TypeScript example using Next.js, react-stripe-js, and stripe-node.
TypeScript
329
star
13

topmodel

Standard evaluations for binary classifiers so you don't have to
Python
316
star
14

gaps

Easy management of your Google Groups subscriptions.
Ruby
284
star
15

developer-office-hours

A collection of Stripe Developer Office Hours demos 🎬
Ruby
245
star
16

ApplePayStubs

Test your Apple Pay integration without Apple Pay
Objective-C
193
star
17

timberlake

Timberlake is a Job Tracker for Hadoop.
Go
177
star
18

wilde-things

A tutorial integrating Stripe in PHP
PHP
175
star
19

sequins

A key/value store for serving static batch data
Go
174
star
20

checkout-subscription-and-add-on

Uses Stripe Checkout to create a payment page that starts a subscription for a new customer.
CSS
162
star
21

mongoriver

A library for writing MongoDB oplog tailers.
Ruby
153
star
22

stripe-demo-connect-kavholm-marketplace

Demo app for Global Marketplace using Stripe Connect
JavaScript
139
star
23

herringbone

Tools for working with parquet, impala, and hive
Thrift
135
star
24

pd2pg

Import PagerDuty data into Postgres for analysis
Ruby
110
star
25

payment-form-modal

How to implement Stripe Elements within a modal dialog.
JavaScript
106
star
26

datadog-checks

Checks for the Datadog Agent that Stripe finds useful.
Python
99
star
27

set-up-subscriptions

Getting started with Stripe Elements and Stripe Billing to charge a customer for a monthly subscription.
CSS
96
star
28

macgyver

A Chrome extension which duct tapes an SSH agent to the platformKey API
Go
90
star
29

react-elements-card-payment

Learn how to build a checkout form with React
CSS
87
star
30

chalk-log

Chalk::Log adds a logger object to any class, which can be used for unstructured or semi-structured logging.
Ruby
72
star
31

agate

Scoring ONNX models on the JVM in scala
Scala
68
star
32

sbt-bazel

Easily convert SBT projects to Bazel workspaces
Scala
54
star
33

charging-for-multiple-plan-subscriptions

Getting started with Stripe Elements and Stripe Billing to charge a customer for a monthly subscription with multiple items.
JavaScript
54
star
34

checkout-remember-me-with-twilio-verify

Use Stripe Checkout to collect payment details for future payments and Twilio Verify to authenticate the customer via SMS code and charge their stored card.
JavaScript
50
star
35

firebase-mobile-payments

Firebase Cloud Functions to create payments in native Android and iOS applications.
Kotlin
49
star
36

identity-verification

Securely collect and verify identity documents
JavaScript
44
star
37

falconer

High throughout, unsampled tracing span buffer with streaming search
Go
40
star
38

web-elements-sepa-debit-payment

Collect SEPA Debit mandates and payments.
Objective-C
37
star
39

payment-tag

CoffeeScript
34
star
40

stripe-stdlib-demo

Sample store accepting universal payments built with @Stripe and @StdLib.
JavaScript
33
star
41

chalk-config

Maps on-disk config files into a loaded global configatron instance, taking into account your current environment.
Ruby
28
star
42

go-einhorn

Talk to einhorn from your Go worker
Go
25
star
43

sample-terminal-ios-app

Learn how to take in-person payments with a physical reader and Terminal in your iOS app
Swift
19
star
44

adding-sales-tax

Learn how to use PaymentIntents to build a simple checkout flow
CSS
18
star
45

javascript-style

Javascript linter with rules for Stripe projects
JavaScript
16
star
46

scrooge-shapes

Shapeless generic instances for Scrooge types
Scala
14
star
47

datadog-cli-tools

CLI tools we find useful for Datadog
Ruby
13
star
48

submigrate

Combine multiple subscriptions into a single subscription with multiple items
Go
12
star
49

web-elements-fpx-payment

Accept Malaysian online bank transfers with the Stripe FPX Element.
JavaScript
12
star
50

siv-go

A pure Go implementation of the SIV AEAD.
Go
11
star
51

au-becs-debit-payment

Collecting AU BECS Direct Debit mandates and payments.
Java
10
star
52

oxxo-payment

Learn how to accept OXXO and card payments
JavaScript
10
star
53

round-up-and-donate

Build a round up and donate feature with Connect
CSS
10
star
54

random

A collection of random utilities
Shell
9
star
55

web-elements-card-payment

Learn how to accept a basic card payment on the web
JavaScript
7
star
56

grabpay-payment

Accept GrabPay Payments with Stripe, a popular digital wallet in Southeast Asia.
CSS
5
star
57

yard-sorbet

Types are documentation
Ruby
5
star
58

terraform-provider-confidant

A terraform provider for confidant. See https://github.com/terraform-providers
Go
5
star
59

simple-powershell-dsc

Simple Powershell DSC pull server in Go
Go
4
star
60

stripe-magento1-releases

4
star
61

pb

Lint protocol buffers
Go
2
star
62

mobile-elements-card-payment

Learn how to accept a basic card payment on iOS & Android
Java
2
star
63

bazel-bloop-exporter

This proof of concept exports a bazel project to bloop. The motivation is to allow the use of any tooling that already has a bloop integration, such as the metals language server.
Starlark
2
star
64

sentry-restricted-github

Python
2
star
65

time-utils

Ruby
1
star