add trans support and hook all compnents excluding preview dir

This commit is contained in:
myl7
2022-02-06 18:35:03 +08:00
parent aa848c92f8
commit 2df258f791
10 changed files with 110 additions and 54 deletions
+6 -3
View File
@@ -3,6 +3,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import Image from 'next/image' import Image from 'next/image'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { FC, useState } from 'react' import { FC, useState } from 'react'
import { useTranslation } from 'next-i18next'
import { matchProtectedRoute } from '../utils/protectedRouteHandler' import { matchProtectedRoute } from '../utils/protectedRouteHandler'
import useLocalStorage from '../utils/useLocalStorage' import useLocalStorage from '../utils/useLocalStorage'
@@ -14,16 +15,18 @@ const Auth: FC<{ redirect: string }> = ({ redirect }) => {
const [token, setToken] = useState('') const [token, setToken] = useState('')
const [_, setPersistedToken] = useLocalStorage(authTokenPath, '') const [_, setPersistedToken] = useLocalStorage(authTokenPath, '')
const { t } = useTranslation()
return ( return (
<div className="md:my-10 flex flex-col max-w-sm mx-auto space-y-4"> <div className="md:my-10 flex flex-col max-w-sm mx-auto space-y-4">
<div className="md:w-5/6 w-3/4 mx-auto"> <div className="md:w-5/6 w-3/4 mx-auto">
<Image src={'/images/fabulous-wapmire-weekdays.png'} alt="authenticate" width={912} height={912} priority /> <Image src={'/images/fabulous-wapmire-weekdays.png'} alt="authenticate" width={912} height={912} priority />
</div> </div>
<div className="dark:text-gray-100 text-lg font-bold text-gray-900">Enter Password</div> <div className="dark:text-gray-100 text-lg font-bold text-gray-900">{t('Enter Password')}</div>
<p className="text-sm text-gray-500 font-medium"> <p className="text-sm text-gray-500 font-medium">
This route (the folder itself and the files inside) is password protected. If you know the password, please {t('This route (the folder itself and the files inside) is password protected. ') +
enter it below. t('If you know the password, please enter it below.')}
</p> </p>
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
+10 -7
View File
@@ -3,6 +3,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { IconProp } from '@fortawesome/fontawesome-svg-core' import { IconProp } from '@fortawesome/fontawesome-svg-core'
import toast from 'react-hot-toast' import toast from 'react-hot-toast'
import { useClipboard } from 'use-clipboard-copy' import { useClipboard } from 'use-clipboard-copy'
import { useTranslation } from 'next-i18next'
import Image from 'next/image' import Image from 'next/image'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
@@ -63,31 +64,33 @@ const DownloadButtonGroup: React.FC<{ downloadUrl: string }> = ({ downloadUrl })
const { asPath } = useRouter() const { asPath } = useRouter()
const clipboard = useClipboard() const clipboard = useClipboard()
const { t } = useTranslation()
return ( return (
<div className="flex flex-wrap justify-center gap-2"> <div className="flex flex-wrap justify-center gap-2">
<DownloadButton <DownloadButton
onClickCallback={() => window.open(downloadUrl)} onClickCallback={() => window.open(downloadUrl)}
btnColor="blue" btnColor="blue"
btnText="Download" btnText={t('Download')}
btnIcon="file-download" btnIcon="file-download"
btnTitle="Download the file directly through OneDrive" btnTitle={t('Download the file directly through OneDrive')}
/> />
{/* <DownloadButton {/* <DownloadButton
onClickCallback={() => window.open(`/api/proxy?url=${encodeURIComponent(downloadUrl)}`)} onClickCallback={() => window.open(`/api/proxy?url=${encodeURIComponent(downloadUrl)}`)}
btnColor="teal" btnColor="teal"
btnText="Proxy download" btnText={t('Proxy download')}
btnIcon="download" btnIcon="download"
btnTitle="Download the file with the stream proxied through Vercel Serverless" btnTitle={t('Download the file with the stream proxied through Vercel Serverless')}
/> */} /> */}
<DownloadButton <DownloadButton
onClickCallback={() => { onClickCallback={() => {
clipboard.copy(`${getBaseUrl()}/api?path=${asPath}&raw=true`) clipboard.copy(`${getBaseUrl()}/api?path=${asPath}&raw=true`)
toast.success('Copied direct link to clipboard.') toast.success(t('Copied direct link to clipboard.'))
}} }}
btnColor="pink" btnColor="pink"
btnText="Copy direct link" btnText={t('Copy direct link')}
btnIcon="copy" btnIcon="copy"
btnTitle="Copy the permalink to the file to the clipboard" btnTitle={t('Copy the permalink to the file to the clipboard')}
/> />
</div> </div>
) )
+5 -2
View File
@@ -321,7 +321,10 @@ const FileListing: FC<{ query?: ParsedUrlQuery }> = ({ query }) => {
{!onlyOnePage && ( {!onlyOnePage && (
<div className="rounded-b bg-white dark:bg-gray-900 dark:text-gray-100"> <div className="rounded-b bg-white dark:bg-gray-900 dark:text-gray-100">
<div className="border-b border-gray-200 p-3 text-center font-mono text-sm text-gray-400 dark:border-gray-700"> <div className="border-b border-gray-200 p-3 text-center font-mono text-sm text-gray-400 dark:border-gray-700">
- showing {size} page{size > 1 ? 's' : ''} of {isLoadingMore ? '...' : folderChildren.length} files - {t('- showing {{count}} page(s) of {{totalFileNum}} files -', {
count: size,
totalFileNum: isLoadingMore ? '...' : folderChildren.length
})}
</div> </div>
<button <button
className={`flex w-full items-center justify-center space-x-2 p-3 disabled:cursor-not-allowed ${ className={`flex w-full items-center justify-center space-x-2 p-3 disabled:cursor-not-allowed ${
@@ -406,7 +409,7 @@ const FileListing: FC<{ query?: ParsedUrlQuery }> = ({ query }) => {
return ( return (
<PreviewContainer> <PreviewContainer>
<FourOhFour errorMsg={`Cannot preview ${path}`} /> <FourOhFour errorMsg={t('Cannot preview {{path}}', { path })} />
</PreviewContainer> </PreviewContainer>
) )
} }
+14 -11
View File
@@ -4,6 +4,7 @@ import Link from 'next/link'
import { useState } from 'react' import { useState } from 'react'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { useClipboard } from 'use-clipboard-copy' import { useClipboard } from 'use-clipboard-copy'
import { useTranslation } from 'next-i18next'
import { getBaseUrl } from '../utils/getBaseUrl' import { getBaseUrl } from '../utils/getBaseUrl'
import { formatModifiedDateTime } from '../utils/fileDetails' import { formatModifiedDateTime } from '../utils/fileDetails'
@@ -65,6 +66,8 @@ const FolderGridLayout = ({
}) => { }) => {
const clipboard = useClipboard() const clipboard = useClipboard()
const { t } = useTranslation()
return ( return (
<div className="rounded bg-white dark:bg-gray-900 dark:text-gray-100"> <div className="rounded bg-white dark:bg-gray-900 dark:text-gray-100">
<div className="flex items-center border-b border-gray-900/10 px-3 text-xs font-bold uppercase tracking-widest text-gray-600 dark:border-gray-500/30 dark:text-gray-400"> <div className="flex items-center border-b border-gray-900/10 px-3 text-xs font-bold uppercase tracking-widest text-gray-600 dark:border-gray-500/30 dark:text-gray-400">
@@ -74,13 +77,13 @@ const FolderGridLayout = ({
checked={totalSelected} checked={totalSelected}
onChange={toggleTotalSelected} onChange={toggleTotalSelected}
indeterminate={true} indeterminate={true}
title={'Select all files'} title={t('Select all files')}
/> />
{totalGenerating ? ( {totalGenerating ? (
<Downloading title="Downloading selected files, refresh page to cancel" /> <Downloading title={t('Downloading selected files, refresh page to cancel')} />
) : ( ) : (
<button <button
title="Download selected files" title={t('Download selected files')}
className="cursor-pointer rounded p-1.5 hover:bg-gray-300 disabled:cursor-not-allowed disabled:text-gray-400 disabled:hover:bg-white dark:hover:bg-gray-600 disabled:dark:text-gray-600 disabled:hover:dark:bg-gray-900" className="cursor-pointer rounded p-1.5 hover:bg-gray-300 disabled:cursor-not-allowed disabled:text-gray-400 disabled:hover:bg-white dark:hover:bg-gray-600 disabled:dark:text-gray-600 disabled:hover:dark:bg-gray-900"
disabled={totalSelected === 0} disabled={totalSelected === 0}
onClick={handleSelectedDownload} onClick={handleSelectedDownload}
@@ -101,20 +104,20 @@ const FolderGridLayout = ({
{c.folder ? ( {c.folder ? (
<div> <div>
<span <span
title="Copy folder permalink" title={t('Copy folder permalink')}
className="cursor-pointer rounded px-1.5 py-1 hover:bg-gray-300 dark:hover:bg-gray-600" className="cursor-pointer rounded px-1.5 py-1 hover:bg-gray-300 dark:hover:bg-gray-600"
onClick={() => { onClick={() => {
clipboard.copy(`${getBaseUrl()}${path === '/' ? '' : path}/${encodeURIComponent(c.name)}`) clipboard.copy(`${getBaseUrl()}${path === '/' ? '' : path}/${encodeURIComponent(c.name)}`)
toast('Copied folder permalink.', { icon: '👌' }) toast(t('Copied folder permalink.'), { icon: '👌' })
}} }}
> >
<FontAwesomeIcon icon={['far', 'copy']} /> <FontAwesomeIcon icon={['far', 'copy']} />
</span> </span>
{folderGenerating[c.id] ? ( {folderGenerating[c.id] ? (
<Downloading title="Downloading folder, refresh page to cancel" /> <Downloading title={t('Downloading folder, refresh page to cancel')} />
) : ( ) : (
<span <span
title="Download folder" title={t('Download folder')}
className="cursor-pointer rounded px-1.5 py-1 hover:bg-gray-300 dark:hover:bg-gray-600" className="cursor-pointer rounded px-1.5 py-1 hover:bg-gray-300 dark:hover:bg-gray-600"
onClick={() => { onClick={() => {
const p = `${path === '/' ? '' : path}/${encodeURIComponent(c.name)}` const p = `${path === '/' ? '' : path}/${encodeURIComponent(c.name)}`
@@ -128,19 +131,19 @@ const FolderGridLayout = ({
) : ( ) : (
<div> <div>
<span <span
title="Copy raw file permalink" title={t('Copy raw file permalink')}
className="cursor-pointer rounded px-1.5 py-1 hover:bg-gray-300 dark:hover:bg-gray-600" className="cursor-pointer rounded px-1.5 py-1 hover:bg-gray-300 dark:hover:bg-gray-600"
onClick={() => { onClick={() => {
clipboard.copy( clipboard.copy(
`${getBaseUrl()}/api?path=${path === '/' ? '' : path}/${encodeURIComponent(c.name)}&raw=true` `${getBaseUrl()}/api?path=${path === '/' ? '' : path}/${encodeURIComponent(c.name)}&raw=true`
) )
toast.success('Copied raw file permalink.') toast.success(t('Copied raw file permalink.'))
}} }}
> >
<FontAwesomeIcon icon={['far', 'copy']} /> <FontAwesomeIcon icon={['far', 'copy']} />
</span> </span>
<a <a
title="Download file" title={t('Download file')}
className="cursor-pointer rounded px-1.5 py-1 hover:bg-gray-300 dark:hover:bg-gray-600" className="cursor-pointer rounded px-1.5 py-1 hover:bg-gray-300 dark:hover:bg-gray-600"
href={c['@microsoft.graph.downloadUrl']} href={c['@microsoft.graph.downloadUrl']}
> >
@@ -159,7 +162,7 @@ const FolderGridLayout = ({
<Checkbox <Checkbox
checked={selected[c.id] ? 2 : 0} checked={selected[c.id] ? 2 : 0}
onChange={() => toggleItemSelected(c.id)} onChange={() => toggleItemSelected(c.id)}
title="Select file" title={t('Select file')}
/> />
)} )}
</div> </div>
+20 -13
View File
@@ -1,4 +1,5 @@
import Image from 'next/image' import Image from 'next/image'
import { Trans } from 'next-i18next'
const FourOhFour: React.FC<{ errorMsg: string }> = ({ errorMsg }) => { const FourOhFour: React.FC<{ errorMsg: string }> = ({ errorMsg }) => {
return ( return (
@@ -8,24 +9,30 @@ const FourOhFour: React.FC<{ errorMsg: string }> = ({ errorMsg }) => {
</div> </div>
<div className="mt-6 text-gray-500 max-w-xl mx-auto"> <div className="mt-6 text-gray-500 max-w-xl mx-auto">
<div className="text-xl font-bold mb-8"> <div className="text-xl font-bold mb-8">
Oops, that&apos;s a <span className="underline decoration-wavy decoration-red-500">four-oh-four</span>. <Trans>
Oops, that&apos;s a <span className="underline decoration-wavy decoration-red-500">four-oh-four</span>.
</Trans>
</div> </div>
<div className="font-mono border border-gray-400/20 rounded p-2 mb-4 text-xs bg-gray-50 dark:bg-gray-800"> <div className="font-mono border border-gray-400/20 rounded p-2 mb-4 text-xs bg-gray-50 dark:bg-gray-800">
{errorMsg} {errorMsg}
</div> </div>
<div className="text-sm"> <div className="text-sm">
Press{' '} <Trans>
<kbd className="border-opacity-20 font-mono text-xs p-1 bg-gray-100 dark:bg-gray-800 border rounded">F12</kbd>{' '} Press{' '}
and open devtools for more details, or seek help at{' '} <kbd className="border-opacity-20 font-mono text-xs p-1 bg-gray-100 dark:bg-gray-800 border rounded">
<a F12
className="text-blue-600 hover:text-blue-700 hover:underline" </kbd>{' '}
href="https://github.com/spencerwooo/onedrive-vercel-index/discussions" and open devtools for more details, or seek help at{' '}
target="_blank" <a
rel="noopener noreferrer" className="text-blue-600 hover:text-blue-700 hover:underline"
> href="https://github.com/spencerwooo/onedrive-vercel-index/discussions"
onedrive-vercel-index discussions target="_blank"
</a> rel="noopener noreferrer"
. >
onedrive-vercel-index discussions
</a>
.
</Trans>
</div> </div>
</div> </div>
</div> </div>
+15 -9
View File
@@ -47,7 +47,7 @@ const Navbar = () => {
localStorage.removeItem(r) localStorage.removeItem(r)
}) })
toast.success('Cleared all tokens') toast.success(t('Cleared all tokens'))
setTimeout(() => { setTimeout(() => {
router.reload() router.reload()
}, 1000) }, 1000)
@@ -95,14 +95,20 @@ const Navbar = () => {
className="flex items-center space-x-2 hover:opacity-80 dark:text-white" className="flex items-center space-x-2 hover:opacity-80 dark:text-white"
> >
<FontAwesomeIcon icon={['fab', l.name.toLowerCase() as IconName]} /> <FontAwesomeIcon icon={['fab', l.name.toLowerCase() as IconName]} />
<span className="hidden text-sm font-medium md:inline-block">{l.name}</span> <span className="hidden text-sm font-medium md:inline-block">
{
// Append link name comments here to add translations
// t('Weibo')
t(l.name)
}
</span>
</a> </a>
))} ))}
{siteConfig.email && ( {siteConfig.email && (
<a href={siteConfig.email} className="flex items-center space-x-2 hover:opacity-80 dark:text-white"> <a href={siteConfig.email} className="flex items-center space-x-2 hover:opacity-80 dark:text-white">
<FontAwesomeIcon icon={['far', 'envelope']} /> <FontAwesomeIcon icon={['far', 'envelope']} />
<span className="hidden text-sm font-medium md:inline-block">Email</span> <span className="hidden text-sm font-medium md:inline-block">{t('Email')}</span>
</a> </a>
)} )}
@@ -111,7 +117,7 @@ const Navbar = () => {
className="flex items-center space-x-2 p-2 hover:opacity-80 dark:text-white" className="flex items-center space-x-2 p-2 hover:opacity-80 dark:text-white"
onClick={() => setIsOpen(true)} onClick={() => setIsOpen(true)}
> >
<span className="text-sm font-medium">Logout</span> <span className="text-sm font-medium">{t('Logout')}</span>
<FontAwesomeIcon icon="sign-out-alt" /> <FontAwesomeIcon icon="sign-out-alt" />
</button> </button>
)} )}
@@ -148,12 +154,12 @@ const Navbar = () => {
> >
<div className="my-8 inline-block w-full max-w-md transform overflow-hidden rounded-lg bg-white p-6 text-left align-middle transition-all dark:bg-gray-900"> <div className="my-8 inline-block w-full max-w-md transform overflow-hidden rounded-lg bg-white p-6 text-left align-middle transition-all dark:bg-gray-900">
<Dialog.Title className="text-lg font-bold text-gray-900 dark:text-gray-100"> <Dialog.Title className="text-lg font-bold text-gray-900 dark:text-gray-100">
Clear all tokens? {t('Clear all tokens?')}
</Dialog.Title> </Dialog.Title>
<div className="mt-2"> <div className="mt-2">
<p className="text-sm text-gray-500"> <p className="text-sm text-gray-500">
These tokens are used to authenticate yourself into password protected folders, clearing them means {t('These tokens are used to authenticate yourself into password protected folders, ') +
that you will need to re-enter the passwords again. t('clearing them means that you will need to re-enter the passwords again.')}
</p> </p>
</div> </div>
@@ -171,14 +177,14 @@ const Navbar = () => {
className="mr-3 inline-flex items-center justify-center space-x-2 rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-400 focus:outline-none focus:ring focus:ring-blue-300" className="mr-3 inline-flex items-center justify-center space-x-2 rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-400 focus:outline-none focus:ring focus:ring-blue-300"
onClick={() => setIsOpen(false)} onClick={() => setIsOpen(false)}
> >
Cancel {t('Cancel')}
</button> </button>
<button <button
className="inline-flex items-center justify-center space-x-2 rounded bg-red-500 px-4 py-2 text-white hover:bg-red-400 focus:outline-none focus:ring focus:ring-red-300" className="inline-flex items-center justify-center space-x-2 rounded bg-red-500 px-4 py-2 text-white hover:bg-red-400 focus:outline-none focus:ring focus:ring-red-300"
onClick={() => clearTokens()} onClick={() => clearTokens()}
> >
<FontAwesomeIcon icon={['far', 'trash-alt']} /> <FontAwesomeIcon icon={['far', 'trash-alt']} />
<span>Clear all</span> <span>{t('Clear all')}</span>
</button> </button>
</div> </div>
</div> </div>
+18 -6
View File
@@ -4,6 +4,7 @@ import { Dispatch, Fragment, SetStateAction, useState } from 'react'
import AwesomeDebouncePromise from 'awesome-debounce-promise' import AwesomeDebouncePromise from 'awesome-debounce-promise'
import { useAsync } from 'react-async-hook' import { useAsync } from 'react-async-hook'
import useConstant from 'use-constant' import useConstant from 'use-constant'
import { useTranslation } from 'next-i18next'
import Link from 'next/link' import Link from 'next/link'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
@@ -112,12 +113,19 @@ function SearchResultItemTemplate({
function SearchResultItemLoadRemote({ result }: { result: OdSearchResult[number] }) { function SearchResultItemLoadRemote({ result }: { result: OdSearchResult[number] }) {
const { data, error }: SWRResponse<OdDriveItem, string> = useSWR(`/api/item?id=${result.id}`, fetcher) const { data, error }: SWRResponse<OdDriveItem, string> = useSWR(`/api/item?id=${result.id}`, fetcher)
const { t } = useTranslation()
if (error) { if (error) {
return <SearchResultItemTemplate driveItem={result} driveItemPath={''} itemDescription={error} disabled={true} /> return <SearchResultItemTemplate driveItem={result} driveItemPath={''} itemDescription={error} disabled={true} />
} }
if (!data) { if (!data) {
return ( return (
<SearchResultItemTemplate driveItem={result} driveItemPath={''} itemDescription={'Loading ...'} disabled={true} /> <SearchResultItemTemplate
driveItem={result}
driveItemPath={''}
itemDescription={t('Loading ...')}
disabled={true}
/>
) )
} }
@@ -159,6 +167,8 @@ export default function SearchModal({
}) { }) {
const { query, setQuery, results } = useDriveItemSearch() const { query, setQuery, results } = useDriveItemSearch()
const { t } = useTranslation()
const closeSearchBox = () => { const closeSearchBox = () => {
setSearchOpen(false) setSearchOpen(false)
setQuery('') setQuery('')
@@ -199,13 +209,13 @@ export default function SearchModal({
type="text" type="text"
id="search-box" id="search-box"
className="w-full bg-transparent focus:outline-none focus-visible:outline-none" className="w-full bg-transparent focus:outline-none focus-visible:outline-none"
placeholder="Search ..." placeholder={t('Search ...')}
value={query} value={query}
onChange={e => setQuery(e.target.value)} onChange={e => setQuery(e.target.value)}
/> />
<div className="px-2 py-1 rounded-lg bg-gray-200 dark:bg-gray-700 font-medium text-xs">ESC</div> <div className="px-2 py-1 rounded-lg bg-gray-200 dark:bg-gray-700 font-medium text-xs">ESC</div>
</Dialog.Title> </Dialog.Title>
<div className="text-center px-4 py-12 text-sm font-medium">{t('Nothing here.')}</div>
<div <div
className="bg-white dark:text-white dark:bg-gray-900 max-h-[80vh] overflow-x-hidden overflow-y-scroll" className="bg-white dark:text-white dark:bg-gray-900 max-h-[80vh] overflow-x-hidden overflow-y-scroll"
onClick={closeSearchBox} onClick={closeSearchBox}
@@ -213,16 +223,18 @@ export default function SearchModal({
{results.loading && ( {results.loading && (
<div className="text-center px-4 py-12 text-sm font-medium"> <div className="text-center px-4 py-12 text-sm font-medium">
<LoadingIcon className="animate-spin w-4 h-4 mr-2 inline-block svg-inline--fa" /> <LoadingIcon className="animate-spin w-4 h-4 mr-2 inline-block svg-inline--fa" />
<span>Loading ...</span> <span>{t('Loading ...')}</span>
</div> </div>
)} )}
{results.error && ( {results.error && (
<div className="text-center px-4 py-12 text-sm font-medium">Error: {results.error.message}</div> <div className="text-center px-4 py-12 text-sm font-medium">
{t('Error: {{message}}', { message: results.error.message })}
</div>
)} )}
{results.result && ( {results.result && (
<> <>
{results.result.length === 0 ? ( {results.result.length === 0 ? (
<div className="text-center px-4 py-12 text-sm font-medium">Nothing here.</div> <div className="text-center px-4 py-12 text-sm font-medium">{t('Nothing here.')}</div>
) : ( ) : (
results.result.map(result => <SearchResultItem key={result.id} result={result} />) results.result.map(result => <SearchResultItem key={result.id} result={result} />)
)} )}
+7 -3
View File
@@ -1,4 +1,5 @@
const path = require('path') const path = require('path')
const tsTransform = require('i18next-scanner-typescript')
const { i18n, localePath } = require('./next-i18next.config') const { i18n, localePath } = require('./next-i18next.config')
@@ -8,8 +9,10 @@ module.exports = {
sort: true, sort: true,
removeUnusedKeys: true, removeUnusedKeys: true,
func: { func: {
list: ['t'], list: ['t']
extensions: ['.ts', '.tsx'] },
trans: {
fallbackKey: (_ns, val) => val
}, },
lngs: i18n.locales, lngs: i18n.locales,
ns: ['common'], ns: ['common'],
@@ -22,5 +25,6 @@ module.exports = {
}, },
nsSeparator: false, nsSeparator: false,
keySeparator: false keySeparator: false
} },
transform: tsTransform()
} }
+1
View File
@@ -63,6 +63,7 @@
"eslint-config-next": "12.0.10", "eslint-config-next": "12.0.10",
"eslint-config-prettier": "^8.3.0", "eslint-config-prettier": "^8.3.0",
"i18next-scanner": "^3.1.0", "i18next-scanner": "^3.1.0",
"i18next-scanner-typescript": "^1.0.6",
"postcss": "^8.4.5", "postcss": "^8.4.5",
"prettier": "^2.5.1", "prettier": "^2.5.1",
"prettier-plugin-tailwindcss": "^0.1.4", "prettier-plugin-tailwindcss": "^0.1.4",
+14
View File
@@ -27,6 +27,7 @@ specifiers:
eslint-config-next: 12.0.10 eslint-config-next: 12.0.10
eslint-config-prettier: ^8.3.0 eslint-config-prettier: ^8.3.0
i18next-scanner: ^3.1.0 i18next-scanner: ^3.1.0
i18next-scanner-typescript: ^1.0.6
ioredis: ^4.28.2 ioredis: ^4.28.2
jszip: ^3.7.1 jszip: ^3.7.1
next: ^12.0.10 next: ^12.0.10
@@ -110,6 +111,7 @@ devDependencies:
eslint-config-next: 12.0.10_9534215cc73b6f260bf33f1b86e3ae0e eslint-config-next: 12.0.10_9534215cc73b6f260bf33f1b86e3ae0e
eslint-config-prettier: 8.3.0_eslint@8.8.0 eslint-config-prettier: 8.3.0_eslint@8.8.0
i18next-scanner: 3.1.0 i18next-scanner: 3.1.0
i18next-scanner-typescript: 1.0.6
postcss: 8.4.6 postcss: 8.4.6
prettier: 2.5.1 prettier: 2.5.1
prettier-plugin-tailwindcss: 0.1.4_prettier@2.5.1 prettier-plugin-tailwindcss: 0.1.4_prettier@2.5.1
@@ -2009,6 +2011,12 @@ packages:
resolution: {integrity: sha512-/MfAGMP0jHonV966uFf9PkWWuDjPYLIcsipnSO3NxpNtAgRUKLTwvm85fEmsF6hGeu0zbZiCQ3W74jwO6K9uXA==} resolution: {integrity: sha512-/MfAGMP0jHonV966uFf9PkWWuDjPYLIcsipnSO3NxpNtAgRUKLTwvm85fEmsF6hGeu0zbZiCQ3W74jwO6K9uXA==}
dev: false dev: false
/i18next-scanner-typescript/1.0.6:
resolution: {integrity: sha512-v6kULnsv32OlFM9pnWTH+wNtRXf5owmFUNBYcX78jbZxQBFnTCUo3w99JjnxuzuXA9ch4UKNQBnt2P/o94eyeQ==}
dependencies:
typescript: 3.9.10
dev: true
/i18next-scanner/3.1.0: /i18next-scanner/3.1.0:
resolution: {integrity: sha512-dHLXUJIiF1CYJNslCkJFDYJySk5fg+dzdg9O73XXqHcdZwJ2947SWusqq8HdNFB7LpkBi8oTG6TWLZPmqbAh8Q==} resolution: {integrity: sha512-dHLXUJIiF1CYJNslCkJFDYJySk5fg+dzdg9O73XXqHcdZwJ2947SWusqq8HdNFB7LpkBi8oTG6TWLZPmqbAh8Q==}
engines: {node: '>=12'} engines: {node: '>=12'}
@@ -4024,6 +4032,12 @@ packages:
resolution: {integrity: sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==} resolution: {integrity: sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==}
dev: false dev: false
/typescript/3.9.10:
resolution: {integrity: sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==}
engines: {node: '>=4.2.0'}
hasBin: true
dev: true
/typescript/4.5.5: /typescript/4.5.5:
resolution: {integrity: sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==} resolution: {integrity: sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==}
engines: {node: '>=4.2.0'} engines: {node: '>=4.2.0'}