refactor(v2): format post date using Intl (#4344)

* refactor(v2): format post date using Intl

* Fix test

* Blog: add localized blog post date test

Co-authored-by: slorber <lorber.sebastien@gmail.com>
This commit is contained in:
Alexey Pyltsyn 2021-03-04 21:11:31 +03:00 committed by GitHub
parent a4b409c93b
commit 1dd400db7e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 87 additions and 214 deletions

View file

@ -45,6 +45,7 @@ declare module '@theme/BlogPostPage' {
export type Metadata = {
readonly title: string;
readonly date: string;
readonly formattedDate: string;
readonly permalink: string;
readonly description?: string;
readonly editUrl?: string;

View file

@ -7,9 +7,16 @@
import path from 'path';
import {generateBlogFeed} from '../blogUtils';
import {LoadContext} from '@docusaurus/types';
import {LoadContext, I18n} from '@docusaurus/types';
import {PluginOptions, BlogContentPaths} from '../types';
const DefaultI18N: I18n = {
currentLocale: 'en',
locales: ['en'],
defaultLocale: 'en',
localeConfigs: {},
};
function getBlogContentPaths(siteDir: string): BlogContentPaths {
return {
contentPath: path.resolve(siteDir, 'blog'),
@ -39,6 +46,7 @@ describe('blogFeed', () => {
{
siteDir,
siteConfig,
i18n: DefaultI18N,
} as LoadContext,
{
path: 'invalid-blog-path',
@ -71,6 +79,7 @@ describe('blogFeed', () => {
siteDir,
siteConfig,
generatedFilesDir,
i18n: DefaultI18N,
} as LoadContext,
{
path: 'blog',

View file

@ -13,12 +13,16 @@ import {PluginOptionSchema} from '../pluginOptionSchema';
import {PluginOptions, EditUrlFunction} from '../types';
import Joi from 'joi';
const DefaultI18N: I18n = {
currentLocale: 'en',
locales: ['en'],
defaultLocale: 'en',
function getI18n(locale: string): I18n {
return {
currentLocale: locale,
locales: [locale],
defaultLocale: locale,
localeConfigs: {},
};
}
const DefaultI18N: I18n = getI18n('en');
function validateAndNormalize(
schema: Joi.ObjectSchema,
@ -40,6 +44,7 @@ describe('loadBlog', () => {
const getBlogPosts = async (
siteDir: string,
pluginOptions: Partial<PluginOptions> = {},
i18n: I18n = DefaultI18N,
) => {
const generatedFilesDir: string = path.resolve(siteDir, '.docusaurus');
const siteConfig = {
@ -52,7 +57,7 @@ describe('loadBlog', () => {
siteDir,
siteConfig,
generatedFilesDir,
i18n: DefaultI18N,
i18n,
} as LoadContext,
validateAndNormalize(PluginOptionSchema, {
path: PluginPath,
@ -80,6 +85,7 @@ describe('loadBlog', () => {
title: 'date-matter',
description: `date inside front matter`,
date: new Date('2019-01-01'),
formattedDate: 'January 1, 2019',
prevItem: undefined,
tags: [],
nextItem: {
@ -106,6 +112,7 @@ describe('loadBlog', () => {
title: 'Happy 1st Birthday Slash! (translated)',
description: `Happy birthday! (translated)`,
date: new Date('2018-12-14'),
formattedDate: 'December 14, 2018',
tags: [],
prevItem: {
permalink: '/blog/date-matter',
@ -130,6 +137,7 @@ describe('loadBlog', () => {
title: 'Simple Slug',
},
date: new Date('2020-08-16'),
formattedDate: 'August 16, 2020',
tags: [],
truncated: false,
});
@ -150,11 +158,33 @@ describe('loadBlog', () => {
title: 'draft',
},
date: new Date('2020-08-15'),
formattedDate: 'August 15, 2020',
tags: [],
truncated: false,
});
});
test('simple website blog dates localized', async () => {
const siteDir = path.join(__dirname, '__fixtures__', 'website');
const blogPostsFrench = await getBlogPosts(siteDir, {}, getI18n('fr'));
expect(blogPostsFrench).toHaveLength(5);
expect(blogPostsFrench[0].metadata.formattedDate).toMatchInlineSnapshot(
`"16 août 2020"`,
);
expect(blogPostsFrench[1].metadata.formattedDate).toMatchInlineSnapshot(
`"15 août 2020"`,
);
expect(blogPostsFrench[2].metadata.formattedDate).toMatchInlineSnapshot(
`"27 février 2020"`,
);
expect(blogPostsFrench[3].metadata.formattedDate).toMatchInlineSnapshot(
`"1 janvier 2019"`,
);
expect(blogPostsFrench[4].metadata.formattedDate).toMatchInlineSnapshot(
`"14 décembre 2018"`,
);
});
test('edit url with editLocalizedBlogs true', async () => {
const siteDir = path.join(__dirname, '__fixtures__', 'website');
const blogPosts = await getBlogPosts(siteDir, {editLocalizedFiles: true});
@ -232,6 +262,11 @@ describe('loadBlog', () => {
const noDateSourceBirthTime = (
await fs.stat(noDateSource.replace('@site', siteDir))
).birthtime;
const formattedDate = Intl.DateTimeFormat('en', {
day: 'numeric',
month: 'long',
year: 'numeric',
}).format(noDateSourceBirthTime);
expect({
...blogPosts.find((v) => v.metadata.title === 'no date')!.metadata,
@ -244,6 +279,7 @@ describe('loadBlog', () => {
title: 'no date',
description: `no date`,
date: noDateSourceBirthTime,
formattedDate,
tags: [],
prevItem: undefined,
nextItem: undefined,

View file

@ -27,6 +27,7 @@ import {
getEditUrl,
getFolderContainingFile,
posixPath,
getDateTimeFormat,
} from '@docusaurus/utils';
import {LoadContext} from '@docusaurus/types';
import {keyBy} from 'lodash';
@ -168,6 +169,14 @@ export async function generateBlogPosts(
// Use file create time for blog.
date = date || (await fs.stat(source)).birthtime;
const formattedDate = getDateTimeFormat(i18n.currentLocale)(
i18n.currentLocale,
{
day: 'numeric',
month: 'long',
year: 'numeric',
},
).format(date);
const slug =
frontMatter.slug || (match ? toUrl({date, link: linkName}) : linkName);
@ -214,6 +223,7 @@ export async function generateBlogPosts(
source: aliasedSource,
description: frontMatter.description || excerpt,
date,
formattedDate,
tags: frontMatter.tags,
title: frontMatter.title,
readingTime: showReadingTime

View file

@ -106,6 +106,7 @@ export interface MetaData {
source: string;
description: string;
date: Date;
formattedDate: string;
tags: (Tag | string)[];
title: string;
readingTime?: number;

View file

@ -22,7 +22,6 @@
"theme.blog.paginator.navAriaLabel": "التنقل في صفحة قائمة المدونة",
"theme.blog.paginator.newerEntries": "إدخالات أحدث",
"theme.blog.paginator.olderEntries": "إدخالات أقدم",
"theme.blog.post.date": "{day} {month} {year}",
"theme.blog.post.nPosts": "{count} مقالات",
"theme.blog.post.onePost": "مقاله واحده",
"theme.blog.post.paginator.navAriaLabel": "التنقل في صفحة مقالات المدونة",
@ -33,18 +32,6 @@
"theme.blog.tagTitle": "{nPosts} موسومة ب \"{tagName}\"",
"theme.common.editThisPage": "تعديل هذه الصفحة",
"theme.common.headingLinkTitle": "ارتباط مباشر بالعنوان",
"theme.common.month.april": "أبريل",
"theme.common.month.august": "أغسطس",
"theme.common.month.december": "ديسمبر",
"theme.common.month.february": "فبراير",
"theme.common.month.january": "يناير",
"theme.common.month.july": "يوليو",
"theme.common.month.june": "يونيو",
"theme.common.month.march": "مارس",
"theme.common.month.may": "مايو",
"theme.common.month.november": "نوفمبر",
"theme.common.month.october": "اكتوبر",
"theme.common.month.september": "سبتمبر",
"theme.common.skipToMainContent": "انتقل إلى المحتوى الرئيسي",
"theme.docs.paginator.navAriaLabel": "التنقل بين صفحات المستندات",
"theme.docs.paginator.next": "التالى",
@ -66,4 +53,3 @@
"theme.tags.tagsPageLink": "عرض كل الوسوم",
"theme.tags.tagsPageTitle": "الوسوم"
}

View file

@ -47,8 +47,6 @@
"theme.blog.paginator.newerEntries___DESCRIPTION": "The label used to navigate to the newer blog posts page (previous page)",
"theme.blog.paginator.olderEntries": "Older Entries",
"theme.blog.paginator.olderEntries___DESCRIPTION": "The label used to navigate to the older blog posts page (next page)",
"theme.blog.post.date": "{month} {day}, {year}",
"theme.blog.post.date___DESCRIPTION": "The label to display the blog post date",
"theme.blog.post.paginator.navAriaLabel": "Blog post page navigation",
"theme.blog.post.paginator.navAriaLabel___DESCRIPTION": "The ARIA label for the blog posts pagination",
"theme.blog.post.paginator.newerPost": "Newer Post",
@ -67,30 +65,6 @@
"theme.common.editThisPage___DESCRIPTION": "The link label to edit the current page",
"theme.common.headingLinkTitle": "Direct link to heading",
"theme.common.headingLinkTitle___DESCRIPTION": "Title for link to heading",
"theme.common.month.april": "April",
"theme.common.month.april___DESCRIPTION": "April month translation",
"theme.common.month.august": "August",
"theme.common.month.august___DESCRIPTION": "August month translation",
"theme.common.month.december": "December",
"theme.common.month.december___DESCRIPTION": "December month translation",
"theme.common.month.february": "February",
"theme.common.month.february___DESCRIPTION": "February month translation",
"theme.common.month.january": "January",
"theme.common.month.january___DESCRIPTION": "January month translation",
"theme.common.month.july": "July",
"theme.common.month.july___DESCRIPTION": "July month translation",
"theme.common.month.june": "June",
"theme.common.month.june___DESCRIPTION": "June month translation",
"theme.common.month.march": "March",
"theme.common.month.march___DESCRIPTION": "March month translation",
"theme.common.month.may": "May",
"theme.common.month.may___DESCRIPTION": "May month translation",
"theme.common.month.november": "November",
"theme.common.month.november___DESCRIPTION": "November month translation",
"theme.common.month.october": "October",
"theme.common.month.october___DESCRIPTION": "October month translation",
"theme.common.month.september": "September",
"theme.common.month.september___DESCRIPTION": "September month translation",
"theme.common.skipToMainContent": "Skip to main content",
"theme.common.skipToMainContent___DESCRIPTION": "The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",
"theme.docs.paginator.navAriaLabel": "Docs pages navigation",

View file

@ -23,7 +23,6 @@
"theme.blog.paginator.navAriaLabel": "Navigation der Blog-Listenseite",
"theme.blog.paginator.newerEntries": "Neuere Einträge",
"theme.blog.paginator.olderEntries": "Ältere Einträge",
"theme.blog.post.date": "{month} {day}, {year}",
"theme.blog.post.paginator.navAriaLabel": "Blog Post Seiten Navigation",
"theme.blog.post.paginator.newerPost": "Neuer Post",
"theme.blog.post.paginator.olderPost": "Älterer Post",
@ -33,18 +32,6 @@
"theme.blog.tagTitle": "{nPosts} tagged with \"{tagName}\"",
"theme.common.editThisPage": "Diese Seite bearbeiten",
"theme.common.headingLinkTitle": "Direkter Link zur Überschrift",
"theme.common.month.april": "April",
"theme.common.month.august": "August",
"theme.common.month.december": "December",
"theme.common.month.february": "February",
"theme.common.month.january": "January",
"theme.common.month.july": "July",
"theme.common.month.june": "June",
"theme.common.month.march": "March",
"theme.common.month.may": "May",
"theme.common.month.november": "November",
"theme.common.month.october": "October",
"theme.common.month.september": "September",
"theme.common.skipToMainContent": "Zum Hauptinhalt springen",
"theme.docs.paginator.navAriaLabel": "Dokumentation Seiten Navigation",
"theme.docs.paginator.next": "Weiter",

View file

@ -23,7 +23,6 @@
"theme.blog.paginator.navAriaLabel": "کنترل لیست صفحه وبسایت",
"theme.blog.paginator.newerEntries": "مطالب جدیدتر",
"theme.blog.paginator.olderEntries": "مطالب قدیمی تر",
"theme.blog.post.date": "{month} {day}, {year}",
"theme.blog.post.paginator.navAriaLabel": "کنترل پست های صفحه وبلاگ",
"theme.blog.post.paginator.newerPost": "پست های جدید تر",
"theme.blog.post.paginator.olderPost": "پست های قدیمی تر",
@ -33,18 +32,6 @@
"theme.blog.tagTitle": "{nPosts} با برچسب \"{tagName}\"",
"theme.common.editThisPage": "ویرایش صفحه",
"theme.common.headingLinkTitle": "لینک مستقیم به عنوان",
"theme.common.month.april": "آوریل",
"theme.common.month.august": "آگوست",
"theme.common.month.december": "دسامبر",
"theme.common.month.february": "فوریه",
"theme.common.month.january": "ژانویه",
"theme.common.month.july": "ژوئیه",
"theme.common.month.june": "جوئن",
"theme.common.month.march": "مارس",
"theme.common.month.may": "مه",
"theme.common.month.november": "نوامبر",
"theme.common.month.october": "اکتبر",
"theme.common.month.september": "سپتامبر",
"theme.common.skipToMainContent": "رفتن به مطلب اصلی",
"theme.docs.paginator.navAriaLabel": "کنترل صفحه اسناد",
"theme.docs.paginator.next": "بعدی",

View file

@ -23,7 +23,6 @@
"theme.blog.paginator.navAriaLabel": "Pagination de la liste des posts du blog",
"theme.blog.paginator.newerEntries": "Nouvelles entrées",
"theme.blog.paginator.olderEntries": "Anciennes entrées",
"theme.blog.post.date": "{day} {month} {year}",
"theme.blog.post.paginator.navAriaLabel": "Pagination des blog posts",
"theme.blog.post.paginator.newerPost": "Article plus récent",
"theme.blog.post.paginator.olderPost": "Article plus ancien",
@ -33,18 +32,6 @@
"theme.blog.tagTitle": "{nPosts} taggés avec \"{tagName}\"",
"theme.common.editThisPage": "Éditer cette page",
"theme.common.headingLinkTitle": "Lien direct vers le titre",
"theme.common.month.april": "Avril",
"theme.common.month.august": "Août",
"theme.common.month.december": "Décembre",
"theme.common.month.february": "Février",
"theme.common.month.january": "Janvier",
"theme.common.month.july": "Juillet",
"theme.common.month.june": "Juin",
"theme.common.month.march": "Mars",
"theme.common.month.may": "Mai",
"theme.common.month.november": "Novembre",
"theme.common.month.october": "Octobre",
"theme.common.month.september": "Septembre",
"theme.common.skipToMainContent": "Aller au contenu principal",
"theme.docs.paginator.navAriaLabel": "Pagination des documents",
"theme.docs.paginator.next": "Suivant",

View file

@ -23,7 +23,6 @@
"theme.blog.paginator.navAriaLabel": "ブログ記事一覧のナビゲーション",
"theme.blog.paginator.newerEntries": "新しい記事",
"theme.blog.paginator.olderEntries": "過去の記事",
"theme.blog.post.date": "{year}年{month}{day}日",
"theme.blog.post.paginator.navAriaLabel": "ブログ記事のナビゲーション",
"theme.blog.post.paginator.newerPost": "新しい記事",
"theme.blog.post.paginator.olderPost": "過去の記事",
@ -33,18 +32,6 @@
"theme.blog.tagTitle": "「{tagName}」タグの記事が{nPosts}あります",
"theme.common.editThisPage": "このページを編集",
"theme.common.headingLinkTitle": "見出しへの直接リンク",
"theme.common.month.april": "4月",
"theme.common.month.august": "8月",
"theme.common.month.december": "12月",
"theme.common.month.february": "2月",
"theme.common.month.january": "1月",
"theme.common.month.july": "7月",
"theme.common.month.june": "6月",
"theme.common.month.march": "3月",
"theme.common.month.may": "5月",
"theme.common.month.november": "11月",
"theme.common.month.october": "10月",
"theme.common.month.september": "9月",
"theme.common.skipToMainContent": "メインコンテンツまでスキップ",
"theme.docs.paginator.navAriaLabel": "ドキュメントのナビゲーション",
"theme.docs.paginator.next": "次へ",

View file

@ -22,7 +22,6 @@
"theme.blog.paginator.navAriaLabel": "Nawigacja na stronie listy wpisów na blogu",
"theme.blog.paginator.newerEntries": "Nowsze wpisy",
"theme.blog.paginator.olderEntries": "Starsze wpisy",
"theme.blog.post.date": "{day} {month} {year}",
"theme.blog.post.nPosts": "{count} posty",
"theme.blog.post.onePost": "Jeden post",
"theme.blog.post.paginator.navAriaLabel": "Nawigacja na stronie postu na blogu",
@ -33,18 +32,6 @@
"theme.blog.tagTitle": "{nPosts} z tagiem \"{tagName}\"",
"theme.common.editThisPage": "Edytuj tą stronę",
"theme.common.headingLinkTitle": "Bezpośredni link do nagłówka",
"theme.common.month.april": "kwiecień",
"theme.common.month.august": "sierpień",
"theme.common.month.december": "grudzień",
"theme.common.month.february": "luty",
"theme.common.month.january": "styczeń",
"theme.common.month.july": "lipiec",
"theme.common.month.june": "czerwiec",
"theme.common.month.march": "marzec",
"theme.common.month.may": "maj",
"theme.common.month.november": "listopad",
"theme.common.month.october": "październik",
"theme.common.month.september": "wrzesień",
"theme.common.skipToMainContent": "Przejdź do głównej zawartości",
"theme.docs.paginator.navAriaLabel": "Nawigacja na stronie dokumentacji",
"theme.docs.paginator.next": "Następna strona",

View file

@ -23,7 +23,6 @@
"theme.blog.paginator.navAriaLabel": "Навигация по странице списка блогов",
"theme.blog.paginator.newerEntries": "Следующие записи",
"theme.blog.paginator.olderEntries": "Предыдущие записи",
"theme.blog.post.date": "{month} {day}, {year}",
"theme.blog.post.paginator.navAriaLabel": "Навигация по странице поста блога",
"theme.blog.post.paginator.newerPost": "Следующий пост",
"theme.blog.post.paginator.olderPost": "Предыдущий пост",
@ -33,18 +32,6 @@
"theme.blog.tagTitle": "{nPosts} tagged with \"{tagName}\"",
"theme.common.editThisPage": "Отредактировать эту страницу",
"theme.common.headingLinkTitle": "Прямая ссылка на этот заголовок",
"theme.common.month.april": "April",
"theme.common.month.august": "August",
"theme.common.month.december": "December",
"theme.common.month.february": "February",
"theme.common.month.january": "January",
"theme.common.month.july": "July",
"theme.common.month.june": "June",
"theme.common.month.march": "March",
"theme.common.month.may": "May",
"theme.common.month.november": "November",
"theme.common.month.october": "October",
"theme.common.month.september": "September",
"theme.common.skipToMainContent": "Перейти к основному содержимому",
"theme.docs.paginator.navAriaLabel": "Навигация по странице документации",
"theme.docs.paginator.next": "Следующая страница",

View file

@ -23,7 +23,6 @@
"theme.blog.paginator.navAriaLabel": "Blog gönderi sayfası navigasyonu",
"theme.blog.paginator.newerEntries": "Yeni Girdiler",
"theme.blog.paginator.olderEntries": "Eski Girdiler",
"theme.blog.post.date": "{day} {month} {year}",
"theme.blog.post.paginator.navAriaLabel": "Blog gönderi sayfası navigasyonu",
"theme.blog.post.paginator.newerPost": "Daha Yeni Gönderi",
"theme.blog.post.paginator.olderPost": "Daha Eski Gönderi",
@ -33,18 +32,6 @@
"theme.blog.tagTitle": "\"{tagName}\" ile etiketlenmiş {nPosts}",
"theme.common.editThisPage": "Bu sayfayı düzenle",
"theme.common.headingLinkTitle": "Başlığa doğrudan bağlantı",
"theme.common.month.april": "Nisan",
"theme.common.month.august": "Ağustos",
"theme.common.month.december": "Aralık",
"theme.common.month.february": "Şubat",
"theme.common.month.january": "Ocak",
"theme.common.month.july": "Temmuz",
"theme.common.month.june": "Haziran",
"theme.common.month.march": "Mart",
"theme.common.month.may": "Mayıs",
"theme.common.month.november": "Kasım",
"theme.common.month.october": "Ekim",
"theme.common.month.september": "Eylül",
"theme.common.skipToMainContent": "Ana içeriğe geç",
"theme.docs.paginator.navAriaLabel": "Dokümanlar sayfası navigasyonu",
"theme.docs.paginator.next": "Sonraki",

View file

@ -38,70 +38,6 @@ function useReadingTimePlural() {
};
}
// TODO we should rely on an Intl api to translate that
const MONTHS = [
translate({
id: 'theme.common.month.january',
description: 'January month translation',
message: 'January',
}),
translate({
id: 'theme.common.month.february',
description: 'February month translation',
message: 'February',
}),
translate({
id: 'theme.common.month.march',
description: 'March month translation',
message: 'March',
}),
translate({
id: 'theme.common.month.april',
description: 'April month translation',
message: 'April',
}),
translate({
id: 'theme.common.month.may',
description: 'May month translation',
message: 'May',
}),
translate({
id: 'theme.common.month.june',
description: 'June month translation',
message: 'June',
}),
translate({
id: 'theme.common.month.july',
description: 'July month translation',
message: 'July',
}),
translate({
id: 'theme.common.month.august',
description: 'August month translation',
message: 'August',
}),
translate({
id: 'theme.common.month.september',
description: 'September month translation',
message: 'September',
}),
translate({
id: 'theme.common.month.october',
description: 'October month translation',
message: 'October',
}),
translate({
id: 'theme.common.month.november',
description: 'November month translation',
message: 'November',
}),
translate({
id: 'theme.common.month.december',
description: 'December month translation',
message: 'December',
}),
];
function BlogPostItem(props: Props): JSX.Element {
const readingTimePlural = useReadingTimePlural();
const {
@ -111,7 +47,7 @@ function BlogPostItem(props: Props): JSX.Element {
truncated,
isBlogPostPage = false,
} = props;
const {date, permalink, tags, readingTime} = metadata;
const {date, formattedDate, permalink, tags, readingTime} = metadata;
const {author, title, image, keywords} = frontMatter;
const authorURL = frontMatter.author_url || frontMatter.authorURL;
@ -121,10 +57,6 @@ function BlogPostItem(props: Props): JSX.Element {
const renderPostHeader = () => {
const TitleHeading = isBlogPostPage ? 'h1' : 'h2';
const match = date.substring(0, 10).split('-');
const year = match[0];
const month = MONTHS[parseInt(match[1], 10) - 1];
const day = parseInt(match[2], 10);
return (
<header>
@ -134,12 +66,7 @@ function BlogPostItem(props: Props): JSX.Element {
</TitleHeading>
<div className="margin-vert--md">
<time dateTime={date} className={styles.blogPostDate}>
<Translate
id="theme.blog.post.date"
description="The label to display the blog post date"
values={{day, month, year}}>
{'{month} {day}, {year}'}
</Translate>{' '}
{formattedDate}
{readingTime && (
<>
{' · '}

View file

@ -23,6 +23,8 @@
"escape-string-regexp": "^4.0.0",
"fs-extra": "^9.1.0",
"gray-matter": "^4.0.2",
"intl": "^1.2.5",
"intl-locales-supported": "^1.8.12",
"lodash": "^4.17.20",
"lodash.camelcase": "^4.3.0",
"lodash.kebabcase": "^4.1.1",

View file

@ -23,6 +23,7 @@ import {
// @ts-expect-error: no typedefs :s
import resolvePathnameUnsafe from 'resolve-pathname';
import {mapValues} from 'lodash';
import areIntlLocalesSupported from 'intl-locales-supported';
const fileHash = new Map();
export async function generate(
@ -634,3 +635,10 @@ export async function readDefaultCodeTranslationMessages({
return {};
}
export function getDateTimeFormat(locale: string) {
return areIntlLocalesSupported([locale])
? global.Intl.DateTimeFormat
: // eslint-disable-next-line @typescript-eslint/no-var-requires
require('intl').DateTimeFormat;
}

View file

@ -11032,6 +11032,16 @@ interpret@^1.0.0:
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296"
integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==
intl-locales-supported@^1.8.12:
version "1.8.12"
resolved "https://registry.yarnpkg.com/intl-locales-supported/-/intl-locales-supported-1.8.12.tgz#bbd83475a1cda61dc026309ca61f64c450af8ccb"
integrity sha512-FJPl7p1LYO/C+LpwlDcvVpq7AeFTdFgwnq1JjdNYKjb51xkIxssXRR8LaA0fJFogjwRRztqw1ahgSJMSZsSFdw==
intl@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/intl/-/intl-1.2.5.tgz#82244a2190c4e419f8371f5aa34daa3420e2abde"
integrity sha1-giRKIZDE5Bn4Nx9ao02qNCDiq94=
into-stream@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6"