{formatDuration(track.dt, 'en', 'hh:mm:ss')}
diff --git a/packages/renderer/src/hooks/useAlbum.ts b/packages/renderer/src/hooks/useAlbum.ts
index 08abbee..7b70ba5 100644
--- a/packages/renderer/src/hooks/useAlbum.ts
+++ b/packages/renderer/src/hooks/useAlbum.ts
@@ -1,6 +1,6 @@
import { fetchAlbum } from '@/api/album'
import { AlbumApiNames } from '@/api/album'
-import type { FetchAlbumParams } from '@/api/album'
+import type { FetchAlbumParams, FetchAlbumResponse } from '@/api/album'
import reactQueryClient from '@/utils/reactQueryClient'
const fetch = async (params: FetchAlbumParams, noCache?: boolean) => {
@@ -17,7 +17,14 @@ export default function useAlbum(params: FetchAlbumParams, noCache?: boolean) {
() => fetch(params, noCache),
{
enabled: !!params.id,
- staleTime: Infinity,
+ staleTime: 24 * 60 * 60 * 1000, // 24 hours
+ placeholderData: (): FetchAlbumResponse =>
+ window.ipcRenderer.sendSync('getApiCacheSync', {
+ api: 'album',
+ query: {
+ id: params.id,
+ },
+ }),
}
)
}
diff --git a/packages/renderer/src/hooks/useArtistAlbums.ts b/packages/renderer/src/hooks/useArtistAlbums.ts
index 7454623..15bf1be 100644
--- a/packages/renderer/src/hooks/useArtistAlbums.ts
+++ b/packages/renderer/src/hooks/useArtistAlbums.ts
@@ -1,6 +1,9 @@
import { fetchArtistAlbums } from '@/api/artist'
import { ArtistApiNames } from '@/api/artist'
-import type { FetchArtistAlbumsParams } from '@/api/artist'
+import type {
+ FetchArtistAlbumsParams,
+ FetchArtistAlbumsResponse,
+} from '@/api/artist'
export default function useUserAlbums(params: FetchArtistAlbumsParams) {
return useQuery(
@@ -12,6 +15,13 @@ export default function useUserAlbums(params: FetchArtistAlbumsParams) {
{
enabled: !!params.id && params.id !== 0,
staleTime: 3600000,
+ placeholderData: (): FetchArtistAlbumsResponse =>
+ window.ipcRenderer.sendSync('getApiCacheSync', {
+ api: 'artist/album',
+ query: {
+ id: params.id,
+ },
+ }),
}
)
}
diff --git a/packages/renderer/src/hooks/usePlaylist.ts b/packages/renderer/src/hooks/usePlaylist.ts
index 131968c..c7fd13d 100644
--- a/packages/renderer/src/hooks/usePlaylist.ts
+++ b/packages/renderer/src/hooks/usePlaylist.ts
@@ -1,6 +1,6 @@
import { fetchPlaylist } from '@/api/playlist'
import { PlaylistApiNames } from '@/api/playlist'
-import type { FetchPlaylistParams } from '@/api/playlist'
+import type { FetchPlaylistParams, FetchPlaylistResponse } from '@/api/playlist'
import reactQueryClient from '@/utils/reactQueryClient'
const fetch = (params: FetchPlaylistParams, noCache?: boolean) => {
@@ -16,7 +16,14 @@ export default function usePlaylist(
() => fetch(params, noCache),
{
enabled: !!(params.id && params.id > 0 && !isNaN(Number(params.id))),
- staleTime: 3600000,
+ staleTime: 60 * 60 * 1000, // 1 hour
+ placeholderData: (): FetchPlaylistResponse | undefined =>
+ window.ipcRenderer.sendSync('getApiCacheSync', {
+ api: 'playlist/detail',
+ query: {
+ id: params.id,
+ },
+ }),
}
)
}
diff --git a/packages/renderer/src/hooks/useTracks.ts b/packages/renderer/src/hooks/useTracks.ts
index 474dad1..c5fee77 100644
--- a/packages/renderer/src/hooks/useTracks.ts
+++ b/packages/renderer/src/hooks/useTracks.ts
@@ -1,5 +1,9 @@
import { TrackApiNames, fetchAudioSource, fetchTracks } from '@/api/track'
-import type { FetchAudioSourceParams, FetchTracksParams } from '@/api/track'
+import type {
+ FetchAudioSourceParams,
+ FetchTracksParams,
+ FetchTracksResponse,
+} from '@/api/track'
import reactQueryClient from '@/utils/reactQueryClient'
export default function useTracks(params: FetchTracksParams) {
@@ -12,6 +16,13 @@ export default function useTracks(params: FetchTracksParams) {
enabled: params.ids.length !== 0,
refetchInterval: false,
staleTime: Infinity,
+ initialData: (): FetchTracksResponse | undefined =>
+ window.ipcRenderer.sendSync('getApiCacheSync', {
+ api: 'song/detail',
+ query: {
+ ids: params.ids.join(','),
+ },
+ }),
}
)
}
@@ -37,7 +48,7 @@ export function fetchAudioSourceWithReactQuery(params: FetchAudioSourceParams) {
},
{
retry: 3,
- staleTime: 1200000,
+ staleTime: 0, // TODO: Web版1小时缓存
}
)
}
diff --git a/packages/renderer/src/hooks/useUser.ts b/packages/renderer/src/hooks/useUser.ts
index ae367e0..c07138d 100644
--- a/packages/renderer/src/hooks/useUser.ts
+++ b/packages/renderer/src/hooks/useUser.ts
@@ -1,8 +1,12 @@
-import { fetchUserAccount } from '@/api/user'
+import { fetchUserAccount, fetchUserAccountResponse } from '@/api/user'
import { UserApiNames } from '@/api/user'
export default function useUser() {
return useQuery(UserApiNames.FETCH_USER_ACCOUNT, fetchUserAccount, {
refetchOnWindowFocus: true,
+ placeholderData: (): fetchUserAccountResponse | undefined =>
+ window.ipcRenderer.sendSync('getApiCacheSync', {
+ api: 'user/account',
+ }),
})
}
diff --git a/packages/renderer/src/hooks/useUserLikedSongsIDs.ts b/packages/renderer/src/hooks/useUserLikedSongsIDs.ts
index 2aabc4e..479bf09 100644
--- a/packages/renderer/src/hooks/useUserLikedSongsIDs.ts
+++ b/packages/renderer/src/hooks/useUserLikedSongsIDs.ts
@@ -1,4 +1,7 @@
-import type { FetchUserLikedSongsIDsParams } from '@/api/user'
+import type {
+ FetchUserLikedSongsIDsParams,
+ FetchUserLikedSongsIDsResponse,
+} from '@/api/user'
import { UserApiNames, fetchUserLikedSongsIDs } from '@/api/user'
export default function useUserLikedSongsIDs(
@@ -10,6 +13,13 @@ export default function useUserLikedSongsIDs(
{
enabled: !!(params.uid && params.uid !== 0),
refetchOnWindowFocus: true,
+ placeholderData: (): FetchUserLikedSongsIDsResponse | undefined =>
+ window.ipcRenderer.sendSync('getApiCacheSync', {
+ api: 'likelist',
+ query: {
+ uid: params.uid,
+ },
+ }),
}
)
}
diff --git a/packages/renderer/src/hooks/useUserPlaylists.ts b/packages/renderer/src/hooks/useUserPlaylists.ts
index 788a193..1a60e6e 100644
--- a/packages/renderer/src/hooks/useUserPlaylists.ts
+++ b/packages/renderer/src/hooks/useUserPlaylists.ts
@@ -1,4 +1,7 @@
-import type { FetchUserPlaylistsParams } from '@/api/user'
+import type {
+ FetchUserPlaylistsParams,
+ FetchUserPlaylistsResponse,
+} from '@/api/user'
import { UserApiNames, fetchUserPlaylists } from '@/api/user'
export default function useUserPlaylists(params: FetchUserPlaylistsParams) {
@@ -14,6 +17,13 @@ export default function useUserPlaylists(params: FetchUserPlaylistsParams) {
params.uid !== 0 &&
params.offset !== undefined
),
+ placeholderData: (): FetchUserPlaylistsResponse =>
+ window.ipcRenderer.sendSync('getApiCacheSync', {
+ api: 'user/playlist',
+ query: {
+ uid: params.uid,
+ },
+ }),
}
)
}
diff --git a/packages/renderer/src/pages/Home.tsx b/packages/renderer/src/pages/Home.tsx
index 363ed8e..ac902c7 100644
--- a/packages/renderer/src/pages/Home.tsx
+++ b/packages/renderer/src/pages/Home.tsx
@@ -7,9 +7,16 @@ export default function Home() {
const {
data: recommendedPlaylists,
isLoading: isLoadingRecommendedPlaylists,
- } = useQuery(PlaylistApiNames.FETCH_RECOMMENDED_PLAYLISTS, () => {
- return fetchRecommendedPlaylists({})
- })
+ } = useQuery(
+ PlaylistApiNames.FETCH_RECOMMENDED_PLAYLISTS,
+ () => {
+ return fetchRecommendedPlaylists({})
+ },
+ {
+ placeholderData: () =>
+ window.ipcRenderer.sendSync('getApiCacheSync', { api: 'personalized' }),
+ }
+ )
return (
diff --git a/packages/renderer/src/utils/common.ts b/packages/renderer/src/utils/common.ts
index ced77ed..aaa5651 100644
--- a/packages/renderer/src/utils/common.ts
+++ b/packages/renderer/src/utils/common.ts
@@ -20,7 +20,10 @@ export function resizeImage(
if (!Object.keys(sizeMap).includes(size)) {
console.error(`Invalid cover size: ${size}`)
}
- return `${url}?param=${sizeMap[size]}y${sizeMap[size]}`
+ return `${url}?param=${sizeMap[size]}y${sizeMap[size]}`.replace(
+ 'http://',
+ 'https://'
+ )
}
export const storage = {
diff --git a/packages/renderer/src/utils/player.ts b/packages/renderer/src/utils/player.ts
index f3fca60..d77330b 100644
--- a/packages/renderer/src/utils/player.ts
+++ b/packages/renderer/src/utils/player.ts
@@ -3,6 +3,7 @@ import {
fetchAudioSourceWithReactQuery,
fetchTracksWithReactQuery,
} from '@/hooks/useTracks'
+import { cacheAudio } from '@/api/yesplaymusic'
type TrackID = number
enum TrackListSourceType {
@@ -19,9 +20,10 @@ export enum Mode {
}
export enum State {
INITIALIZING = 'initializing',
+ READY = 'ready',
PLAYING = 'playing',
PAUSED = 'paused',
- LOADED = 'loaded',
+ LOADING = 'loading',
}
export enum RepeatMode {
OFF = 'off',
@@ -107,8 +109,7 @@ export class Player {
private _setupProgressInterval() {
this._progressInterval = setInterval(() => {
- this._progress = _howler.seek()
- console.log(this.progress)
+ if (this.state === State.PLAYING) this._progress = _howler.seek()
}, 1000)
}
@@ -116,6 +117,7 @@ export class Player {
* Fetch track details from Netease based on this.trackID
*/
private async _fetchTrack(trackID: TrackID) {
+ this.state = State.LOADING
const response = await fetchTracksWithReactQuery({ ids: [trackID] })
if (response.songs.length) {
return response.songs[0]
@@ -161,6 +163,8 @@ export class Player {
})
_howler = howler
this.play()
+ this.state = State.PLAYING
+ _howler.once('load', () => this._cacheAudio(this.trackID, audio))
if (!this._progressInterval) {
this._setupProgressInterval()
@@ -177,6 +181,11 @@ export class Player {
}
}
+ private _cacheAudio(id: number, audio: string) {
+ if (audio.includes('yesplaymusic')) return
+ cacheAudio(id, audio)
+ }
+
/**
* Play current track
* @param {boolean} fade fade in
@@ -184,6 +193,7 @@ export class Player {
play() {
_howler.play()
this.state = State.PLAYING
+ this._progress = _howler.seek()
}
/**
diff --git a/packages/renderer/vite.config.ts b/packages/renderer/vite.config.ts
index ba57ae7..fe4ad61 100644
--- a/packages/renderer/vite.config.ts
+++ b/packages/renderer/vite.config.ts
@@ -84,6 +84,11 @@ export default defineConfig({
changeOrigin: true,
rewrite: path => path.replace(/^\/netease/, ''),
},
+ '/yesplaymusic/': {
+ target: `http://127.0.0.1:${process.env.ELECTRON_DEV_NETEASE_API_PORT}/yesplaymusic`,
+ changeOrigin: true,
+ rewrite: path => path.replace(/^\/yesplaymusic/, ''),
+ },
},
},
})
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 4129111..d0ec83e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1,9 +1,9 @@
lockfileVersion: 5.3
specifiers:
- '@trivago/prettier-plugin-sort-imports': ^3.2.0
'@types/cookie-parser': ^1.4.2
'@types/express': ^4.17.13
+ '@types/express-fileupload': ^1.2.2
'@types/howler': ^2.2.6
'@types/js-cookie': ^3.0.1
'@types/lodash-es': ^4.17.6
@@ -19,6 +19,7 @@ specifiers:
ansi-styles: ^6.1.0
autoprefixer: ^10.4.4
axios: ^0.26.1
+ body-parser: ^1.19.2
change-case: ^4.1.2
classnames: ^2.3.1
color.js: ^1.2.0
@@ -37,10 +38,13 @@ specifiers:
eslint-plugin-react: ^7.29.4
eslint-plugin-react-hooks: ^4.3.0
express: ^4.17.3
+ express-fileupload: ^1.3.1
+ fast-folder-size: ^1.6.1
howler: ^2.2.3
js-cookie: ^3.0.1
lodash-es: ^4.17.21
md5: ^2.3.0
+ music-metadata: ^7.12.2
postcss: ^8.4.12
prettier: 2.5.1
prettier-plugin-tailwindcss: ^0.1.8
@@ -74,9 +78,9 @@ dependencies:
realm: 10.13.0
devDependencies:
- '@trivago/prettier-plugin-sort-imports': 3.2.0_prettier@2.5.1
'@types/cookie-parser': 1.4.2
'@types/express': 4.17.13
+ '@types/express-fileupload': 1.2.2
'@types/howler': 2.2.6
'@types/js-cookie': 3.0.1
'@types/lodash-es': 4.17.6
@@ -91,6 +95,7 @@ devDependencies:
ansi-styles: 6.1.0
autoprefixer: 10.4.4_postcss@8.4.12
axios: 0.26.1
+ body-parser: 1.19.2
classnames: 2.3.1
color.js: 1.2.0
colord: 2.9.2
@@ -104,10 +109,13 @@ devDependencies:
eslint: 8.11.0
eslint-plugin-react: 7.29.4_eslint@8.11.0
eslint-plugin-react-hooks: 4.3.0_eslint@8.11.0
+ express-fileupload: 1.3.1
+ fast-folder-size: 1.6.1
howler: 2.2.3
js-cookie: 3.0.1
lodash-es: 4.17.21
md5: 2.3.0
+ music-metadata: 7.12.2
postcss: 8.4.12
prettier: 2.5.1
prettier-plugin-tailwindcss: 0.1.8_prettier@2.5.1
@@ -159,30 +167,6 @@ packages:
engines: {node: '>=6.9.0'}
dev: true
- /@babel/core/7.13.10:
- resolution: {integrity: sha512-bfIYcT0BdKeAZrovpMqX2Mx5NrgAckGbwT982AkdS5GNfn3KMGiprlBAtmBcFZRUmpaufS6WZFP8trvx8ptFDw==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/code-frame': 7.16.7
- '@babel/generator': 7.17.3
- '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.13.10
- '@babel/helper-module-transforms': 7.17.6
- '@babel/helpers': 7.17.2
- '@babel/parser': 7.17.3
- '@babel/template': 7.16.7
- '@babel/traverse': 7.17.3
- '@babel/types': 7.17.0
- convert-source-map: 1.8.0
- debug: 4.3.3
- gensync: 1.0.0-beta.2
- json5: 2.2.0
- lodash: 4.17.21
- semver: 6.3.0
- source-map: 0.5.7
- transitivePeerDependencies:
- - supports-color
- dev: true
-
/@babel/core/7.17.2:
resolution: {integrity: sha512-R3VH5G42VSDolRHyUO4V2cfag8WHcZyxdq5Z/m8Xyb92lW/Erm/6kM+XtRFGf3Mulre3mveni2NHfEUws8wSvw==}
engines: {node: '>=6.9.0'}
@@ -206,14 +190,6 @@ packages:
- supports-color
dev: true
- /@babel/generator/7.13.9:
- resolution: {integrity: sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw==}
- dependencies:
- '@babel/types': 7.17.0
- jsesc: 2.5.2
- source-map: 0.5.7
- dev: true
-
/@babel/generator/7.17.3:
resolution: {integrity: sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg==}
engines: {node: '>=6.9.0'}
@@ -230,19 +206,6 @@ packages:
'@babel/types': 7.17.0
dev: true
- /@babel/helper-compilation-targets/7.16.7_@babel+core@7.13.10:
- resolution: {integrity: sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0
- dependencies:
- '@babel/compat-data': 7.17.0
- '@babel/core': 7.13.10
- '@babel/helper-validator-option': 7.16.7
- browserslist: 4.19.1
- semver: 6.3.0
- dev: true
-
/@babel/helper-compilation-targets/7.16.7_@babel+core@7.17.2:
resolution: {integrity: sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==}
engines: {node: '>=6.9.0'}
@@ -358,12 +321,6 @@ packages:
js-tokens: 4.0.0
dev: true
- /@babel/parser/7.14.6:
- resolution: {integrity: sha512-oG0ej7efjEXxb4UgE+klVx+3j4MVo+A2vCzm7OUN4CLo6WhQ+vSOD2yJ8m7B+DghObxtLxt3EfgMWpq+AsWehQ==}
- engines: {node: '>=6.0.0'}
- hasBin: true
- dev: true
-
/@babel/parser/7.17.3:
resolution: {integrity: sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==}
engines: {node: '>=6.0.0'}
@@ -440,22 +397,6 @@ packages:
'@babel/types': 7.17.0
dev: true
- /@babel/traverse/7.13.0:
- resolution: {integrity: sha512-xys5xi5JEhzC3RzEmSGrs/b3pJW/o87SypZ+G/PhaE7uqVQNv/jlmVIBXuoh5atqQ434LfXV+sf23Oxj0bchJQ==}
- dependencies:
- '@babel/code-frame': 7.16.7
- '@babel/generator': 7.17.3
- '@babel/helper-function-name': 7.16.7
- '@babel/helper-split-export-declaration': 7.16.7
- '@babel/parser': 7.17.3
- '@babel/types': 7.17.0
- debug: 4.3.3
- globals: 11.12.0
- lodash: 4.17.21
- transitivePeerDependencies:
- - supports-color
- dev: true
-
/@babel/traverse/7.17.3:
resolution: {integrity: sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==}
engines: {node: '>=6.9.0'}
@@ -474,14 +415,6 @@ packages:
- supports-color
dev: true
- /@babel/types/7.13.0:
- resolution: {integrity: sha512-hE+HE8rnG1Z6Wzo+MhaKE5lM5eMx71T4EHJgku2E3xIfaULhDcxiiRxUYgwX8qwP1BBSlag+TdGOt6JAidIZTA==}
- dependencies:
- '@babel/helper-validator-identifier': 7.16.7
- lodash: 4.17.21
- to-fast-properties: 2.0.0
- dev: true
-
/@babel/types/7.17.0:
resolution: {integrity: sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==}
engines: {node: '>=6.9.0'}
@@ -643,7 +576,6 @@ packages:
/@tokenizer/token/0.3.0:
resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==}
- dev: false
/@tootallnate/once/1.1.2:
resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==}
@@ -655,23 +587,6 @@ packages:
engines: {node: '>= 10'}
dev: true
- /@trivago/prettier-plugin-sort-imports/3.2.0_prettier@2.5.1:
- resolution: {integrity: sha512-DnwLe+z8t/dZX5xBbYZV1+C5STkyK/P6SSq3Nk6NXlJZsgvDZX2eN4ND7bMFgGV/NL/YChWzcNf6ziGba1ktQQ==}
- peerDependencies:
- prettier: 2.x
- dependencies:
- '@babel/core': 7.13.10
- '@babel/generator': 7.13.9
- '@babel/parser': 7.14.6
- '@babel/traverse': 7.13.0
- '@babel/types': 7.13.0
- javascript-natural-sort: 0.7.1
- lodash: 4.17.21
- prettier: 2.5.1
- transitivePeerDependencies:
- - supports-color
- dev: true
-
/@trysound/sax/0.2.0:
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
engines: {node: '>=10.13.0'}
@@ -684,6 +599,12 @@ packages:
'@types/node': 14.18.10
dev: true
+ /@types/busboy/0.3.2:
+ resolution: {integrity: sha512-iEvdm9Z9KdSs/ozuh1Z7ZsXrOl8F4M/CLMXPZHr3QuJ4d6Bjn+HBMC5EMKpwpAo8oi8iK9GZfFoHaIMrrZgwVw==}
+ dependencies:
+ '@types/node': 14.18.10
+ dev: true
+
/@types/connect/3.4.35:
resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==}
dependencies:
@@ -702,6 +623,13 @@ packages:
'@types/ms': 0.7.31
dev: true
+ /@types/express-fileupload/1.2.2:
+ resolution: {integrity: sha512-sWU1EVFfLsdAginKVrkwTRbRPnbn7dawxEFEBgaRDcpNFCUuksZtASaAKEhqwEIg6fSdeTyI6dIUGl3thhrypg==}
+ dependencies:
+ '@types/busboy': 0.3.2
+ '@types/express': 4.17.13
+ dev: true
+
/@types/express-serve-static-core/4.17.28:
resolution: {integrity: sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==}
dependencies:
@@ -1456,6 +1384,13 @@ packages:
engines: {node: '>=8'}
dev: true
+ /binary/0.3.0:
+ resolution: {integrity: sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=}
+ dependencies:
+ buffers: 0.1.1
+ chainsaw: 0.1.0
+ dev: true
+
/bindings/1.5.0:
resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
dependencies:
@@ -1476,6 +1411,10 @@ packages:
bluebird: 3.7.2
dev: true
+ /bluebird/3.4.7:
+ resolution: {integrity: sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=}
+ dev: true
+
/bluebird/3.7.2:
resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==}
dev: true
@@ -1494,7 +1433,6 @@ packages:
qs: 6.9.7
raw-body: 2.4.3
type-is: 1.6.18
- dev: false
/boolbase/1.0.0:
resolution: {integrity: sha1-aN/1++YMUes3cl6p4+0xDcwed24=}
@@ -1619,12 +1557,22 @@ packages:
/buffer-from/1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
+ /buffer-indexof-polyfill/1.0.2:
+ resolution: {integrity: sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==}
+ engines: {node: '>=0.10'}
+ dev: true
+
/buffer/5.7.1:
resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
dependencies:
base64-js: 1.5.1
ieee754: 1.2.1
+ /buffers/0.1.1:
+ resolution: {integrity: sha1-skV5w77U1tOWru5tmorn9Ugqt7s=}
+ engines: {node: '>=0.2.0'}
+ dev: true
+
/builder-util-runtime/8.9.2:
resolution: {integrity: sha512-rhuKm5vh7E0aAmT6i8aoSfEjxzdYEFX7zDApK+eNgOhjofnWb74d9SRJv0H/8nsgOkos0TZ4zxW0P8J4N7xQ2A==}
engines: {node: '>=12.0.0'}
@@ -1664,12 +1612,10 @@ packages:
engines: {node: '>=4.5.0'}
dependencies:
dicer: 0.3.0
- dev: false
/bytes/3.1.2:
resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
engines: {node: '>= 0.8'}
- dev: false
/cache-base/1.0.1:
resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==}
@@ -1751,6 +1697,12 @@ packages:
resolution: {integrity: sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=}
dev: false
+ /chainsaw/0.1.0:
+ resolution: {integrity: sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=}
+ dependencies:
+ traverse: 0.3.9
+ dev: true
+
/chalk/1.1.3:
resolution: {integrity: sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=}
engines: {node: '>=0.10.0'}
@@ -2054,7 +2006,6 @@ packages:
/content-type/1.0.4:
resolution: {integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==}
engines: {node: '>= 0.6'}
- dev: false
/convert-source-map/1.8.0:
resolution: {integrity: sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==}
@@ -2342,7 +2293,6 @@ packages:
/depd/1.1.2:
resolution: {integrity: sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=}
engines: {node: '>= 0.6'}
- dev: false
/destroy/1.0.4:
resolution: {integrity: sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=}
@@ -2372,7 +2322,6 @@ packages:
engines: {node: '>=4.5.0'}
dependencies:
streamsearch: 0.1.2
- dev: false
/didyoumean/1.2.2:
resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
@@ -2536,6 +2485,12 @@ packages:
engines: {node: '>=10'}
dev: true
+ /duplexer2/0.1.4:
+ resolution: {integrity: sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=}
+ dependencies:
+ readable-stream: 2.3.7
+ dev: true
+
/duplexer3/0.1.4:
resolution: {integrity: sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=}
dev: true
@@ -2549,7 +2504,6 @@ packages:
/ee-first/1.1.1:
resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=}
- dev: false
/ejs/3.1.6:
resolution: {integrity: sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==}
@@ -3166,7 +3120,6 @@ packages:
engines: {node: '>=12.0.0'}
dependencies:
busboy: 0.3.1
- dev: false
/express/4.17.3:
resolution: {integrity: sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==}
@@ -3259,6 +3212,14 @@ packages:
/fast-deep-equal/3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+ /fast-folder-size/1.6.1:
+ resolution: {integrity: sha512-F3tRpfkAzb7TT2JNKaJUglyuRjRa+jelQD94s9OSqkfEeytLmupCqQiD+H2KoIXGtp4pB5m4zNmv5m2Ktcr+LA==}
+ hasBin: true
+ requiresBuild: true
+ dependencies:
+ unzipper: 0.10.11
+ dev: true
+
/fast-glob/3.2.11:
resolution: {integrity: sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==}
engines: {node: '>=8.6.0'}
@@ -3310,7 +3271,6 @@ packages:
readable-web-to-node-stream: 3.0.2
strtok3: 6.3.0
token-types: 4.2.0
- dev: false
/file-uri-to-path/1.0.0:
resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
@@ -3504,6 +3464,16 @@ packages:
dev: true
optional: true
+ /fstream/1.0.12:
+ resolution: {integrity: sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==}
+ engines: {node: '>=0.6'}
+ dependencies:
+ graceful-fs: 4.2.9
+ inherits: 2.0.4
+ mkdirp: 0.5.5
+ rimraf: 2.7.1
+ dev: true
+
/ftp/0.3.10:
resolution: {integrity: sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=}
engines: {node: '>=0.8.0'}
@@ -3878,7 +3848,6 @@ packages:
setprototypeof: 1.2.0
statuses: 1.5.0
toidentifier: 1.0.1
- dev: false
/http-proxy-agent/4.0.1:
resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==}
@@ -3951,7 +3920,6 @@ packages:
engines: {node: '>=0.10.0'}
dependencies:
safer-buffer: 2.1.2
- dev: false
/iconv-lite/0.6.3:
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
@@ -4349,10 +4317,6 @@ packages:
minimatch: 3.1.2
dev: true
- /javascript-natural-sort/0.7.1:
- resolution: {integrity: sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k=}
- dev: true
-
/js-base64/2.6.4:
resolution: {integrity: sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==}
dev: true
@@ -4547,6 +4511,10 @@ packages:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
dev: true
+ /listenercount/1.0.1:
+ resolution: {integrity: sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=}
+ dev: true
+
/loader-utils/1.4.0:
resolution: {integrity: sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==}
engines: {node: '>=4.0.0'}
@@ -4674,12 +4642,10 @@ packages:
/media-typer/0.3.0:
resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=}
engines: {node: '>= 0.6'}
- dev: false
/media-typer/1.1.0:
resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==}
engines: {node: '>= 0.8'}
- dev: false
/merge-descriptors/1.0.1:
resolution: {integrity: sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=}
@@ -4852,7 +4818,6 @@ packages:
token-types: 4.2.0
transitivePeerDependencies:
- supports-color
- dev: false
/nano-css/5.3.4_react-dom@17.0.2+react@17.0.2:
resolution: {integrity: sha512-wfcviJB6NOxDIDfr7RFn/GlaN7I/Bhe4d39ZRCJ3xvZX60LVe2qZ+rDqM49nm4YT81gAjzS+ZklhKP/Gnfnubg==}
@@ -5103,7 +5068,6 @@ packages:
engines: {node: '>= 0.8'}
dependencies:
ee-first: 1.1.1
- dev: false
/once/1.4.0:
resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=}
@@ -5303,7 +5267,6 @@ packages:
/peek-readable/4.1.0:
resolution: {integrity: sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==}
engines: {node: '>=8'}
- dev: false
/pend/1.2.0:
resolution: {integrity: sha1-elfrVQpng/kRUzH89GY9XI4AelA=}
@@ -5592,7 +5555,6 @@ packages:
/qs/6.9.7:
resolution: {integrity: sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==}
engines: {node: '>=0.6'}
- dev: false
/query-string/4.3.4:
resolution: {integrity: sha1-u7aTucqRXCMlFbIosaArYJBD2+s=}
@@ -5628,7 +5590,6 @@ packages:
http-errors: 1.8.1
iconv-lite: 0.4.24
unpipe: 1.0.0
- dev: false
/rc/1.2.8:
resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
@@ -5798,7 +5759,6 @@ packages:
engines: {node: '>=8'}
dependencies:
readable-stream: 3.6.0
- dev: false
/readdirp/3.6.0:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
@@ -5992,6 +5952,13 @@ packages:
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
dev: true
+ /rimraf/2.7.1:
+ resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==}
+ hasBin: true
+ dependencies:
+ glob: 7.2.0
+ dev: true
+
/rimraf/3.0.2:
resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
hasBin: true
@@ -6190,9 +6157,12 @@ packages:
split-string: 3.1.0
dev: true
+ /setimmediate/1.0.5:
+ resolution: {integrity: sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=}
+ dev: true
+
/setprototypeof/1.2.0:
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
- dev: false
/shebang-command/2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
@@ -6427,7 +6397,6 @@ packages:
/statuses/1.5.0:
resolution: {integrity: sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=}
engines: {node: '>= 0.6'}
- dev: false
/stream-counter/1.0.0:
resolution: {integrity: sha1-kc8lac5NxQYf6816yyY5SloRR1E=}
@@ -6437,7 +6406,6 @@ packages:
/streamsearch/0.1.2:
resolution: {integrity: sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=}
engines: {node: '>=0.8.0'}
- dev: false
/strict-uri-encode/1.1.0:
resolution: {integrity: sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=}
@@ -6524,7 +6492,6 @@ packages:
dependencies:
'@tokenizer/token': 0.3.0
peek-readable: 4.1.0
- dev: false
/stylis/4.0.13:
resolution: {integrity: sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==}
@@ -6763,7 +6730,6 @@ packages:
/toidentifier/1.0.1:
resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
engines: {node: '>=0.6'}
- dev: false
/token-types/4.2.0:
resolution: {integrity: sha512-P0rrp4wUpefLncNamWIef62J0v0kQR/GfDVji9WKY7GDCWy5YbVSrKUTam07iWPZQGy0zWNOfstYTykMmPNR7w==}
@@ -6771,7 +6737,6 @@ packages:
dependencies:
'@tokenizer/token': 0.3.0
ieee754: 1.2.1
- dev: false
/tough-cookie/2.5.0:
resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==}
@@ -6785,6 +6750,10 @@ packages:
resolution: {integrity: sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=}
dev: false
+ /traverse/0.3.9:
+ resolution: {integrity: sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=}
+ dev: true
+
/traverse/0.6.6:
resolution: {integrity: sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=}
dev: true
@@ -6866,7 +6835,6 @@ packages:
dependencies:
media-typer: 0.3.0
mime-types: 2.1.34
- dev: false
/typedarray-to-buffer/3.1.5:
resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==}
@@ -6933,7 +6901,6 @@ packages:
/unpipe/1.0.0:
resolution: {integrity: sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=}
engines: {node: '>= 0.8'}
- dev: false
/unplugin-auto-import/0.6.6_rollup@2.70.1+vite@2.8.6:
resolution: {integrity: sha512-x3YxAI9ePoumXOakuS5YJlFkSyAkl5vJlaFZSJhSp75nH5gg8LpqQ/0Gz1/CG/JRRv+xaE1CZpEV161AqFGjEg==}
@@ -6996,6 +6963,21 @@ packages:
yaku: 0.16.7
dev: true
+ /unzipper/0.10.11:
+ resolution: {integrity: sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==}
+ dependencies:
+ big-integer: 1.6.51
+ binary: 0.3.0
+ bluebird: 3.4.7
+ buffer-indexof-polyfill: 1.0.2
+ duplexer2: 0.1.4
+ fstream: 1.0.12
+ graceful-fs: 4.2.9
+ listenercount: 1.0.1
+ readable-stream: 2.3.7
+ setimmediate: 1.0.5
+ dev: true
+
/update-notifier/5.1.0:
resolution: {integrity: sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==}
engines: {node: '>=10'}
diff --git a/prettier.config.js b/prettier.config.js
index a48fdbf..8d662fa 100644
--- a/prettier.config.js
+++ b/prettier.config.js
@@ -14,9 +14,4 @@ module.exports = {
// Tailwind CSS
plugins: [require('prettier-plugin-tailwindcss')],
tailwindConfig: './tailwind.config.js',
-
- // Sort import order
- importOrder: ['^@/(.*)$', '^[./]'],
- importOrderSeparation: false,
- importOrderSortSpecifiers: true,
}