From f23d0977e66e94878e2f1dcb43c5d021e59b690b Mon Sep 17 00:00:00 2001 From: Carlos Cuesta Date: Wed, 28 Dec 2022 16:27:23 +0100 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Migrate=20`website`=20to?= =?UTF-8?q?=20TypeScript=20(#1244)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🔧 Add typescript configuration files * ➕ Install typescript dependencies * ♻️ Migrate `lint-staged` to .ts(x) files * ♻️ Migrate `eslint` configuration to TypeScript * ♻️ Migrate `jest` configuration to TypeScript * 🔥 Remove `babel` configuration * ➖ Uninstall flow dependencies * 🔥 Remove `flow` configuration * 👷 Run `tsc` in `ci` workflow * 🔧 Update `pre-push` hook * ♻️ Migrate `pages/api` to TS * ♻️ Migrate `pages/_app` to TS * ♻️ Migrate `pages/_document` to TS * ♻️ Migrate `pages/about` to TS * ♻️ Migrate `pages/contributors` to TS * ♻️ Migrate `pages/index` to TS * ♻️ Migrate `pages/related-tools` to TS * ♻️ Migrate `components/Button` to TS * ♻️ Migrate `components/CarbonAd` to TS * ♻️ Migrate `components/ContributorsList` to TS * ♻️ Migrate `components/Icon` to TS * ♻️ Migrate `components/SEO` to TS * ♻️ Migrate `components/Layout` to TS * ♻️ Migrate `components/GitmojiList` to TS * ♻️ Migrate `__tests__/` pages to TS * 🏷️ Update `next-env.d.ts` --- .flowconfig | 15 - .github/workflows/ci.yml | 4 +- .gitignore | 3 + .husky/pre-push | 2 +- packages/website/.lintstagedrc.json | 4 +- packages/website/babel.config.json | 6 - packages/website/jest.config.js | 20 + packages/website/next-env.d.ts | 5 + packages/website/package.json | 66 +-- ...pages.spec.js.snap => pages.spec.tsx.snap} | 162 +++--- .../{pages.spec.js => pages.spec.tsx} | 28 +- packages/website/src/__tests__/stubs.js | 35 -- packages/website/src/__tests__/stubs.tsx | 21 + ...tton.spec.js.snap => button.spec.tsx.snap} | 1 + .../{button.spec.js => button.spec.tsx} | 0 .../Button/__tests__/{stubs.js => stubs.ts} | 1 + .../components/Button/{index.js => index.tsx} | 7 +- ...Ad.spec.js.snap => carbonAd.spec.tsx.snap} | 4 +- .../{carbonAd.spec.js => carbonAd.spec.tsx} | 0 .../CarbonAd/{index.js => index.tsx} | 9 +- .../Contributor/{index.js => index.tsx} | 7 +- ...js.snap => contributorsList.spec.tsx.snap} | 2 + ...List.spec.js => contributorsList.spec.tsx} | 4 +- .../__tests__/{stubs.js => stubs.ts} | 0 .../ContributorsList/{index.js => index.tsx} | 13 +- .../components/GitmojiList/Gitmoji/index.js | 49 -- .../components/GitmojiList/Gitmoji/index.tsx | 52 ++ .../ListModeSelector/{index.js => index.tsx} | 9 +- .../ThemeSelector/{index.js => index.tsx} | 5 +- .../Toolbar/{index.js => index.tsx} | 15 +- ...spec.js.snap => gitmojiList.spec.tsx.snap} | 24 +- ...tmojiList.spec.js => gitmojiList.spec.tsx} | 10 +- .../__tests__/{stubs.js => stubs.ts} | 0 .../{emojiColorsMap.js => emojiColorsMap.ts} | 3 +- .../hooks/__tests__/{stubs.js => stubs.ts} | 0 ...orage.spec.js => useLocalStorage.spec.tsx} | 29 +- .../GitmojiList/hooks/useLocalStorage.js | 27 - .../GitmojiList/hooks/useLocalStorage.tsx | 23 + .../GitmojiList/{index.js => index.tsx} | 31 +- .../{icon.spec.js.snap => icon.spec.tsx.snap} | 0 .../__tests__/{icon.spec.js => icon.spec.tsx} | 0 .../Icon/__tests__/{stubs.js => stubs.ts} | 0 .../Icon/{definitions.js => definitions.tsx} | 5 +- .../components/Icon/{index.js => index.tsx} | 5 +- .../Layout/Footer/{index.js => index.tsx} | 4 +- .../CloseIcon/{index.js => index.tsx} | 5 +- .../MenuLink/{index.js => index.tsx} | 6 +- .../OpenIcon/{index.js => index.tsx} | 5 +- .../Layout/Hamburger/{index.js => index.tsx} | 9 +- .../Logo/Status/Joy/{index.js => index.tsx} | 5 +- .../Logo/Status/Loved/{index.js => index.tsx} | 5 +- .../Logo/Status/Sexy/{index.js => index.tsx} | 5 +- .../Status/Smiling/{index.js => index.tsx} | 5 +- .../Status/Sunglasses/{index.js => index.tsx} | 5 +- .../Status/Tongue/{index.js => index.tsx} | 5 +- .../Logo/Status/{index.js => index.tsx} | 29 +- .../Header/Logo/{index.js => index.tsx} | 15 +- .../Layout/Header/{index.js => index.tsx} | 5 +- ...yout.spec.js.snap => layout.spec.tsx.snap} | 12 +- .../{layout.spec.js => layout.spec.tsx} | 8 - .../Layout/__tests__/{stubs.js => stubs.ts} | 0 .../components/Layout/{index.js => index.tsx} | 7 +- .../__tests__/__snapshots__/seo.spec.js.snap | 5 - .../__tests__/__snapshots__/seo.spec.tsx.snap | 325 +++++++++++ .../__tests__/{seo.spec.js => seo.spec.tsx} | 4 +- .../SEO/__tests__/{stubs.js => stubs.ts} | 0 .../components/SEO/{index.js => index.tsx} | 6 +- .../website/src/pages/{_app.js => _app.tsx} | 7 +- .../src/pages/{_document.js => _document.tsx} | 4 +- .../website/src/pages/{about.js => about.tsx} | 4 +- .../api/gitmojis/{index.js => index.tsx} | 4 +- .../{contributors.js => contributors.tsx} | 28 +- .../website/src/pages/{index.js => index.tsx} | 4 +- .../{related-tools.js => related-tools.tsx} | 7 +- packages/website/tsconfig.json | 31 ++ turbo.json | 2 +- yarn.lock | 517 +++++++++++------- 77 files changed, 1087 insertions(+), 702 deletions(-) delete mode 100644 .flowconfig delete mode 100644 packages/website/babel.config.json create mode 100644 packages/website/jest.config.js create mode 100644 packages/website/next-env.d.ts rename packages/website/src/__tests__/__snapshots__/{pages.spec.js.snap => pages.spec.tsx.snap} (97%) rename packages/website/src/__tests__/{pages.spec.js => pages.spec.tsx} (76%) delete mode 100644 packages/website/src/__tests__/stubs.js create mode 100644 packages/website/src/__tests__/stubs.tsx rename packages/website/src/components/Button/__tests__/__snapshots__/{button.spec.js.snap => button.spec.tsx.snap} (95%) rename packages/website/src/components/Button/__tests__/{button.spec.js => button.spec.tsx} (100%) rename packages/website/src/components/Button/__tests__/{stubs.js => stubs.ts} (85%) rename packages/website/src/components/Button/{index.js => index.tsx} (64%) rename packages/website/src/components/CarbonAd/__tests__/__snapshots__/{carbonAd.spec.js.snap => carbonAd.spec.tsx.snap} (52%) rename packages/website/src/components/CarbonAd/__tests__/{carbonAd.spec.js => carbonAd.spec.tsx} (100%) rename packages/website/src/components/CarbonAd/{index.js => index.tsx} (92%) rename packages/website/src/components/ContributorsList/Contributor/{index.js => index.tsx} (62%) rename packages/website/src/components/ContributorsList/__tests__/__snapshots__/{contributorsList.spec.js.snap => contributorsList.spec.tsx.snap} (89%) rename packages/website/src/components/ContributorsList/__tests__/{contributorsList.spec.js => contributorsList.spec.tsx} (82%) rename packages/website/src/components/ContributorsList/__tests__/{stubs.js => stubs.ts} (100%) rename packages/website/src/components/ContributorsList/{index.js => index.tsx} (66%) delete mode 100644 packages/website/src/components/GitmojiList/Gitmoji/index.js create mode 100644 packages/website/src/components/GitmojiList/Gitmoji/index.tsx rename packages/website/src/components/GitmojiList/Toolbar/ListModeSelector/{index.js => index.tsx} (80%) rename packages/website/src/components/GitmojiList/Toolbar/ThemeSelector/{index.js => index.tsx} (84%) rename packages/website/src/components/GitmojiList/Toolbar/{index.js => index.tsx} (85%) rename packages/website/src/components/GitmojiList/__tests__/__snapshots__/{gitmojiList.spec.js.snap => gitmojiList.spec.tsx.snap} (97%) rename packages/website/src/components/GitmojiList/__tests__/{gitmojiList.spec.js => gitmojiList.spec.tsx} (91%) rename packages/website/src/components/GitmojiList/__tests__/{stubs.js => stubs.ts} (100%) rename packages/website/src/components/GitmojiList/{emojiColorsMap.js => emojiColorsMap.ts} (99%) rename packages/website/src/components/GitmojiList/hooks/__tests__/{stubs.js => stubs.ts} (100%) rename packages/website/src/components/GitmojiList/hooks/__tests__/{useLocalStorage.spec.js => useLocalStorage.spec.tsx} (71%) delete mode 100644 packages/website/src/components/GitmojiList/hooks/useLocalStorage.js create mode 100644 packages/website/src/components/GitmojiList/hooks/useLocalStorage.tsx rename packages/website/src/components/GitmojiList/{index.js => index.tsx} (77%) rename packages/website/src/components/Icon/__tests__/__snapshots__/{icon.spec.js.snap => icon.spec.tsx.snap} (100%) rename packages/website/src/components/Icon/__tests__/{icon.spec.js => icon.spec.tsx} (100%) rename packages/website/src/components/Icon/__tests__/{stubs.js => stubs.ts} (100%) rename packages/website/src/components/Icon/{definitions.js => definitions.tsx} (98%) rename packages/website/src/components/Icon/{index.js => index.tsx} (72%) rename packages/website/src/components/Layout/Footer/{index.js => index.tsx} (89%) rename packages/website/src/components/Layout/Hamburger/CloseIcon/{index.js => index.tsx} (78%) rename packages/website/src/components/Layout/Hamburger/MenuLink/{index.js => index.tsx} (80%) rename packages/website/src/components/Layout/Hamburger/OpenIcon/{index.js => index.tsx} (72%) rename packages/website/src/components/Layout/Hamburger/{index.js => index.tsx} (91%) rename packages/website/src/components/Layout/Header/Logo/Status/Joy/{index.js => index.tsx} (94%) rename packages/website/src/components/Layout/Header/Logo/Status/Loved/{index.js => index.tsx} (93%) rename packages/website/src/components/Layout/Header/Logo/Status/Sexy/{index.js => index.tsx} (94%) rename packages/website/src/components/Layout/Header/Logo/Status/Smiling/{index.js => index.tsx} (94%) rename packages/website/src/components/Layout/Header/Logo/Status/Sunglasses/{index.js => index.tsx} (91%) rename packages/website/src/components/Layout/Header/Logo/Status/Tongue/{index.js => index.tsx} (92%) rename packages/website/src/components/Layout/Header/Logo/Status/{index.js => index.tsx} (63%) rename packages/website/src/components/Layout/Header/Logo/{index.js => index.tsx} (91%) rename packages/website/src/components/Layout/Header/{index.js => index.tsx} (89%) rename packages/website/src/components/Layout/__tests__/__snapshots__/{layout.spec.js.snap => layout.spec.tsx.snap} (98%) rename packages/website/src/components/Layout/__tests__/{layout.spec.js => layout.spec.tsx} (93%) rename packages/website/src/components/Layout/__tests__/{stubs.js => stubs.ts} (100%) rename packages/website/src/components/Layout/{index.js => index.tsx} (72%) delete mode 100644 packages/website/src/components/SEO/__tests__/__snapshots__/seo.spec.js.snap create mode 100644 packages/website/src/components/SEO/__tests__/__snapshots__/seo.spec.tsx.snap rename packages/website/src/components/SEO/__tests__/{seo.spec.js => seo.spec.tsx} (87%) rename packages/website/src/components/SEO/__tests__/{stubs.js => stubs.ts} (100%) rename packages/website/src/components/SEO/{index.js => index.tsx} (96%) rename packages/website/src/pages/{_app.js => _app.tsx} (61%) rename packages/website/src/pages/{_document.js => _document.tsx} (97%) rename packages/website/src/pages/{about.js => about.tsx} (98%) rename packages/website/src/pages/api/gitmojis/{index.js => index.tsx} (67%) rename packages/website/src/pages/{contributors.js => contributors.tsx} (63%) rename packages/website/src/pages/{index.js => index.tsx} (81%) rename packages/website/src/pages/{related-tools.js => related-tools.tsx} (95%) create mode 100644 packages/website/tsconfig.json diff --git a/.flowconfig b/.flowconfig deleted file mode 100644 index 81d09f9..0000000 --- a/.flowconfig +++ /dev/null @@ -1,15 +0,0 @@ -[ignore] -/.next -.*/node_modules/resolve/test/resolver/malformed_package_json -.*/node_modules/jsonlint-mod - -[include] - -[libs] - -[lints] - -[options] -module.name_mapper='src\/\(.*\)$' -> '/packages/website/src/\1' -exact_by_default=true -react.runtime=automatic diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 20ef20f..45d5da7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: run: yarn install --immutable - name: Lint 🎨 run: yarn turbo lint - - name: Flow types 🏷 - run: yarn turbo flow + - name: TypeScript check 🏷 + run: yarn turbo tscheck - name: Tests ✅ run: yarn turbo test diff --git a/.gitignore b/.gitignore index 381f01e..8d3e0a2 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,6 @@ packages/website/public/*.map packages/website/public/robots.txt packages/website/public/sitemap.xml packages/website/public/sitemap-*.xml + +# TS +*.tsbuildinfo diff --git a/.husky/pre-push b/.husky/pre-push index 82f3c6f..3206cd9 100755 --- a/.husky/pre-push +++ b/.husky/pre-push @@ -1,4 +1,4 @@ #!/bin/sh . "$(dirname "$0")/_/husky.sh" -yarn turbo flow && yarn turbo test +yarn turbo tscheck && yarn turbo test diff --git a/packages/website/.lintstagedrc.json b/packages/website/.lintstagedrc.json index 16da795..f5bc9a5 100644 --- a/packages/website/.lintstagedrc.json +++ b/packages/website/.lintstagedrc.json @@ -1,6 +1,6 @@ { - "./src/**/*.{js,css}": [ + "./src/**/*.{ts,tsx,css}": [ "eslint --cache --fix", - "prettier --write ./src/**/*.{js,css}" + "prettier --write ./src/**/*.{ts,tsx,css}" ] } diff --git a/packages/website/babel.config.json b/packages/website/babel.config.json deleted file mode 100644 index 6ad5889..0000000 --- a/packages/website/babel.config.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "presets": [ - "next/babel", - "@babel/preset-flow" - ] -} diff --git a/packages/website/jest.config.js b/packages/website/jest.config.js new file mode 100644 index 0000000..e197080 --- /dev/null +++ b/packages/website/jest.config.js @@ -0,0 +1,20 @@ +const nextJest = require('next/jest') + +const createJestConfig = nextJest({ + dir: './' +}) + +/** @type {import('jest').Config} */ +module.exports = createJestConfig({ + "collectCoverageFrom": [ + "src/**/*.{ts,tsx}", + ], + "testMatch": [ + "**/*.(spec).(ts)", + "**/*.(spec).(tsx)" + ], + "moduleNameMapper": { + "src/(.*)$": "/src/$1" + }, + "testEnvironment": "jsdom" +}) diff --git a/packages/website/next-env.d.ts b/packages/website/next-env.d.ts new file mode 100644 index 0000000..4f11a03 --- /dev/null +++ b/packages/website/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/packages/website/package.json b/packages/website/package.json index 33fcc5a..549b5f9 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -7,29 +7,28 @@ }, "scripts": { "build": "next build && next-sitemap", + "tscheck": "yarn tsc --noEmit", "dev": "next dev", - "flow": "flow", - "lint": "eslint ./src && prettier --check ./src/**/*.{js,css}", + "lint": "eslint ./src && prettier --check ./src/**/*.{ts,tsx,css}", "start": "next start", "test": "FORCE_COLOR=1 jest --coverage" }, "devDependencies": { - "@babel/core": "^7.19.6", - "@babel/eslint-parser": "^7.19.1", - "@babel/preset-flow": "^7.0.0", - "@babel/preset-react": "^7.18.6", + "@types/fetch-mock": "^7.3.5", + "@types/jest": "^29.2.4", + "@types/react": "^18.0.26", + "@types/react-test-renderer": "^18.0.0", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", "clipboard": "^2.0.4", "eslint": "^8.26.0", "eslint-config-next": "^13.1.1", "eslint-config-prettier": "^8.5.0", "eslint-import-resolver-alias": "^1.1.2", - "eslint-plugin-flowtype": "^8.0.3", "eslint-plugin-jest": "^27.1.3", "eslint-plugin-react": "^7.31.10", - "flow-bin": "^0.196.3", "focus-trap-react": "^10.0.0", "gitmojis": "workspace:*", - "identity-obj-proxy": "^3.0.0", "jest": "^29.0.1", "jest-environment-jsdom": "^29.0.1", "jest-fetch-mock": "^3.0.3", @@ -38,11 +37,13 @@ "next-pwa": "^5.4.4", "next-sitemap": "^3.1.43", "next-themes": "^0.2.0", + "node-mocks-http": "^1.12.1", "prettier": "2.8.1", "prop-types": "^15.8.1", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-test-renderer": "^18.2.0" + "react-test-renderer": "^18.2.0", + "typescript": "^4.9.4" }, "author": { "name": "carloscuesta", @@ -69,24 +70,11 @@ "singleQuote": true, "arrowParens": "always" }, - "jest": { - "collectCoverageFrom": [ - "./src/**/*.{js,jsx}" - ], - "testMatch": [ - "**/*.(spec).(js)" - ], - "moduleNameMapper": { - "^.+\\.css$": "identity-obj-proxy", - "src/(.*)$": "/src/$1" - }, - "testEnvironment": "jsdom" - }, "volta": { "node": "16.15.0" }, "eslintConfig": { - "parser": "@babel/eslint-parser", + "parser": "@typescript-eslint/parser", "env": { "jest": true, "browser": true, @@ -94,7 +82,7 @@ }, "extends": [ "eslint:recommended", - "plugin:flowtype/recommended", + "plugin:@typescript-eslint/recommended", "plugin:react/recommended", "prettier", "plugin:@next/next/recommended" @@ -108,24 +96,15 @@ "requireConfigFile": false, "babelOptions": { "presets": [ - "next/babel", - "@babel/preset-react", - "@babel/preset-flow" + "next/babel" ] } }, "plugins": [ "react", - "flowtype" + "@typescript-eslint" ], "rules": { - "flowtype/require-valid-file-annotation": [ - 2, - "always", - { - "annotationStyle": "line" - } - ], "react/react-in-jsx-scope": "off", "@next/next/no-img-element": "off", "react/no-unknown-property": [ @@ -138,22 +117,9 @@ } ] }, - "overrides": [ - { - "files": [ - "*.spec.js", - "stubs.js", - "**/__mocks__/*.js" - ], - "rules": { - "flowtype/require-valid-file-annotation": 0 - } - } - ], "settings": { "react": { - "version": "detect", - "flowVersion": "detect" + "version": "detect" }, "import/resolver": { "alias": { diff --git a/packages/website/src/__tests__/__snapshots__/pages.spec.js.snap b/packages/website/src/__tests__/__snapshots__/pages.spec.tsx.snap similarity index 97% rename from packages/website/src/__tests__/__snapshots__/pages.spec.js.snap rename to packages/website/src/__tests__/__snapshots__/pages.spec.tsx.snap index 9bcc633..80bf7ff 100644 --- a/packages/website/src/__tests__/__snapshots__/pages.spec.js.snap +++ b/packages/website/src/__tests__/__snapshots__/pages.spec.tsx.snap @@ -3,10 +3,10 @@ exports[`Pages About should render the page 1`] = `
@@ -532,10 +532,10 @@ exports[`Pages App should render the page 1`] = ` exports[`Pages Contributors should render the page 1`] = `
@@ -567,10 +567,10 @@ exports[`Pages Contributors should render the page 1`] = ` exports[`Pages Index should render the page 1`] = `
@@ -718,7 +718,7 @@ exports[`Pages Index should render the page 1`] = ` - -
- -

{props.description}

-
-
- -) - -export default Gitmoji diff --git a/packages/website/src/components/GitmojiList/Gitmoji/index.tsx b/packages/website/src/components/GitmojiList/Gitmoji/index.tsx new file mode 100644 index 0000000..45ae6af --- /dev/null +++ b/packages/website/src/components/GitmojiList/Gitmoji/index.tsx @@ -0,0 +1,52 @@ +import emojiColorsMap from '../emojiColorsMap' +import styles from './styles.module.css' + +type Props = { + code: string + description: string + emoji: string + isListMode: boolean + name: keyof typeof emojiColorsMap +} + +const Gitmoji = (props: Props) => { + const style = { + '--emojiColor': emojiColorsMap[props.name], + } as React.CSSProperties + + return ( +
+
+
+ +
+
+ +

{props.description}

+
+
+
+ ) +} + +export default Gitmoji diff --git a/packages/website/src/components/GitmojiList/Toolbar/ListModeSelector/index.js b/packages/website/src/components/GitmojiList/Toolbar/ListModeSelector/index.tsx similarity index 80% rename from packages/website/src/components/GitmojiList/Toolbar/ListModeSelector/index.js rename to packages/website/src/components/GitmojiList/Toolbar/ListModeSelector/index.tsx index 2814b53..ed62b0d 100644 --- a/packages/website/src/components/GitmojiList/Toolbar/ListModeSelector/index.js +++ b/packages/website/src/components/GitmojiList/Toolbar/ListModeSelector/index.tsx @@ -1,15 +1,12 @@ -// @flow -import { type Element } from 'react' - import Icon from 'src/components/Icon' import styles from './styles.module.css' type Props = { - isListMode: boolean, - setIsListMode: Function, + isListMode: boolean + setIsListMode: (isListMode: boolean) => void } -const ListModeSelector = (props: Props): Element<'div'> => ( +const ListModeSelector = (props: Props) => (