()).doc(),
+ )
const [currentSort, setCurrentSort] = useState(userStatSortNames[0])
- if (documentData.state === 'success') {
- const data = documentData.data
+ if (documentQuery.status === 'success') {
+ const data = documentQuery.data
+
+ if (!data)
+ return (
+ Couldn`t find that Raid - did you fall into the wrong dungeon?
+ )
+
return (
<$StatsView>
<$Header>
@@ -84,14 +93,10 @@ const ViewRaid = () => {
$StatContainer>
$StatsView>
)
- } else if (documentData.state === 'error') {
- return {JSON.stringify(documentData.error)}
+ } else if (documentQuery.status === 'error') {
+ return {JSON.stringify(documentQuery.error)}
} else {
- return documentData.state === 'loading' ? (
-
- ) : (
- Couldn`t find that Raid - did you fall into the wrong dungeon?
- )
+ return
}
}
diff --git a/src/routes/raids/index.tsx b/src/routes/raids/index.tsx
index 8e55f72..2a7687e 100644
--- a/src/routes/raids/index.tsx
+++ b/src/routes/raids/index.tsx
@@ -2,13 +2,16 @@ import React from 'react'
import { Link } from 'react-router-dom'
import LoadingSpinner from '#components/loadingSpinner'
-import useCollection from '#utils/useCollection'
+import useFirestoreQuery, { to } from '#utils/useFirestoreQuery'
+import { RAID_STATS } from '#utils/firestoreCollections'
const AllRaids = () => {
- const collectionData = useCollection('raid-stats')
+ const collectionQuery = useFirestoreQuery((firestore) =>
+ firestore.collection(RAID_STATS).withConverter(to()),
+ )
- if (collectionData.state === 'success') {
- const data = collectionData.data
+ if (collectionQuery.status === 'success') {
+ const data = collectionQuery.data
return (
<>
Raids
@@ -40,7 +43,7 @@ const AllRaids = () => {
)
}
- return collectionData.state === 'loading' ? (
+ return collectionQuery.status === 'loading' ? (
) : (
// Theoretically this can/should never be hit... But a fun message nonetheless
diff --git a/src/utils/firestoreCollections.ts b/src/utils/firestoreCollections.ts
new file mode 100644
index 0000000..a6ab158
--- /dev/null
+++ b/src/utils/firestoreCollections.ts
@@ -0,0 +1 @@
+export const RAID_STATS = 'raid-stats'
diff --git a/src/utils/useCollection/index.ts b/src/utils/useCollection/index.ts
deleted file mode 100644
index 9941801..0000000
--- a/src/utils/useCollection/index.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import { useState, useEffect } from 'react'
-import firestore from '#utils/useFirestore'
-
-function useCollection(
- collectionName: string,
-): UseFirestoreData[]> {
- const [collectionData, setCollectionData] = useState<
- UseFirestoreData[]>
- >({
- state: 'loading',
- data: null,
- error: null,
- })
-
- useEffect(() => {
- firestore
- .collection(collectionName)
- .get()
- .then((snapshot) => {
- if (!snapshot.empty) {
- setCollectionData({
- state: 'success',
- data: snapshot.docs.map>(
- (s) =>
- ({
- id: s.id,
- ...s.data(),
- } as DocumentWithId),
- ),
- error: null,
- })
- } else {
- setCollectionData({
- state: 'not-found',
- data: null,
- error: null,
- })
- }
- })
- .catch((error) => {
- setCollectionData({
- state: 'error',
- data: null,
- error,
- })
- })
- }, [collectionName])
-
- return collectionData
-}
-
-export default useCollection
diff --git a/src/utils/useDocument/index.ts b/src/utils/useDocument/index.ts
deleted file mode 100644
index bca187e..0000000
--- a/src/utils/useDocument/index.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import { useState, useEffect } from 'react'
-import firestore from '#utils/useFirestore'
-
-function useDocument(
- collectionName: string,
- documentId: string,
-): UseFirestoreData> {
- const [documentData, setDocumentData] = useState<
- UseFirestoreData>
- >({
- state: 'loading',
- data: null,
- error: null,
- })
-
- useEffect(() => {
- firestore
- .collection(collectionName)
- .doc(documentId)
- .get()
- .then((snapshot) => {
- if (snapshot.exists) {
- setDocumentData({
- state: 'success',
- data: {
- ...snapshot.data(),
- id: snapshot.id,
- } as DocumentWithId,
- error: null,
- })
- } else {
- setDocumentData({
- state: 'not-found',
- data: null,
- error: null,
- })
- }
- })
- .catch((error) => {
- setDocumentData({
- state: 'error',
- data: null,
- error: error,
- })
- })
- }, [collectionName, documentId])
-
- return documentData
-}
-
-export default useDocument
diff --git a/src/utils/useFirestore/index.ts b/src/utils/useFirestore/index.ts
deleted file mode 100644
index 8317c17..0000000
--- a/src/utils/useFirestore/index.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import firebase from 'firebase/app'
-import 'firebase/firestore'
-
-const firebaseConfig = {
- apiKey: 'AIzaSyCAgs6SNew9kKKFgQh7NLkqHK1n9Akq-GM',
- authDomain: 'raid-stats-c1d5a.firebaseapp.com',
- databaseURL: 'https://raid-stats-c1d5a-default-rtdb.firebaseio.com',
- projectId: 'raid-stats-c1d5a',
- storageBucket: 'raid-stats-c1d5a.appspot.com',
- messagingSenderId: '47482470658',
- appId: '1:47482470658:web:bd07aa5f9e1b0df3c2c21b',
-}
-
-if (!firebase.apps.length) {
- firebase.initializeApp(firebaseConfig)
-}
-
-const firestore = firebase.firestore()
-
-// Comment out the following to pull from the live firestore DB
-if (import.meta.env.NODE_ENV !== 'production') {
- firestore.useEmulator('localhost', 8080)
-}
-
-export default firestore
diff --git a/src/utils/useFirestoreQuery.ts b/src/utils/useFirestoreQuery.ts
new file mode 100644
index 0000000..7fa92c3
--- /dev/null
+++ b/src/utils/useFirestoreQuery.ts
@@ -0,0 +1,209 @@
+import { useReducer, useEffect } from 'react'
+import useMemoCompare from './useMemoCompare'
+
+import firebase from 'firebase/app'
+import 'firebase/firestore'
+
+const firebaseConfig = {
+ apiKey: 'AIzaSyCAgs6SNew9kKKFgQh7NLkqHK1n9Akq-GM',
+ authDomain: 'raid-stats-c1d5a.firebaseapp.com',
+ databaseURL: 'https://raid-stats-c1d5a-default-rtdb.firebaseio.com',
+ projectId: 'raid-stats-c1d5a',
+ storageBucket: 'raid-stats-c1d5a.appspot.com',
+ messagingSenderId: '47482470658',
+ appId: '1:47482470658:web:bd07aa5f9e1b0df3c2c21b',
+}
+
+if (!firebase.apps.length) {
+ firebase.initializeApp(firebaseConfig)
+}
+
+const firestore = firebase.firestore()
+
+// Comment out the following to pull from the live firestore DB
+if (import.meta.env.NODE_ENV !== 'production') {
+ firestore.useEmulator('localhost', 8080)
+}
+
+export function to() {
+ return {
+ toFirestore(data: TData): firebase.firestore.DocumentData {
+ return data
+ },
+ fromFirestore(
+ snapshot: firebase.firestore.QueryDocumentSnapshot,
+ options: firebase.firestore.SnapshotOptions,
+ ): TData {
+ return snapshot.data(options) as TData
+ },
+ }
+}
+
+const reducer = <
+ TQueryResult extends FirestoreQueryResultUnion,
+ TData
+>(
+ state: FirestoreQueryState,
+ action: FirestoreQueryStateAction,
+): FirestoreQueryState => {
+ switch (action.type) {
+ case 'idle':
+ case 'loading':
+ return { status: action.type, data: null, error: null }
+ case 'success':
+ return {
+ status: 'success',
+ data: action.payload as FirestoreQueryStateData,
+ error: null,
+ }
+ case 'error':
+ return { status: 'error', data: null, error: action.payload }
+ default:
+ throw new Error('invalid action')
+ }
+}
+
+export default function useFirestoreQuery<
+ TQuery extends FirestoreQuery,
+ TQueryResult extends ReturnType,
+ TData extends FirestoreQueryDataType
+>(query: TQuery): FirestoreQueryState {
+ const [state, dispatch] = useReducer<
+ FirestoreQueryReducer
+ >(reducer, {
+ status: 'loading',
+ data: null,
+ error: null,
+ })
+
+ // Get cached Firestore query object with useMemoCompare (https://usehooks.com/useMemoCompare)
+ // Needed because firestore.collection().doc() will always be a new object reference
+ // causing effect to run -> state change -> rerender -> effect runs -> etc ...
+ // This is nicer than requiring hook consumer to always memoize query with useMemo.
+ const queryCached = useMemoCompare(query(firestore), (prevQuery) => {
+ if (prevQuery && query) {
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore
+ query.isEqual(prevQuery)
+ }
+
+ return false
+ })
+
+ useEffect(() => {
+ if (!queryCached) {
+ dispatch({ type: 'idle' })
+ return
+ }
+
+ dispatch({ type: 'loading' })
+
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore
+ return queryCached.onSnapshot(
+ (
+ snapshot:
+ | firebase.firestore.QuerySnapshot
+ | firebase.firestore.DocumentSnapshot,
+ ) => {
+ if ('docs' in snapshot) {
+ dispatch({
+ type: 'success',
+ payload: getCollectionData(snapshot),
+ })
+ } else {
+ const data = getDocData(snapshot)
+
+ dispatch({ type: 'success', payload: data }) // need something better for the null case...
+ }
+ },
+ (error: firebase.firestore.FirestoreError) => {
+ dispatch({ type: 'error', payload: error })
+ },
+ )
+ }, [queryCached]) // Only run effect if queryCached changes
+
+ return state
+}
+
+function getDocData(
+ docSnapshot: firebase.firestore.DocumentSnapshot,
+): FirestoreDocumentData | null {
+ return docSnapshot.exists === true
+ ? { id: docSnapshot.id, ...(docSnapshot.data() as TData) }
+ : null
+}
+
+function getCollectionData(
+ collectionSnapshot: firebase.firestore.QuerySnapshot,
+) {
+ return collectionSnapshot.docs
+ .map(getDocData)
+ .filter((d) => d) as FirestoreDocumentData[]
+}
+
+type FirestoreDocumentData = TData & { id: string }
+
+type FirestoreQueryResultUnion =
+ | firebase.firestore.Query
+ | firebase.firestore.CollectionReference
+ | firebase.firestore.DocumentReference
+
+type FirestoreQuery = (
+ firestore: firebase.firestore.Firestore,
+) => FirestoreQueryResultUnion
+
+type FirestoreQueryDataType<
+ TQuery extends FirestoreQuery
+> = TQuery extends FirestoreQuery ? TData : never
+
+type FirestoreQueryState<
+ TQueryResult extends FirestoreQueryResultUnion,
+ TData
+> =
+ | {
+ status: 'idle' | 'loading'
+ data: null
+ error: null
+ }
+ | {
+ status: 'success'
+ data: FirestoreQueryStateData
+ error: null
+ }
+ | {
+ status: 'error'
+ data: null
+ error: Error
+ }
+
+type FirestoreQueryStateData<
+ TQueryResult extends FirestoreQueryResultUnion,
+ TData
+> = TQueryResult extends firebase.firestore.DocumentReference
+ ? FirestoreDocumentData | null
+ : FirestoreDocumentData[]
+
+type FirestoreQueryReducer<
+ TQueryResult extends FirestoreQueryResultUnion,
+ TData
+> = (
+ state: FirestoreQueryState,
+ action: FirestoreQueryStateAction,
+) => FirestoreQueryState
+
+type FirestoreQueryStateAction =
+ | {
+ type: 'idle' | 'loading'
+ }
+ | {
+ type: 'success'
+ payload:
+ | FirestoreDocumentData
+ | FirestoreDocumentData[]
+ | null
+ }
+ | {
+ type: 'error'
+ payload: Error
+ }
diff --git a/src/utils/useMemoCompare.ts b/src/utils/useMemoCompare.ts
new file mode 100644
index 0000000..b63fc8f
--- /dev/null
+++ b/src/utils/useMemoCompare.ts
@@ -0,0 +1,26 @@
+import { useEffect, useRef } from 'react'
+
+export default function useMemoCompare(
+ next: T,
+ compare: (previous: T | undefined, next: T | undefined) => boolean,
+) {
+ // Ref for storing previous value
+ const previousRef = useRef()
+ const previous = previousRef.current
+
+ // Pass previous and next value to compare function
+ // to determine whether to consider them equal.
+ const isEqual = compare(previous, next)
+
+ // If not equal update previousRef to next value.
+ // We only update if not equal so that this hook continues to return
+ // the same old value if compare keeps returning true.
+ useEffect(() => {
+ if (!isEqual) {
+ previousRef.current = next
+ }
+ })
+
+ // Finally, if equal then return the previous value
+ return isEqual ? previous : next
+}
diff --git a/types/utils/firestore.d.ts b/types/utils/firestore.d.ts
deleted file mode 100644
index 5b71703..0000000
--- a/types/utils/firestore.d.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-type UseFirestoreData =
- | {
- state: 'loading' | 'not-found'
- data: null
- error: null
- }
- | {
- state: 'success'
- data: TDocument
- error: null
- }
- | {
- state: 'error'
- data: null
- error: Error
- }
-
-type DocumentWithId = TDocument & { id: string }
diff --git a/types/viewRaidData.d.ts b/types/viewRaidData.d.ts
index ffd7178..6d5dde4 100644
--- a/types/viewRaidData.d.ts
+++ b/types/viewRaidData.d.ts
@@ -8,6 +8,7 @@ interface UserStats {
}
interface ViewRaidData {
+ id: string
dungeon: string
title: string
status: 'active' | 'completed'
From f218e191b8c54a52f38cffacd08ff9700dcc6d18 Mon Sep 17 00:00:00 2001
From: Braydon Hall <40751395+nobrayner@users.noreply.github.com>
Date: Sat, 27 Mar 2021 08:57:16 +1100
Subject: [PATCH 5/5] Actually make stuff work
---
snowpack.config.js | 2 +-
{assets => src/assets}/bg_logo.svg | 0
{assets => src/assets}/logo.svg | 0
src/routes/Home.tsx | 4 +-
src/routes/raids/ViewRaid.tsx | 5 +-
src/routes/raids/index.tsx | 15 ++--
src/utils/useFirestoreQuery.ts | 48 +++++++------
tsconfig.json | 2 +-
yarn.lock | 107 ++++++++++++++++++++++-------
9 files changed, 128 insertions(+), 55 deletions(-)
rename {assets => src/assets}/bg_logo.svg (100%)
rename {assets => src/assets}/logo.svg (100%)
diff --git a/snowpack.config.js b/snowpack.config.js
index 5e48833..9343ceb 100644
--- a/snowpack.config.js
+++ b/snowpack.config.js
@@ -20,7 +20,7 @@ module.exports = {
alias: {
'#components': './src/components',
'#utils': './src/utils',
- '#assets': './assets',
+ assets: './src/assets',
},
exclude: ['**/*.stories.@(js|jsx|ts|tsx)'],
}
diff --git a/assets/bg_logo.svg b/src/assets/bg_logo.svg
similarity index 100%
rename from assets/bg_logo.svg
rename to src/assets/bg_logo.svg
diff --git a/assets/logo.svg b/src/assets/logo.svg
similarity index 100%
rename from assets/logo.svg
rename to src/assets/logo.svg
diff --git a/src/routes/Home.tsx b/src/routes/Home.tsx
index e2c5b57..cb35a79 100644
--- a/src/routes/Home.tsx
+++ b/src/routes/Home.tsx
@@ -1,7 +1,7 @@
import React from 'react'
import { NavLink } from 'react-router-dom'
-import backgroundLogo from '#assets/bg_logo.svg'
-import logo from '#assets/logo.svg'
+import backgroundLogo from 'assets/bg_logo.svg'
+import logo from 'assets/logo.svg'
import styled from '@emotion/styled'
const Home = () => {
diff --git a/src/routes/raids/ViewRaid.tsx b/src/routes/raids/ViewRaid.tsx
index bcdc300..31fbeae 100644
--- a/src/routes/raids/ViewRaid.tsx
+++ b/src/routes/raids/ViewRaid.tsx
@@ -21,7 +21,10 @@ const userStatSortNames = Object.keys(userStatSorts)
const ViewRaid = () => {
const { raidId } = useParams<{ raidId: string }>()
const documentQuery = useFirestoreQuery((firestore) =>
- firestore.collection(RAID_STATS).withConverter(to()).doc(),
+ firestore
+ .collection(RAID_STATS)
+ .withConverter(to())
+ .doc(raidId),
)
const [currentSort, setCurrentSort] = useState(userStatSortNames[0])
diff --git a/src/routes/raids/index.tsx b/src/routes/raids/index.tsx
index 2a7687e..14ad061 100644
--- a/src/routes/raids/index.tsx
+++ b/src/routes/raids/index.tsx
@@ -2,10 +2,11 @@ import React from 'react'
import { Link } from 'react-router-dom'
import LoadingSpinner from '#components/loadingSpinner'
-import useFirestoreQuery, { to } from '#utils/useFirestoreQuery'
import { RAID_STATS } from '#utils/firestoreCollections'
+import useFirestoreQuery, { to } from '#utils/useFirestoreQuery'
const AllRaids = () => {
+ console.log('Rendering page...')
const collectionQuery = useFirestoreQuery((firestore) =>
firestore.collection(RAID_STATS).withConverter(to()),
)
@@ -41,16 +42,20 @@ const AllRaids = () => {
>
)
+ } else if (collectionQuery.status === 'error') {
+ return (
+ <>
+ An error occurred
+ {JSON.stringify(collectionQuery.error)}
+ >
+ )
}
return collectionQuery.status === 'loading' ? (
) : (
// Theoretically this can/should never be hit... But a fun message nonetheless
-
- {`Strange... I could've sworn the Manticore was here a second ago! Seems
- there aren't any Raids right now. Try again later!`}
-
+ {`We ain't doing much, here`}
)
}
diff --git a/src/utils/useFirestoreQuery.ts b/src/utils/useFirestoreQuery.ts
index 7fa92c3..c48c433 100644
--- a/src/utils/useFirestoreQuery.ts
+++ b/src/utils/useFirestoreQuery.ts
@@ -25,18 +25,20 @@ if (import.meta.env.NODE_ENV !== 'production') {
firestore.useEmulator('localhost', 8080)
}
+const converter = {
+ toFirestore(data: unknown): firebase.firestore.DocumentData {
+ return data as firebase.firestore.DocumentData
+ },
+ fromFirestore(
+ snapshot: firebase.firestore.QueryDocumentSnapshot,
+ options: firebase.firestore.SnapshotOptions,
+ ): unknown {
+ return snapshot.data(options)
+ },
+}
+
export function to() {
- return {
- toFirestore(data: TData): firebase.firestore.DocumentData {
- return data
- },
- fromFirestore(
- snapshot: firebase.firestore.QueryDocumentSnapshot,
- options: firebase.firestore.SnapshotOptions,
- ): TData {
- return snapshot.data(options) as TData
- },
- }
+ return converter as firebase.firestore.FirestoreDataConverter
}
const reducer = <
@@ -71,7 +73,7 @@ export default function useFirestoreQuery<
const [state, dispatch] = useReducer<
FirestoreQueryReducer
>(reducer, {
- status: 'loading',
+ status: 'idle',
data: null,
error: null,
})
@@ -80,15 +82,20 @@ export default function useFirestoreQuery<
// Needed because firestore.collection().doc() will always be a new object reference
// causing effect to run -> state change -> rerender -> effect runs -> etc ...
// This is nicer than requiring hook consumer to always memoize query with useMemo.
- const queryCached = useMemoCompare(query(firestore), (prevQuery) => {
- if (prevQuery && query) {
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore
- query.isEqual(prevQuery)
- }
+ const queryCached = useMemoCompare(
+ query(firestore),
+ (prevQueryResult, nextQueryResult) => {
+ if (prevQueryResult && nextQueryResult) {
+ return nextQueryResult.isEqual(
+ prevQueryResult as firebase.firestore.Query &
+ firebase.firestore.CollectionReference &
+ firebase.firestore.DocumentReference,
+ )
+ }
- return false
- })
+ return prevQueryResult === nextQueryResult // If both are undefined, then they are the same
+ },
+ )
useEffect(() => {
if (!queryCached) {
@@ -113,7 +120,6 @@ export default function useFirestoreQuery<
})
} else {
const data = getDocData(snapshot)
-
dispatch({ type: 'success', payload: data }) // need something better for the null case...
}
},
diff --git a/tsconfig.json b/tsconfig.json
index 0681609..6b53677 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -10,7 +10,7 @@
"paths": {
"#components/*": ["./src/components/*"],
"#utils/*": ["./src/utils/*"],
- "#assets/*": ["./assets/*"]
+ "assets/*": ["./src/assets/*"]
},
/* noEmit - Snowpack builds (emits) files, not tsc. */
"noEmit": true,
diff --git a/yarn.lock b/yarn.lock
index 5e7507c..68d2a16 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4398,7 +4398,7 @@ better-opn@^2.0.0:
dependencies:
open "^7.0.3"
-big-integer@^1.6.17:
+big-integer@^1.6.17, big-integer@^1.6.7:
version "1.6.48"
resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.48.tgz"
integrity sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==
@@ -4507,6 +4507,13 @@ boxen@^4.1.0, boxen@^4.2.0:
type-fest "^0.8.1"
widest-line "^3.1.0"
+bplist-parser@^0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.1.1.tgz#d60d5dcc20cba6dc7e1f299b35d3e1f95dafbae6"
+ integrity sha1-1g1dzCDLptx+HymbNdPh+V2vuuY=
+ dependencies:
+ big-integer "^1.6.7"
+
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz"
@@ -5073,6 +5080,11 @@ cli-spinners@^2.0.0:
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.5.0.tgz"
integrity sha512-PC+AmIuK04E6aeSs/pUccSujsTzBhu4HzC2dL+CfJB/Jcc2qTRbEwZQDfIUpt2Xl8BodYBEq8w4fc0kU2I9DjQ==
+cli-spinners@^2.5.0:
+ version "2.6.0"
+ resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.0.tgz#36c7dc98fb6a9a76bd6238ec3f77e2425627e939"
+ integrity sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q==
+
cli-table3@0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.0.tgz"
@@ -5820,6 +5832,15 @@ deepmerge@^4.2.2:
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz"
integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==
+default-browser-id@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-2.0.0.tgz#01ecce371a71e85f15a17177e7863047e73dbe7d"
+ integrity sha1-AezONxpx6F8VoXF354YwR+c9vn0=
+ dependencies:
+ bplist-parser "^0.1.0"
+ pify "^2.3.0"
+ untildify "^2.0.0"
+
defaults@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz"
@@ -6437,10 +6458,10 @@ es6-weak-map@^2.0.3:
es6-iterator "^2.0.3"
es6-symbol "^3.1.1"
-esbuild@^0.8.7:
- version "0.8.36"
- resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.8.36.tgz"
- integrity sha512-kcUQB61Tf8rLJ3mOwP2ruWi/iFufaQcEs4No+JA6e7W2kMOtFExOsbyeFpEF6zNacwk2RF5fYUz5jfZwgn/SJg==
+esbuild@^0.9.3:
+ version "0.9.7"
+ resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.9.7.tgz#ea0d639cbe4b88ec25fbed4d6ff00c8d788ef70b"
+ integrity sha512-VtUf6aQ89VTmMLKrWHYG50uByMF4JQlVysb8dmg6cOgW8JnFCipmz7p+HNBl+RR3LLCuBxFGVauAe2wfnF9bLg==
escalade@^3.1.1:
version "3.1.1"
@@ -7032,6 +7053,11 @@ fb-watchman@^2.0.0:
dependencies:
bser "2.1.1"
+fdir@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/fdir/-/fdir-5.0.0.tgz#a40b5d9adfb530daeca55558e8ad87ec14a44769"
+ integrity sha512-cteqwWMA43lEmgwOg5HSdvhVFD39vHjQDhZkRMlKmeoNPtSSgUw1nUypydiY2upMdGiBFBZvNBDbnoBh0yCzaQ==
+
fecha@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.0.tgz"
@@ -7485,15 +7511,15 @@ fsevents@^1.2.7:
bindings "^1.5.0"
nan "^2.12.1"
-fsevents@^2.1.2, fsevents@^2.2.0, fsevents@~2.3.1:
+fsevents@^2.1.2, fsevents@~2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.1.tgz#b209ab14c61012636c8863507edf7fb68cc54e9f"
integrity sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw==
-fsevents@~2.1.2:
- version "2.1.3"
- resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e"
- integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==
+fsevents@^2.2.0:
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
+ integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
fstream@^1.0.12:
version "1.0.12"
@@ -8634,7 +8660,7 @@ is-ci@^2.0.0:
dependencies:
ci-info "^2.0.0"
-is-core-module@^2.1.0:
+is-core-module@^2.1.0, is-core-module@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz"
integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==
@@ -8690,7 +8716,7 @@ is-directory@^0.3.1:
is-docker@^2.0.0:
version "2.1.1"
- resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.1.1.tgz"
+ resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.1.1.tgz#4125a88e44e450d384e09047ede71adc2d144156"
integrity sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==
is-dom@^1.0.0:
@@ -8944,7 +8970,7 @@ is-wsl@^1.1.0:
is-wsl@^2.1.1, is-wsl@^2.2.0:
version "2.2.0"
- resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz"
+ resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271"
integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==
dependencies:
is-docker "^2.0.0"
@@ -11042,7 +11068,7 @@ open@^6.3.0:
dependencies:
is-wsl "^1.1.0"
-open@^7.0.2, open@^7.0.3, open@^7.0.4:
+open@^7.0.2, open@^7.0.3:
version "7.3.1"
resolved "https://registry.yarnpkg.com/open/-/open-7.3.1.tgz"
integrity sha512-f2wt9DCBKKjlFbjzGb8MOAW8LH8F0mrs1zc7KTjAJ9PZNQbfenzWbNP1VZJvw6ICMG9r14Ah6yfwPn7T7i646A==
@@ -11050,6 +11076,14 @@ open@^7.0.2, open@^7.0.3, open@^7.0.4:
is-docker "^2.0.0"
is-wsl "^2.1.1"
+open@^7.0.4:
+ version "7.4.2"
+ resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321"
+ integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==
+ dependencies:
+ is-docker "^2.0.0"
+ is-wsl "^2.1.1"
+
openapi3-ts@^1.2.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/openapi3-ts/-/openapi3-ts-1.4.0.tgz"
@@ -11101,6 +11135,11 @@ os-browserify@^0.3.0:
resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz"
integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=
+os-homedir@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
+ integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M=
+
os-tmpdir@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz"
@@ -11463,12 +11502,12 @@ performance-now@^2.1.0:
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz"
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
-picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1:
+picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1, picomatch@^2.2.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz"
integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==
-pify@^2.0.0:
+pify@^2.0.0, pify@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz"
integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw=
@@ -12702,6 +12741,14 @@ resolve@^1.1.6, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.17
is-core-module "^2.1.0"
path-parse "^1.0.6"
+resolve@^1.20.0:
+ version "1.20.0"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
+ integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
+ dependencies:
+ is-core-module "^2.2.0"
+ path-parse "^1.0.6"
+
responselike@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz"
@@ -12765,11 +12812,11 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
inherits "^2.0.1"
rollup@^2.34.0:
- version "2.38.1"
- resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.38.1.tgz"
- integrity sha512-q07T6vU/V1kqM8rGRRyCgEvIQcIAXoKIE5CpkYAlHhfiWM1Iuh4dIPWpIbqFngCK6lwAB2aYHiUVhIbSWHQWhw==
+ version "2.42.4"
+ resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.42.4.tgz#97c910a48bd0db6aaa4271dd48745870cbbbf970"
+ integrity sha512-Zqv3EvNfcllBHyyEUM754npqsZw82VIjK34cDQMwrQ1d6aqxzeYu5yFb7smGkPU4C1Bj7HupIMeT6WU7uIdnMw==
optionalDependencies:
- fsevents "~2.1.2"
+ fsevents "~2.3.1"
router@^1.3.1:
version "1.3.5"
@@ -13169,12 +13216,17 @@ snapdragon@^0.8.1:
use "^3.1.0"
snowpack@^3.0.1:
- version "3.0.11"
- resolved "https://registry.yarnpkg.com/snowpack/-/snowpack-3.0.11.tgz"
- integrity sha512-lBxgkvWTgdg0szE31JUt01wQkA9Lnmm+6lxqeV9rxDfflpx7ASnldVHFvu7Se70QJmPTQB0UJjfKI+xmYGwiiQ==
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/snowpack/-/snowpack-3.1.2.tgz#47f376ac48b83de07093722c402c9218a6c9b542"
+ integrity sha512-LsYlBNjB/t/p5QP434Pa1TqjyuX8VtXiYQaAWZkOn1d1TVKEt7nigMBr8Z+EDXYn6YlLXYKHXDvv/NhUS7Ri9A==
dependencies:
- esbuild "^0.8.7"
+ cli-spinners "^2.5.0"
+ default-browser-id "^2.0.0"
+ esbuild "^0.9.3"
+ fdir "^5.0.0"
open "^7.0.4"
+ picomatch "^2.2.2"
+ resolve "^1.20.0"
rollup "^2.34.0"
optionalDependencies:
fsevents "^2.2.0"
@@ -14361,6 +14413,13 @@ unset-value@^1.0.0:
has-value "^0.3.1"
isobject "^3.0.0"
+untildify@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/untildify/-/untildify-2.1.0.tgz#17eb2807987f76952e9c0485fc311d06a826a2e0"
+ integrity sha1-F+soB5h/dpUunASF/DEdBqgmouA=
+ dependencies:
+ os-homedir "^1.0.0"
+
unzipper@^0.10.10:
version "0.10.11"
resolved "https://registry.yarnpkg.com/unzipper/-/unzipper-0.10.11.tgz"