diff --git a/.eslintrc b/.eslintrc index 6b80ad4e..11c23a0a 100644 --- a/.eslintrc +++ b/.eslintrc @@ -19,6 +19,7 @@ "plugin:prettier/recommended", "plugin:react/recommended" ], + "plugins": ["@typescript-eslint", "react"], "rules": { "object-curly-spacing": ["error", "always"], "react/prop-types": "off", diff --git a/jest.config.js b/jest.config.js index ec1c65f2..25f921f2 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,13 +1,17 @@ module.exports = { transform: { - '^.+\\.tsx?$': '/jest/jest-preprocess.js' + '^.+\\.(tsx?|jsx?)$': 'ts-jest', + '^.+\\.jsx?$': '/jest/jest-preprocess.js' }, + testRegex: '(/__tests__/.*|\\.(test|spec))\\.(ts|tsx)$', + moduleNameMapper: { '.+\\.(css|styl|less|sass|scss)$': 'identity-obj-proxy', '.+\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': - '/jest/__mocks__/file-mock.js', - '\\.svg': '/jest/__mocks__/svgr-mock.js' + '/jest/__mocks__/file-mock.ts', + '\\.svg': '/jest/__mocks__/svgr-mock.ts' }, + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], testPathIgnorePatterns: ['node_modules', '.cache', 'public', 'coverage'], transformIgnorePatterns: ['node_modules/(?!(gatsby)/)'], globals: { @@ -15,6 +19,6 @@ module.exports = { }, testURL: 'http://localhost', setupFiles: ['/jest/loadershim.js'], - setupFilesAfterEnv: ['/jest/setup-test-env.js'], + setupFilesAfterEnv: ['/jest/setup-test-env.ts'], collectCoverageFrom: ['src/**/*.{ts,tsx}', '!src/@types/**/*'] } diff --git a/jest/__mocks__/file-mock.js b/jest/__mocks__/file-mock.js deleted file mode 100644 index 0e56c5b5..00000000 --- a/jest/__mocks__/file-mock.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = 'test-file-stub' diff --git a/jest/__mocks__/file-mock.ts b/jest/__mocks__/file-mock.ts new file mode 100644 index 00000000..2b9e53d9 --- /dev/null +++ b/jest/__mocks__/file-mock.ts @@ -0,0 +1 @@ +export default 'test-file-stub' diff --git a/jest/__mocks__/gatsby.js b/jest/__mocks__/gatsby.ts similarity index 72% rename from jest/__mocks__/gatsby.js rename to jest/__mocks__/gatsby.ts index d325f6ea..67e6940e 100644 --- a/jest/__mocks__/gatsby.js +++ b/jest/__mocks__/gatsby.ts @@ -1,13 +1,13 @@ -const React = require('react') +import React from 'react' const gatsby = jest.requireActual('gatsby') -module.exports = { +export default { ...gatsby, graphql: jest.fn(), Link: jest.fn().mockImplementation( // these props are invalid for an `a` tag ({ - /* eslint-disable no-unused-vars */ + /* eslint-disable @typescript-eslint/no-unused-vars */ activeClassName, activeStyle, getProps, @@ -15,7 +15,7 @@ module.exports = { ref, replace, to, - /* eslint-enable no-unused-vars */ + /* eslint-enable @typescript-eslint/no-unused-vars */ ...rest }) => React.createElement('a', { diff --git a/jest/__mocks__/svgr-mock.js b/jest/__mocks__/svgr-mock.js deleted file mode 100644 index d067fa02..00000000 --- a/jest/__mocks__/svgr-mock.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { ReactComponent: 'svg' } diff --git a/jest/__mocks__/svgr-mock.ts b/jest/__mocks__/svgr-mock.ts new file mode 100644 index 00000000..13b64e5a --- /dev/null +++ b/jest/__mocks__/svgr-mock.ts @@ -0,0 +1,3 @@ +const content = 'svg' +export const ReactComponent = content +export default content diff --git a/jest/setup-test-env.js b/jest/setup-test-env.js deleted file mode 100644 index 5df3c44b..00000000 --- a/jest/setup-test-env.js +++ /dev/null @@ -1 +0,0 @@ -require('@testing-library/jest-dom/extend-expect') diff --git a/jest/setup-test-env.ts b/jest/setup-test-env.ts new file mode 100644 index 00000000..264828a9 --- /dev/null +++ b/jest/setup-test-env.ts @@ -0,0 +1 @@ +import '@testing-library/jest-dom/extend-expect' diff --git a/package.json b/package.json index e4b72ec9..0ae07e1f 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "lint:css": "stylelint 'src/**/*.{css,scss}'", "lint:md": "markdownlint './**/*.{md,markdown}' --ignore './{node_modules,public,.cache,.git,coverage}/**/*'", "format": "prettier --write 'src/**/*.{js,jsx,ts,tsx,md,json,css,scss}'", + "tsc": "tsc --noEmit", "deploy": "./scripts/deploy.sh", "new": "babel-node ./scripts/new.js" }, @@ -90,6 +91,7 @@ "@testing-library/react": "^9.2.0", "@types/classnames": "^2.2.9", "@types/jest": "^24.0.18", + "@types/lunr": "^2.3.2", "@types/node": "^12.7.8", "@types/react": "^16.9.4", "@types/react-dom": "^16.9.1", @@ -124,6 +126,7 @@ "stylelint-config-prettier": "^6.0.0", "stylelint-config-standard": "^19.0.0", "stylelint-prettier": "^1.1.1", + "ts-jest": "^24.1.0", "typescript": "^3.6.3", "why-did-you-update": "^1.0.6" }, diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index 5925eaf8..5559a19d 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -1,23 +1,18 @@ -interface CSSModule { - [className: string]: string -} - -// type shims for CSS modules -declare module '*.module.scss' { - const cssModule: CSSModule - export = cssModule -} - declare module '*.module.css' { - const cssModule: CSSModule - export = cssModule + const classes: { [key: string]: string } + export default classes } -/* eslint-disable-next-line @typescript-eslint/no-empty-interface */ -interface SvgrComponent - extends React.StatelessComponent> {} +declare module '*.module.scss' { + const classes: { [key: string]: string } + export default classes +} declare module '*.svg' { - const value: SvgrComponent - export default value + import * as React from 'react' + export const ReactComponent: React.FunctionComponent< + React.SVGProps + > + const src: string + export default src } diff --git a/src/@types/node_modules.d.ts b/src/@types/node_modules.d.ts new file mode 100644 index 00000000..57bfe4ce --- /dev/null +++ b/src/@types/node_modules.d.ts @@ -0,0 +1,5 @@ +declare module 'pigeon-maps' +declare module 'pigeon-marker' +declare module 'react-blockies' +declare module 'react-time' +declare module 'remark-react' diff --git a/src/@types/pigeon-maps.d.ts b/src/@types/pigeon-maps.d.ts deleted file mode 100644 index dd469466..00000000 --- a/src/@types/pigeon-maps.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare module 'pigeon-maps' diff --git a/src/@types/pigeon-marker.d.ts b/src/@types/pigeon-marker.d.ts deleted file mode 100644 index 77862d53..00000000 --- a/src/@types/pigeon-marker.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare module 'pigeon-marker' diff --git a/src/@types/react-blockies.d.ts b/src/@types/react-blockies.d.ts deleted file mode 100644 index 04fd4afe..00000000 --- a/src/@types/react-blockies.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare module 'react-blockies' diff --git a/src/@types/react-time.d.ts b/src/@types/react-time.d.ts deleted file mode 100644 index 3681ee34..00000000 --- a/src/@types/react-time.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare module 'react-time' diff --git a/src/@types/remark-react.d.ts b/src/@types/remark-react.d.ts deleted file mode 100644 index 63b20dd7..00000000 --- a/src/@types/remark-react.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare module 'remark-react' diff --git a/src/components/Search/SearchResults.tsx b/src/components/Search/SearchResults.tsx index f65fdc2b..cb271e1a 100644 --- a/src/components/Search/SearchResults.tsx +++ b/src/components/Search/SearchResults.tsx @@ -5,6 +5,7 @@ import Container from '../atoms/Container' import PostTeaser from '../Post/PostTeaser' import SearchResultsEmpty from './SearchResultsEmpty' import styles from './SearchResults.module.scss' +import { GatsbyImageProps } from 'gatsby-image' const query = graphql` query { @@ -29,6 +30,22 @@ const query = graphql` } ` +interface Page { + slug: string +} + +interface PostNode { + node: { + id: string + fields: { slug: string } + frontmatter: { + title: string + type: string + image: { childImageSharp: GatsbyImageProps } + } + } +} + export default function SearchResults({ searchQuery, results, @@ -48,13 +65,13 @@ export default function SearchResults({ {results.length > 0 ? (