From 9131254f3371f12a17de44b6fa8f9bfb0e5c002e Mon Sep 17 00:00:00 2001 From: sct Date: Thu, 17 Sep 2020 16:17:41 +0000 Subject: [PATCH] feat(frontend/api): i18n support --- .eslintrc.js | 3 +- babel.config.js | 25 + ormconfig.js | 2 +- package.json | 11 +- server/api/themoviedb.ts | 4 +- server/overseerr-api.yml | 30 ++ server/routes/discover.ts | 10 +- server/routes/movie.ts | 7 +- server/routes/search.ts | 1 + src/components/Discover/index.tsx | 27 +- .../Layout/LanguagePicker/index.tsx | 109 ++++ src/components/Layout/index.tsx | 2 + src/components/MovieDetails/index.tsx | 93 +++- src/components/TitleCard/RequestCard.tsx | 8 +- src/context/LanguageContext.tsx | 15 + src/i18n/locale/en.json | 15 + src/i18n/locale/ja.json | 15 + src/pages/_app.tsx | 166 ++++--- src/pages/movie/[movieId]/index.tsx | 4 +- src/pages/plextest.tsx | 13 - src/types/react-intl-auto.d.ts | 11 + yarn.lock | 470 +++++++++++++++++- 22 files changed, 926 insertions(+), 115 deletions(-) create mode 100644 babel.config.js create mode 100644 src/components/Layout/LanguagePicker/index.tsx create mode 100644 src/context/LanguageContext.tsx create mode 100644 src/i18n/locale/en.json create mode 100644 src/i18n/locale/ja.json delete mode 100644 src/pages/plextest.tsx create mode 100644 src/types/react-intl-auto.d.ts diff --git a/.eslintrc.js b/.eslintrc.js index 18995a31..ee3dbce6 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -29,6 +29,7 @@ module.exports = { 'react-hooks/exhaustive-deps': 'warn', '@typescript-eslint/explicit-function-return-type': 'off', 'prettier/prettier': ['error', { endOfLine: 'auto' }], + 'formatjs/no-offset': 'error', }, overrides: [ { @@ -38,7 +39,7 @@ module.exports = { }, }, ], - plugins: ['jsx-a11y', 'prettier', 'react-hooks'], + plugins: ['jsx-a11y', 'prettier', 'react-hooks', 'formatjs'], settings: { react: { pragma: 'React', diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 00000000..f7a1042f --- /dev/null +++ b/babel.config.js @@ -0,0 +1,25 @@ +module.exports = function (api) { + api.cache(true); + + return { + presets: [ + [ + 'next/babel', + { + 'preset-env': { + useBuiltIns: 'entry', + corejs: '3', + }, + }, + ], + ], + plugins: [ + [ + 'react-intl-auto', + { + removePrefix: 'src/', + }, + ], + ], + }; +}; diff --git a/ormconfig.js b/ormconfig.js index 96d7611d..92205cda 100644 --- a/ormconfig.js +++ b/ormconfig.js @@ -2,7 +2,7 @@ const devConfig = { type: 'sqlite', database: 'config/db/db.sqlite3', synchronize: true, - logging: true, + logging: false, entities: ['server/entity/**/*.ts'], migrations: ['server/migration/**/*.ts'], cli: { diff --git a/package.json b/package.json index 04c63ecd..48daab52 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "build:next": "next build", "build": "yarn build:next && yarn build:server", "lint": "eslint \"./server/**/*.{ts,tsx}\" \"./src/**/*.{ts,tsx}\"", - "start": "NODE_ENV=production node dist/index.js" + "start": "NODE_ENV=production node dist/index.js", + "i18n:extract": "extract-messages -l=en,ja -o src/i18n/locale -d en --flat true './src/**/!(*.test).{ts,tsx}'" }, "dependencies": { "@svgr/webpack": "^5.4.0", @@ -21,10 +22,13 @@ "express": "^4.17.1", "express-openapi-validator": "^3.16.15", "express-session": "^1.17.1", + "intl": "^1.2.5", "lodash": "^4.17.20", "next": "9.5.3", + "nookies": "^2.4.0", "react": "16.13.1", "react-dom": "16.13.1", + "react-intl": "^5.8.1", "react-spring": "^8.0.27", "react-toast-notifications": "^2.4.0", "react-transition-group": "^4.4.1", @@ -36,6 +40,7 @@ "yamljs": "^0.3.0" }, "devDependencies": { + "@babel/cli": "^7.11.6", "@commitlint/cli": "^9.1.2", "@commitlint/config-conventional": "^9.1.2", "@types/body-parser": "^1.19.0", @@ -52,14 +57,18 @@ "@types/yamljs": "^0.2.31", "@typescript-eslint/eslint-plugin": "^4.0.0", "@typescript-eslint/parser": "^3.10.1", + "babel-plugin-react-intl": "^8.2.2", + "babel-plugin-react-intl-auto": "^3.3.0", "commitizen": "^4.2.1", "cz-conventional-changelog": "^3.3.0", "eslint": "^7.8.1", "eslint-config-prettier": "^6.11.0", + "eslint-plugin-formatjs": "^2.7.10", "eslint-plugin-jsx-a11y": "^6.3.1", "eslint-plugin-prettier": "^3.1.4", "eslint-plugin-react": "^7.20.6", "eslint-plugin-react-hooks": "^4.1.0", + "extract-react-intl-messages": "^4.1.1", "husky": "^4.3.0", "lint-staged": "^10.3.0", "nodemon": "^2.0.4", diff --git a/server/api/themoviedb.ts b/server/api/themoviedb.ts index e7e7d1b4..6e305de8 100644 --- a/server/api/themoviedb.ts +++ b/server/api/themoviedb.ts @@ -4,6 +4,7 @@ interface SearchOptions { query: string; page?: number; includeAdult?: boolean; + language?: string; } interface DiscoverMovieOptions { @@ -260,10 +261,11 @@ class TheMovieDb { query, page = 1, includeAdult = false, + language = 'en-US', }: SearchOptions): Promise => { try { const response = await this.axios.get('/search/multi', { - params: { query, page, include_adult: includeAdult }, + params: { query, page, include_adult: includeAdult, language }, }); return response.data; diff --git a/server/overseerr-api.yml b/server/overseerr-api.yml index 60d921d3..8dd2b128 100644 --- a/server/overseerr-api.yml +++ b/server/overseerr-api.yml @@ -1060,6 +1060,11 @@ paths: type: number example: 1 default: 1 + - in: query + name: language + schema: + type: string + example: en responses: '200': description: Results @@ -1097,6 +1102,11 @@ paths: type: number example: 1 default: 1 + - in: query + name: language + schema: + type: string + example: en responses: '200': description: Results @@ -1131,6 +1141,11 @@ paths: type: number example: 1 default: 1 + - in: query + name: language + schema: + type: string + example: en responses: '200': description: Results @@ -1282,6 +1297,11 @@ paths: schema: type: number example: 337401 + - in: query + name: language + schema: + type: string + example: en responses: '200': description: Movie details @@ -1308,6 +1328,11 @@ paths: type: number example: 1 default: 1 + - in: query + name: language + schema: + type: string + example: en responses: '200': description: List of movies @@ -1348,6 +1373,11 @@ paths: type: number example: 1 default: 1 + - in: query + name: language + schema: + type: string + example: en responses: '200': description: List of movies diff --git a/server/routes/discover.ts b/server/routes/discover.ts index a0009ca7..797796f0 100644 --- a/server/routes/discover.ts +++ b/server/routes/discover.ts @@ -8,7 +8,10 @@ const discoverRoutes = Router(); discoverRoutes.get('/movies', async (req, res) => { const tmdb = new TheMovieDb(); - const data = await tmdb.getDiscoverMovies({ page: Number(req.query.page) }); + const data = await tmdb.getDiscoverMovies({ + page: Number(req.query.page), + language: req.query.language as string, + }); const requests = await MediaRequest.getRelatedRequests( data.results.map((result) => result.id) @@ -30,7 +33,10 @@ discoverRoutes.get('/movies', async (req, res) => { discoverRoutes.get('/tv', async (req, res) => { const tmdb = new TheMovieDb(); - const data = await tmdb.getDiscoverTv({ page: Number(req.query.page) }); + const data = await tmdb.getDiscoverTv({ + page: Number(req.query.page), + language: req.query.language as string, + }); const requests = await MediaRequest.getRelatedRequests( data.results.map((result) => result.id) diff --git a/server/routes/movie.ts b/server/routes/movie.ts index ff0a5585..8e50bf0e 100644 --- a/server/routes/movie.ts +++ b/server/routes/movie.ts @@ -9,7 +9,10 @@ const movieRoutes = Router(); movieRoutes.get('/:id', async (req, res) => { const tmdb = new TheMovieDb(); - const movie = await tmdb.getMovie({ movieId: Number(req.params.id) }); + const movie = await tmdb.getMovie({ + movieId: Number(req.params.id), + language: req.query.language as string, + }); const request = await MediaRequest.getRequest(movie.id); @@ -22,6 +25,7 @@ movieRoutes.get('/:id/recommendations', async (req, res) => { const results = await tmdb.getMovieRecommendations({ movieId: Number(req.params.id), page: Number(req.query.page), + language: req.query.language as string, }); const requests = await MediaRequest.getRelatedRequests( @@ -47,6 +51,7 @@ movieRoutes.get('/:id/similar', async (req, res) => { const results = await tmdb.getMovieSimilar({ movieId: Number(req.params.id), page: Number(req.query.page), + language: req.query.language as string, }); const requests = await MediaRequest.getRelatedRequests( diff --git a/server/routes/search.ts b/server/routes/search.ts index 20aebe4c..d76a61ee 100644 --- a/server/routes/search.ts +++ b/server/routes/search.ts @@ -11,6 +11,7 @@ searchRoutes.get('/', async (req, res) => { const results = await tmdb.searchMulti({ query: req.query.query as string, page: Number(req.query.page), + language: req.query.language as string, }); const requests = await MediaRequest.getRelatedRequests( diff --git a/src/components/Discover/index.tsx b/src/components/Discover/index.tsx index eebe5d49..324afa97 100644 --- a/src/components/Discover/index.tsx +++ b/src/components/Discover/index.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useContext } from 'react'; import useSWR from 'swr'; import type { MovieResult, TvResult } from '../../../server/models/Search'; import TitleCard from '../TitleCard'; @@ -6,6 +6,14 @@ import { MediaRequest } from '../../../server/entity/MediaRequest'; import RequestCard from '../TitleCard/RequestCard'; import Slider from '../Slider'; import Link from 'next/link'; +import { defineMessages, FormattedMessage } from 'react-intl'; +import { LanguageContext } from '../../context/LanguageContext'; + +const messages = defineMessages({ + recentrequests: 'Recent Requests', + popularmovies: 'Popular Movies', + populartv: 'Popular Series', +}); interface MovieDiscoverResult { page: number; @@ -22,11 +30,12 @@ interface TvDiscoverResult { } const Discover: React.FC = () => { + const { locale } = useContext(LanguageContext); const { data: movieData, error: movieError } = useSWR( - '/api/v1/discover/movies' + `/api/v1/discover/movies?language=${locale}` ); const { data: tvData, error: tvError } = useSWR( - '/api/v1/discover/tv' + `/api/v1/discover/tv?language=${locale}` ); const { data: requests, error: requestError } = useSWR( @@ -39,7 +48,9 @@ const Discover: React.FC = () => {
- Recent Requests + + + {
- Popular Movies + + + {
- Popular TV Shows + + + ; + +const availableLanguages: AvailableLanguageObject = { + en: { + code: 'en', + display: 'English', + }, + ja: { + code: 'ja', + display: '日本語', + }, +}; + +const LanguagePicker: React.FC = () => { + const dropdownRef = useRef(null); + const { locale, setLocale } = useContext(LanguageContext); + const [isDropdownOpen, setDropdownOpen] = useState(false); + useClickOutside(dropdownRef, () => setDropdownOpen(false)); + + return ( +
+
+ +
+ +
+
+
+ + +
+
+
+
+
+ ); +}; + +export default LanguagePicker; diff --git a/src/components/Layout/index.tsx b/src/components/Layout/index.tsx index 0b66105b..1e5f2244 100644 --- a/src/components/Layout/index.tsx +++ b/src/components/Layout/index.tsx @@ -3,6 +3,7 @@ import SearchInput from './SearchInput'; import UserDropdown from './UserDropdown'; import Sidebar from './Sidebar'; import Notifications from './Notifications'; +import LanguagePicker from './LanguagePicker'; const Layout: React.FC = ({ children }) => { const [isSidebarOpen, setSidebarOpen] = useState(false); @@ -35,6 +36,7 @@ const Layout: React.FC = ({ children }) => {
+
diff --git a/src/components/MovieDetails/index.tsx b/src/components/MovieDetails/index.tsx index fe21a473..1031d737 100644 --- a/src/components/MovieDetails/index.tsx +++ b/src/components/MovieDetails/index.tsx @@ -1,4 +1,10 @@ -import React, { useState } from 'react'; +import React, { useState, useContext } from 'react'; +import { + FormattedMessage, + defineMessages, + FormattedNumber, + FormattedDate, +} from 'react-intl'; import type { MovieDetails as MovieDetailsType } from '../../../server/models/Movie'; import useSWR from 'swr'; import { useRouter } from 'next/router'; @@ -12,6 +18,19 @@ import Link from 'next/link'; import Slider from '../Slider'; import TitleCard from '../TitleCard'; import PersonCard from '../PersonCard'; +import { LanguageContext } from '../../context/LanguageContext'; + +const messages = defineMessages({ + releasedate: 'Release Date', + userrating: 'User Rating', + status: 'Status', + revenue: 'Revenue', + budget: 'Budget', + originallanguage: 'Original Language', + overview: 'Overview', + runtime: '{minutes} minutes', + cast: 'Cast', +}); interface MovieDetailsProps { movie?: MovieDetailsType; @@ -33,20 +52,21 @@ enum MediaRequestStatus { const MovieDetails: React.FC = ({ movie }) => { const router = useRouter(); + const { locale } = useContext(LanguageContext); const { addToast } = useToasts(); const [showRequestModal, setShowRequestModal] = useState(false); const [showCancelModal, setShowCancelModal] = useState(false); const { data, error, revalidate } = useSWR( - `/api/v1/movie/${router.query.movieId}`, + `/api/v1/movie/${router.query.movieId}?language=${locale}`, { initialData: movie, } ); const { data: recommended, error: recommendedError } = useSWR( - `/api/v1/movie/${router.query.movieId}/recommendations` + `/api/v1/movie/${router.query.movieId}/recommendations?language=${locale}` ); const { data: similar, error: similarError } = useSWR( - `/api/v1/movie/${router.query.movieId}/similar` + `/api/v1/movie/${router.query.movieId}/similar?language=${locale}` ); const request = async () => { @@ -110,7 +130,7 @@ const MovieDetails: React.FC = ({ movie }) => {
@@ -119,7 +139,11 @@ const MovieDetails: React.FC = ({ movie }) => {

{data.title}

- {data.runtime} minutes | {data.genres.map((g) => g.name).join(', ')} + {' '} + | {data.genres.map((g) => g.name).join(', ')}
@@ -249,31 +273,70 @@ const MovieDetails: React.FC = ({ movie }) => {
-

Overview

+

+ +

{data.overview}

- Status + + + + + {data.voteAverage}/10 + +
+
+ + + + + + +
+
+ + + {data.status}
- Revenue + + + - {data.revenue} +
- Budget + + + - {data.budget} +
- Original Language + + + {data.originalLanguage} @@ -285,7 +348,9 @@ const MovieDetails: React.FC = ({ movie }) => {
- Cast + + + { }; const RequestCard: React.FC = ({ tmdbId, type }) => { + const { locale } = useContext(LanguageContext); const url = type === 'movie' ? `/api/v1/movie/${tmdbId}` : `/api/v1/tv/${tmdbId}`; - const { data: title, error } = useSWR(url); + const { data: title, error } = useSWR( + `${url}?language=${locale}` + ); if (!title && !error) { return ; diff --git a/src/context/LanguageContext.tsx b/src/context/LanguageContext.tsx new file mode 100644 index 00000000..d40c4668 --- /dev/null +++ b/src/context/LanguageContext.tsx @@ -0,0 +1,15 @@ +import React, { ReactNode } from 'react'; + +export type AvailableLocales = 'en' | 'ja'; + +interface LanguageContextProps { + locale: AvailableLocales; + children: (locale: string) => ReactNode; + setLocale?: React.Dispatch>; +} + +export const LanguageContext = React.createContext< + Omit +>({ + locale: 'en', +}); diff --git a/src/i18n/locale/en.json b/src/i18n/locale/en.json new file mode 100644 index 00000000..01086969 --- /dev/null +++ b/src/i18n/locale/en.json @@ -0,0 +1,15 @@ +{ + "components.Discover.popularmovies": "Popular Movies", + "components.Discover.populartv": "Popular Series", + "components.Discover.recentrequests": "Recent Requests", + "components.Layout.LanguagePicker.changelanguage": "Change Language", + "components.MovieDetails.budget": "Budget", + "components.MovieDetails.cast": "Cast", + "components.MovieDetails.originallanguage": "Original Language", + "components.MovieDetails.overview": "Overview", + "components.MovieDetails.releasedate": "Release Date", + "components.MovieDetails.revenue": "Revenue", + "components.MovieDetails.runtime": "{minutes} minutes", + "components.MovieDetails.status": "Status", + "components.MovieDetails.userrating": "User Rating" +} diff --git a/src/i18n/locale/ja.json b/src/i18n/locale/ja.json new file mode 100644 index 00000000..58ab84db --- /dev/null +++ b/src/i18n/locale/ja.json @@ -0,0 +1,15 @@ +{ + "components.Discover.popularmovies": "人気映画", + "components.Discover.populartv": "人気テレビ番組", + "components.Discover.recentrequests": "最近のリクエスト", + "components.Layout.LanguagePicker.changelanguage": "言語", + "components.MovieDetails.budget": "興行収入", + "components.MovieDetails.cast": "キャスト", + "components.MovieDetails.originallanguage": "言語", + "components.MovieDetails.overview": "ストーリー", + "components.MovieDetails.releasedate": "公開日", + "components.MovieDetails.revenue": "製作費", + "components.MovieDetails.runtime": "{minutes}分", + "components.MovieDetails.status": "状態", + "components.MovieDetails.userrating": "ユーザー評価" +} diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 2cae5c0f..9552e379 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -1,82 +1,136 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import '../styles/globals.css'; -import App, { AppInitialProps } from 'next/app'; +import App, { AppInitialProps, AppProps } from 'next/app'; import { SWRConfig } from 'swr'; import { ToastProvider } from 'react-toast-notifications'; +import { parseCookies, setCookie } from 'nookies'; import Layout from '../components/Layout'; import { UserContext } from '../context/UserContext'; import axios from 'axios'; import { User } from '../hooks/useUser'; +import { IntlProvider } from 'react-intl'; +import { LanguageContext, AvailableLocales } from '../context/LanguageContext'; + +const loadLocaleData = (locale: string) => { + switch (locale) { + case 'ja': + return import('../i18n/locale/ja.json'); + default: + return import('../i18n/locale/en.json'); + } +}; // Custom types so we can correctly type our GetInitialProps function // with our combined user prop // This is specific to _app.tsx. Other pages will not need to do this! type NextAppComponentType = typeof App; -type GetInitialPropsFn = NextAppComponentType['getInitialProps']; +type MessagesType = Record; -interface AppProps { +interface ExtendedAppProps extends AppProps { user: User; + messages: MessagesType; + locale: AvailableLocales; } -class CoreApp extends App { - public static getInitialProps: GetInitialPropsFn = async (initialProps) => { - // Run the default getInitialProps for the main nextjs initialProps - const appInitialProps: AppInitialProps = await App.getInitialProps( - initialProps +if (typeof window === 'undefined') { + global.Intl = require('intl'); +} + +const CoreApp: Omit = ({ + Component, + pageProps, + router, + user, + messages, + locale, +}: ExtendedAppProps) => { + let component: React.ReactNode; + const [loadedMessages, setMessages] = useState(messages); + const [currentLocale, setLocale] = useState(locale); + + useEffect(() => { + loadLocaleData(currentLocale).then(setMessages); + setCookie(null, 'locale', currentLocale, { path: '/' }); + }, [currentLocale]); + + if (router.asPath === '/login') { + component = ; + } else { + component = ( + + + ); - const { ctx, router } = initialProps; - let user = undefined; - if (ctx.res) { - try { - // Attempt to get the user by running a request to the local api - const response = await axios.get( - `http://localhost:${process.env.PORT || 3000}/api/v1/auth/me`, - { headers: ctx.req ? { cookie: ctx.req.headers.cookie } : undefined } - ); - user = response.data; - } catch (e) { - // If there is no user, and ctx.res is set (to check if we are on the server side) - // _AND_ we are not already on the login or setup route, redirect to /login with a 307 - // before anything actually renders - if (!router.pathname.match(/(login|setup)/)) { - ctx.res.writeHead(307, { - Location: '/login', - }); - ctx.res.end(); - } - } - } + } - return { ...appInitialProps, user }; - }; + return ( + axios.get(url).then((res) => res.data), + }} + > + + + + {component} + + + + + ); +}; - public render(): JSX.Element { - const { Component, pageProps, router, user } = this.props; +CoreApp.getInitialProps = async (initialProps) => { + // Run the default getInitialProps for the main nextjs initialProps + const appInitialProps: AppInitialProps = await App.getInitialProps( + initialProps + ); + const { ctx, router } = initialProps; + let user = undefined; - let component: React.ReactNode; + let locale = 'en'; - if (router.asPath === '/login') { - component = ; - } else { - component = ( - - - - ); + if (ctx.res) { + const cookies = parseCookies(ctx); + + if (cookies.locale) { + locale = cookies.locale; } - return ( - axios.get(url).then((res) => res.data), - }} - > - - {component} - - - ); + try { + // Attempt to get the user by running a request to the local api + const response = await axios.get( + `http://localhost:${process.env.PORT || 3000}/api/v1/auth/me`, + { headers: ctx.req ? { cookie: ctx.req.headers.cookie } : undefined } + ); + user = response.data; + + if (router.pathname.match(/login/)) { + ctx.res.writeHead(307, { + Location: '/', + }); + ctx.res.end(); + } + } catch (e) { + // If there is no user, and ctx.res is set (to check if we are on the server side) + // _AND_ we are not already on the login or setup route, redirect to /login with a 307 + // before anything actually renders + if (!router.pathname.match(/(login|setup)/)) { + ctx.res.writeHead(307, { + Location: '/login', + }); + ctx.res.end(); + } + } } -} + + const messages = await loadLocaleData(locale); + + return { ...appInitialProps, user, messages, locale }; +}; export default CoreApp; diff --git a/src/pages/movie/[movieId]/index.tsx b/src/pages/movie/[movieId]/index.tsx index fc5ae500..1a97edcf 100644 --- a/src/pages/movie/[movieId]/index.tsx +++ b/src/pages/movie/[movieId]/index.tsx @@ -3,6 +3,7 @@ import { NextPage } from 'next'; import type { MovieDetails as MovieDetailsType } from '../../../../server/models/Movie'; import MovieDetails from '../../../components/MovieDetails'; import axios from 'axios'; +import { parseCookies } from 'nookies'; interface MoviePageProps { movie?: MovieDetailsType; @@ -14,10 +15,11 @@ const MoviePage: NextPage = ({ movie }) => { MoviePage.getInitialProps = async (ctx) => { if (ctx.req) { + const cookies = parseCookies(ctx); const response = await axios.get( `http://localhost:${process.env.PORT || 3000}/api/v1/movie/${ ctx.query.movieId - }`, + }?language=${cookies.locale}`, { headers: ctx.req ? { cookie: ctx.req.headers.cookie } : undefined } ); diff --git a/src/pages/plextest.tsx b/src/pages/plextest.tsx deleted file mode 100644 index 45b0a356..00000000 --- a/src/pages/plextest.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react'; -import { NextPage } from 'next'; -import PersonCard from '../components/PersonCard'; - -const PlexText: NextPage = () => { - return ( -
- -
- ); -}; - -export default PlexText; diff --git a/src/types/react-intl-auto.d.ts b/src/types/react-intl-auto.d.ts new file mode 100644 index 00000000..23216860 --- /dev/null +++ b/src/types/react-intl-auto.d.ts @@ -0,0 +1,11 @@ +import { MessageDescriptor } from 'react-intl'; + +declare module 'react-intl' { + interface ExtractableMessage { + [key: string]: string; + } + + export function defineMessages( + messages: T + ): { [K in keyof T]: MessageDescriptor }; +} diff --git a/yarn.lock b/yarn.lock index 3713d1b1..3c0604ec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -62,6 +62,22 @@ call-me-maybe "^1.0.1" js-yaml "^3.13.1" +"@babel/cli@^7.11.6": + version "7.11.6" + resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.11.6.tgz#1fcbe61c2a6900c3539c06ee58901141f3558482" + integrity sha512-+w7BZCvkewSmaRM6H4L2QM3RL90teqEIHDIFXAmrW33+0jhlymnDAEdqVeCZATvxhQuio1ifoGVlJJbIiH9Ffg== + dependencies: + commander "^4.0.1" + convert-source-map "^1.1.0" + fs-readdir-recursive "^1.1.0" + glob "^7.0.0" + lodash "^4.17.19" + make-dir "^2.1.0" + slash "^2.0.0" + source-map "^0.5.0" + optionalDependencies: + chokidar "^2.1.8" + "@babel/code-frame@7.10.4", "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.5.5": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" @@ -373,16 +389,16 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@babel/parser@^7.1.0", "@babel/parser@^7.11.5": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.5.tgz#c7ff6303df71080ec7a4f5b8c003c58f1cf51037" + integrity sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q== + "@babel/parser@^7.10.4", "@babel/parser@^7.11.0", "@babel/parser@^7.7.7": version "7.11.3" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.3.tgz#9e1eae46738bcd08e23e867bab43e7b95299a8f9" integrity sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA== -"@babel/parser@^7.11.5": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.5.tgz#c7ff6303df71080ec7a4f5b8c003c58f1cf51037" - integrity sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q== - "@babel/plugin-proposal-async-generator-functions@^7.10.4": version "7.10.5" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz#3491cabf2f7c179ab820606cec27fed15e0e8558" @@ -1067,7 +1083,7 @@ globals "^11.1.0" lodash "^4.17.19" -"@babel/traverse@^7.11.5": +"@babel/traverse@^7.11.5", "@babel/traverse@^7.9.0": version "7.11.5" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.5.tgz#be777b93b518eb6d76ee2e1ea1d143daa11e61c3" integrity sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ== @@ -1082,7 +1098,7 @@ globals "^11.1.0" lodash "^4.17.19" -"@babel/types@7.11.5", "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.11.5", "@babel/types@^7.4.4", "@babel/types@^7.7.4", "@babel/types@^7.9.5": +"@babel/types@7.11.5", "@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.11.5", "@babel/types@^7.3.0", "@babel/types@^7.4.4", "@babel/types@^7.7.4", "@babel/types@^7.9.0", "@babel/types@^7.9.5": version "7.11.5" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d" integrity sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q== @@ -1334,6 +1350,60 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@formatjs/ecma402-abstract@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.2.1.tgz#ad966998d7f0e96fca4bdc5de0ca28d02f371279" + integrity sha512-LvbwgHxprafjceDfOC7yMl4sP5al71rAWahXk3qug5bV020aCq64WjqAo+zNnkIJk8hqK2pFKnNdDsT58HZJQw== + +"@formatjs/intl-displaynames@^3.3.7": + version "3.3.7" + resolved "https://registry.yarnpkg.com/@formatjs/intl-displaynames/-/intl-displaynames-3.3.7.tgz#7d8cc73d0a67a7c51b182233121eaa2c85f9f751" + integrity sha512-sMdV3QaFy2RMOZ6YaRYInDzThEEIiD8vZjue20/CYvxgNKw3ZIZROvpEaKHvHr197Si3RFaxhAGUWk/lI7NAeA== + dependencies: + "@formatjs/ecma402-abstract" "^1.2.1" + +"@formatjs/intl-listformat@^4.2.6": + version "4.2.6" + resolved "https://registry.yarnpkg.com/@formatjs/intl-listformat/-/intl-listformat-4.2.6.tgz#31638a6cb3e33047d81161b139c1d68fb377d3c2" + integrity sha512-4JGDYVwZyEMGpwhUKXIcSXjRVuSrz5ox1rQCQVzj0CzgEoojrQoaUkcuW+Vj89JlpCtRS8NS46d3CWLUSDC+2g== + dependencies: + "@formatjs/ecma402-abstract" "^1.2.1" + +"@formatjs/intl-numberformat@^5.5.2": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@formatjs/intl-numberformat/-/intl-numberformat-5.6.1.tgz#eaa16b68be6a8c7dddbb2495a9271046c51293c5" + integrity sha512-ENtX07hT/GJD/GZIvk1jf/nYHg8Hq3twZ4fOGAZIVhwd6ZqlAm6dgqqRxpNXw3ul8UCwx9tOeptF1gT42HwjKA== + dependencies: + "@formatjs/ecma402-abstract" "^1.2.1" + +"@formatjs/intl-relativetimeformat@^7.2.6": + version "7.2.6" + resolved "https://registry.yarnpkg.com/@formatjs/intl-relativetimeformat/-/intl-relativetimeformat-7.2.6.tgz#7452e0feaa433f341b306e308166058e8126e934" + integrity sha512-SHwrzk9HuAUwl3/qfupU3ZnW4ZgVOpI2+3gwGmvoPOmAlKFlo7liSCszA5hcRpsnhjS66BqUzfx6BWOwzYvmKQ== + dependencies: + "@formatjs/ecma402-abstract" "^1.2.1" + +"@formatjs/intl@^1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@formatjs/intl/-/intl-1.3.1.tgz#8604b1bcef60572a2ecd22db91c0599760ceebf6" + integrity sha512-W1m8vLAQHjrox3ZrJRD6ArMp2AOvUCBeeID7NNhcezZ2fWXtzIKi8k9jeptkO54HZbueLcpshWb2gbUSR5Xy0Q== + dependencies: + "@formatjs/ecma402-abstract" "^1.2.1" + "@formatjs/intl-displaynames" "^3.3.7" + "@formatjs/intl-listformat" "^4.2.6" + "@formatjs/intl-relativetimeformat" "^7.2.6" + fast-memoize "^2.5.2" + intl-messageformat "^9.3.7" + intl-messageformat-parser "^6.0.6" + +"@formatjs/ts-transformer@^2.10.0", "@formatjs/ts-transformer@^2.6.0": + version "2.10.0" + resolved "https://registry.yarnpkg.com/@formatjs/ts-transformer/-/ts-transformer-2.10.0.tgz#06f292b6cbcea661e2cecf7b8945ac59f21b7c93" + integrity sha512-ff+gIzsbd5WEm6mLn1x0A1gD4oJomst8pF7NEjrI0Egn+82v8PEEZeYrsGjUzRt3jyOaRguQUYJGHiw+5d84dQ== + dependencies: + intl-messageformat-parser "^6.0.6" + typescript "^4.0" + "@fullhuman/postcss-purgecss@^2.1.2": version "2.3.0" resolved "https://registry.yarnpkg.com/@fullhuman/postcss-purgecss/-/postcss-purgecss-2.3.0.tgz#50a954757ec78696615d3e118e3fee2d9291882e" @@ -1528,6 +1598,39 @@ hex-rgb "^4.1.0" postcss-selector-parser "^6.0.2" +"@types/babel__core@^7.1.7": + version "7.1.9" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.9.tgz#77e59d438522a6fb898fa43dc3455c6e72f3963d" + integrity sha512-sY2RsIJ5rpER1u3/aQ8OFSI7qGIy8o1NEEbgb2UaJcvOtXOMpd39ko723NBpjQFg9SIX7TXtjejZVGeIMLhoOw== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.1" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.1.tgz#4901767b397e8711aeb99df8d396d7ba7b7f0e04" + integrity sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.0.2.tgz#4ff63d6b52eddac1de7b975a5223ed32ecea9307" + integrity sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*": + version "7.0.14" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.0.14.tgz#e99da8c075d4fb098c774ba65dabf7dc9954bd13" + integrity sha512-8w9szzKs14ZtBVuP6Wn7nMLRJ0D6dfB0VEBEyRgxrZ/Ln49aNMykrghM2FaNn4FJRzNppCSa0Rv9pBRM5Xc3wg== + dependencies: + "@babel/types" "^7.3.0" + "@types/body-parser@*", "@types/body-parser@^1.19.0": version "1.19.0" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f" @@ -1560,11 +1663,29 @@ resolved "https://registry.yarnpkg.com/@types/debug/-/debug-0.0.31.tgz#bac8d8aab6a823e91deb7f79083b2a35fa638f33" integrity sha512-LS1MCPaQKqspg7FvexuhmDbWUhE2yIJ+4AgVIyObfc06/UKZ8REgxGNjZc82wPLWmbeOm7S+gSsLgo75TanG4A== +"@types/emoji-regex@^8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@types/emoji-regex/-/emoji-regex-8.0.0.tgz#df215c9ff818e071087fb8e7e6e74c4cb42a1303" + integrity sha512-iacbaYN9IWWrGWTwlYLVOeUtN/e4cjN9Uh6v7Yo1Qa/vJzeSQeh10L/erBBSl53BTmbnQ07vsWp8mmNHGI4WbQ== + "@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" integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== +"@types/eslint@^7.2.0": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.2.2.tgz#c88426b896efeb0b2732a92431ce8aa7ec0dee61" + integrity sha512-psWuwNXuKR2e6vMU5d2qH0Kqzrb2Zxwk+uBCF2LsyEph+Nex3lFIPMJXwxfGesdtJM2qtjKoCYsyh76K3x9wLg== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*", "@types/estree@^0.0.45": + version "0.0.45" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.45.tgz#e9387572998e5ecdac221950dab3e8c3b16af884" + integrity sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g== + "@types/express-serve-static-core@*": version "4.17.9" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.9.tgz#2d7b34dcfd25ec663c25c85d76608f8b249667f1" @@ -1592,6 +1713,26 @@ "@types/qs" "*" "@types/serve-static" "*" +"@types/fs-extra@^9.0.1": + version "9.0.1" + resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-9.0.1.tgz#91c8fc4c51f6d5dbe44c2ca9ab09310bd00c7918" + integrity sha512-B42Sxuaz09MhC3DDeW5kubRcQ5by4iuVQ0cRRWM2lggLzAa/KVom0Aft/208NgMvNQQZ86s5rVcqDdn/SH0/mg== + dependencies: + "@types/node" "*" + +"@types/hoist-non-react-statics@^3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" + integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== + dependencies: + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + +"@types/json-schema@*", "@types/json-schema@^7.0.5": + version "7.0.6" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" + integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== + "@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4": version "7.0.5" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd" @@ -1676,6 +1817,13 @@ "@types/prop-types" "*" csstype "^3.0.2" +"@types/schema-utils@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@types/schema-utils/-/schema-utils-2.4.0.tgz#9983012045d541dcee053e685a27c9c87c840fcd" + integrity sha512-454hrj5gz/FXcUE20ygfEiN4DxZ1sprUo0V1gqIqkNZ/CzoEzAZEll2uxMsuyz6BYjiQan4Aa65xbTemfzW9hQ== + dependencies: + schema-utils "*" + "@types/serve-static@*": version "1.13.5" resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.5.tgz#3d25d941a18415d3ab092def846e135a08bbcf53" @@ -1762,7 +1910,7 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.0.0.tgz#ec1f9fc06b8558a1d5afa6e337182d08beece7f5" integrity sha512-bK+c2VLzznX2fUWLK6pFDv3cXGTp7nHIuBMq1B9klA+QCsqLHOOqe5TQReAQDl7DN2RfH+neweo0oC5hYlG7Rg== -"@typescript-eslint/typescript-estree@3.10.1": +"@typescript-eslint/typescript-estree@3.10.1", "@typescript-eslint/typescript-estree@^3.6.0": version "3.10.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.10.1.tgz#fd0061cc38add4fad45136d654408569f365b853" integrity sha512-QbcXOuq6WYvnB3XPsZpIwztBoquEYLXh2MtwVU+kO8jgYCiv4G5xrSP/1wg4tkvrEE+esZVquIPX/dxPlePk1w== @@ -2048,7 +2196,7 @@ ajv-errors@^1.0.0: resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== -ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: +ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== @@ -2339,6 +2487,11 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + atob@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" @@ -2416,6 +2569,46 @@ babel-plugin-macros@^2.0.0: cosmiconfig "^6.0.0" resolve "^1.12.0" +babel-plugin-react-intl-auto@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/babel-plugin-react-intl-auto/-/babel-plugin-react-intl-auto-3.3.0.tgz#75c6ba8a1eb442f43c2ab85f1a75f4cc1e0d7857" + integrity sha512-08ZyGWtKrQY/rMNfdvrWPBsjqx+8CirqV4/JUM46FAS2aU98Mi/uWM60K6Wg6Zapdyqs3fCbQ8S4OfqMPsBiqQ== + dependencies: + "@babel/core" "^7.9.0" + "@babel/traverse" "^7.9.0" + "@babel/types" "^7.9.0" + murmurhash3js "^3.0.1" + +babel-plugin-react-intl@^7.0.0: + version "7.9.4" + resolved "https://registry.yarnpkg.com/babel-plugin-react-intl/-/babel-plugin-react-intl-7.9.4.tgz#1fc9ab50470d41b934df50d8f436578ee1732cb0" + integrity sha512-cMKrHEXrw43yT4M89Wbgq8A8N8lffSquj1Piwov/HVukR7jwOw8gf9btXNsQhT27ccyqEwy+M286JQYy0jby2g== + dependencies: + "@babel/core" "^7.9.0" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/types" "^7.9.5" + "@formatjs/ts-transformer" "^2.6.0" + "@types/babel__core" "^7.1.7" + "@types/fs-extra" "^9.0.1" + "@types/schema-utils" "^2.4.0" + fs-extra "^9.0.0" + intl-messageformat-parser "^5.3.7" + schema-utils "^2.6.6" + +babel-plugin-react-intl@^8.2.2: + version "8.2.2" + resolved "https://registry.yarnpkg.com/babel-plugin-react-intl/-/babel-plugin-react-intl-8.2.2.tgz#fcaab15a4f481f64405795a915cce7fab520dc6d" + integrity sha512-lFq03ZdEX8ggSCKAxVCJKwFE+m9VhpGEK/Q0P7lAPfdYUTNlT5abirDOV3kolrZ9keqlYY00B+4hPUQoHpPVrw== + dependencies: + "@babel/core" "^7.9.0" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/types" "^7.9.5" + "@formatjs/ts-transformer" "^2.10.0" + "@types/babel__core" "^7.1.7" + "@types/schema-utils" "^2.4.0" + intl-messageformat-parser "^6.0.6" + schema-utils "^2.6.6" + babel-plugin-syntax-jsx@6.18.0, babel-plugin-syntax-jsx@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" @@ -3133,6 +3326,11 @@ commander@^2.20.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== +commander@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + commander@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" @@ -3300,7 +3498,7 @@ conventional-commits-parser@^3.0.0: through2 "^3.0.0" trim-off-newlines "^1.0.0" -convert-source-map@1.7.0, convert-source-map@^1.5.0, convert-source-map@^1.7.0: +convert-source-map@1.7.0, convert-source-map@^1.1.0, convert-source-map@^1.5.0, convert-source-map@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== @@ -3330,6 +3528,11 @@ cookie@0.4.0: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== +cookie@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" + integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== + copy-concurrently@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" @@ -3832,7 +4035,7 @@ detect-file@^1.0.0: resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= -detect-indent@6.0.0: +detect-indent@6.0.0, detect-indent@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.0.0.tgz#0abd0f549f69fc6659a254fe96786186b6f528fd" integrity sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA== @@ -4174,6 +4377,19 @@ eslint-config-prettier@^6.11.0: dependencies: get-stdin "^6.0.0" +eslint-plugin-formatjs@^2.7.10: + version "2.7.10" + resolved "https://registry.yarnpkg.com/eslint-plugin-formatjs/-/eslint-plugin-formatjs-2.7.10.tgz#436bfe8283d5108c3e93617c8bea929cbbc8e35b" + integrity sha512-rqhw+AgicCWDD38jluqwLKqAEuVEBI3/XcUu/AWoWrhsyg692KmBdNl0hiKaN9bv+U837q0PYXcdcFwv5TuBeQ== + dependencies: + "@formatjs/ts-transformer" "^2.10.0" + "@types/emoji-regex" "^8.0.0" + "@types/eslint" "^7.2.0" + "@types/estree" "^0.0.45" + "@typescript-eslint/typescript-estree" "^3.6.0" + emoji-regex "^9.0.0" + intl-messageformat-parser "^6.0.6" + eslint-plugin-jsx-a11y@^6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.3.1.tgz#99ef7e97f567cc6a5b8dd5ab95a94a67058a2660" @@ -4516,6 +4732,27 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" +extract-react-intl-messages@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/extract-react-intl-messages/-/extract-react-intl-messages-4.1.1.tgz#cd01d99053bb053ecc8410ccdccb9ac56daae91c" + integrity sha512-dPogci5X7HVtV7VbUxajH/1YgfNRaW2VtEiVidZ/31Tq8314uzOtzVMNo0IrAPD2E+H1wHoPiu/j565TZsyIZg== + dependencies: + "@babel/core" "^7.9.0" + babel-plugin-react-intl "^7.0.0" + flat "^5.0.0" + glob "^7.1.6" + js-yaml "^3.13.1" + load-json-file "^6.2.0" + lodash.merge "^4.6.2" + lodash.mergewith "^4.6.2" + lodash.pick "^4.4.0" + meow "^6.1.0" + mkdirp "^1.0.3" + pify "^5.0.0" + read-babelrc-up "^1.1.0" + sort-keys "^4.0.0" + write-json-file "^4.3.0" + extsprintf@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" @@ -4563,6 +4800,11 @@ fast-levenshtein@^2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +fast-memoize@^2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/fast-memoize/-/fast-memoize-2.5.2.tgz#79e3bb6a4ec867ea40ba0e7146816f6cdce9b57e" + integrity sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw== + fastq@^1.6.0: version "1.8.0" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.8.0.tgz#550e1f9f59bbc65fe185cb6a9b4d95357107f481" @@ -4708,6 +4950,11 @@ flat-cache@^2.0.1: rimraf "2.6.3" write "1.0.3" +flat@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + flatted@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" @@ -4796,6 +5043,16 @@ fs-extra@8.1.0, fs-extra@^8.0.0, fs-extra@^8.1.0: jsonfile "^4.0.0" universalify "^0.1.0" +fs-extra@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc" + integrity sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^1.0.0" + fs-minipass@^1.2.5: version "1.2.7" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" @@ -4810,6 +5067,11 @@ fs-minipass@^2.0.0: dependencies: minipass "^3.0.0" +fs-readdir-recursive@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" + integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA== + fs-write-stream-atomic@^1.0.8: version "1.0.10" resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" @@ -5187,6 +5449,13 @@ hmac-drbg@^1.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" +hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + homedir-polyfill@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" @@ -5419,6 +5688,33 @@ internal-slot@^1.0.2: has "^1.0.3" side-channel "^1.0.2" +intl-messageformat-parser@^5.3.7: + version "5.5.1" + resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-5.5.1.tgz#f09a692755813e6220081e3374df3fb1698bd0c6" + integrity sha512-TvB3LqF2VtP6yI6HXlRT5TxX98HKha6hCcrg9dwlPwNaedVNuQA9KgBdtWKgiyakyCTYHQ+KJeFEstNKfZr64w== + dependencies: + "@formatjs/intl-numberformat" "^5.5.2" + +intl-messageformat-parser@^6.0.6: + version "6.0.6" + resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-6.0.6.tgz#c06c79c534612808e1f3c39288a3c009fb1ff7cd" + integrity sha512-XPAgYvCTSwgr92zzy5sfaglUu4uKjIWXHNTenEQRTo5t3o2TGxuPYPruxZqnvSLgnlAegiT/hBemmPcnFPNjAg== + dependencies: + "@formatjs/ecma402-abstract" "^1.2.1" + +intl-messageformat@^9.3.7: + version "9.3.7" + resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-9.3.7.tgz#d40e61dc20ded8952fef00d97237880ff380550a" + integrity sha512-DUc+BJ6QN/IyT05gyKTuSJuauuYheV/5IhP+KEwmLhaJzONu0U/nnL5P6L5Ck9DXAx8iy7HM0CwFUctD7CmqZw== + dependencies: + fast-memoize "^2.5.2" + intl-messageformat-parser "^6.0.6" + +intl@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/intl/-/intl-1.2.5.tgz#82244a2190c4e419f8371f5aa34daa3420e2abde" + integrity sha1-giRKIZDE5Bn4Nx9ao02qNCDiq94= + invariant@^2.2.2, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" @@ -5616,6 +5912,11 @@ is-plain-obj@^1.1.0: resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= +is-plain-obj@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -5810,6 +6111,15 @@ jsonfile@^4.0.0: optionalDependencies: graceful-fs "^4.1.6" +jsonfile@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.0.1.tgz#98966cba214378c8c84b82e085907b40bf614179" + integrity sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg== + dependencies: + universalify "^1.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + jsonparse@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" @@ -5960,6 +6270,16 @@ listr2@^2.6.0: rxjs "^6.6.2" through "^2.3.8" +load-json-file@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-6.2.0.tgz#5c7770b42cafa97074ca2848707c61662f4251a1" + integrity sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ== + dependencies: + graceful-fs "^4.1.15" + parse-json "^5.0.0" + strip-bom "^4.0.0" + type-fest "^0.6.0" + loader-runner@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" @@ -6022,6 +6342,16 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash.mergewith@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55" + integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ== + +lodash.pick@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" + integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM= + lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" @@ -6115,7 +6445,7 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" -make-dir@^2.0.0: +make-dir@^2.0.0, make-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== @@ -6202,6 +6532,23 @@ memory-fs@^0.5.0: errno "^0.1.3" readable-stream "^2.0.1" +meow@^6.1.0: + version "6.1.1" + resolved "https://registry.yarnpkg.com/meow/-/meow-6.1.1.tgz#1ad64c4b76b2a24dfb2f635fddcadf320d251467" + integrity sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg== + dependencies: + "@types/minimist" "^1.2.0" + camelcase-keys "^6.2.2" + decamelize-keys "^1.1.0" + hard-rejection "^2.1.0" + minimist-options "^4.0.2" + normalize-package-data "^2.5.0" + read-pkg-up "^7.0.1" + redent "^3.0.0" + trim-newlines "^3.0.0" + type-fest "^0.13.1" + yargs-parser "^18.1.3" + meow@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/meow/-/meow-7.1.0.tgz#50ecbcdafa16f8b58fb7eb9675b933f6473b3a59" @@ -6347,7 +6694,7 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" -minimist-options@4.1.0: +minimist-options@4.1.0, minimist-options@^4.0.2: version "4.1.0" resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619" integrity sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A== @@ -6496,6 +6843,11 @@ multer@^1.4.2: type-is "^1.6.4" xtend "^4.0.0" +murmurhash3js@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/murmurhash3js/-/murmurhash3js-3.0.1.tgz#3e983e5b47c2a06f43a713174e7e435ca044b998" + integrity sha1-Ppg+W0fCoG9DpxMXTn5DXKBEuZg= + mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" @@ -6751,6 +7103,14 @@ nodemon@^2.0.4: undefsafe "^2.0.2" update-notifier "^4.0.0" +nookies@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/nookies/-/nookies-2.4.0.tgz#1bd4eb244f54d6e622e8ff1c7aeca692892d292d" + integrity sha512-QC1+Ih9/BedZOIUVXneHBQgp8n9NzvsqyfmzAoUTrwOdwJOjB+phWzeLXuLqcxgxztTq3t3PeHtuosFKclL+Hw== + dependencies: + cookie "^0.4.0" + set-cookie-parser "^2.4.3" + "nopt@2 || 3": version "3.0.6" resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" @@ -7260,6 +7620,11 @@ pify@^4.0.1: resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== +pify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-5.0.0.tgz#1f5eca3f5e87ebec28cc6d54a0e4aaf00acc127f" + integrity sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA== + pkg-dir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" @@ -7928,7 +8293,24 @@ react-dom@16.13.1: prop-types "^15.6.2" scheduler "^0.19.1" -react-is@16.13.1, react-is@^16.8.1: +react-intl@^5.8.1: + version "5.8.1" + resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-5.8.1.tgz#2974499d438bcde58437100b0c19043ca0ffcc3b" + integrity sha512-NGwtadXCoPUYHqQFNYR0Rbwv08QkCLECeBPUUFndhJIudvgmVqNrX3x6A3LMEYY76vLOovmoy+xiTAx7yWGkBg== + dependencies: + "@formatjs/ecma402-abstract" "^1.2.1" + "@formatjs/intl" "^1.3.1" + "@formatjs/intl-displaynames" "^3.3.7" + "@formatjs/intl-listformat" "^4.2.6" + "@formatjs/intl-relativetimeformat" "^7.2.6" + "@types/hoist-non-react-statics" "^3.3.1" + fast-memoize "^2.5.2" + hoist-non-react-statics "^3.3.2" + intl-messageformat "^9.3.7" + intl-messageformat-parser "^6.0.6" + shallow-equal "^1.2.1" + +react-is@16.13.1, react-is@^16.7.0, react-is@^16.8.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -7973,6 +8355,14 @@ react@16.13.1: object-assign "^4.1.1" prop-types "^15.6.2" +read-babelrc-up@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-babelrc-up/-/read-babelrc-up-1.1.0.tgz#10fd5baaf6ca03eaba6748fa65ddae25bca61e70" + integrity sha512-fcl0JeI85Ss3//kfC3z2rsG2VxSiHl1bJgpjQWrne2YuQEewZpAgAjb17A6q/Q3ozWeZsUSroiIBVsnjmOU8vw== + dependencies: + find-up "^4.1.0" + json5 "^2.1.2" + read-pkg-up@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" @@ -8396,6 +8786,15 @@ scheduler@^0.19.1: loose-envify "^1.1.0" object-assign "^4.1.1" +schema-utils@*: + version "2.7.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" + integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== + dependencies: + "@types/json-schema" "^7.0.5" + ajv "^6.12.4" + ajv-keywords "^3.5.2" + schema-utils@2.6.6: version "2.6.6" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.6.tgz#299fe6bd4a3365dc23d99fd446caff8f1d6c330c" @@ -8505,6 +8904,11 @@ set-blocking@^2.0.0, set-blocking@~2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= +set-cookie-parser@^2.4.3: + version "2.4.6" + resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-2.4.6.tgz#43bdea028b9e6f176474ee5298e758b4a44799c3" + integrity sha512-mNCnTUF0OYPwYzSHbdRdCfNNHqrne+HS5tS5xNb6yJbdP9wInV0q5xPLE0EyfV/Q3tImo3y/OXpD8Jn0Jtnjrg== + set-value@^2.0.0, set-value@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" @@ -8550,6 +8954,11 @@ shallow-clone@^3.0.0: dependencies: kind-of "^6.0.2" +shallow-equal@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-1.2.1.tgz#4c16abfa56043aa20d050324efa68940b0da79da" + integrity sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA== + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -8587,6 +8996,11 @@ simple-swizzle@^0.2.2: dependencies: is-arrayish "^0.3.1" +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -8649,6 +9063,13 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^3.1.0" +sort-keys@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-4.0.0.tgz#56dc5e256637bfe3fec8db0dc57c08b1a2be22d6" + integrity sha512-hlJLzrn/VN49uyNkZ8+9b+0q9DjmmYcYOnbMQtpkLrYpPwRApDPZfmqbUfJnAA3sb/nRib+nDot7Zi/1ER1fuA== + dependencies: + is-plain-obj "^2.0.0" + source-list-map@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" @@ -8984,7 +9405,7 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" -strip-bom@4.0.0: +strip-bom@4.0.0, strip-bom@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== @@ -9487,7 +9908,7 @@ typeorm@^0.2.26: yargonaut "^1.1.2" yargs "^13.2.1" -typescript@^4.0.2: +typescript@^4.0, typescript@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.2.tgz#7ea7c88777c723c681e33bf7988be5d008d05ac2" integrity sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ== @@ -9570,6 +9991,11 @@ universalify@^0.1.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== +universalify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d" + integrity sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug== + unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" @@ -9887,6 +10313,18 @@ write-file-atomic@^3.0.0: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" +write-json-file@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-4.3.0.tgz#908493d6fd23225344af324016e4ca8f702dd12d" + integrity sha512-PxiShnxf0IlnQuMYOPPhPkhExoCQuTUNPOa/2JWCYTmBquU9njyyDuwRKN26IZBlp4yn1nt+Agh2HOOBl+55HQ== + dependencies: + detect-indent "^6.0.0" + graceful-fs "^4.1.15" + is-plain-obj "^2.0.0" + make-dir "^3.0.0" + sort-keys "^4.0.0" + write-file-atomic "^3.0.0" + write@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3"