feat(fs.dev): Initial search implementation
This commit is contained in:
parent
09c2b89aed
commit
8f165dbe6d
9 changed files with 612 additions and 37 deletions
206
packages/freesewing.dev/components/search.js
Normal file
206
packages/freesewing.dev/components/search.js
Normal file
|
@ -0,0 +1,206 @@
|
||||||
|
import { useState, useRef, useEffect } from 'react'
|
||||||
|
import Link from 'next/link'
|
||||||
|
import { useRouter } from 'next/router'
|
||||||
|
|
||||||
|
import algoliasearch from 'algoliasearch/lite';
|
||||||
|
import { useHotkeys } from 'react-hotkeys-hook'
|
||||||
|
import { InstantSearch, connectHits, connectHighlight, connectSearchBox } from 'react-instantsearch-dom'
|
||||||
|
import config from 'site/freesewing.config.js'
|
||||||
|
|
||||||
|
const searchClient = algoliasearch(config.algolia.app, config.algolia.key)
|
||||||
|
|
||||||
|
const Hits = props => {
|
||||||
|
|
||||||
|
// When we hit enter in the text field, we want to navigate to the result
|
||||||
|
// which means we must make the result links available in the input somehow
|
||||||
|
// so let's stuff them in a data attribute
|
||||||
|
const links = props.hits.map(hit => hit.page)
|
||||||
|
props.input.current.setAttribute('data-links', JSON.stringify(links))
|
||||||
|
|
||||||
|
return props.hits.map((hit, index) => (
|
||||||
|
<Hit
|
||||||
|
{...props}
|
||||||
|
hit={hit}
|
||||||
|
index={index}
|
||||||
|
len={props.hits.length}
|
||||||
|
activeLink={links[props.active]}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
const CustomHits = connectHits(Hits);
|
||||||
|
|
||||||
|
const Highlight = ({ highlight, attribute, hit }) => {
|
||||||
|
const parsedHit = highlight({
|
||||||
|
highlightProperty: '_highlightResult',
|
||||||
|
attribute,
|
||||||
|
hit,
|
||||||
|
});
|
||||||
|
|
||||||
|
return parsedHit.map((part, index) => part.isHighlighted
|
||||||
|
? <mark key={index}>{part.value}</mark>
|
||||||
|
: <span key={index}>{part.value}</span>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const CustomHighlight = connectHighlight(Highlight);
|
||||||
|
|
||||||
|
const Hit = props => (
|
||||||
|
<div
|
||||||
|
className={`
|
||||||
|
border-base-300
|
||||||
|
border px-3 py-1 rounded mt-1
|
||||||
|
lg:px-6 lg:py-3 lg:border-2 lg:mt-4 lg:rounded-lg
|
||||||
|
hover:bg-base-100 hover:text-base-content
|
||||||
|
${props.index === props.active
|
||||||
|
? 'bg-base-300 text-base-content bg-opacity-30'
|
||||||
|
: ''
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
<Link href={props.hit.page}>
|
||||||
|
<a href={props.hit.page}>
|
||||||
|
<h4 className="text-lg lg:text-2xl">
|
||||||
|
{props.hit?._highlightResult?.title
|
||||||
|
? <CustomHighlight hit={props.hit} attribute='title' />
|
||||||
|
: props.hit.title
|
||||||
|
}
|
||||||
|
</h4>
|
||||||
|
<p className="text-sm lg:text-lg">
|
||||||
|
/
|
||||||
|
<b className="font-bold px-1 lg:text-lg">
|
||||||
|
{props.hit.page.split('/')[1]}
|
||||||
|
</b>
|
||||||
|
/
|
||||||
|
{props.hit.page.split('/').slice(2).join('/')}
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
// We use this for trapping ctrl-c
|
||||||
|
let prev
|
||||||
|
const handleInputKeydown = (evt, setSearch, setActive, active, router) => {
|
||||||
|
if (evt.key === 'Escape') setSearch(false)
|
||||||
|
if (evt.key === 'ArrowDown') setActive(act => act + 1)
|
||||||
|
if (evt.key === 'ArrowUp') setActive(act => act - 1)
|
||||||
|
if (evt.key === 'c' && prev === 'Control') evt.target.value = ''
|
||||||
|
if (evt.key === 'Enter') {
|
||||||
|
// Trigger navigation
|
||||||
|
if (evt?.target?.dataset?.links) {
|
||||||
|
router.push(JSON.parse(evt.target.dataset.links)[active])
|
||||||
|
setSearch(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const SearchBox = props => {
|
||||||
|
|
||||||
|
const input = useRef(null)
|
||||||
|
const router = useRouter()
|
||||||
|
useHotkeys('ctrl+x', () => {
|
||||||
|
input.current.value = ''
|
||||||
|
})
|
||||||
|
if (input.current && props.active < 0) input.current.focus()
|
||||||
|
|
||||||
|
const { currentRefinement, isSearchStalled, refine, setSearch, setActive } = props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<form noValidate action="" role="search" onSubmit={(evt) => evt.preventDefault()}>
|
||||||
|
<div className="form-control">
|
||||||
|
<label className="label hidden lg:block">
|
||||||
|
<span className="label-text">
|
||||||
|
<b> Escape</b> to exit
|
||||||
|
<span className="px-4">|</span>
|
||||||
|
<b> Up</b> or <b>Down</b> to select
|
||||||
|
<span className="px-4">|</span>
|
||||||
|
<b> Enter</b> to navigate
|
||||||
|
<span className="px-4">|</span>
|
||||||
|
<b> Ctrl+c</b> to clear
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<div className="relative">
|
||||||
|
<input
|
||||||
|
ref={input}
|
||||||
|
type="search"
|
||||||
|
autoFocus={true}
|
||||||
|
value={currentRefinement}
|
||||||
|
onChange={event => refine(event.currentTarget.value)}
|
||||||
|
onKeyDown={(evt) => handleInputKeydown(evt, setSearch, setActive, props.active, router)}
|
||||||
|
className="input lg:input-lg input-bordered input-primary w-full pr-16"
|
||||||
|
placeholder='Type to search'
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
className="absolute right-0 top-0 rounded-l-none btn btn-primary lg:btn-lg"
|
||||||
|
onClick={() => props.setSearch(false)}
|
||||||
|
>X</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="overscroll-auto overflow-y-auto"
|
||||||
|
style={{maxHeight: 'calc(100vh - 10rem)'}}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
input.current
|
||||||
|
&& input.current.value.length > 0
|
||||||
|
&& <CustomHits hitComponent={Hit} {...props} input={input}/>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<div className={`
|
||||||
|
bg-neutral text-neutral-content
|
||||||
|
z-20 w-full mx-auto
|
||||||
|
lg:bg-base-100 lg:border-base-200
|
||||||
|
fixed bottom-0 left-0 border-t-2
|
||||||
|
lg:hidden
|
||||||
|
`}>
|
||||||
|
<div className='px-4 py-0 flex flex-row w-full lg:py-2'>
|
||||||
|
<button
|
||||||
|
className={`btn btn-ghost btn-block`}
|
||||||
|
onClick={() => props.setSearch(false)}
|
||||||
|
>
|
||||||
|
<span className='px-2 pt-2 pb-2'>Close Search</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const CustomSearchBox = connectSearchBox(SearchBox);
|
||||||
|
|
||||||
|
const Search = props => {
|
||||||
|
|
||||||
|
const [active, setActive] = useState(0)
|
||||||
|
useHotkeys('esc', () => props.setSearch(false))
|
||||||
|
useHotkeys('up', () => {
|
||||||
|
if (active) setActive(act => act - 1)
|
||||||
|
})
|
||||||
|
useHotkeys('down', () => {
|
||||||
|
setActive(act => act + 1)
|
||||||
|
})
|
||||||
|
useHotkeys('down', () => {
|
||||||
|
console.log('enter', active)
|
||||||
|
})
|
||||||
|
|
||||||
|
const stateProps = {
|
||||||
|
setSearch: props.setSearch,
|
||||||
|
setMenu: props.setMenu,
|
||||||
|
active, setActive
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="max-w-prose m-auto">
|
||||||
|
<h1>Search</h1>
|
||||||
|
<InstantSearch indexName={config.algolia.index} searchClient={searchClient}>
|
||||||
|
<div>
|
||||||
|
<CustomSearchBox {...stateProps}/>
|
||||||
|
</div>
|
||||||
|
</InstantSearch>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Search
|
12
packages/freesewing.dev/freesewing.config.js
Normal file
12
packages/freesewing.dev/freesewing.config.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
const config = {
|
||||||
|
algolia: {
|
||||||
|
app: 'MA0Y5A2PF0', // Application ID
|
||||||
|
index: 'canary_freesewing.dev',
|
||||||
|
key: '589c7a7e4d9c95a4f12868581259bf3a', // Search-only API key
|
||||||
|
},
|
||||||
|
strapi: 'https://posts.freesewing.org',
|
||||||
|
monorepo: 'https://github.com/freesewing/freesewing'
|
||||||
|
}
|
||||||
|
|
||||||
|
export default config
|
||||||
|
|
|
@ -21,16 +21,21 @@
|
||||||
"@mdx-js/react": "^2.0.0-rc.2",
|
"@mdx-js/react": "^2.0.0-rc.2",
|
||||||
"@mdx-js/runtime": "next",
|
"@mdx-js/runtime": "next",
|
||||||
"@tailwindcss/typography": "^0.5.0",
|
"@tailwindcss/typography": "^0.5.0",
|
||||||
|
"algoliasearch": "^4.11.0",
|
||||||
"daisyui": "^1.16.2",
|
"daisyui": "^1.16.2",
|
||||||
"lodash.get": "^4.4.2",
|
"lodash.get": "^4.4.2",
|
||||||
"lodash.orderby": "^4.6.0",
|
"lodash.orderby": "^4.6.0",
|
||||||
"lodash.set": "^4.3.2",
|
"lodash.set": "^4.3.2",
|
||||||
"netlify-cli": "^8.4.2",
|
"netlify-cli": "^8.4.2",
|
||||||
"next": "latest",
|
"next": "latest",
|
||||||
|
"react-hotkeys-hook": "^3.4.4",
|
||||||
|
"react-instantsearch-dom": "^6.18.0",
|
||||||
"react-markdown": "^7.1.1",
|
"react-markdown": "^7.1.1",
|
||||||
"react-swipeable": "^6.2.0",
|
"react-swipeable": "^6.2.0",
|
||||||
"react-timeago": "^6.2.1",
|
"react-timeago": "^6.2.1",
|
||||||
"rehype-highlight": "^5.0.1",
|
"rehype-highlight": "^5.0.1",
|
||||||
|
"rehype-sanitize": "^5.0.1",
|
||||||
|
"rehype-stringify": "^9.0.2",
|
||||||
"remark-copy-linked-files": "https://github.com/joostdecock/remark-copy-linked-files",
|
"remark-copy-linked-files": "https://github.com/joostdecock/remark-copy-linked-files",
|
||||||
"remark-gfm": "^3.0.1",
|
"remark-gfm": "^3.0.1",
|
||||||
"remark-jargon": "^2.19.6"
|
"remark-jargon": "^2.19.6"
|
||||||
|
|
150
packages/freesewing.dev/scripts/algolia.mjs
Normal file
150
packages/freesewing.dev/scripts/algolia.mjs
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
/*
|
||||||
|
* This will update (replace really) the Algolia index with the
|
||||||
|
* current website contents. Or at least the markdown and Strapi
|
||||||
|
* content
|
||||||
|
*
|
||||||
|
* It expects the following environment vars to be set in a
|
||||||
|
* .env file in the 'packages/freesewing.dev' folder:
|
||||||
|
*
|
||||||
|
* ALGOLIA_APP_ID -> probably MA0Y5A2PF0
|
||||||
|
* ALGOLIA_API_KEY -> Needs permission to index/create/delete
|
||||||
|
* ALGOLIA_INDEX -> Name of the index to index to
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
import dotenv from 'dotenv'
|
||||||
|
import fs from 'fs'
|
||||||
|
import path from 'path'
|
||||||
|
import algoliasearch from 'algoliasearch'
|
||||||
|
import { unified } from 'unified'
|
||||||
|
import remarkParser from 'remark-parse'
|
||||||
|
import remarkCompiler from 'remark-stringify'
|
||||||
|
import remarkFrontmatter from 'remark-frontmatter'
|
||||||
|
import remarkFrontmatterExtractor from 'remark-extract-frontmatter'
|
||||||
|
import remarkRehype from 'remark-rehype'
|
||||||
|
import rehypeSanitize from 'rehype-sanitize'
|
||||||
|
import rehypeStringify from 'rehype-stringify'
|
||||||
|
import yaml from 'yaml'
|
||||||
|
import { getPosts } from '../../freesewing.shared/prebuild/strapi.mjs'
|
||||||
|
import { getMdxFileList } from '../../freesewing.shared/prebuild/mdx.mjs'
|
||||||
|
dotenv.config()
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize Algolia client
|
||||||
|
*/
|
||||||
|
const client = algoliasearch(process.env.ALGOLIA_APP_ID, process.env.ALGOLIA_API_KEY)
|
||||||
|
const index = client.initIndex(process.env.ALGOLIA_INDEX)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Turn a Strapi blog post into an object ready for indexing
|
||||||
|
*/
|
||||||
|
const transformBlogpost = post => ({
|
||||||
|
objectID: `/blog/${post.slug}`,
|
||||||
|
page: `/blog/${post.slug}`,
|
||||||
|
title: post.title,
|
||||||
|
date: post.date,
|
||||||
|
slug: post.slug,
|
||||||
|
body: post.body,
|
||||||
|
author: post.author,
|
||||||
|
caption: post.caption,
|
||||||
|
type: 'blog',
|
||||||
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Turn a Strapi author into an object ready for indexing
|
||||||
|
*/
|
||||||
|
const transformAuthor = author => ({
|
||||||
|
objectID: `/blog/authors/${author.name}`,
|
||||||
|
page: `/blog/authors/${author.name}`,
|
||||||
|
name: author.name,
|
||||||
|
displayname: author.displayname,
|
||||||
|
about: author.about,
|
||||||
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get and index blog posts and author info from Strapi
|
||||||
|
*/
|
||||||
|
const indexStrapiContent = async () => {
|
||||||
|
|
||||||
|
// Say hi
|
||||||
|
console.log()
|
||||||
|
console.log(`Indexing Strapi content to Algolia`)
|
||||||
|
|
||||||
|
const authors = {}
|
||||||
|
const rawPosts = await getPosts('blog', 'dev', 'en')
|
||||||
|
// Extract list of authors
|
||||||
|
for (const [slug, post] of Object.entries(rawPosts)) {
|
||||||
|
authors[post.author.slug] = transformAuthor(post.author)
|
||||||
|
rawPosts[slug].author = post.author.slug
|
||||||
|
}
|
||||||
|
// Index posts to Algolia
|
||||||
|
index
|
||||||
|
.saveObjects(Object.values(rawPosts).map(post => transformBlogpost(post)))
|
||||||
|
.then(({ objectIDs }) => console.log(objectIDs))
|
||||||
|
.catch(err => console.log(err))
|
||||||
|
// Index authors to Algolia
|
||||||
|
index
|
||||||
|
.saveObjects(Object.values(authors))
|
||||||
|
.then(({ objectIDs }) => console.log(objectIDs))
|
||||||
|
.catch(err => console.log(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Loads markdown from disk and compiles it into HTML for indexing
|
||||||
|
*/
|
||||||
|
const markdownLoader = async file => {
|
||||||
|
|
||||||
|
const md = await fs.promises.readFile(file, 'utf-8')
|
||||||
|
|
||||||
|
const page = await unified()
|
||||||
|
.use(remarkParser)
|
||||||
|
.use(remarkCompiler)
|
||||||
|
.use(remarkFrontmatter)
|
||||||
|
.use(remarkFrontmatterExtractor, { yaml: yaml.parse })
|
||||||
|
.use(remarkRehype)
|
||||||
|
.use(rehypeSanitize)
|
||||||
|
.use(rehypeStringify)
|
||||||
|
.process(md)
|
||||||
|
const id = file.split('freesewing/markdown/dev').pop().slice(0, -6)
|
||||||
|
|
||||||
|
return {
|
||||||
|
objectID: id,
|
||||||
|
page: id,
|
||||||
|
title: page.data.title,
|
||||||
|
body: page.value,
|
||||||
|
type: 'docs',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get and index markdown content
|
||||||
|
*/
|
||||||
|
const indexMarkdownContent = async () => {
|
||||||
|
|
||||||
|
// Say hi
|
||||||
|
console.log()
|
||||||
|
console.log(`Indexing Markdown content to Algolia`)
|
||||||
|
|
||||||
|
// Setup MDX root path
|
||||||
|
const mdxRoot = path.resolve('..', '..', 'markdown', 'dev')
|
||||||
|
|
||||||
|
// Get list of filenames
|
||||||
|
const list = await getMdxFileList(mdxRoot, 'en')
|
||||||
|
const pages = []
|
||||||
|
for (const file of list) pages.push(await markdownLoader(file))
|
||||||
|
// Index markdown to Algolia
|
||||||
|
index
|
||||||
|
.saveObjects(pages)
|
||||||
|
.then(({ objectIDs }) => console.log(objectIDs))
|
||||||
|
.catch(err => console.log(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
const run = async () => {
|
||||||
|
await indexMarkdownContent()
|
||||||
|
await indexStrapiContent()
|
||||||
|
console.log()
|
||||||
|
}
|
||||||
|
|
||||||
|
run()
|
||||||
|
|
|
@ -8,6 +8,7 @@ import get from 'lodash.get'
|
||||||
// Site components
|
// Site components
|
||||||
import Header from 'site/components/header'
|
import Header from 'site/components/header'
|
||||||
import Footer from 'site/components/footer'
|
import Footer from 'site/components/footer'
|
||||||
|
import Search from 'site/components/search'
|
||||||
|
|
||||||
const iconSize= 48
|
const iconSize= 48
|
||||||
|
|
||||||
|
@ -59,7 +60,7 @@ const Breadcrumbs = ({ app, slug=false, title }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const DefaultLayout = ({ app, title=false, children=[]}) => {
|
const DefaultLayout = ({ app, title=false, children=[], search, setSearch}) => {
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
router?.events?.on('routeChangeStart', () => app.startLoading())
|
router?.events?.on('routeChangeStart', () => app.startLoading())
|
||||||
|
@ -117,6 +118,11 @@ const DefaultLayout = ({ app, title=false, children=[]}) => {
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
{search && (
|
||||||
|
<div className={`fixed w-full min-h-screen bg-base-200 px-4 lg:py-24 top-0 z-20`}>
|
||||||
|
<Search app={app} search={search} setSearch={setSearch}/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<Footer app={app} />
|
<Footer app={app} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,18 +1,9 @@
|
||||||
import React, { useState, useEffect } from 'react'
|
import React, { useState } from 'react'
|
||||||
import { useSwipeable } from 'react-swipeable'
|
import { useSwipeable } from 'react-swipeable'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
//import Head from 'next/head'
|
import { useHotkeys } from 'react-hotkeys-hook'
|
||||||
//import { useHotkeys } from 'react-hotkeys-hook'
|
|
||||||
//import themes from '@/shared/themes'
|
|
||||||
//import config from '@/site/freesewing.config.js'
|
|
||||||
// Shared components
|
// Shared components
|
||||||
import Layout from 'shared/components/layouts/default'
|
import Layout from 'shared/components/layouts/default'
|
||||||
//import ProgressBar from '@/shared/components/progress-bar'
|
|
||||||
//import Navbar from '@/shared/components/sections/navbar'
|
|
||||||
//import Footer from '@/site/components/footer'
|
|
||||||
//import useNavigation from '@/shared/hooks/useNavigation'
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
/* This component should wrap all page content */
|
/* This component should wrap all page content */
|
||||||
const AppWrapper= props => {
|
const AppWrapper= props => {
|
||||||
|
@ -25,34 +16,20 @@ const AppWrapper= props => {
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
props.app.setSlug(router.asPath.slice(1))
|
props.app.setSlug(router.asPath.slice(1))
|
||||||
//const locale = router.locale || config.language
|
|
||||||
//const tree = useNavigation(locale, path)
|
|
||||||
|
|
||||||
// Trigger search with Ctrl+k
|
// Trigger search with Ctrl+k
|
||||||
//useHotkeys('ctrl+k', (evt) => {
|
useHotkeys('ctrl+k', (evt) => {
|
||||||
// evt.preventDefault()
|
evt.preventDefault()
|
||||||
// setSearch(true)
|
setSearch(true)
|
||||||
//})
|
})
|
||||||
|
|
||||||
//const [menu, setMenu] = useState(false)
|
const [search, setSearch] = useState(false)
|
||||||
//const [search, setSearch] = useState(false)
|
|
||||||
|
|
||||||
//useEffect(() => {
|
|
||||||
// themeChange(false)
|
|
||||||
//}, [menu])
|
|
||||||
|
|
||||||
const childProps = {
|
const childProps = {
|
||||||
app: props.app,
|
app: props.app,
|
||||||
title: props.title,
|
title: props.title,
|
||||||
|
search, setSearch, toggleSearch: () => setSearch(!search),
|
||||||
}
|
}
|
||||||
// menu, setMenu, toggleMenu: () => setMenu(!menu),
|
|
||||||
// search, setSearch, toggleSearch: () => setSearch(!search),
|
|
||||||
// path, tree,
|
|
||||||
// title: props.title,
|
|
||||||
// t: props.t ? props.t : (x) => x,
|
|
||||||
// locale, languages: config.languages,
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -21,8 +21,10 @@ import yaml from 'js-yaml'
|
||||||
*
|
*
|
||||||
* - folder: the root folder to look in
|
* - folder: the root folder to look in
|
||||||
* - lang: the language files to looks for
|
* - lang: the language files to looks for
|
||||||
|
*
|
||||||
|
* Exported because it's also used by the Algolia index script
|
||||||
*/
|
*/
|
||||||
const getMdxFileList = async (folder, lang) => {
|
export const getMdxFileList = async (folder, lang) => {
|
||||||
let allFiles
|
let allFiles
|
||||||
try {
|
try {
|
||||||
allFiles = await rdir(folder)
|
allFiles = await rdir(folder)
|
||||||
|
|
|
@ -35,8 +35,9 @@ const buildUrl = (type, site, lang) => (type === 'blog')
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper method to load posts from Strapi
|
* Helper method to load posts from Strapi
|
||||||
|
* Exported because it's re-used by the Algolia indexing script
|
||||||
*/
|
*/
|
||||||
const getPosts = async (type, site, lang) => {
|
export const getPosts = async (type, site, lang) => {
|
||||||
let res
|
let res
|
||||||
try {
|
try {
|
||||||
res = await axios.get(buildUrl(type, site, lang))
|
res = await axios.get(buildUrl(type, site, lang))
|
||||||
|
|
222
yarn.lock
222
yarn.lock
|
@ -2,6 +2,115 @@
|
||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
"@algolia/cache-browser-local-storage@4.11.0":
|
||||||
|
version "4.11.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.11.0.tgz#1c168add00b398a860db6c86039e33b2843a9425"
|
||||||
|
integrity sha512-4sr9vHIG1fVA9dONagdzhsI/6M5mjs/qOe2xUP0yBmwsTsuwiZq3+Xu6D3dsxsuFetcJgC6ydQoCW8b7fDJHYQ==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/cache-common" "4.11.0"
|
||||||
|
|
||||||
|
"@algolia/cache-common@4.11.0":
|
||||||
|
version "4.11.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/cache-common/-/cache-common-4.11.0.tgz#066fe6d58b18e4b028dbef9bb8de07c5e22a3594"
|
||||||
|
integrity sha512-lODcJRuPXqf+6mp0h6bOxPMlbNoyn3VfjBVcQh70EDP0/xExZbkpecgHyyZK4kWg+evu+mmgvTK3GVHnet/xKw==
|
||||||
|
|
||||||
|
"@algolia/cache-in-memory@4.11.0":
|
||||||
|
version "4.11.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/cache-in-memory/-/cache-in-memory-4.11.0.tgz#763c8cb655e6fd2261588e04214fca0959ac07c1"
|
||||||
|
integrity sha512-aBz+stMSTBOBaBEQ43zJXz2DnwS7fL6dR0e2myehAgtfAWlWwLDHruc/98VOy1ZAcBk1blE2LCU02bT5HekGxQ==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/cache-common" "4.11.0"
|
||||||
|
|
||||||
|
"@algolia/client-account@4.11.0":
|
||||||
|
version "4.11.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/client-account/-/client-account-4.11.0.tgz#67fadd3b0802b013ebaaa4b47bb7babae892374e"
|
||||||
|
integrity sha512-jwmFBoUSzoMwMqgD3PmzFJV/d19p1RJXB6C1ADz4ju4mU7rkaQLtqyZroQpheLoU5s5Tilmn/T8/0U2XLoJCRQ==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/client-common" "4.11.0"
|
||||||
|
"@algolia/client-search" "4.11.0"
|
||||||
|
"@algolia/transporter" "4.11.0"
|
||||||
|
|
||||||
|
"@algolia/client-analytics@4.11.0":
|
||||||
|
version "4.11.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-4.11.0.tgz#cbdc8128205e2da749cafc79e54708d14c413974"
|
||||||
|
integrity sha512-v5U9585aeEdYml7JqggHAj3E5CQ+jPwGVztPVhakBk8H/cmLyPS2g8wvmIbaEZCHmWn4TqFj3EBHVYxAl36fSA==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/client-common" "4.11.0"
|
||||||
|
"@algolia/client-search" "4.11.0"
|
||||||
|
"@algolia/requester-common" "4.11.0"
|
||||||
|
"@algolia/transporter" "4.11.0"
|
||||||
|
|
||||||
|
"@algolia/client-common@4.11.0":
|
||||||
|
version "4.11.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-4.11.0.tgz#9a2d1f6f8eaad25ba5d6d4ce307ba5bd84e6f999"
|
||||||
|
integrity sha512-Qy+F+TZq12kc7tgfC+FM3RvYH/Ati7sUiUv/LkvlxFwNwNPwWGoZO81AzVSareXT/ksDDrabD4mHbdTbBPTRmQ==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/requester-common" "4.11.0"
|
||||||
|
"@algolia/transporter" "4.11.0"
|
||||||
|
|
||||||
|
"@algolia/client-personalization@4.11.0":
|
||||||
|
version "4.11.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-4.11.0.tgz#d3bf0e760f85df876b4baf5b81996f0aa3a59940"
|
||||||
|
integrity sha512-mI+X5IKiijHAzf9fy8VSl/GTT67dzFDnJ0QAM8D9cMPevnfX4U72HRln3Mjd0xEaYUOGve8TK/fMg7d3Z5yG6g==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/client-common" "4.11.0"
|
||||||
|
"@algolia/requester-common" "4.11.0"
|
||||||
|
"@algolia/transporter" "4.11.0"
|
||||||
|
|
||||||
|
"@algolia/client-search@4.11.0":
|
||||||
|
version "4.11.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-4.11.0.tgz#c1105d715a2a04ba27231eca86f5d6620f68f4ae"
|
||||||
|
integrity sha512-iovPLc5YgiXBdw2qMhU65sINgo9umWbHFzInxoNErWnYoTQWfXsW6P54/NlKx5uscoLVjSf+5RUWwFu5BX+lpw==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/client-common" "4.11.0"
|
||||||
|
"@algolia/requester-common" "4.11.0"
|
||||||
|
"@algolia/transporter" "4.11.0"
|
||||||
|
|
||||||
|
"@algolia/events@^4.0.1":
|
||||||
|
version "4.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/events/-/events-4.0.1.tgz#fd39e7477e7bc703d7f893b556f676c032af3950"
|
||||||
|
integrity sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==
|
||||||
|
|
||||||
|
"@algolia/logger-common@4.11.0":
|
||||||
|
version "4.11.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/logger-common/-/logger-common-4.11.0.tgz#bac1c2d59d29dee378b57412c8edd435b97de663"
|
||||||
|
integrity sha512-pRMJFeOY8hoWKIxWuGHIrqnEKN/kqKh7UilDffG/+PeEGxBuku+Wq5CfdTFG0C9ewUvn8mAJn5BhYA5k8y0Jqg==
|
||||||
|
|
||||||
|
"@algolia/logger-console@4.11.0":
|
||||||
|
version "4.11.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/logger-console/-/logger-console-4.11.0.tgz#ced19e3abb22eb782ed5268d51efb5aa9ef109ef"
|
||||||
|
integrity sha512-wXztMk0a3VbNmYP8Kpc+F7ekuvaqZmozM2eTLok0XIshpAeZ/NJDHDffXK2Pw+NF0wmHqurptLYwKoikjBYvhQ==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/logger-common" "4.11.0"
|
||||||
|
|
||||||
|
"@algolia/requester-browser-xhr@4.11.0":
|
||||||
|
version "4.11.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.11.0.tgz#f9e1ad56f185432aa8dde8cad53ae271fd5d6181"
|
||||||
|
integrity sha512-Fp3SfDihAAFR8bllg8P5ouWi3+qpEVN5e7hrtVIYldKBOuI/qFv80Zv/3/AMKNJQRYglS4zWyPuqrXm58nz6KA==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/requester-common" "4.11.0"
|
||||||
|
|
||||||
|
"@algolia/requester-common@4.11.0":
|
||||||
|
version "4.11.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/requester-common/-/requester-common-4.11.0.tgz#d16de98d3ff72434bac39e4d915eab08035946a9"
|
||||||
|
integrity sha512-+cZGe/9fuYgGuxjaBC+xTGBkK7OIYdfapxhfvEf03dviLMPmhmVYFJtJlzAjQ2YmGDJpHrGgAYj3i/fbs8yhiA==
|
||||||
|
|
||||||
|
"@algolia/requester-node-http@4.11.0":
|
||||||
|
version "4.11.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-4.11.0.tgz#beb2b6b68d5f4ce15aec80ede623f0ac96991368"
|
||||||
|
integrity sha512-qJIk9SHRFkKDi6dMT9hba8X1J1z92T5AZIgl+tsApjTGIRQXJLTIm+0q4yOefokfu4CoxYwRZ9QAq+ouGwfeOg==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/requester-common" "4.11.0"
|
||||||
|
|
||||||
|
"@algolia/transporter@4.11.0":
|
||||||
|
version "4.11.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/transporter/-/transporter-4.11.0.tgz#a8de3c173093ceceb02b26b577395ce3b3d4b96f"
|
||||||
|
integrity sha512-k4dyxiaEfYpw4UqybK9q7lrFzehygo6KV3OCYJMMdX0IMWV0m4DXdU27c1zYRYtthaFYaBzGF4Kjcl8p8vxCKw==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/cache-common" "4.11.0"
|
||||||
|
"@algolia/logger-common" "4.11.0"
|
||||||
|
"@algolia/requester-common" "4.11.0"
|
||||||
|
|
||||||
"@babel/code-frame@7.10.4":
|
"@babel/code-frame@7.10.4":
|
||||||
version "7.10.4"
|
version "7.10.4"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a"
|
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a"
|
||||||
|
@ -6218,6 +6327,33 @@ ajv@^8.0.0, ajv@^8.0.1, ajv@^8.6.3:
|
||||||
require-from-string "^2.0.2"
|
require-from-string "^2.0.2"
|
||||||
uri-js "^4.2.2"
|
uri-js "^4.2.2"
|
||||||
|
|
||||||
|
algoliasearch-helper@^3.6.2:
|
||||||
|
version "3.7.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/algoliasearch-helper/-/algoliasearch-helper-3.7.0.tgz#c0a0493df84d850360f664ad7a9d4fc78a94fd78"
|
||||||
|
integrity sha512-XJ3QfERBLfeVCyTVx80gon7r3/rgm/CE8Ha1H7cbablRe/X7SfYQ14g/eO+MhjVKIQp+gy9oC6G5ilmLwS1k6w==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/events" "^4.0.1"
|
||||||
|
|
||||||
|
algoliasearch@^4.11.0:
|
||||||
|
version "4.11.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-4.11.0.tgz#234befb3ac355c094077f0edf3777240b1ee013c"
|
||||||
|
integrity sha512-IXRj8kAP2WrMmj+eoPqPc6P7Ncq1yZkFiyDrjTBObV1ADNL8Z/KdZ+dWC5MmYcBLAbcB/mMCpak5N/D1UIZvsA==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/cache-browser-local-storage" "4.11.0"
|
||||||
|
"@algolia/cache-common" "4.11.0"
|
||||||
|
"@algolia/cache-in-memory" "4.11.0"
|
||||||
|
"@algolia/client-account" "4.11.0"
|
||||||
|
"@algolia/client-analytics" "4.11.0"
|
||||||
|
"@algolia/client-common" "4.11.0"
|
||||||
|
"@algolia/client-personalization" "4.11.0"
|
||||||
|
"@algolia/client-search" "4.11.0"
|
||||||
|
"@algolia/logger-common" "4.11.0"
|
||||||
|
"@algolia/logger-console" "4.11.0"
|
||||||
|
"@algolia/requester-browser-xhr" "4.11.0"
|
||||||
|
"@algolia/requester-common" "4.11.0"
|
||||||
|
"@algolia/requester-node-http" "4.11.0"
|
||||||
|
"@algolia/transporter" "4.11.0"
|
||||||
|
|
||||||
align-text@^0.1.1, align-text@^0.1.3:
|
align-text@^0.1.1, align-text@^0.1.3:
|
||||||
version "0.1.4"
|
version "0.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117"
|
resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117"
|
||||||
|
@ -9050,7 +9186,7 @@ classnames@2.2.6:
|
||||||
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
|
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
|
||||||
integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
|
integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
|
||||||
|
|
||||||
classnames@^2.2.0, classnames@^2.2.3, classnames@^2.2.6, classnames@^2.3.1:
|
classnames@^2.2.0, classnames@^2.2.3, classnames@^2.2.5, classnames@^2.2.6, classnames@^2.3.1:
|
||||||
version "2.3.1"
|
version "2.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e"
|
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e"
|
||||||
integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==
|
integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==
|
||||||
|
@ -14268,6 +14404,13 @@ hast-util-sanitize@^3.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
xtend "^4.0.0"
|
xtend "^4.0.0"
|
||||||
|
|
||||||
|
hast-util-sanitize@^4.0.0:
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/hast-util-sanitize/-/hast-util-sanitize-4.0.0.tgz#71a02ca2e50d04b852a5500846418070ca364f60"
|
||||||
|
integrity sha512-pw56+69jq+QSr/coADNvWTmBPDy+XsmwaF5KnUys4/wM1jt/fZdl7GPxhXXXYdXnz3Gj3qMkbUCH2uKjvX0MgQ==
|
||||||
|
dependencies:
|
||||||
|
"@types/hast" "^2.0.0"
|
||||||
|
|
||||||
hast-util-to-estree@^1.1.0:
|
hast-util-to-estree@^1.1.0:
|
||||||
version "1.4.0"
|
version "1.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/hast-util-to-estree/-/hast-util-to-estree-1.4.0.tgz#896ef9150a3f5cfbaff37334f75f31d6a324bab6"
|
resolved "https://registry.yarnpkg.com/hast-util-to-estree/-/hast-util-to-estree-1.4.0.tgz#896ef9150a3f5cfbaff37334f75f31d6a324bab6"
|
||||||
|
@ -14319,6 +14462,22 @@ hast-util-to-html@^7.0.0:
|
||||||
unist-util-is "^4.0.0"
|
unist-util-is "^4.0.0"
|
||||||
xtend "^4.0.0"
|
xtend "^4.0.0"
|
||||||
|
|
||||||
|
hast-util-to-html@^8.0.0:
|
||||||
|
version "8.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/hast-util-to-html/-/hast-util-to-html-8.0.3.tgz#4e37580872e143ea9ce0dba87918b19e4ea997e3"
|
||||||
|
integrity sha512-/D/E5ymdPYhHpPkuTHOUkSatxr4w1ZKrZsG0Zv/3C2SRVT0JFJG53VS45AMrBtYk0wp5A7ksEhiC8QaOZM95+A==
|
||||||
|
dependencies:
|
||||||
|
"@types/hast" "^2.0.0"
|
||||||
|
ccount "^2.0.0"
|
||||||
|
comma-separated-tokens "^2.0.0"
|
||||||
|
hast-util-is-element "^2.0.0"
|
||||||
|
hast-util-whitespace "^2.0.0"
|
||||||
|
html-void-elements "^2.0.0"
|
||||||
|
property-information "^6.0.0"
|
||||||
|
space-separated-tokens "^2.0.0"
|
||||||
|
stringify-entities "^4.0.2"
|
||||||
|
unist-util-is "^5.0.0"
|
||||||
|
|
||||||
hast-util-to-text@^3.0.0:
|
hast-util-to-text@^3.0.0:
|
||||||
version "3.1.1"
|
version "3.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/hast-util-to-text/-/hast-util-to-text-3.1.1.tgz#b7699a75f7a61af6e0befb67660cd78460d96dc6"
|
resolved "https://registry.yarnpkg.com/hast-util-to-text/-/hast-util-to-text-3.1.1.tgz#b7699a75f7a61af6e0befb67660cd78460d96dc6"
|
||||||
|
@ -14428,6 +14587,11 @@ hosted-git-info@^4.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
lru-cache "^6.0.0"
|
lru-cache "^6.0.0"
|
||||||
|
|
||||||
|
hotkeys-js@3.8.7:
|
||||||
|
version "3.8.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/hotkeys-js/-/hotkeys-js-3.8.7.tgz#c16cab978b53d7242f860ca3932e976b92399981"
|
||||||
|
integrity sha512-ckAx3EkUr5XjDwjEHDorHxRO2Kb7z6Z2Sxul4MbBkN8Nho7XDslQsgMJT+CiJ5Z4TgRxxvKHEpuLE3imzqy4Lg==
|
||||||
|
|
||||||
hpack.js@^2.1.6:
|
hpack.js@^2.1.6:
|
||||||
version "2.1.6"
|
version "2.1.6"
|
||||||
resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2"
|
resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2"
|
||||||
|
@ -14507,6 +14671,11 @@ html-void-elements@^1.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-1.0.5.tgz#ce9159494e86d95e45795b166c2021c2cfca4483"
|
resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-1.0.5.tgz#ce9159494e86d95e45795b166c2021c2cfca4483"
|
||||||
integrity sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==
|
integrity sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==
|
||||||
|
|
||||||
|
html-void-elements@^2.0.0:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-2.0.1.tgz#29459b8b05c200b6c5ee98743c41b979d577549f"
|
||||||
|
integrity sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==
|
||||||
|
|
||||||
html-webpack-plugin@4.5.0:
|
html-webpack-plugin@4.5.0:
|
||||||
version "4.5.0"
|
version "4.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.5.0.tgz#625097650886b97ea5dae331c320e3238f6c121c"
|
resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.5.0.tgz#625097650886b97ea5dae331c320e3238f6c121c"
|
||||||
|
@ -23436,7 +23605,7 @@ react-fast-compare@^2.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9"
|
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9"
|
||||||
integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==
|
integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==
|
||||||
|
|
||||||
react-fast-compare@^3.1.1, react-fast-compare@^3.2.0:
|
react-fast-compare@^3.0.0, react-fast-compare@^3.1.1, react-fast-compare@^3.2.0:
|
||||||
version "3.2.0"
|
version "3.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb"
|
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb"
|
||||||
integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==
|
integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==
|
||||||
|
@ -23451,6 +23620,13 @@ react-helmet@^6.1.0:
|
||||||
react-fast-compare "^3.1.1"
|
react-fast-compare "^3.1.1"
|
||||||
react-side-effect "^2.1.0"
|
react-side-effect "^2.1.0"
|
||||||
|
|
||||||
|
react-hotkeys-hook@^3.4.4:
|
||||||
|
version "3.4.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-hotkeys-hook/-/react-hotkeys-hook-3.4.4.tgz#52ba5d8ef5e47cc2e776c70a9036d518e0993d51"
|
||||||
|
integrity sha512-vaORq07rWgmuF3owWRhgFV/3VL8/l2q9lz0WyVEddJnWTtKW+AOgU5YgYKuwN6h6h7bCcLG3MFsJIjCrM/5DvQ==
|
||||||
|
dependencies:
|
||||||
|
hotkeys-js "3.8.7"
|
||||||
|
|
||||||
react-input-autosize@^3.0.0:
|
react-input-autosize@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-3.0.0.tgz#6b5898c790d4478d69420b55441fcc31d5c50a85"
|
resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-3.0.0.tgz#6b5898c790d4478d69420b55441fcc31d5c50a85"
|
||||||
|
@ -23458,6 +23634,28 @@ react-input-autosize@^3.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
prop-types "^15.5.8"
|
prop-types "^15.5.8"
|
||||||
|
|
||||||
|
react-instantsearch-core@^6.18.0:
|
||||||
|
version "6.18.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-instantsearch-core/-/react-instantsearch-core-6.18.0.tgz#fbcbb0bc96fdd08f31cdf7ee73f2e53168d60cce"
|
||||||
|
integrity sha512-lPbKGsprh7eV0ILR5Sj9qoP7R3jJ6/I3+++iB6rWOmBzMhbZ8ivl6i6LDJwYYt9lOghYqRDbtdWVx/hAE4O4Ng==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.1.2"
|
||||||
|
algoliasearch-helper "^3.6.2"
|
||||||
|
prop-types "^15.6.2"
|
||||||
|
react-fast-compare "^3.0.0"
|
||||||
|
|
||||||
|
react-instantsearch-dom@^6.18.0:
|
||||||
|
version "6.18.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-instantsearch-dom/-/react-instantsearch-dom-6.18.0.tgz#6d9ba255d6e5156df0dcfa5d0feafed1c4fecfa7"
|
||||||
|
integrity sha512-gsxSyzviDMcCX9+cgEnmOxRcQhoQq6e3+hCh/QvlF36Qw6xASeAt5VD+f+fRXCYX0oFJ3SoIoJXjcag4E4C4kQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.1.2"
|
||||||
|
algoliasearch-helper "^3.6.2"
|
||||||
|
classnames "^2.2.5"
|
||||||
|
prop-types "^15.6.2"
|
||||||
|
react-fast-compare "^3.0.0"
|
||||||
|
react-instantsearch-core "^6.18.0"
|
||||||
|
|
||||||
react-intl@4.5.0:
|
react-intl@4.5.0:
|
||||||
version "4.5.0"
|
version "4.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-4.5.0.tgz#f1ea00eb393b1a0e33850819b5ce8947abed187e"
|
resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-4.5.0.tgz#f1ea00eb393b1a0e33850819b5ce8947abed187e"
|
||||||
|
@ -24361,6 +24559,24 @@ rehype-minify-whitespace@^4.0.0:
|
||||||
hast-util-whitespace "^1.0.4"
|
hast-util-whitespace "^1.0.4"
|
||||||
unist-util-is "^4.0.0"
|
unist-util-is "^4.0.0"
|
||||||
|
|
||||||
|
rehype-sanitize@^5.0.1:
|
||||||
|
version "5.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/rehype-sanitize/-/rehype-sanitize-5.0.1.tgz#dac01a7417bdd329260c74c74449697b4be5eb56"
|
||||||
|
integrity sha512-da/jIOjq8eYt/1r9GN6GwxIR3gde7OZ+WV8pheu1tL8K0D9KxM2AyMh+UEfke+FfdM3PvGHeYJU0Td5OWa7L5A==
|
||||||
|
dependencies:
|
||||||
|
"@types/hast" "^2.0.0"
|
||||||
|
hast-util-sanitize "^4.0.0"
|
||||||
|
unified "^10.0.0"
|
||||||
|
|
||||||
|
rehype-stringify@^9.0.2:
|
||||||
|
version "9.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/rehype-stringify/-/rehype-stringify-9.0.2.tgz#2d95e06e246abbee504cf2f54c8d12f27d7bfd8e"
|
||||||
|
integrity sha512-BuVA6lAEYtOpXO2xuHLohAzz8UNoQAxAqYRqh4QEEtU39Co+P1JBZhw6wXA9hMWp+JLcmrxWH8+UKcNSr443Fw==
|
||||||
|
dependencies:
|
||||||
|
"@types/hast" "^2.0.0"
|
||||||
|
hast-util-to-html "^8.0.0"
|
||||||
|
unified "^10.0.0"
|
||||||
|
|
||||||
relateurl@0.2.x, relateurl@^0.2.7:
|
relateurl@0.2.x, relateurl@^0.2.7:
|
||||||
version "0.2.7"
|
version "0.2.7"
|
||||||
resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9"
|
resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9"
|
||||||
|
@ -26888,7 +27104,7 @@ stringify-entities@^3.1.0:
|
||||||
character-entities-legacy "^1.0.0"
|
character-entities-legacy "^1.0.0"
|
||||||
xtend "^4.0.0"
|
xtend "^4.0.0"
|
||||||
|
|
||||||
stringify-entities@^4.0.0:
|
stringify-entities@^4.0.0, stringify-entities@^4.0.2:
|
||||||
version "4.0.2"
|
version "4.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-4.0.2.tgz#13d113dc7449dc8ae4cb22c28883ee3fff8753e3"
|
resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-4.0.2.tgz#13d113dc7449dc8ae4cb22c28883ee3fff8753e3"
|
||||||
integrity sha512-MTxTVcEkorNtBbNpoFJPEh0kKdM6+QbMjLbaxmvaPMmayOXdr/AIVIIJX7FReUVweRBFJfZepK4A4AKgwuFpMQ==
|
integrity sha512-MTxTVcEkorNtBbNpoFJPEh0kKdM6+QbMjLbaxmvaPMmayOXdr/AIVIIJX7FReUVweRBFJfZepK4A4AKgwuFpMQ==
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue