diff --git a/package.json b/package.json index 5b7324e76..4998eebdf 100644 --- a/package.json +++ b/package.json @@ -64,9 +64,12 @@ "@jest-runner/electron": "^2.0.3", "@testing-library/react": "^9.3.0", "@types/algoliasearch": "^3.30.19", + "@types/babel-code-frame": "^6.20.2", "@types/decompress": "4.2.3", "@types/deep-equal": "^1.0.1", + "@types/detect-port": "^1.1.0", "@types/expand-tilde": "^2.0.0", + "@types/express": "^4.17.2", "@types/fb-watchman": "^2.0.0", "@types/fs-extra": "^8.0.0", "@types/invariant": "^2.2.31", @@ -83,6 +86,7 @@ "@types/redux-persist": "^4.3.1", "@types/requestidlecallback": "^0.3.1", "@types/rsocket-core": "^0.0.5", + "@types/socket.io": "^2.1.4", "@types/testing-library__react": "^9.1.2", "@types/tmp": "^0.1.0", "@types/uuid": "^3.4.5", @@ -112,6 +116,7 @@ "recursive-readdir": "^2.2.2", "redux-mock-store": "^1.5.3", "ts-jest": "^25.1.0", + "ts-node": "^8.6.2", "typescript": "^3.7.2" }, "dependencies": { @@ -210,9 +215,9 @@ "rm-temp": "rimraf $TMPDIR/jest* $TMPDIR/react-native-packager*", "rm-bundle": "rimraf static/main.bundle.*", "reset": "yarn rm-dist && yarn rm-temp && yarn cache clean && yarn rm-modules && yarn rm-bundle", - "start": "cross-env NODE_ENV=development node scripts/start-dev-server.js --inspect=9229", - "start:break": "cross-env NODE_ENV=development node scripts/start-dev-server.js --inspect-brk=9229", - "start:no-embedded-plugins": "cross-env NODE_ENV=development cross-env FLIPPER_NO_EMBEDDED_PLUGINS=true node scripts/start-dev-server.js", + "start": "cross-env NODE_ENV=development ts-node --files scripts/start-dev-server.ts --inspect=9229", + "start:break": "cross-env NODE_ENV=development ts-node scripts/start-dev-server.ts --inspect-brk=9229", + "start:no-embedded-plugins": "cross-env NODE_ENV=development cross-env FLIPPER_NO_EMBEDDED_PLUGINS=true ts-node scripts/start-dev-server.ts", "build": "yarn rm-dist && cross-env NODE_ENV=production node scripts/build-release.js $@", "build-headless": "yarn rm-dist && mkdir dist && cross-env NODE_ENV=production node scripts/build-headless.js $@", "fix": "eslint . --fix --ext .js,.tsx", diff --git a/scripts/start-dev-server.js b/scripts/start-dev-server.ts similarity index 80% rename from scripts/start-dev-server.js rename to scripts/start-dev-server.ts index b6daba04e..f1af76b7f 100644 --- a/scripts/start-dev-server.js +++ b/scripts/start-dev-server.ts @@ -7,30 +7,38 @@ * @format */ -const electronBinary = require('electron'); -const codeFrame = require('babel-code-frame'); -const socketIo = require('socket.io'); -const express = require('express'); -const detect = require('detect-port'); -const child = require('child_process'); -const Convert = require('ansi-to-html'); -const chalk = require('chalk'); -const http = require('http'); -const path = require('path'); +const electronBinary: string = require('electron') as any; +import codeFrame from 'babel-code-frame'; +import socketIo from 'socket.io'; +import express, {Express} from 'express'; +import detect from 'detect-port'; +import child from 'child_process'; +import AnsiToHtmlConverter from 'ansi-to-html'; +import chalk from 'chalk'; +import http from 'http'; +import path from 'path'; +import fs from 'fs'; +const Watchman = require('../static/watchman'); const {compileMain} = require('./build-utils'); const Metro = require('../static/node_modules/metro'); const MetroResolver = require('../static/node_modules/metro-resolver'); -const fs = require('fs'); -const Watchman = require('../static/watchman'); -const convertAnsi = new Convert(); +const ansiToHtmlConverter = new AnsiToHtmlConverter(); -const DEFAULT_PORT = process.env.PORT || 3000; +const DEFAULT_PORT = (process.env.PORT || 3000) as number; const STATIC_DIR = path.join(__dirname, '..', 'static'); -let shutdownElectron = undefined; +let shutdownElectron: (() => void) | undefined = undefined; -function launchElectron({devServerURL, bundleURL, electronURL}) { +function launchElectron({ + devServerURL, + bundleURL, + electronURL, +}: { + devServerURL: string; + bundleURL: string; + electronURL: string; +}) { const args = [ path.join(STATIC_DIR, 'index.js'), '--remote-debugging-port=9222', @@ -67,7 +75,7 @@ function launchElectron({devServerURL, bundleURL, electronURL}) { }; } -function startMetroServer(app) { +function startMetroServer(app: Express) { const projectRoot = path.join(__dirname, '..'); return Metro.runMetro({ projectRoot, @@ -83,7 +91,7 @@ function startMetroServer(app) { }, resolver: { blacklistRE: /(\/|\\)(sonar|flipper|flipper-public)(\/|\\)(dist|doctor)(\/|\\)|(\.native\.js$)/, - resolveRequest: (context, moduleName, platform) => { + resolveRequest: (context: any, moduleName: string, platform: string) => { if (moduleName.startsWith('./localhost:3000')) { moduleName = moduleName.replace('./localhost:3000', '.'); } @@ -95,12 +103,14 @@ function startMetroServer(app) { }, }, watch: true, - }).then(metroBundlerServer => { + }).then((metroBundlerServer: any) => { app.use(metroBundlerServer.processRequest.bind(metroBundlerServer)); }); } -function startAssetServer(port) { +function startAssetServer( + port: number, +): Promise<{app: Express; server: http.Server}> { const app = express(); app.use((req, res, next) => { @@ -138,7 +148,7 @@ function startAssetServer(port) { app.use(express.static(STATIC_DIR)); - app.use(function(err, req, res, next) { + app.use(function(err: any, req: any, res: any, _next: any) { knownErrors[req.url] = err; outputScreen(); res.status(500).send('Something broke, check the console!'); @@ -146,18 +156,18 @@ function startAssetServer(port) { const server = http.createServer(app); - return new Promise((resolve, reject) => { + return new Promise(resolve => { server.listen(port, 'localhost', () => resolve({app, server})); }); } -async function addWebsocket(server) { +async function addWebsocket(server: http.Server) { const io = socketIo(server); // notify connected clients that there's errors in the console io.on('connection', client => { if (hasErrors()) { - client.emit('hasErrors', convertAnsi.toHtml(buildErrorScreen())); + client.emit('hasErrors', ansiToHtmlConverter.toHtml(buildErrorScreen())); } }); @@ -190,7 +200,7 @@ async function addWebsocket(server) { return io; } -const knownErrors = {}; +const knownErrors: {[key: string]: any} = {}; function hasErrors() { return Object.keys(knownErrors).length > 0; @@ -226,14 +236,14 @@ function buildErrorScreen() { return lines.join('\n'); } -function outputScreen(socket) { +function outputScreen(socket?: socketIo.Server) { // output screen if (hasErrors()) { const errorScreen = buildErrorScreen(); console.error(errorScreen); // notify live clients of errors - socket.emit('hasErrors', convertAnsi.toHtml(errorScreen)); + socket?.emit('hasErrors', ansiToHtmlConverter.toHtml(errorScreen)); } else { // eslint-disable-next-line no-console console.log(chalk.green('✔ No known errors')); diff --git a/tsconfig.json b/tsconfig.json index 60e5530fd..9801cea36 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,12 +1,11 @@ { "compilerOptions": { - "module": "system", + "module": "commonjs", "lib": ["es7", "dom", "es2017"], "esModuleInterop": true, "target": "es6", "removeComments": true, "preserveConstEnums": true, - "outFile": "../../built/local/tsc.js", "sourceMap": true, "jsx": "react", "moduleResolution": "node", @@ -18,6 +17,6 @@ }, "strict": true }, - "include": ["src/**/*", "static/**/*", "types/*", "headless/*"], + "include": ["src/**/*", "static/**/*", "scripts/**/*", "types/*", "headless/*"], "exclude": ["node_modules", "**/*.spec.ts"] } diff --git a/types/ansi-to-html.d.ts b/types/ansi-to-html.d.ts new file mode 100644 index 000000000..8e84eae7c --- /dev/null +++ b/types/ansi-to-html.d.ts @@ -0,0 +1,14 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + */ + +declare module 'ansi-to-html' { + export default class Filter { + toHtml: (input: string) => string; + } +} diff --git a/yarn.lock b/yarn.lock index 2f4419efd..e6ed28f6a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1248,6 +1248,11 @@ resolved "https://registry.yarnpkg.com/@types/algoliasearch/-/algoliasearch-3.34.5.tgz#c40e346a6c5526f9b27af7863117d1200456e7d2" integrity sha512-JS+5KT9SfwzGIkoCsj7EyYHzhrsagj321BEPH3oroHYnuKUfPVoei58qLsBPo9RRa27Vb79WJssSSPBicnaAng== +"@types/babel-code-frame@^6.20.2": + version "6.20.2" + resolved "https://registry.yarnpkg.com/@types/babel-code-frame/-/babel-code-frame-6.20.2.tgz#d923c88d94e66b864fd3693f07b18ad78489a222" + integrity sha512-HAdhFeYOZKIkrR2jbonCJxp3I/o2G/kxY+CIx7qX9Kmv5jY+9D7OgmgSLdRqeHacB5RlqE5efj2WIDFL9NXCyg== + "@types/babel__core@^7.1.0": version "7.1.3" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.3.tgz#e441ea7df63cd080dfcd02ab199e6d16a735fc30" @@ -1281,11 +1286,26 @@ dependencies: "@babel/types" "^7.3.0" +"@types/body-parser@*": + version "1.19.0" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f" + integrity sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ== + dependencies: + "@types/connect" "*" + "@types/node" "*" + "@types/color-name@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== +"@types/connect@*": + version "3.4.33" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.33.tgz#31610c901eca573b8713c3330abc6e6b9f588546" + integrity sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A== + dependencies: + "@types/node" "*" + "@types/debug@^4.1.4", "@types/debug@^4.1.5": version "4.1.5" resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd" @@ -1303,6 +1323,11 @@ resolved "https://registry.yarnpkg.com/@types/deep-equal/-/deep-equal-1.0.1.tgz#71cfabb247c22bcc16d536111f50c0ed12476b03" integrity sha512-mMUu4nWHLBlHtxXY17Fg6+ucS/MnndyOWyOe7MmwkoMYxvfQU2ajtRaEvqSUv+aVkMqH/C0NCI8UoVfRNQ10yg== +"@types/detect-port@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@types/detect-port/-/detect-port-1.1.0.tgz#07075d264e2e5a432624b1e7ffc11379fe66be8a" + integrity sha1-BwddJk4uWkMmJLHn/8ETef5mvoo= + "@types/eslint-visitor-keys@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" @@ -1318,6 +1343,23 @@ resolved "https://registry.yarnpkg.com/@types/expand-tilde/-/expand-tilde-2.0.0.tgz#c01a706675b9d60931bf6a7dc7dfa45d63540c97" integrity sha512-17h/6MRHoetV2QVUVnUfrmaFCXNIFJ3uDJmXlklX2xDtlEb1W0OXLgP+qwND2Ibg/PtQfQi0vx19KGuPayjLiw== +"@types/express-serve-static-core@*": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.2.tgz#f6f41fa35d42e79dbf6610eccbb2637e6008a0cf" + integrity sha512-El9yMpctM6tORDAiBwZVLMcxoTMcqqRO9dVyYcn7ycLWbvR8klrDn8CAOwRfZujZtWD7yS/mshTdz43jMOejbg== + dependencies: + "@types/node" "*" + "@types/range-parser" "*" + +"@types/express@^4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.2.tgz#a0fb7a23d8855bac31bc01d5a58cadd9b2173e6c" + integrity sha512-5mHFNyavtLoJmnusB8OKJ5bshSzw+qkMIBAobLrIM48HJvunFva9mOa6aBwh64lBFyNwBbs0xiEFuj4eU/NjCA== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "*" + "@types/serve-static" "*" + "@types/fb-watchman@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@types/fb-watchman/-/fb-watchman-2.0.0.tgz#ca60ded406baa8c81c65ac1f86763a5d00aa7c55" @@ -1411,6 +1453,11 @@ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.144.tgz#12e57fc99064bce45e5ab3c8bc4783feb75eab8e" integrity sha512-ogI4g9W5qIQQUhXAclq6zhqgqNUr7UlFaqDHbch7WLSLeeM/7d3CRaw7GLajxvyFvhJqw4Rpcz5bhoaYtIx6Tg== +"@types/mime@*": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.1.tgz#dc488842312a7f075149312905b5e3c0b054c79d" + integrity sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw== + "@types/minimatch@*": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" @@ -1469,6 +1516,11 @@ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== +"@types/range-parser@*": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" + integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== + "@types/react-color@^3.0.1": version "3.0.1" resolved "https://registry.yarnpkg.com/@types/react-color/-/react-color-3.0.1.tgz#5433e2f503ea0e0831cbc6fd0c20f8157d93add0" @@ -1616,6 +1668,21 @@ resolved "https://registry.yarnpkg.com/@types/semver/-/semver-6.2.0.tgz#d688d574400d96c5b0114968705366f431831e1a" integrity sha512-1OzrNb4RuAzIT7wHSsgZRlMBlNsJl+do6UblR7JMW4oB7bbR+uBEYtUh7gEc/jM84GGilh68lSOokyM/zNUlBA== +"@types/serve-static@*": + version "1.13.3" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.3.tgz#eb7e1c41c4468272557e897e9171ded5e2ded9d1" + integrity sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g== + dependencies: + "@types/express-serve-static-core" "*" + "@types/mime" "*" + +"@types/socket.io@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@types/socket.io/-/socket.io-2.1.4.tgz#674e7bc193c5ccdadd4433f79f3660d31759e9ac" + integrity sha512-cI98INy7tYnweTsUlp8ocveVdAxENUThO0JsLSCs51cjOP2yV5Mqo5QszMDPckyRRA+PO6+wBgKvGvHUCc23TQ== + dependencies: + "@types/node" "*" + "@types/stack-utils@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" @@ -1993,6 +2060,11 @@ app-builder-lib@21.2.0, app-builder-lib@~21.2.0: semver "^6.3.0" temp-file "^3.3.4" +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -3331,6 +3403,11 @@ diff-sequences@^25.1.0: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.1.0.tgz#fd29a46f1c913fd66c22645dc75bffbe43051f32" integrity sha512-nFIfVk5B/NStCsJ+zaPO4vYuLjlzQ6uFvPxzYyHlejNZ/UGa7G/n7peOXVrVNvRuyfstt+mZQYGpjxg9Z6N8Kw== +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" @@ -6300,6 +6377,11 @@ make-error@1.x: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8" integrity sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g== +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + makeerror@1.0.x: version "1.0.11" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" @@ -9064,6 +9146,17 @@ ts-jest@^25.1.0: semver "^5.5" yargs-parser "10.x" +ts-node@^8.6.2: + version "8.6.2" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.6.2.tgz#7419a01391a818fbafa6f826a33c1a13e9464e35" + integrity sha512-4mZEbofxGqLL2RImpe3zMJukvEvcO1XP8bj8ozBPySdCUXEcU5cIRwR0aM3R+VoZq7iXc8N86NC0FspGRqP4gg== + dependencies: + arg "^4.1.0" + diff "^4.0.1" + make-error "^1.1.1" + source-map-support "^0.5.6" + yn "3.1.1" + tslib@^1.8.1, tslib@^1.9.0: version "1.10.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" @@ -9844,3 +9937,8 @@ yeast@0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk= + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==