Update React, fix null dates, add default route for missing season ID and move blurred area effect to table only
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -32,8 +32,9 @@ export class AppController {
|
||||
return await this.sinusBotService.fetchStats();
|
||||
}
|
||||
|
||||
@Get('/stats/season/:id')
|
||||
@Get('/stats/season/:id?')
|
||||
async getStats(@Param('id') id?: string): Promise<UserStatsResponse> {
|
||||
logger.info(`Got id ${id}`)
|
||||
return await this.databaseService
|
||||
.fetchStats(id)
|
||||
.catch(err => {
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
} from '../models/aliases';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
import { seasons } from '@prisma/client';
|
||||
import logger from 'src/logger/Logger';
|
||||
|
||||
@Injectable()
|
||||
export class DatabaseService {
|
||||
@@ -25,7 +26,7 @@ export class DatabaseService {
|
||||
})
|
||||
.then(value => this.prismaClient.seasons.findUnique({
|
||||
where: {
|
||||
season_id: Number((!seasonId ? value : seasonId))
|
||||
season_id: Number(seasonId ?? value)
|
||||
}
|
||||
}) as Promise<seasons>)
|
||||
.then((result: SeasonInfo) => {
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
"husky": "^4.3.7",
|
||||
"lint-staged": "^10.5.3",
|
||||
"prettier": "^2.2.1",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react": "17.0.0",
|
||||
"react-dom": "17.0.0",
|
||||
"react-router": "^5.2.0",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-scripts": "3.4.1",
|
||||
|
||||
@@ -11,30 +11,10 @@ library.add(faArrowCircleLeft, faArrowCircleRight)
|
||||
const App: FunctionComponent = () => (
|
||||
<Router>
|
||||
<Switch>
|
||||
{/*<Route exact path={'/'} component={(props: IMainPageProps) => (<MainPage {...props}/>)} />*/}
|
||||
<Route path={'/season/:id'} component={(props: IMainPageProps) => (<MainPage {...props}/>)} />
|
||||
<Route path={'/season/:id?'} component={(props: IMainPageProps) => (<MainPage {...props}/>)} />
|
||||
<Redirect to={'/season'} />
|
||||
</Switch>
|
||||
</Router>
|
||||
);
|
||||
|
||||
export default App;
|
||||
|
||||
|
||||
// export default class App extends React.Component {
|
||||
|
||||
// componentDidMount() {
|
||||
// this.setState({loading: false, mock: this.mockService.getStatsWithoutPromise()});
|
||||
// this.apiService.getStats()
|
||||
// .then(data => this.setState({
|
||||
// isLoaded: true,
|
||||
// users: data
|
||||
// }))
|
||||
// .catch(error => {
|
||||
// error.response.json()
|
||||
// .then((err: any) => this.setState({
|
||||
// isLoaded: true,
|
||||
// error: err.error
|
||||
// }))
|
||||
// });
|
||||
// }
|
||||
@@ -7,17 +7,21 @@ const SeasonDetail: React.FC<IUserListProperties> = (props: IUserListProperties)
|
||||
|
||||
return (
|
||||
<span className="SeasonDetail" data-testid="SeasonDetail">
|
||||
Season {seasonId} - Duration: {dates.start.toDateString()} - {dates.end.toDateString()}
|
||||
Season {seasonId} - Duration: {dateToString(dates.start)} - {dateToString(dates.end)}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
const dateToString = (date?: Date): string => {
|
||||
return date ? date.toLocaleDateString('en-GB') : 'TBD';
|
||||
}
|
||||
|
||||
export interface SeasonDetailProperties {
|
||||
seasonId: string,
|
||||
seasonId?: string,
|
||||
maxSeasonId: string
|
||||
dates: {
|
||||
start: Date,
|
||||
end: Date
|
||||
start?: Date,
|
||||
end?: Date
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,14 +10,18 @@ const SeasonSwitch: React.FC<IUserListProperties> = (props: IUserListProperties)
|
||||
const maxSeasonId = Number(props.userStats.maxSeasonId)
|
||||
|
||||
return (
|
||||
<div className={"SeasonSwitch " + (!props.enabled && " no-click")} data-testid="SeasonSwitch">
|
||||
<div className={"SeasonSwitch"} data-testid="SeasonSwitch">
|
||||
{
|
||||
seasonId > 1
|
||||
&& (props.enabled
|
||||
? <Link to={"/season/" + (seasonId - 1)} onClick={() => props.onSeasonIdChange('' + (seasonId - 1))}>
|
||||
&& <Link to={"/season/" + (seasonId - 1)} onClick={() => {
|
||||
console.log("nothing happens")
|
||||
props.onSeasonIdChange('' + (seasonId - 1))}}>
|
||||
<FontAwesomeIcon icon="arrow-circle-left"/>
|
||||
</Link>
|
||||
: <Link to={""} onClick={(e) => e.preventDefault()}>
|
||||
|| <Link to={""} onClick={(e) => {
|
||||
console.log("nothing happens2")
|
||||
e.preventDefault()}}>
|
||||
<FontAwesomeIcon icon="arrow-circle-left"/>
|
||||
</Link>)
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ const createTableEntries = (entries: TableEntry[]) =>
|
||||
const UserList: React.FC<IUserListProperties> = (props: IUserListProperties) => (
|
||||
<div className="UserList" data-testid="UserList">
|
||||
<SeasonSwitch {...props} />
|
||||
<table>
|
||||
<table className={!props.enabled ? "blurred" : ""}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Placement</th>
|
||||
@@ -43,7 +43,7 @@ const UserList: React.FC<IUserListProperties> = (props: IUserListProperties) =>
|
||||
export interface IUserListProperties {
|
||||
userStats: UserStatsResponse
|
||||
mocked?: boolean
|
||||
onSeasonIdChange: any
|
||||
onSeasonIdChange: React.Dispatch<React.SetStateAction<string | undefined>>
|
||||
enabled: boolean
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import UserStatsResponse from "../models/UserStatsResponse";
|
||||
import UserStatsService from "../services/UserStatsService";
|
||||
|
||||
export default class UserStatsMockService {
|
||||
export default class UserStatsMockService extends UserStatsService {
|
||||
private static readonly mocks: UserStatsResponse[] = [
|
||||
{
|
||||
seasonId: "1",
|
||||
@@ -33,14 +34,30 @@ export default class UserStatsMockService {
|
||||
{ name: "Humen", rank: "12", onlineTime: "0d 1h 0m 0s" },
|
||||
{ name: "Humen", rank: "ok", onlineTime: "0d 1h 0m 0s" }
|
||||
]
|
||||
},
|
||||
{
|
||||
seasonId: 'undefined',
|
||||
maxSeasonId: "2",
|
||||
dates: {
|
||||
start: undefined,
|
||||
end: undefined
|
||||
},
|
||||
stats: [
|
||||
{ name: "Humen", rank: "Overwatch Noob", onlineTime: "0d 1h 0m 0s" },
|
||||
{ name: "Humen", rank: "Random Rank 3", onlineTime: "0d 1h 0m 0s" },
|
||||
{ name: "Humen", rank: "Kas is cool", onlineTime: "0d 1h 0m 0s" },
|
||||
{ name: "Humen", rank: "Bremsspur", onlineTime: "0d 1h 0m 0s" },
|
||||
{ name: "Humen", rank: "12", onlineTime: "0d 1h 0m 0s" },
|
||||
{ name: "Humen", rank: "ok", onlineTime: "0d 1h 0m 0s" }
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
static async getStats(seasonId: string): Promise<UserStatsResponse> {
|
||||
return Promise.resolve(this.mocks[Number(seasonId) - 1])
|
||||
public static async getStats(seasonId?: string): Promise<UserStatsResponse> {
|
||||
return Promise.resolve(this.mocks[Number((seasonId ? seasonId : 2)) - 1])
|
||||
}
|
||||
|
||||
static getStatsWithoutPromise(seasonId: string): UserStatsResponse {
|
||||
return this.mocks[Number(seasonId) - 1]
|
||||
static getStatsWithoutPromise(seasonId?: string): UserStatsResponse {
|
||||
return this.mocks[Number((seasonId ? seasonId : 2)) - 1]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,13 +13,15 @@ import {ClipLoader} from "react-spinners";
|
||||
import UserStatsService from "../../services/UserStatsService";
|
||||
|
||||
const MainPage: FC<IMainPageProps> = (props: IMainPageProps) => {
|
||||
const [seasonId, setSeasonId] = useState(props.match.params.id)
|
||||
const [error, setError] = useState<RequestError | undefined>(undefined)
|
||||
const [loading, setLoadingState] = useState(true)
|
||||
const [seasonId, setSeasonId] = useState(props.match.params.id)
|
||||
const [error, setError] = useState<RequestError | undefined>(undefined)
|
||||
const [loading, setLoadingState] = useState(true)
|
||||
const [seasonStats, setSeasonStats] = useState<UserStatsResponse>(UserStatsMockService.getStatsWithoutPromise(seasonId))
|
||||
const [spinnerColor] = useState('#61dafb')
|
||||
|
||||
useEffect(() => {
|
||||
setLoadingState(true)
|
||||
setSeasonStats(UserStatsMockService.getStatsWithoutPromise('3'))
|
||||
UserStatsService.getStats(seasonId)
|
||||
.then(res => {
|
||||
setSeasonStats(res)
|
||||
@@ -30,7 +32,7 @@ const MainPage: FC<IMainPageProps> = (props: IMainPageProps) => {
|
||||
setLoadingState(false)
|
||||
setError(new RequestError(0, "Could not retrieve stats. Try again later."))
|
||||
})
|
||||
}, [seasonId, setLoadingState])
|
||||
}, [seasonId])
|
||||
|
||||
const spinnerCss = `
|
||||
margin: 0;
|
||||
@@ -46,16 +48,14 @@ const MainPage: FC<IMainPageProps> = (props: IMainPageProps) => {
|
||||
}
|
||||
|
||||
<ClipLoader color={spinnerColor} loading={loading} size={150} css={spinnerCss} />
|
||||
<div className={loading || error ? "blurred" : ""}>
|
||||
<UserList enabled={loading || !(!error)} onSeasonIdChange={setSeasonId} userStats={seasonStats} />
|
||||
</div>
|
||||
<UserList enabled={!loading && (error == null)} onSeasonIdChange={setSeasonId} userStats={seasonStats} />
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export interface IMainPageProps extends RouteComponentProps<{ id: string }> {
|
||||
export interface IMainPageProps extends RouteComponentProps<{ id?: string }> {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,7 @@ import UserStatsResponse from "../models/UserStatsResponse";
|
||||
export default class UserStatsService {
|
||||
|
||||
private static apiURL = 'https://api.tsotr.humenius.me/stats'
|
||||
// private static apiURL = 'http://localhost:3500/stats'
|
||||
//private static apiURL = 'https://mock.codes/501'
|
||||
//private static apiURL = 'http://localhost:3500/stats'
|
||||
|
||||
private static requestInit: RequestInit = {
|
||||
method: 'GET',
|
||||
@@ -14,13 +13,13 @@ export default class UserStatsService {
|
||||
},
|
||||
};
|
||||
|
||||
public static async getStats(seasonId: string): Promise<UserStatsResponse> {
|
||||
return fetch(`${this.apiURL}/season/${seasonId}`, this.requestInit)
|
||||
public static async getStats(seasonId?: string): Promise<UserStatsResponse> {
|
||||
return fetch(`${this.apiURL}/season/${seasonId ?? ''}`, this.requestInit)
|
||||
.then(res => UserStatsService.checkResponse(res))
|
||||
.then(data => data.json())
|
||||
.then(data => {
|
||||
data.dates.start = new Date(data.dates.start)
|
||||
data.dates.end = new Date(data.dates.end)
|
||||
data.dates.start = data.dates.start ? new Date(data.dates.start) : undefined
|
||||
data.dates.end = data.dates.end ? new Date(data.dates.end) : undefined
|
||||
return data
|
||||
})
|
||||
}
|
||||
@@ -33,69 +32,3 @@ export default class UserStatsService {
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
// const checkResponse = <T extends Response>(response: T): T => {
|
||||
// if (!response.ok) {
|
||||
// console.log(response);
|
||||
// let error = new RequestError(response.statusText);
|
||||
// error.response = response;
|
||||
// throw error;
|
||||
// }
|
||||
// return response;
|
||||
// }
|
||||
//
|
||||
// const useApiService = <T>(url: string, method: string = 'GET'): { response: T | null; error: RequestError | null } => {
|
||||
// const baseUrl = "https://api.tsotr.humenius.me"
|
||||
// const [response, setResponse] = useState<T | null>(null)
|
||||
// const [error, setError] = useState<RequestError | null>(null)
|
||||
// const requestInit = {
|
||||
// method: method,
|
||||
// headers: {
|
||||
// 'Content-Type': 'application/json'
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// useEffect(() => {
|
||||
// const fetchData = async (): Promise<void> => {
|
||||
// const result = await fetch(`${baseUrl}${url}`, requestInit)
|
||||
// .then(res => checkResponse(res))
|
||||
// .then(data => data.json())
|
||||
// .catch(err => setError(err))
|
||||
// setResponse(result)
|
||||
// }
|
||||
//
|
||||
// fetchData()
|
||||
// }, [url])
|
||||
//
|
||||
// return { response, error }
|
||||
// }
|
||||
//
|
||||
// // const seasonStatsQuery = (seasonId: number): { response: UserStatsResponse | null; error: RequestError | null } => {
|
||||
// // const baseUrl = "https://api.tsotr.humenius.me/stats/season/"
|
||||
// // const [response, setResponse] = useState<UserStatsResponse | null>(null)
|
||||
// // const [error, setError] = useState<RequestError | null>(null)
|
||||
// // const requestInit = {
|
||||
// // method: 'GET',
|
||||
// // headers: {
|
||||
// // 'Content-Type': 'application/json'
|
||||
// // }
|
||||
// // }
|
||||
// //
|
||||
// // useEffect(() => {
|
||||
// // const fetchData = async (): Promise<void> => {
|
||||
// // const result = await fetch(baseUrl, requestInit)
|
||||
// // .then(res => checkResponse(res))
|
||||
// // .then(data => data.json())
|
||||
// // .catch(err => setError(err))
|
||||
// // setResponse(result)
|
||||
// // }
|
||||
// //
|
||||
// // fetchData()
|
||||
// // }, [seasonId])
|
||||
// //
|
||||
// // return { response, error }
|
||||
// // }
|
||||
//
|
||||
// const currentSeasonStatsQuery = useApiService<UserStatsResponse>('/stats')
|
||||
//
|
||||
// export default useApiService;
|
||||
@@ -1667,11 +1667,6 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.8.tgz#49348387983075705fe8f4e02fb67f7daaec4934"
|
||||
integrity sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA==
|
||||
|
||||
"@types/isomorphic-fetch@^0.0.35":
|
||||
version "0.0.35"
|
||||
resolved "https://registry.yarnpkg.com/@types/isomorphic-fetch/-/isomorphic-fetch-0.0.35.tgz#c1c0d402daac324582b6186b91f8905340ea3361"
|
||||
integrity sha512-DaZNUvLDCAnCTjgwxgiL1eQdxIKEpNLOlTNtAgnZc50bG2copGhRrFN9/PxPBuJe+tZVLCbQ7ls0xveXVRPkvw==
|
||||
|
||||
"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0":
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762"
|
||||
@@ -4806,11 +4801,6 @@ fb-watchman@^2.0.0:
|
||||
dependencies:
|
||||
bser "2.1.1"
|
||||
|
||||
fetch-retry-ts@^1.1.23:
|
||||
version "1.1.23"
|
||||
resolved "https://registry.yarnpkg.com/fetch-retry-ts/-/fetch-retry-ts-1.1.23.tgz#7659974215c7a66b9bb81c006e5acee34d932ca8"
|
||||
integrity sha512-UwqrMGfDPRa60etXl1HkDgIhY9k2AoB/Qa41/U2thzHtA/NVHGSmn037dw4iOg62ccyX2imtkU8SFfSwxLLEYA==
|
||||
|
||||
figgy-pudding@^3.5.1:
|
||||
version "3.5.2"
|
||||
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e"
|
||||
@@ -6179,14 +6169,6 @@ isobject@^3.0.0, isobject@^3.0.1:
|
||||
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
|
||||
integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
|
||||
|
||||
isomorphic-fetch@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz#0267b005049046d2421207215d45d6a262b8b8b4"
|
||||
integrity sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==
|
||||
dependencies:
|
||||
node-fetch "^2.6.1"
|
||||
whatwg-fetch "^3.4.1"
|
||||
|
||||
isstream@~0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
|
||||
@@ -7522,11 +7504,6 @@ no-case@^3.0.4:
|
||||
lower-case "^2.0.2"
|
||||
tslib "^2.0.3"
|
||||
|
||||
node-fetch@^2.6.1:
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
|
||||
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
|
||||
|
||||
node-forge@^0.10.0:
|
||||
version "0.10.0"
|
||||
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3"
|
||||
@@ -9241,15 +9218,14 @@ react-dev-utils@^10.2.1:
|
||||
strip-ansi "6.0.0"
|
||||
text-table "0.2.0"
|
||||
|
||||
react-dom@^16.13.1:
|
||||
version "16.14.0"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.14.0.tgz#7ad838ec29a777fb3c75c3a190f661cf92ab8b89"
|
||||
integrity sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==
|
||||
react-dom@17.0.0:
|
||||
version "17.0.0"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.0.tgz#f8266e4d9861584553ccbd186d596a1c7dd8dcb4"
|
||||
integrity sha512-OGnFbxCjI2TMAZYMVxi4hqheJiN8rCEVVrL7XIGzCB6beNc4Am8M47HtkvxODZw9QgjmAPKpLba9FTu4fC1byA==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
prop-types "^15.6.2"
|
||||
scheduler "^0.19.1"
|
||||
scheduler "^0.20.0"
|
||||
|
||||
react-error-overlay@^6.0.7:
|
||||
version "6.0.8"
|
||||
@@ -9362,14 +9338,13 @@ react-spinners@^0.10.4:
|
||||
dependencies:
|
||||
"@emotion/core" "^10.0.35"
|
||||
|
||||
react@^16.13.1:
|
||||
version "16.14.0"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d"
|
||||
integrity sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==
|
||||
react@17.0.0:
|
||||
version "17.0.0"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-17.0.0.tgz#ad96d5fa1a33bb9b06d0cc52672f7992d84aa662"
|
||||
integrity sha512-rG9bqS3LMuetoSUKHN8G3fMNuQOePKDThK6+2yXFWtoeTDLVNh/QCaxT+Jr+rNf4lwNXpx+atdn3Aa0oi8/6eQ==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
prop-types "^15.6.2"
|
||||
|
||||
read-pkg-up@^2.0.0:
|
||||
version "2.0.0"
|
||||
@@ -9864,10 +9839,10 @@ saxes@^3.1.9:
|
||||
dependencies:
|
||||
xmlchars "^2.1.1"
|
||||
|
||||
scheduler@^0.19.1:
|
||||
version "0.19.1"
|
||||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196"
|
||||
integrity sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==
|
||||
scheduler@^0.20.0:
|
||||
version "0.20.1"
|
||||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.1.tgz#da0b907e24026b01181ecbc75efdc7f27b5a000c"
|
||||
integrity sha512-LKTe+2xNJBNxu/QhHvDR14wUXHRQbVY5ZOYpOGWRzhydZUqrLb2JBvLPY7cAqFmqrWuDED0Mjk7013SZiOz6Bw==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
@@ -11335,7 +11310,7 @@ whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3, whatwg-encoding@^1.0.5:
|
||||
dependencies:
|
||||
iconv-lite "0.4.24"
|
||||
|
||||
whatwg-fetch@^3.0.0, whatwg-fetch@^3.4.1:
|
||||
whatwg-fetch@^3.0.0:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.5.0.tgz#605a2cd0a7146e5db141e29d1c62ab84c0c4c868"
|
||||
integrity sha512-jXkLtsR42xhXg7akoDKvKWE40eJeI+2KZqcp2h3NsOrRnDvtWX36KcKl30dy+hxECivdk2BVUHVNrPtoMBUx6A==
|
||||
|
||||
Reference in New Issue
Block a user