From ae3a078a2bdeb1016e4acb355de5cdef636eb74b Mon Sep 17 00:00:00 2001 From: Orka Arnest CRUZE <33525693+ocruze@users.noreply.github.com> Date: Fri, 20 Oct 2023 17:03:06 +0200 Subject: [PATCH] feat: mise en place i18n avec i18nifty et traductions page Contact (#117, #135) --- assets/i18n/index.ts | 26 ++++++ assets/i18n/languages/en.tsx | 7 ++ assets/i18n/languages/fr.tsx | 7 ++ assets/pages/contact/Contact.tsx | 127 ++++++++++++++++++++++----- package.json | 1 + yarn.lock | 146 +++++++++++++++++++++++++++++++ 6 files changed, 290 insertions(+), 24 deletions(-) create mode 100644 assets/i18n/index.ts create mode 100644 assets/i18n/languages/en.tsx create mode 100644 assets/i18n/languages/fr.tsx diff --git a/assets/i18n/index.ts b/assets/i18n/index.ts new file mode 100644 index 00000000..f187bf11 --- /dev/null +++ b/assets/i18n/index.ts @@ -0,0 +1,26 @@ +import { createI18nApi, declareComponentKeys, type GenericTranslations } from "i18nifty"; + +// déclaration des langues +/** liste des langues supportées */ +export const languages = ["fr", "en"] as const; + +/** langue de fallback */ +export const fallbackLanguage = "fr"; + +// types +export type Language = (typeof languages)[number]; +export type ComponentKey = typeof import("../pages/contact/Contact").i18n; +export type Translations = GenericTranslations; +export type LocalizedString = Parameters[0]; + +/** initialisation de l'instance de i18n */ +export const { useTranslation, getTranslation, resolveLocalizedString, useLang, $lang, useResolveLocalizedString, useIsI18nFetching } = + createI18nApi()( + { languages, fallbackLanguage }, + { + en: () => import("./languages/en").then(({ translations }) => translations), + fr: () => import("./languages/fr").then(({ translations }) => translations), + } + ); + +export { declareComponentKeys }; diff --git a/assets/i18n/languages/en.tsx b/assets/i18n/languages/en.tsx new file mode 100644 index 00000000..cc4ca09c --- /dev/null +++ b/assets/i18n/languages/en.tsx @@ -0,0 +1,7 @@ +import type { Translations } from ".."; + +import { enTranslations as contactTranslations } from "../../pages/contact/Contact"; + +export const translations: Translations<"en"> = { + Contact: contactTranslations, +}; diff --git a/assets/i18n/languages/fr.tsx b/assets/i18n/languages/fr.tsx new file mode 100644 index 00000000..e5665e86 --- /dev/null +++ b/assets/i18n/languages/fr.tsx @@ -0,0 +1,7 @@ +import type { Translations } from ".."; + +import { frTranslations as contactTranslations } from "../../pages/contact/Contact"; + +export const translations: Translations<"fr"> = { + Contact: contactTranslations, +}; diff --git a/assets/pages/contact/Contact.tsx b/assets/pages/contact/Contact.tsx index b2914473..23e68cac 100644 --- a/assets/pages/contact/Contact.tsx +++ b/assets/pages/contact/Contact.tsx @@ -3,8 +3,9 @@ import Alert from "@codegouvfr/react-dsfr/Alert"; import Button from "@codegouvfr/react-dsfr/Button"; import Input from "@codegouvfr/react-dsfr/Input"; import Select from "@codegouvfr/react-dsfr/Select"; +import { RegisteredLinkProps } from "@codegouvfr/react-dsfr/link"; import { yupResolver } from "@hookform/resolvers/yup"; -import { useState } from "react"; +import { JSX, useState } from "react"; import { useForm } from "react-hook-form"; import * as yup from "yup"; @@ -12,8 +13,8 @@ import AppLayout from "../../components/Layout/AppLayout"; import Wait from "../../components/Utils/Wait"; import { defaultNavItems } from "../../config/navItems"; import useUser from "../../hooks/useUser"; +import { declareComponentKeys, getTranslation, useTranslation, type Translations } from "../../i18n"; import SymfonyRouting from "../../modules/Routing"; -import Translator from "../../modules/Translator"; import { jsonFetch } from "../../modules/jsonFetch"; import { routes } from "../../router/router"; import { regex } from "../../utils"; @@ -21,21 +22,20 @@ import { regex } from "../../utils"; import "../../sass/components/spinner.scss"; import "../../sass/pages/nous_ecrire.scss"; +const { t } = getTranslation("Contact"); const schema = yup .object({ - email_contact: yup - .string() - .matches(regex.email, Translator.trans("contact.form.email_contact_error")) - .required(Translator.trans("contact.form.email_contact_mandatory_error")), + email_contact: yup.string().matches(regex.email, t("form.email_contact_error")).required(t("form.email_contact_mandatory_error")), last_name: yup.string(), first_name: yup.string(), organization: yup.string(), importance: yup.number(), - message: yup.string().min(10, Translator.trans("contact.form.message_minlength_error")), + message: yup.string().min(10, t("form.message_minlength_error")), }) .required(); const Contact = () => { + const { t } = useTranslation({ Contact }); const { user } = useUser(); const [isSending, setIsSending] = useState(false); @@ -48,9 +48,6 @@ const Contact = () => { getValues: getFormValues, } = useForm({ resolver: yupResolver(schema) }); - const explanation = { __html: Translator.trans("contact.form.explain", { href: routes.docs().href }) }; - const infos = { __html: Translator.trans("contact.form.infos", { href: routes.personal_data().href }) }; - const onSubmit = () => { setError(null); setIsSending(true); @@ -72,21 +69,21 @@ const Contact = () => { }; return ( - +
-

{Translator.trans("contact.title")}

-

+

{t("title")}

+

{t("form.explanation", { docsLinkProps: routes.docs().link })}

-

{Translator.trans("mandatory_fields")}

+

{t("mandatory_fields")}

- {error && } + {error && } { }} /> { }} /> { }} /> -

+

{t("form.infos", { personalDataLinkProps: routes.personal_data().link })}

- +
{isSending && ( @@ -171,3 +168,85 @@ const Contact = () => { }; export default Contact; + +// traductions +export const { i18n } = declareComponentKeys< + | "title" + | "mandatory_fields" + | "form.error_title" + | { K: "form.explanation"; P: { docsLinkProps: RegisteredLinkProps }; R: JSX.Element } + | "form.email_contact" + | "form.email_contact_hint" + | "form.email_contact_mandatory_error" + | "form.email_contact_error" + | "form.lastName" + | "form.firstName" + | "form.organization" + | "form.message" + | "form.message_placeholder" + | "form.message_minlength_error" + | "send" + | { K: "form.infos"; P: { personalDataLinkProps: RegisteredLinkProps }; R: JSX.Element } +>()({ + Contact, +}); + +export const frTranslations: Translations<"fr">["Contact"] = { + title: "Nous écrire", + mandatory_fields: "Sauf mention contraire “(optionnel)” dans le label, tous les champs sont obligatoires.", + "form.error_title": "Votre message n'a pas pu être envoyé", + "form.explanation": ({ docsLinkProps }) => ( + <> + {"Vous n'avez pas trouvé la réponse à votre question dans "} + {"l'aide en ligne"} + {" ? Vous souhaitez la configuration d'un espace de travail pour vos besoins ? Utilisez ce formulaire pour nous contacter."} + + ), + "form.email_contact": "Votre email", + "form.email_contact_hint": "Format attendu : nom@domaine.fr", + "form.email_contact_mandatory_error": "Veuillez saisir une adresse email", + "form.email_contact_error": "Veuillez saisir une adresse email valide", + "form.lastName": "Votre nom (optionnel)", + "form.firstName": "Votre prénom (optionnel)", + "form.organization": "Votre organisme (optionnel)", + "form.message": "Votre demande", + "form.message_placeholder": "Décrivez votre demande en quelques lignes", + "form.message_minlength_error": "Veuillez saisir une demande d'au moins 10 caractères.", + send: "Envoyer", + "form.infos": ({ personalDataLinkProps }) => ( + <> + {"Les informations recueillies à partir de ce formulaire sont nécessaires à la gestion de votre demande par les services de l'IGN concernés. "} + {"En savoir plus sur la gestion des données à caractère personnel."} + + ), +}; + +export const enTranslations: Translations<"en">["Contact"] = { + title: "Contact us", + mandatory_fields: "All fields are mandatory unless label states “optional”", + "form.error_title": "Your message could not be sent", + "form.explanation": ({ docsLinkProps }) => ( + <> + {"You did not find the answer to your question in "} + {"our documentation"} + {"? Do you want to configure a workspace for your needs? Use this form to contact us."} + + ), + "form.email_contact": "Email", + "form.email_contact_hint": "Expected format: name@domain.fr", + "form.email_contact_mandatory_error": "Enter an email address", + "form.email_contact_error": "Enter a valid email address", + "form.lastName": "Last name (optional)", + "form.firstName": "First name (optional)", + "form.organization": "Organization (optional)", + "form.message": "Message", + "form.message_placeholder": "Describe your request in a few lines", + "form.message_minlength_error": "Message must be at least 10 caractères.", + send: "Send", + "form.infos": ({ personalDataLinkProps }) => ( + <> + {"The information collected from this form is necessary to process your request by the appropriate services at IGN. "} + {"Learn more about how personal data is stored and used."} + + ), +}; diff --git a/package.json b/package.json index 15da8af3..e70d09f3 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "geoportal-extensions-openlayers": "^3.3.3", "geostyler-sld-parser": "^5.1.0", "geostyler-style": "^7.3.1", + "i18nifty": "^2.1.1", "ol": "6.15.1", "postcss-loader": "^7.3.3", "prop-types": "^15.8.1", diff --git a/yarn.lock b/yarn.lock index 7a255da1..af2c1ec0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3238,6 +3238,14 @@ cypress@^13.1.0: untildify "^4.0.0" yauzl "^2.10.0" +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -3656,11 +3664,47 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: + version "0.10.62" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5" + integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA== + dependencies: + es6-iterator "^2.0.3" + es6-symbol "^3.1.3" + next-tick "^1.1.0" + +es6-iterator@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + es6-promise@^4.2.4: version "4.2.8" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== +es6-symbol@^3.1.1, es6-symbol@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + +es6-weak-map@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53" + integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA== + dependencies: + d "1" + es5-ext "^0.10.46" + es6-iterator "^2.0.3" + es6-symbol "^3.1.1" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -3862,6 +3906,14 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== +event-emitter@^0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + integrity sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA== + dependencies: + d "1" + es5-ext "~0.10.14" + eventbusjs@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/eventbusjs/-/eventbusjs-0.2.0.tgz#9ceb3d174fb1e56ebe02aee7dd5dd953bb637a93" @@ -3882,6 +3934,15 @@ events@^3.2.0: resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== +evt@^2.5.3: + version "2.5.3" + resolved "https://registry.yarnpkg.com/evt/-/evt-2.5.3.tgz#eda564afdda6dfe1da687bb54933706af3f844d6" + integrity sha512-wZKx0JgXaTOVOXI2saNVxINU6VToOHDowMwb3NRcU6l+C59eW3w9dZgNxjokiM8rvMgc7/11yFG0cSDxn4qxgA== + dependencies: + minimal-polyfills "^2.2.3" + run-exclusive "^2.2.19" + tsafe "^1.6.5" + execa@4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" @@ -3956,6 +4017,13 @@ express@^4.17.3: utils-merge "1.0.1" vary "~1.1.2" +ext@^1.1.2: + version "1.7.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" + integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw== + dependencies: + type "^2.7.2" + extend@^3.0.0, extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" @@ -4748,6 +4816,14 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== +i18nifty@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/i18nifty/-/i18nifty-2.1.1.tgz#34b96410ddebe852ac78ce56ffc65e5e818b50bd" + integrity sha512-ZEQfwYD+BvBxvvnkS5wxqYHlBCNmpYDsHyqjsuFGKDDVmBSFv7smxAaZ8qhpgZqJioV0ypn6umhd4onVYUkLxg== + dependencies: + powerhooks "^1.0.1" + tsafe "^1.6.5" + iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -5062,6 +5138,11 @@ is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" +is-promise@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" + integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== + is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" @@ -5529,6 +5610,13 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +lru-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3" + integrity sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ== + dependencies: + es5-ext "~0.10.2" + make-dir@^3.0.2, make-dir@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" @@ -5706,6 +5794,20 @@ memfs@^3.4.3: dependencies: fs-monkey "^1.0.4" +memoizee@^0.4.15: + version "0.4.15" + resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.15.tgz#e6f3d2da863f318d02225391829a6c5956555b72" + integrity sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ== + dependencies: + d "^1.0.1" + es5-ext "^0.10.53" + es6-weak-map "^2.0.3" + event-emitter "^0.3.5" + is-promise "^2.2.2" + lru-queue "^0.1.0" + next-tick "^1.1.0" + timers-ext "^0.1.7" + merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" @@ -6041,6 +6143,11 @@ mini-css-extract-plugin@^2.6.0: dependencies: schema-utils "^4.0.0" +minimal-polyfills@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/minimal-polyfills/-/minimal-polyfills-2.2.3.tgz#22af58de16807b325f29b83ca38ffb83e75ec3f4" + integrity sha512-oxdmJ9cL+xV72h0xYxp4tP2d5/fTBpP45H8DIOn9pASuF8a3IYTf+25fMGDYGiWW+MFsuog6KD6nfmhZJQ+uUw== + minimalistic-assert@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" @@ -6106,6 +6213,11 @@ neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== +next-tick@1, next-tick@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== + node-fetch@^2.6.1: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" @@ -6803,6 +6915,15 @@ postcss@^8.2.14, postcss@^8.4.21, postcss@^8.4.24: picocolors "^1.0.0" source-map-js "^1.0.2" +powerhooks@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/powerhooks/-/powerhooks-1.0.3.tgz#b5ab065d663f4ac03c9fa1638f9c0aa70ab09454" + integrity sha512-zvakanvHYkkbsnfOJmMKHV0jtCfgRF1ji37BPjX6/JA8jAiqkVm1OWlis2l+pK0mvEpOz7boZounD0/AxD5sSA== + dependencies: + evt "^2.5.3" + memoizee "^0.4.15" + tsafe "^1.6.5" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -7403,6 +7524,13 @@ rimraf@^3.0.0, rimraf@^3.0.2: dependencies: glob "^7.1.3" +run-exclusive@^2.2.19: + version "2.2.19" + resolved "https://registry.yarnpkg.com/run-exclusive/-/run-exclusive-2.2.19.tgz#37a2fb6e3671f8ae0d63521ebd1865fc796cf307" + integrity sha512-K3mdoAi7tjJ/qT7Flj90L7QyPozwUaAG+CVhkdDje4HLKXUYC3N/Jzkau3flHVDLQVhiHBtcimVodMjN9egYbA== + dependencies: + minimal-polyfills "^2.2.3" + run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -7998,6 +8126,14 @@ thunky@^1.0.2: resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== +timers-ext@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.7.tgz#6f57ad8578e07a3fb9f91d9387d65647555e25c6" + integrity sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ== + dependencies: + es5-ext "~0.10.46" + next-tick "1" + tiny-case@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/tiny-case/-/tiny-case-1.0.3.tgz#d980d66bc72b5d5a9ca86fb7c9ffdb9c898ddd03" @@ -8143,6 +8279,16 @@ type-route@^1.0.1: dependencies: history "^5.3.0" +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.7.2: + version "2.7.2" + resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0" + integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw== + typed-array-buffer@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60"