From b3b8df7b6dcb6c2800ba440d1b063d3a1ae0e7a1 Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Thu, 3 Aug 2023 20:06:49 +0800 Subject: [PATCH] feat: Typescript! (#461) * feat: Typescript! Signed-off-by: Frost Ming * chore: use node 16 as the base Signed-off-by: Frost Ming * fix: remove use dependencies Signed-off-by: Frost Ming --------- Signed-off-by: Frost Ming --- .eslintrc.js | 5 + .gitignore | 1 + Dockerfile | 2 +- README-CN.md | 122 ++++----- README.md | 117 ++++---- gatsby-config.js => gatsby-config.ts | 13 +- gatsby-node.js => gatsby-node.ts | 14 +- jsconfig.json | 18 -- package.json | 25 +- .../Header/{index.jsx => index.tsx} | 2 +- .../Layout/{index.jsx => index.tsx} | 8 +- .../{CitiesStat.jsx => CitiesStat.tsx} | 6 +- ...ocationSummary.jsx => LocationSummary.tsx} | 14 +- .../{PeriodStat.jsx => PeriodStat.tsx} | 6 +- .../LocationStat/{index.jsx => index.tsx} | 12 +- .../RunMap/{RunMaker.jsx => RunMaker.tsx} | 13 +- .../{RunMapButtons.jsx => RunMapButtons.tsx} | 6 +- .../RunMap/{index.jsx => index.tsx} | 37 ++- .../RunTable/{RunRow.jsx => RunRow.tsx} | 15 +- .../RunTable/{index.jsx => index.tsx} | 34 ++- .../SVGStat/{index.jsx => index.tsx} | 4 +- src/components/Stat/{index.jsx => index.tsx} | 16 +- .../YearStat/{index.jsx => index.tsx} | 12 +- .../YearsStat/{index.jsx => index.tsx} | 11 +- .../{useActivities.js => useActivities.ts} | 26 +- src/hooks/{useHover.js => useHover.ts} | 8 +- ...{useSiteMetadata.js => useSiteMetadata.ts} | 17 +- src/main.d.ts | 11 + src/pages/{404.jsx => 404.tsx} | 4 +- src/pages/{index.jsx => index.tsx} | 91 ++++--- src/static/{city.js => city.ts} | 11 +- .../{run_countries.js => run_countries.ts} | 8 +- src/utils/{const.js => const.ts} | 4 +- src/utils/{utils.js => utils.ts} | 116 +++++--- tsconfig.json | 113 ++++++++ yarn.lock | 256 ++++-------------- 36 files changed, 639 insertions(+), 539 deletions(-) rename gatsby-config.js => gatsby-config.ts (90%) rename gatsby-node.js => gatsby-node.ts (61%) delete mode 100644 jsconfig.json rename src/components/Header/{index.jsx => index.tsx} (93%) rename src/components/Layout/{index.jsx => index.tsx} (80%) rename src/components/LocationStat/{CitiesStat.jsx => CitiesStat.tsx} (78%) rename src/components/LocationStat/{LocationSummary.jsx => LocationSummary.tsx} (50%) rename src/components/LocationStat/{PeriodStat.jsx => PeriodStat.tsx} (77%) rename src/components/LocationStat/{index.jsx => index.tsx} (72%) rename src/components/RunMap/{RunMaker.jsx => RunMaker.tsx} (74%) rename src/components/RunMap/{RunMapButtons.jsx => RunMapButtons.tsx} (73%) rename src/components/RunMap/{index.jsx => index.tsx} (77%) rename src/components/RunTable/{RunRow.jsx => RunRow.tsx} (74%) rename src/components/RunTable/{index.jsx => index.tsx} (71%) rename src/components/SVGStat/{index.jsx => index.tsx} (73%) rename src/components/Stat/{index.jsx => index.tsx} (52%) rename src/components/YearStat/{index.jsx => index.tsx} (87%) rename src/components/YearsStat/{index.jsx => index.tsx} (71%) rename src/hooks/{useActivities.js => useActivities.ts} (69%) rename src/hooks/{useHover.js => useHover.ts} (56%) rename src/hooks/{useSiteMetadata.js => useSiteMetadata.ts} (58%) create mode 100644 src/main.d.ts rename src/pages/{404.jsx => 404.tsx} (81%) rename src/pages/{index.jsx => index.tsx} (63%) rename src/static/{city.js => city.ts} (99%) rename src/static/{run_countries.js => run_countries.ts} (99%) rename src/utils/{const.js => const.ts} (94%) rename src/utils/{utils.js => utils.ts} (67%) create mode 100644 tsconfig.json diff --git a/.eslintrc.js b/.eslintrc.js index 11748a961c5..2925873c0e4 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,5 +1,6 @@ // eslint-disable-next-line no-undef module.exports = { + parser: '@typescript-eslint/parser', env: { browser: true, es2021: true, @@ -24,5 +25,9 @@ module.exports = { rules: { 'prettier/prettier': 'off', 'react/prop-types': 'off', + 'no-unused-vars': ['error', { argsIgnorePattern: '^_' }], + }, + globals: { + NodeJS: true, }, }; diff --git a/.gitignore b/.gitignore index 40f3902dd1e..977f0b00768 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ _site/ .idea config.yaml +.venv/ diff --git a/Dockerfile b/Dockerfile index 1ace48439ef..4950735973e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ RUN apt-get update \ && pip3 config set global.index-url https://mirrors.aliyun.com/pypi/simple/ \ && pip3 install -r requirements.txt -FROM node:14 AS develop-node +FROM node:16 AS develop-node WORKDIR /root/running_page COPY ./package.json /root/running_page/package.json COPY ./yarn.lock /root/running_page/yarn.lock diff --git a/README-CN.md b/README-CN.md index 2c29ca050cd..632abddfb75 100644 --- a/README-CN.md +++ b/README-CN.md @@ -20,62 +20,62 @@ R.I.P. 希望大家都能健康顺利的跑过终点,逝者安息。
Running page runners -| Runner | page | App | -| ------------------------------------------------- | ---------------------------------------------- | --------- | -| [zhubao315](https://github.com/zhubao315) | | Strava | -| [shaonianche](https://github.com/shaonianche) | | Strava | -| [yihong0618](https://github.com/yihong0618) | | Nike | -| [superleeyom](https://github.com/superleeyom) | | Nike | -| [geekplux](https://github.com/geekplux) | | Nike | -| [guanlan](https://github.com/guanlan) | | Strava | -| [tuzimoe](https://github.com/tuzimoe) | | Nike | -| [ben_29](https://github.com/ben-29) | | Strava | -| [kcllf](https://github.com/kcllf) | | Garmin-cn | -| [mq](https://github.com/MQ-0707) | | Keep | -| [zhaohongxuan](https://github.com/zhaohongxuan) | | Strava | -| [yvetterowe](https://github.com/yvetterowe) | | Strava | -| [love-exercise](https://github.com/KaiOrange) | | Keep | -| [zstone12](https://github.com/zstone12) | | Keep | -| [Lax](https://github.com/Lax) | | Keep | -| [lusuzi](https://github.com/lusuzi) | | Nike | -| [wh1994](https://github.com/wh1994) | | Garmin | -| [liuyihui](https://github.com/YiHui-Liu) | | Keep | -| [sunyunxian](https://github.com/sunyunxian) | | Strava | -| [AhianZhang](https://github.com/AhianZhang) | | Nike | -| [L1cardo](https://github.com/L1cardo) | | Nike | -| [luckylele666](https://github.com/luckylele666) | | Strava | -| [MFYDev](https://github.com/MFYDev) | | Garmin-cn | -| [Oysmart](https://github.com/oysmart) | | Garmin-cn | -| [Eished](https://github.com/eished) | | Keep | -| [Liuxin](https://github.com/liuxindtc) | | Nike | -| [loucx](https://github.com/loucx) | | Nike | -| [winf42](https://github.com/winf42) | | Garmin-cn | -| [sun0225SUN](https://github.com/sun0225SUN) | | Nike | -| [Zhan](https://www.zlog.in/about) | | Nike | -| [Dennis](https://run.domon.cn) | | Garmin-cn | -| [hanpei](https://running.nexts.top) | | Garmin-cn | -| [liugezhou](https://github.com/liugezhou) | | Strava | -| [zhubao315](https://github.com/zhubao315) | | Strava | -| [Jason Tan](https://github.com/Jason-cqtan) | | Nike | -| [Conge](https://github.com/conge) | | Strava | -| [cvvz](https://github.com/cvvz) | | Strava | -| [zHElEARN](https://github.com/zHElEARN) | | Strava | -| [Rhfeng](https://sport.frh.life) | | Garmin-cn | -| [Ym9i](https://github.com/Ym9i) | | Strava | -| [jianchengwang](https://github.com/jianchengwang) | | Suunto | -| [fxbin](https://github.com/fxbin) | | Keep | -| [shensl4499](https://github.com/shensl4499) | | codoon | -| [haowei93](https://github.com/haowei93) | | gpx | -| [stevenash0822](https://github.com/stevenash0822) | | Strava | -| [Vint](https://github.com/VintLin) | | Keep | -| [Muyids](https://github.com/muyids) | | Garmin-cn | -| [Gao Hao](https://github.com/efish2002) | | Garmin-cn | -| [Jinlei](https://github.com/iamjinlei0312) | | AW-GPX | -| [Ray Wang](https://github.com/raywangsy) | | Garmin | -| [RealTiny656](https://github.com/tiny656) | | JoyRun | -| [EINDEX](https://github.com/eindex) | | Strava/Nike| -| [Melt](https://github.com/fpGHwd) | | Strava | -| [deepinwine](https://github.com/deepinwine) | | Garmin-cn | +| Runner | page | App | +| ------------------------------------------------- | ---------------------------------------------- | ----------- | +| [zhubao315](https://github.com/zhubao315) | | Strava | +| [shaonianche](https://github.com/shaonianche) | | Strava | +| [yihong0618](https://github.com/yihong0618) | | Nike | +| [superleeyom](https://github.com/superleeyom) | | Nike | +| [geekplux](https://github.com/geekplux) | | Nike | +| [guanlan](https://github.com/guanlan) | | Strava | +| [tuzimoe](https://github.com/tuzimoe) | | Nike | +| [ben_29](https://github.com/ben-29) | | Strava | +| [kcllf](https://github.com/kcllf) | | Garmin-cn | +| [mq](https://github.com/MQ-0707) | | Keep | +| [zhaohongxuan](https://github.com/zhaohongxuan) | | Strava | +| [yvetterowe](https://github.com/yvetterowe) | | Strava | +| [love-exercise](https://github.com/KaiOrange) | | Keep | +| [zstone12](https://github.com/zstone12) | | Keep | +| [Lax](https://github.com/Lax) | | Keep | +| [lusuzi](https://github.com/lusuzi) | | Nike | +| [wh1994](https://github.com/wh1994) | | Garmin | +| [liuyihui](https://github.com/YiHui-Liu) | | Keep | +| [sunyunxian](https://github.com/sunyunxian) | | Strava | +| [AhianZhang](https://github.com/AhianZhang) | | Nike | +| [L1cardo](https://github.com/L1cardo) | | Nike | +| [luckylele666](https://github.com/luckylele666) | | Strava | +| [MFYDev](https://github.com/MFYDev) | | Garmin-cn | +| [Oysmart](https://github.com/oysmart) | | Garmin-cn | +| [Eished](https://github.com/eished) | | Keep | +| [Liuxin](https://github.com/liuxindtc) | | Nike | +| [loucx](https://github.com/loucx) | | Nike | +| [winf42](https://github.com/winf42) | | Garmin-cn | +| [sun0225SUN](https://github.com/sun0225SUN) | | Nike | +| [Zhan](https://www.zlog.in/about) | | Nike | +| [Dennis](https://run.domon.cn) | | Garmin-cn | +| [hanpei](https://running.nexts.top) | | Garmin-cn | +| [liugezhou](https://github.com/liugezhou) | | Strava | +| [zhubao315](https://github.com/zhubao315) | | Strava | +| [Jason Tan](https://github.com/Jason-cqtan) | | Nike | +| [Conge](https://github.com/conge) | | Strava | +| [cvvz](https://github.com/cvvz) | | Strava | +| [zHElEARN](https://github.com/zHElEARN) | | Strava | +| [Rhfeng](https://sport.frh.life) | | Garmin-cn | +| [Ym9i](https://github.com/Ym9i) | | Strava | +| [jianchengwang](https://github.com/jianchengwang) | | Suunto | +| [fxbin](https://github.com/fxbin) | | Keep | +| [shensl4499](https://github.com/shensl4499) | | codoon | +| [haowei93](https://github.com/haowei93) | | gpx | +| [stevenash0822](https://github.com/stevenash0822) | | Strava | +| [Vint](https://github.com/VintLin) | | Keep | +| [Muyids](https://github.com/muyids) | | Garmin-cn | +| [Gao Hao](https://github.com/efish2002) | | Garmin-cn | +| [Jinlei](https://github.com/iamjinlei0312) | | AW-GPX | +| [Ray Wang](https://github.com/raywangsy) | | Garmin | +| [RealTiny656](https://github.com/tiny656) | | JoyRun | +| [EINDEX](https://github.com/eindex) | | Strava/Nike | +| [Melt](https://github.com/fpGHwd) | | Strava | +| [deepinwine](https://github.com/deepinwine) | | Garmin-cn |
@@ -217,7 +217,7 @@ const LINE_OPACITY = 0.4; IGNORE_START_END_RANGE = 200 # 忽略每个 polyline 的起点和终点的长度(单位:米)。 IGNORE_RANGE = 200 # 忽略下面 polyline 中每个点的距离的圆圈(单位:米)。 -IGNORE_POLYLINE = ktjrFoemeU~IorGq}DeB # 包含要忽略的点的折线。 +IGNORE_POLYLINE = ktjrFoemeU~IorGq}DeB # 包含要忽略的点的折线。 # 在保存到数据库之前进行过滤,你会丢失一些数据,但可以保护你的隐私,如果你使用的是公共仓库,建议设置为1。不设置可关闭。 IGNORE_BEFORE_SAVING = 1 @@ -587,6 +587,7 @@ curl -X POST https://www.strava.com/oauth/token \ > 第一次同步 Strava 数据时需要更改在 strava_sync.py 中的第 12 行代码 False 改为 True,运行完成后,再改为 False。 如果你只想同步跑步数据增加命令 --only-run + ```python python3(python) scripts/strava_sync.py ${client_id} ${client_secret} ${refresh_token} ``` @@ -716,11 +717,10 @@ python3(python) scripts/strava_to_garmin_sync.py ${{ secrets.STRAVA_CLIENT_ID }} python3(python) scripts/strava_to_garmin_sync.py ${{ secrets.STRAVA_CLIENT_ID }} ${{ secrets.STRAVA_CLIENT_SECRET }} ${{ secrets.STRAVA_CLIENT_REFRESH_TOKEN }} ${{ secrets.GARMIN_CN_EMAIL }} ${{ secrets.GARMIN_CN_PASSWORD }} ${{ secrets.STRAVA_EMAIL }} ${{ secrets.STRAVA_PASSWORD }} --is-cn ``` -如果要在同步到Garmin的运动记录中添加Garmin设备信息,需要添加`--use_fake_garmin_device`参数,这将在同步的Garmin锻炼记录中添加一个Garmin设备(默认情况下为 `Garmin Forerunner 245`,您可以在`garmin_device_adaptor.py`中更改设备信息),运动记录中有了设备信息之后就可以同步到其他APP中,比如数字心动(攒上马积分)这类不能通过Apple Watch同步的APP,当然也可以同步到Keep,悦跑圈,咕咚等APP。 +如果要在同步到 Garmin 的运动记录中添加 Garmin 设备信息,需要添加`--use_fake_garmin_device`参数,这将在同步的 Garmin 锻炼记录中添加一个 Garmin 设备(默认情况下为 `Garmin Forerunner 245`,您可以在`garmin_device_adaptor.py`中更改设备信息),运动记录中有了设备信息之后就可以同步到其他 APP 中,比如数字心动(攒上马积分)这类不能通过 Apple Watch 同步的 APP,当然也可以同步到 Keep,悦跑圈,咕咚等 APP。 image - 最终执行的命令如下: ```python @@ -832,14 +832,14 @@ Actions [源码](https://github.com/yihong0618/running_page/blob/master/.github/ # Fit 文件 -测试发现,不同厂商在写fit文件的时候有略微差异。 +测试发现,不同厂商在写 fit 文件的时候有略微差异。 已调试设备: - [x] 佳明手表 - [x] 迈金码表 -如果发现自己的fit文件解析有问题。可以提issue。 +如果发现自己的 fit 文件解析有问题。可以提 issue。 # TODO diff --git a/README.md b/README.md index cb13435c883..ce06e475123 100644 --- a/README.md +++ b/README.md @@ -24,58 +24,57 @@ English | [简体中文](https://github.com/yihong0618/running_page/blob/master/
Running page runners -| Runner | page | App | -| ------------------------------------------------- | ---------------------------------------------- | --------- | -| [zhubao315](https://github.com/zhubao315) | | Strava | -| [shaonianche](https://github.com/shaonianche) | | Strava | -| [yihong0618](https://github.com/yihong0618) | | Nike | -| [superleeyom](https://github.com/superleeyom) | | Nike | -| [geekplux](https://github.com/geekplux) | | Nike | -| [guanlan](https://github.com/guanlan) | | Strava | -| [tuzimoe](https://github.com/tuzimoe) | | Nike | -| [ben_29](https://github.com/ben-29) | | Strava | -| [kcllf](https://github.com/kcllf) | | Garmin-cn | -| [mq](https://github.com/MQ-0707) | | Keep | -| [zhaohongxuan](https://github.com/zhaohongxuan) | | Strava | -| [yvetterowe](https://github.com/yvetterowe) | | Strava | -| [love-exercise](https://github.com/KaiOrange) | | Keep | -| [zstone12](https://github.com/zstone12) | | Keep | -| [Lax](https://github.com/Lax) | | Keep | -| [lusuzi](https://github.com/lusuzi) | | Nike | -| [wh1994](https://github.com/wh1994) | | Garmin | -| [liuyihui](https://github.com/YiHui-Liu) | | Keep | -| [sunyunxian](https://github.com/sunyunxian) | | Strava | -| [AhianZhang](https://github.com/AhianZhang) | | Nike | -| [L1cardo](https://github.com/L1cardo) | | Nike | -| [luckylele666](https://github.com/luckylele666) | | Strava | -| [MFYDev](https://github.com/MFYDev) | | Garmin-cn | -| [Eished](https://github.com/eished) | | Keep | -| [Liuxin](https://github.com/liuxindtc) | | Nike | -| [loucx](https://github.com/loucx) | | Nike | -| [winf42](https://github.com/winf42) | | Garmin-cn | -| [sun0225SUN](https://github.com/sun0225SUN) | | Nike | -| [Zhan](https://www.zlog.in/about/) | | Nike | -| [Dennis](https://run.domon.cn) | | Garmin-cn | -| [hanpei](https://running.nexts.top) | | Garmin-cn | -| [liugezhou](https://github.com/liugezhou) | | Strava | -| [Jason Tan](https://github.com/Jason-cqtan) | | Nike | -| [Conge](https://github.com/conge) | | Strava | -| [zHElEARN](https://github.com/zHElEARN) | | Strava | -| [Ym9i](https://github.com/Ym9i) | | Strava | -| [jianchengwang](https://github.com/jianchengwang) | | Suunto | -| [fxbin](https://github.com/fxbin) | | Keep | -| [shensl4499](https://github.com/shensl4499) | | codoon | -| [haowei93](https://github.com/haowei93) | | gpx | -| [stevenash0822](https://github.com/stevenash0822) | | Strava | -| [Vint](https://github.com/VintLin) | | Keep | -| [Muyids](https://github.com/muyids) | | Garmin-cn | -| [Gao Hao](https://github.com/efish2002) | | Garmin-cn | -| [Jinlei](https://github.com/iamjinlei0312) | | AW-GPX | -| [RealTiny656](https://github.com/tiny656) | | JoyRun | -| [EINDEX](https://github.com/eindex) | | Strava/Nike| -| [Melt](https://github.com/fpGHwd) | | Strava | -| [deepinwine](https://github.com/deepinwine) | | Garmin-cn | - +| Runner | page | App | +| ------------------------------------------------- | ---------------------------------------------- | ----------- | +| [zhubao315](https://github.com/zhubao315) | | Strava | +| [shaonianche](https://github.com/shaonianche) | | Strava | +| [yihong0618](https://github.com/yihong0618) | | Nike | +| [superleeyom](https://github.com/superleeyom) | | Nike | +| [geekplux](https://github.com/geekplux) | | Nike | +| [guanlan](https://github.com/guanlan) | | Strava | +| [tuzimoe](https://github.com/tuzimoe) | | Nike | +| [ben_29](https://github.com/ben-29) | | Strava | +| [kcllf](https://github.com/kcllf) | | Garmin-cn | +| [mq](https://github.com/MQ-0707) | | Keep | +| [zhaohongxuan](https://github.com/zhaohongxuan) | | Strava | +| [yvetterowe](https://github.com/yvetterowe) | | Strava | +| [love-exercise](https://github.com/KaiOrange) | | Keep | +| [zstone12](https://github.com/zstone12) | | Keep | +| [Lax](https://github.com/Lax) | | Keep | +| [lusuzi](https://github.com/lusuzi) | | Nike | +| [wh1994](https://github.com/wh1994) | | Garmin | +| [liuyihui](https://github.com/YiHui-Liu) | | Keep | +| [sunyunxian](https://github.com/sunyunxian) | | Strava | +| [AhianZhang](https://github.com/AhianZhang) | | Nike | +| [L1cardo](https://github.com/L1cardo) | | Nike | +| [luckylele666](https://github.com/luckylele666) | | Strava | +| [MFYDev](https://github.com/MFYDev) | | Garmin-cn | +| [Eished](https://github.com/eished) | | Keep | +| [Liuxin](https://github.com/liuxindtc) | | Nike | +| [loucx](https://github.com/loucx) | | Nike | +| [winf42](https://github.com/winf42) | | Garmin-cn | +| [sun0225SUN](https://github.com/sun0225SUN) | | Nike | +| [Zhan](https://www.zlog.in/about/) | | Nike | +| [Dennis](https://run.domon.cn) | | Garmin-cn | +| [hanpei](https://running.nexts.top) | | Garmin-cn | +| [liugezhou](https://github.com/liugezhou) | | Strava | +| [Jason Tan](https://github.com/Jason-cqtan) | | Nike | +| [Conge](https://github.com/conge) | | Strava | +| [zHElEARN](https://github.com/zHElEARN) | | Strava | +| [Ym9i](https://github.com/Ym9i) | | Strava | +| [jianchengwang](https://github.com/jianchengwang) | | Suunto | +| [fxbin](https://github.com/fxbin) | | Keep | +| [shensl4499](https://github.com/shensl4499) | | codoon | +| [haowei93](https://github.com/haowei93) | | gpx | +| [stevenash0822](https://github.com/stevenash0822) | | Strava | +| [Vint](https://github.com/VintLin) | | Keep | +| [Muyids](https://github.com/muyids) | | Garmin-cn | +| [Gao Hao](https://github.com/efish2002) | | Garmin-cn | +| [Jinlei](https://github.com/iamjinlei0312) | | AW-GPX | +| [RealTiny656](https://github.com/tiny656) | | JoyRun | +| [EINDEX](https://github.com/eindex) | | Strava/Nike | +| [Melt](https://github.com/fpGHwd) | | Strava | +| [deepinwine](https://github.com/deepinwine) | | Garmin-cn |
@@ -198,19 +197,19 @@ const LINE_OPACITY = 0.4; - privacy protection setting flowing env: + ```shell IGNORE_START_END_RANGE = 200 # ignore distance for each polyline start and end. -IGNORE_RANGE = 200 # ignore meters for each point in below polyline. -IGNORE_POLYLINE = ktjrFoemeU~IorGq}DeB # a polyline include point you want to ignore. +IGNORE_RANGE = 200 # ignore meters for each point in below polyline. +IGNORE_POLYLINE = ktjrFoemeU~IorGq}DeB # a polyline include point you want to ignore. # Do filter before saving to database, you will lose some data, but you can protect your privacy, when you using public repo. enable for set 1, disable via unset. -IGNORE_BEFORE_SAVING = +IGNORE_BEFORE_SAVING = ``` You can using [this](https://developers.google.com/maps/documentation/utilities/polylineutility), to making your `IGNORE_POLYLINE`. - ## Download your running data and do not forget to [generate svg in `total` page](#total-data-analysis) ### GPX @@ -413,7 +412,7 @@ curl -X POST https://www.strava.com/oauth/token \ 7. Sync `Strava` data > The first time you synchronize Strava data you need to change line 12 of the code False to True in strava_sync.py, and then change it to False after it finishes running. -If you only want to sync `type running` add args --only-run +> If you only want to sync `type running` add args --only-run ```python python3(python) scripts/strava_sync.py ${client_id} ${client_secret} ${refresh_token} @@ -545,7 +544,7 @@ if your garmin account region is **China**, you need to execute the command: python3(python) scripts/strava_to_garmin_sync.py ${{ secrets.STRAVA_CLIENT_ID }} ${{ secrets.STRAVA_CLIENT_SECRET }} ${{ secrets.STRAVA_CLIENT_REFRESH_TOKEN }} ${{ secrets.GARMIN_CN_EMAIL }} ${{ secrets.GARMIN_CN_PASSWORD }} ${{ secrets.STRAVA_EMAIL }} ${{ secrets.STRAVA_PASSWORD }} --is-cn ``` -If you want to add Garmin Device during sync, you should add `--use_fake_garmin_device` argument, this will add a Garmin Device (Garmin Forerunner 245 by default, and you can change device in `garmin_device_adaptor.py`) in synced Garmin workout record, this is essential when you want to sync the workout record to other APP like Keep, JoyRun etc. +If you want to add Garmin Device during sync, you should add `--use_fake_garmin_device` argument, this will add a Garmin Device (Garmin Forerunner 245 by default, and you can change device in `garmin_device_adaptor.py`) in synced Garmin workout record, this is essential when you want to sync the workout record to other APP like Keep, JoyRun etc. image @@ -691,7 +690,7 @@ supported manufacturer: - [ ] support the world map - [ ] support multiple types, like hiking, biking~ - [ ] support for Zeep life - + # Contribution - Any Issues PR welcome. diff --git a/gatsby-config.js b/gatsby-config.ts similarity index 90% rename from gatsby-config.js rename to gatsby-config.ts index 6347de67bad..0378973911b 100644 --- a/gatsby-config.js +++ b/gatsby-config.ts @@ -1,6 +1,6 @@ -/* eslint-disable no-undef */ -// eslint-disable-next-line no-undef -module.exports = { +import type { GatsbyConfig } from 'gatsby'; + +const config: GatsbyConfig = { pathPrefix: process.env.PATH_PREFIX || '/', siteMetadata: { siteTitle: 'Running Page', @@ -45,7 +45,10 @@ module.exports = { { resolve: 'gatsby-alias-imports', options: { - rootFolder: '.', + aliases: { + '@': 'src/', + '@assets': 'assets/', + }, }, }, { @@ -81,3 +84,5 @@ module.exports = { }, ], }; + +export default config; diff --git a/gatsby-node.js b/gatsby-node.ts similarity index 61% rename from gatsby-node.js rename to gatsby-node.ts index 9e75ece670a..928ab9a909e 100644 --- a/gatsby-node.js +++ b/gatsby-node.ts @@ -1,7 +1,9 @@ -// eslint-disable-next-line no-undef -exports.createSchemaCustomization = ({ actions }) => { - const { createTypes } = actions; - const typeDefs = ` +import type { GatsbyNode } from 'gatsby'; + +export const createSchemaCustomization: GatsbyNode['createSchemaCustomization'] = + ({ actions }) => { + const { createTypes } = actions; + const typeDefs = ` type ActivitiesJson implements Node @dontInfer { id: String distance: Float @@ -18,5 +20,5 @@ exports.createSchemaCustomization = ({ actions }) => { summary_polyline: String } `; - createTypes(typeDefs); -}; + createTypes(typeDefs); + }; diff --git a/jsconfig.json b/jsconfig.json deleted file mode 100644 index ec30136685c..00000000000 --- a/jsconfig.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "compilerOptions": { - "module": "ESNext", - "moduleResolution": "Node", - "target": "ES2020", - "jsx": "react", - "checkJs": true, - "experimentalDecorators": true, - "strictNullChecks": true, - "strictFunctionTypes": true, - "baseUrl": ".", - "paths": { - "src/*": ["./src/*"] - } - }, - "include": ["src/**/*"], - "exclude": ["node_modules", "**/node_modules/*"] -} diff --git a/package.json b/package.json index a5a6ca3e630..d5c6e41ec4a 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,6 @@ "@mapbox/mapbox-gl-language": "^1.0.0", "@mapbox/polyline": "^1.1.1", "@vercel/analytics": "^0.1.6", - "classnames": "^2.3.1", - "date-fns": "^2.28.0", "gatsby": "^4.25.0", "gatsby-alias-imports": "^1.0.6", "gatsby-plugin-manifest": "^4.16.0", @@ -20,6 +18,7 @@ "gatsby-source-filesystem": "^4.16.0", "gatsby-transformer-json": "^4.16.0", "gcoord": "^0.3.2", + "geojson": "^0.5.0", "mapbox-gl": "^2.8.2", "prop-types": "^15.8.1", "react": "^17.0.2", @@ -28,11 +27,8 @@ "react-map-gl": "^5.1.22", "sass": "^1.52.3", "sass-mq": "^6.0.0", - "styled-components": "^5.3.5", "tachyons": "^4.12.0", - "tachyons-sass": "git+https://github.com/tachyons-css/tachyons-sass.git", - "viewport-mercator-project": "^7.0.4", - "webpack": "^5.73.0" + "tachyons-sass": "git+https://github.com/tachyons-css/tachyons-sass.git" }, "license": "MIT", "private": true, @@ -45,9 +41,9 @@ "develop": "gatsby develop", "serve": "gatsby serve", "serve-prefix": "gatsby serve --prefix-paths", - "lint": "eslint --ext .js,.jsx src --fix", - "check": "npx prettier --write {*,src/**/*}.{js,jsx,scss,json,md,yaml}", - "ci": "yarn run check && yarn run build && yarn run test" + "lint": "eslint --ext .ts,.tsx src --fix", + "check": "prettier --write src/**/*.{scss,json,ts,tsx} *.{md,yaml,json,ts,js}", + "ci": "yarn run check && yarn run lint && yarn run build && yarn run test" }, "engineStrict": true, "browserslist": "defaults, not ie 11", @@ -59,19 +55,18 @@ "url": "https://github.com/yihong0618/running_page" }, "devDependencies": { + "@types/mapbox__polyline": "^1.0.2", + "@types/node": "^20.3.3", + "@types/react": "^18.2.14", + "@types/react-dom": "^18.2.6", "@types/react-helmet": "^6.1.6", - "@typescript-eslint/eslint-plugin": "^5.59.2", "@typescript-eslint/parser": "^5.59.2", - "babel-eslint": "^10.1.0", "eslint": "^8.17.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-react": "^7.32.2", - "graphql": "15.0.0", "prettier": "2.8.8", - "react-is": "^18.2.0", - "react-server-dom-webpack": "^0.0.1", - "typescript": "^5.0.4" + "typescript": "^5.1.6" }, "volta": { "node": "18.16.0", diff --git a/src/components/Header/index.jsx b/src/components/Header/index.tsx similarity index 93% rename from src/components/Header/index.jsx rename to src/components/Header/index.tsx index c5017425e25..b4e838a7fdd 100644 --- a/src/components/Header/index.jsx +++ b/src/components/Header/index.tsx @@ -1,6 +1,6 @@ import { Link } from 'gatsby'; import React from 'react'; -import useSiteMetadata from 'src/hooks/useSiteMetadata'; +import useSiteMetadata from '@/hooks/useSiteMetadata'; const Header = () => { const { logo, siteUrl, navLinks } = useSiteMetadata(); diff --git a/src/components/Layout/index.jsx b/src/components/Layout/index.tsx similarity index 80% rename from src/components/Layout/index.jsx rename to src/components/Layout/index.tsx index 345a1e94ab5..5ff026b6c73 100644 --- a/src/components/Layout/index.jsx +++ b/src/components/Layout/index.tsx @@ -1,12 +1,12 @@ import PropTypes from 'prop-types'; import React from 'react'; import { Helmet } from 'react-helmet'; -import Header from 'src/components/Header'; -import useSiteMetadata from 'src/hooks/useSiteMetadata'; -import 'src/styles/index.scss'; +import Header from '@/components/Header'; +import useSiteMetadata from '@/hooks/useSiteMetadata'; +import '@/styles/index.scss'; import styles from './style.module.scss'; -const Layout = ({ children }) => { +const Layout = ({ children }: React.PropsWithChildren) => { const { siteTitle, description } = useSiteMetadata(); return ( diff --git a/src/components/LocationStat/CitiesStat.jsx b/src/components/LocationStat/CitiesStat.tsx similarity index 78% rename from src/components/LocationStat/CitiesStat.jsx rename to src/components/LocationStat/CitiesStat.tsx index 1b691c8b7d5..18f0d83a0a5 100644 --- a/src/components/LocationStat/CitiesStat.jsx +++ b/src/components/LocationStat/CitiesStat.tsx @@ -1,9 +1,9 @@ import React from 'react'; -import Stat from 'src/components/Stat'; -import useActivities from 'src/hooks/useActivities'; +import Stat from '@/components/Stat'; +import useActivities from '@/hooks/useActivities'; // only support China for now -const CitiesStat = ({ onClick }) => { +const CitiesStat = ({ onClick }: { onClick: (_city: string) => void }) => { const { cities } = useActivities(); const citiesArr = Object.entries(cities); diff --git a/src/components/LocationStat/LocationSummary.jsx b/src/components/LocationStat/LocationSummary.tsx similarity index 50% rename from src/components/LocationStat/LocationSummary.jsx rename to src/components/LocationStat/LocationSummary.tsx index bda9de93134..4c5b618ba44 100644 --- a/src/components/LocationStat/LocationSummary.jsx +++ b/src/components/LocationStat/LocationSummary.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import Stat from 'src/components/Stat'; -import useActivities from 'src/hooks/useActivities'; +import Stat from '@/components/Stat'; +import useActivities from '@/hooks/useActivities'; // only support China for now const LocationSummary = () => { @@ -8,12 +8,12 @@ const LocationSummary = () => { return (
- {years && } - {countries && } - {provinces && } - {cities && ( + {years ? : null} + {countries ? : null} + {provinces ? : null} + {cities ? ( - )} + ) : null}

diff --git a/src/components/LocationStat/PeriodStat.jsx b/src/components/LocationStat/PeriodStat.tsx similarity index 77% rename from src/components/LocationStat/PeriodStat.jsx rename to src/components/LocationStat/PeriodStat.tsx index 06c50534c6f..b733e97771b 100644 --- a/src/components/LocationStat/PeriodStat.jsx +++ b/src/components/LocationStat/PeriodStat.tsx @@ -1,8 +1,8 @@ import React from 'react'; -import Stat from 'src/components/Stat'; -import useActivities from 'src/hooks/useActivities'; +import Stat from '@/components/Stat'; +import useActivities from '@/hooks/useActivities'; -const PeriodStat = ({ onClick }) => { +const PeriodStat = ({ onClick }: { onClick: (_period: string) => void }) => { const { runPeriod } = useActivities(); const periodArr = Object.entries(runPeriod); diff --git a/src/components/LocationStat/index.jsx b/src/components/LocationStat/index.tsx similarity index 72% rename from src/components/LocationStat/index.jsx rename to src/components/LocationStat/index.tsx index 54b4501ecb5..d23548ad167 100644 --- a/src/components/LocationStat/index.jsx +++ b/src/components/LocationStat/index.tsx @@ -1,14 +1,20 @@ import React from 'react'; -import YearStat from 'src/components/YearStat'; +import YearStat from '@/components/YearStat'; import { CHINESE_LOCATION_INFO_MESSAGE_FIRST, CHINESE_LOCATION_INFO_MESSAGE_SECOND, -} from 'src/utils/const'; +} from '@/utils/const'; import CitiesStat from './CitiesStat'; import LocationSummary from './LocationSummary'; import PeriodStat from './PeriodStat'; -const LocationStat = ({ changeYear, changeCity, changeTitle }) => ( +interface ILocationStatProps { + changeYear: (_year: string) => void; + changeCity: (_city: string) => void; + changeTitle: (_title: string) => void; +} + +const LocationStat = ({ changeYear, changeCity, changeTitle }: ILocationStatProps) => (

diff --git a/src/components/RunMap/RunMaker.jsx b/src/components/RunMap/RunMaker.tsx similarity index 74% rename from src/components/RunMap/RunMaker.jsx rename to src/components/RunMap/RunMaker.tsx index 86b024537f2..82fbc9f29f3 100644 --- a/src/components/RunMap/RunMaker.jsx +++ b/src/components/RunMap/RunMaker.tsx @@ -1,10 +1,17 @@ -import EndSvg from 'assets/end.svg'; -import StartSvg from 'assets/start.svg'; +import EndSvg from '@assets/end.svg'; +import StartSvg from '@assets/start.svg'; import React from 'react'; import { Marker } from 'react-map-gl'; import styles from './style.module.scss'; -const RunMarker = ({ startLon, startLat, endLon, endLat }) => { +interface IRunMarkerProperties { + startLon: number; + startLat: number; + endLon: number; + endLat: number; +} + +const RunMarker = ({ startLon, startLat, endLon, endLat }: IRunMarkerProperties) => { const size = 20; return ( <> diff --git a/src/components/RunMap/RunMapButtons.jsx b/src/components/RunMap/RunMapButtons.tsx similarity index 73% rename from src/components/RunMap/RunMapButtons.jsx rename to src/components/RunMap/RunMapButtons.tsx index 279c4ed2a84..5153a63a288 100644 --- a/src/components/RunMap/RunMapButtons.jsx +++ b/src/components/RunMap/RunMapButtons.tsx @@ -1,8 +1,8 @@ -import React, { useEffect, useState } from 'react'; -import useActivities from 'src/hooks/useActivities'; +import React from 'react'; +import useActivities from '@/hooks/useActivities'; import styles from './style.module.scss'; -const RunMapButtons = ({ changeYear, thisYear }) => { +const RunMapButtons = ({ changeYear, thisYear }: { changeYear: (_year: string) => void, thisYear: string }) => { const { years } = useActivities(); const yearsButtons = years.slice(); yearsButtons.push('Total'); diff --git a/src/components/RunMap/index.jsx b/src/components/RunMap/index.tsx similarity index 77% rename from src/components/RunMap/index.jsx rename to src/components/RunMap/index.tsx index f4b379fbb77..7daffc050a2 100644 --- a/src/components/RunMap/index.jsx +++ b/src/components/RunMap/index.tsx @@ -1,7 +1,7 @@ import MapboxLanguage from '@mapbox/mapbox-gl-language'; import React, { useRef, useCallback } from 'react'; -import ReactMapGL, { Layer, Source, FullscreenControl } from 'react-map-gl'; -import useActivities from 'src/hooks/useActivities'; +import ReactMapGL, { Layer, Source, FullscreenControl, MapRef } from 'react-map-gl'; +import useActivities from '@/hooks/useActivities'; import { MAP_LAYER_LIST, IS_CHINESE, @@ -12,11 +12,22 @@ import { USE_DASH_LINE, LINE_OPACITY, MAP_HEIGHT, -} from 'src/utils/const'; -import { geoJsonForMap } from 'src/utils/utils'; +} from '@/utils/const'; +import { Coordinate, IViewport, geoJsonForMap } from '@/utils/utils'; import RunMarker from './RunMaker'; import RunMapButtons from './RunMapButtons'; import styles from './style.module.scss'; +import { FeatureCollection } from 'geojson'; +import { RPGeometry } from '@/static/run_countries'; + +interface IRunMapProps { + title: string; + viewport: IViewport; + setViewport: (_viewport: IViewport) => void; + changeYear: (_year: string) => void; + geoData: FeatureCollection; + thisYear: string; +} const RunMap = ({ title, @@ -25,11 +36,11 @@ const RunMap = ({ changeYear, geoData, thisYear, -}) => { +}: IRunMapProps) => { const { provinces } = useActivities(); - const mapRef = useRef(); + const mapRef = useRef(); const mapRefCallback = useCallback( - (ref) => { + (ref: MapRef) => { if (ref !== null) { mapRef.current = ref; const map = ref.getMap(); @@ -52,7 +63,7 @@ const RunMap = ({ // for geojson format filterProvinces.unshift('in', 'name'); - const isBigMap = viewport.zoom <= 3; + const isBigMap = (viewport.zoom ?? 0) <= 3; if (isBigMap && IS_CHINESE) { geoData = geoJsonForMap(); } @@ -60,12 +71,12 @@ const RunMap = ({ const isSingleRun = geoData.features.length === 1 && geoData.features[0].geometry.coordinates.length; - let startLon; - let startLat; - let endLon; - let endLat; + let startLon = 0; + let startLat = 0; + let endLon = 0; + let endLat = 0; if (isSingleRun) { - const points = geoData.features[0].geometry.coordinates; + const points = geoData.features[0].geometry.coordinates as Coordinate[]; [startLon, startLat] = points[0]; [endLon, endLat] = points[points.length - 1]; } diff --git a/src/components/RunTable/RunRow.jsx b/src/components/RunTable/RunRow.tsx similarity index 74% rename from src/components/RunTable/RunRow.jsx rename to src/components/RunTable/RunRow.tsx index 899a07afd97..ecd3b2cb3c2 100644 --- a/src/components/RunTable/RunRow.jsx +++ b/src/components/RunTable/RunRow.tsx @@ -1,14 +1,21 @@ import React from 'react'; -import { formatPace, titleForRun, formatRunTime } from 'src/utils/utils'; +import { formatPace, titleForRun, formatRunTime, Activity } from '@/utils/utils'; import styles from './style.module.scss'; -import { element } from 'prop-types'; -const RunRow = ({ elementIndex, locateActivity, run, runIndex, setRunIndex }) => { +interface IRunRowProperties { + elementIndex: number; + locateActivity: (_date: string) => void; + run: Activity; + runIndex: number; + setRunIndex: (_ndex: number) => void; +} + +const RunRow = ({ elementIndex, locateActivity, run, runIndex, setRunIndex }: IRunRowProperties) => { const distance = (run.distance / 1000.0).toFixed(2); const paceParts = run.average_speed ? formatPace(run.average_speed) : null; const heartRate = run.average_heartrate; const runTime = formatRunTime(run.moving_time); - const handleClick = (e) => { + const handleClick = () => { if (runIndex === elementIndex) return; setRunIndex(elementIndex); locateActivity(run.start_date_local.slice(0, 10)); diff --git a/src/components/RunTable/index.jsx b/src/components/RunTable/index.tsx similarity index 71% rename from src/components/RunTable/index.jsx rename to src/components/RunTable/index.tsx index a5624f060d5..eee99356b67 100644 --- a/src/components/RunTable/index.jsx +++ b/src/components/RunTable/index.tsx @@ -3,30 +3,42 @@ import { sortDateFunc, sortDateFuncReverse, convertMovingTime2Sec, -} from 'src/utils/utils'; + Activity, +} from '@/utils/utils'; import RunRow from './RunRow'; import styles from './style.module.scss'; +interface IRunTableProperties { + runs: Activity[]; + locateActivity: (_date: string) => void; + setActivity: (_runs: Activity[]) => void; + runIndex: number; + setRunIndex: (_index: number) => void; +} + +type SortFunc = (_a: Activity, _b: Activity) => number; + const RunTable = ({ runs, locateActivity, setActivity, runIndex, setRunIndex, -}) => { +}: IRunTableProperties) => { const [sortFuncInfo, setSortFuncInfo] = useState(''); // TODO refactor? - const sortKMFunc = (a, b) => + const sortKMFunc: SortFunc = (a, b) => sortFuncInfo === 'KM' ? a.distance - b.distance : b.distance - a.distance; - const sortPaceFunc = (a, b) => + const sortPaceFunc: SortFunc = (a, b) => sortFuncInfo === 'Pace' ? a.average_speed - b.average_speed : b.average_speed - a.average_speed; - const sortBPMFunc = (a, b) => - sortFuncInfo === 'BPM' - ? a.average_heartrate - b.average_heartrate - : b.average_heartrate - a.average_heartrate; - const sortRunTimeFunc = (a, b) => { + const sortBPMFunc: SortFunc = (a, b) => { + return sortFuncInfo === 'BPM' + ? a.average_heartrate ?? 0 - (b.average_heartrate ?? 0) + : b.average_heartrate ?? 0 - (a.average_heartrate ?? 0); + } + const sortRunTimeFunc: SortFunc = (a, b) => { const aTotalSeconds = convertMovingTime2Sec(a.moving_time); const bTotalSeconds = convertMovingTime2Sec(b.moving_time); return sortFuncInfo === 'Time' @@ -43,8 +55,8 @@ const RunTable = ({ ['Date', sortDateFuncClick], ]); - const handleClick = (e) => { - const funcName = e.target.innerHTML; + const handleClick: React.MouseEventHandler = (e) => { + const funcName = (e.target as HTMLElement).innerHTML; const f = sortFuncMap.get(funcName); setRunIndex(-1) diff --git a/src/components/SVGStat/index.jsx b/src/components/SVGStat/index.tsx similarity index 73% rename from src/components/SVGStat/index.jsx rename to src/components/SVGStat/index.tsx index 3948e91de17..5e428566220 100644 --- a/src/components/SVGStat/index.jsx +++ b/src/components/SVGStat/index.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import GitHubSvg from 'assets/github.svg'; -import GridSvg from 'assets/grid.svg'; +import GitHubSvg from '@assets/github.svg'; +import GridSvg from '@assets/grid.svg'; import styles from './style.module.scss'; const SVGStat = () => ( diff --git a/src/components/Stat/index.jsx b/src/components/Stat/index.tsx similarity index 52% rename from src/components/Stat/index.jsx rename to src/components/Stat/index.tsx index ff64429ea41..bff741a2eff 100644 --- a/src/components/Stat/index.jsx +++ b/src/components/Stat/index.tsx @@ -1,14 +1,22 @@ import React from 'react'; -import { intComma } from 'src/utils/utils'; +import { intComma } from '@/utils/utils'; -const divStyle = { +const divStyle: React.CSSProperties = { fontWeight: '700', }; -const Stat = ({ value, description, className = 'pb2 w-100', citySize, onClick }) => ( +interface IStatProperties { + value: string | number; + description: string; + className?: string; + citySize?: number; + onClick?: () => void; +} + +const Stat = ({ value, description, className = 'pb2 w-100', citySize, onClick }: IStatProperties) => (

- {intComma(value)} + {intComma(value.toString())} {description}
diff --git a/src/components/YearStat/index.jsx b/src/components/YearStat/index.tsx similarity index 87% rename from src/components/YearStat/index.jsx rename to src/components/YearStat/index.tsx index 941974d9126..0bca614c34d 100644 --- a/src/components/YearStat/index.jsx +++ b/src/components/YearStat/index.tsx @@ -1,17 +1,17 @@ import React from 'react'; -import Stat from 'src/components/Stat'; -import useActivities from 'src/hooks/useActivities'; -import useHover from 'src/hooks/useHover'; -import { formatPace } from 'src/utils/utils'; +import Stat from '@/components/Stat'; +import useActivities from '@/hooks/useActivities'; +import useHover from '@/hooks/useHover'; +import { formatPace } from '@/utils/utils'; import styles from './style.module.scss'; -const YearStat = ({ year, onClick }) => { +const YearStat = ({ year, onClick }: { year: string, onClick: (_year: string) => void }) => { let { activities: runs, years } = useActivities(); // for hover const [hovered, eventHandlers] = useHover(); // lazy Component const YearSVG = React.lazy(() => - import(`assets/year_${year}.svg`).catch(() => ({ + import(`@assets/year_${year}.svg`).catch(() => ({ default: () =>
, })) ); diff --git a/src/components/YearsStat/index.jsx b/src/components/YearsStat/index.tsx similarity index 71% rename from src/components/YearsStat/index.jsx rename to src/components/YearsStat/index.tsx index 14f09b84b12..3d9d4a25a4c 100644 --- a/src/components/YearsStat/index.jsx +++ b/src/components/YearsStat/index.tsx @@ -1,9 +1,9 @@ import React from 'react'; -import YearStat from 'src/components/YearStat'; -import useActivities from 'src/hooks/useActivities'; -import { INFO_MESSAGE } from 'src/utils/const'; +import YearStat from '@/components/YearStat'; +import useActivities from '@/hooks/useActivities'; +import { INFO_MESSAGE } from '@/utils/const'; -const YearsStat = ({ year, onClick }) => { +const YearsStat = ({ year, onClick }: { year: string, onClick: (_year: string) => void }) => { const { years } = useActivities(); // make sure the year click on front let yearsArrayUpdate = years.slice(); @@ -24,7 +24,8 @@ const YearsStat = ({ year, onClick }) => { {yearsArrayUpdate.map((year) => ( ))} - {yearsArrayUpdate.hasOwnProperty('Total') ? ( + {// eslint-disable-next-line no-prototype-builtins + yearsArrayUpdate.hasOwnProperty('Total') ? ( ) : (
diff --git a/src/hooks/useActivities.js b/src/hooks/useActivities.ts similarity index 69% rename from src/hooks/useActivities.js rename to src/hooks/useActivities.ts index ed7a1602387..3013cc61589 100644 --- a/src/hooks/useActivities.js +++ b/src/hooks/useActivities.ts @@ -1,8 +1,14 @@ import { useStaticQuery, graphql } from 'gatsby'; -import { locationForRun, titleForRun } from 'src/utils/utils'; +import { locationForRun, titleForRun, Activity } from '@/utils/utils'; + +interface IActivityResult { + allActivitiesJson: { + nodes: Activity[]; + }; +} const useActivities = () => { - const { allActivitiesJson } = useStaticQuery( + const { allActivitiesJson } = useStaticQuery( graphql` query AllActivities { allActivitiesJson { @@ -27,11 +33,11 @@ const useActivities = () => { ); const activities = allActivitiesJson.nodes; - const cities = {}; - const runPeriod = {}; - const provinces = new Set(); - const countries = new Set(); - let years = new Set(); + const cities: Record = {}; + const runPeriod: Record = {}; + const provinces: Set = new Set(); + const countries: Set = new Set(); + let years: Set = new Set(); let thisYear = ''; activities.forEach((run) => { @@ -55,12 +61,12 @@ const useActivities = () => { years.add(year); }); - years = [...years].sort().reverse(); - if (years) [thisYear] = years; // set current year as first one of years array + let yearsArray = [...years].sort().reverse(); + if (years) [thisYear] = yearsArray; // set current year as first one of years array return { activities, - years, + years: yearsArray, countries: [...countries], provinces: [...provinces], cities, diff --git a/src/hooks/useHover.js b/src/hooks/useHover.ts similarity index 56% rename from src/hooks/useHover.js rename to src/hooks/useHover.ts index 92dd22f0f17..0f6fc2b5836 100644 --- a/src/hooks/useHover.js +++ b/src/hooks/useHover.ts @@ -1,8 +1,10 @@ import { useState } from 'react'; -const useHover = () => { - const [hovered, setHovered] = useState(); - const [timer, setTimer] = useState(); +type HoverHook = [boolean, { onMouseOver: () => void; onMouseOut: () => void }]; + +const useHover = (): HoverHook => { + const [hovered, setHovered] = useState(false); + const [timer, setTimer] = useState(); const eventHandlers = { onMouseOver() { diff --git a/src/hooks/useSiteMetadata.js b/src/hooks/useSiteMetadata.ts similarity index 58% rename from src/hooks/useSiteMetadata.js rename to src/hooks/useSiteMetadata.ts index 70f10ae2a1d..9ea15515b10 100644 --- a/src/hooks/useSiteMetadata.js +++ b/src/hooks/useSiteMetadata.ts @@ -1,7 +1,22 @@ import { graphql, useStaticQuery } from 'gatsby'; +interface ISiteMetadataResult { + site: { + siteMetadata: { + siteTitle: string; + siteUrl: string; + description: string; + logo: string; + navLinks: { + name: string; + url: string; + }[]; + }; + }; +} + const useSiteMetadata = () => { - const { site } = useStaticQuery( + const { site } = useStaticQuery( graphql` query SiteMetaData { site { diff --git a/src/main.d.ts b/src/main.d.ts new file mode 100644 index 00000000000..d0ddd42f688 --- /dev/null +++ b/src/main.d.ts @@ -0,0 +1,11 @@ +declare module "*.module.scss"; + +declare module "*.svg" { + import * as React from "react"; + + const ReactComponent: React.FunctionComponent< + React.SVGProps & { title?: string } + >; + + export default ReactComponent; +} diff --git a/src/pages/404.jsx b/src/pages/404.tsx similarity index 81% rename from src/pages/404.jsx rename to src/pages/404.tsx index bb366d305fc..60aaf7be6e9 100644 --- a/src/pages/404.jsx +++ b/src/pages/404.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import Layout from 'src/components/Layout'; -import useSiteMetadata from 'src/hooks/useSiteMetadata'; +import Layout from '@/components/Layout'; +import useSiteMetadata from '@/hooks/useSiteMetadata'; const NotFoundPage = () => { const { siteUrl } = useSiteMetadata(); diff --git a/src/pages/index.jsx b/src/pages/index.tsx similarity index 63% rename from src/pages/index.jsx rename to src/pages/index.tsx index ce9568dd299..1f6b7c95640 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.tsx @@ -1,15 +1,17 @@ import { Analytics } from '@vercel/analytics/react'; import React, { useEffect, useState } from 'react'; -import Layout from 'src/components/Layout'; -import LocationStat from 'src/components/LocationStat'; -import RunMap from 'src/components/RunMap'; -import RunTable from 'src/components/RunTable'; -import SVGStat from 'src/components/SVGStat'; -import YearsStat from 'src/components/YearsStat'; -import useActivities from 'src/hooks/useActivities'; -import useSiteMetadata from 'src/hooks/useSiteMetadata'; -import { IS_CHINESE } from 'src/utils/const'; +import Layout from '@/components/Layout'; +import LocationStat from '@/components/LocationStat'; +import RunMap from '@/components/RunMap'; +import RunTable from '@/components/RunTable'; +import SVGStat from '@/components/SVGStat'; +import YearsStat from '@/components/YearsStat'; +import useActivities from '@/hooks/useActivities'; +import useSiteMetadata from '@/hooks/useSiteMetadata'; +import { IS_CHINESE } from '@/utils/const'; import { + Activity, + IViewport, filterAndSortRuns, filterCityRuns, filterTitleRuns, @@ -19,7 +21,7 @@ import { scrollToMap, sortDateFunc, titleForShow, -} from 'src/utils/utils'; +} from '@/utils/utils'; const Index = () => { const { siteTitle } = useSiteMetadata(); @@ -33,50 +35,57 @@ const Index = () => { const [geoData, setGeoData] = useState(geoJsonForRuns(runs)); // for auto zoom const bounds = getBoundsForGeoData(geoData); - const [intervalId, setIntervalId] = useState(); + const [intervalId, setIntervalId] = useState(); - const [viewport, setViewport] = useState({ + const [viewport, setViewport] = useState({ ...bounds, }); - const changeByItem = (item, name, func, isChanged) => { + const changeByItem = ( + item: string, + name: string, + func: (_run: Activity, _value: string) => boolean + ) => { scrollToMap(); setActivity(filterAndSortRuns(activities, item, func, sortDateFunc)); setRunIndex(-1); setTitle(`${item} ${name} Running Heatmap`); }; - const changeYear = (y) => { - const isChanged = y === year; + const changeYear = (y: string) => { // default year setYear(y); - if (viewport.zoom > 3) { + if ((viewport.zoom ?? 0) > 3) { setViewport({ ...bounds, }); } - changeByItem(y, 'Year', filterYearRuns, isChanged); + changeByItem(y, 'Year', filterYearRuns); clearInterval(intervalId); }; - const changeCity = (city) => { - changeByItem(city, 'City', filterCityRuns, false); + const changeCity = (city: string) => { + changeByItem(city, 'City', filterCityRuns); }; - const changeTitle = (title) => { - changeByItem(title, 'Title', filterTitleRuns, false); + const changeTitle = (title: string) => { + changeByItem(title, 'Title', filterTitleRuns); }; - const locateActivity = (runDate) => { - const activitiesOnDate = runs.filter((r) => r.start_date_local.slice(0, 10) === runDate); + const locateActivity = (runDate: string) => { + const activitiesOnDate = runs.filter( + (r) => r.start_date_local.slice(0, 10) === runDate + ); if (!activitiesOnDate.length) { return; } - const sortedActivities = activitiesOnDate.sort((a, b) => b.distance - a.distance); + const sortedActivities = activitiesOnDate.sort( + (a, b) => b.distance - a.distance + ); const info = sortedActivities[0]; if (!info) { @@ -117,27 +126,29 @@ const Index = () => { return; } - let svgStat = document.getElementById('svgStat') + let svgStat = document.getElementById('svgStat'); if (!svgStat) { - return + return; } svgStat.addEventListener('click', (e) => { - const target = e.target; + const target = e.target as HTMLElement; if (target) { - const tagName = target.tagName.toLowerCase() - - if ((tagName === 'rect' && - parseFloat(target.getAttribute('width')) === 2.6 && - parseFloat(target.getAttribute('height')) === 2.6 && - target.getAttribute('fill') !== '#444444' - ) || ( - tagName === 'polyline' - )) { - const [runDate] = target.innerHTML.match(/\d{4}-\d{1,2}-\d{1,2}/) || [`${+thisYear + 1}`]; - locateActivity(runDate) + const tagName = target.tagName.toLowerCase(); + + if ( + (tagName === 'rect' && + parseFloat(target.getAttribute('width') as string) === 2.6 && + parseFloat(target.getAttribute('height') as string) === 2.6 && + target.getAttribute('fill') !== '#444444') || + tagName === 'polyline' + ) { + const [runDate] = target.innerHTML.match(/\d{4}-\d{1,2}-\d{1,2}/) || [ + `${+thisYear + 1}`, + ]; + locateActivity(runDate); } } - }) + }); }, [year]); return ( @@ -146,7 +157,7 @@ const Index = () => {

{siteTitle}

- {viewport.zoom <= 3 && IS_CHINESE ? ( + {(viewport.zoom ?? 0) <= 3 && IS_CHINESE ? ( = { type: 'FeatureCollection', features: [ { @@ -3211,5 +3215,3 @@ const chinaGeojson = { }, ], }; - -export { chinaGeojson }; diff --git a/src/utils/const.js b/src/utils/const.ts similarity index 94% rename from src/utils/const.js rename to src/utils/const.ts index e2aae1b45d7..75a5d36bdf1 100644 --- a/src/utils/const.js +++ b/src/utils/const.ts @@ -36,11 +36,11 @@ const ROAD_LABEL_DISPLAY = true; // IF you outside China please make sure IS_CHINESE = false const IS_CHINESE = true; const USE_ANIMATION_FOR_GRID = false; -const CHINESE_INFO_MESSAGE = (yearLength, year) => { +const CHINESE_INFO_MESSAGE = (yearLength: number, year: string): string => { const yearStr = year === 'Total' ? '所有' : ` ${year} `; return `我用 App 记录自己跑步 ${yearLength} 年了,下面列表展示的是${yearStr}的数据`; }; -const ENGLISH_INFO_MESSAGE = (yearLength, year) => +const ENGLISH_INFO_MESSAGE = (yearLength: number, year: string): string => `Running Journey with ${yearLength} Years, the table shows year ${year} data`; // not support English for now diff --git a/src/utils/utils.js b/src/utils/utils.ts similarity index 67% rename from src/utils/utils.js rename to src/utils/utils.ts index 2d91644b687..7de9c247e39 100644 --- a/src/utils/utils.js +++ b/src/utils/utils.ts @@ -1,11 +1,29 @@ import * as mapboxPolyline from '@mapbox/polyline'; import gcoord from 'gcoord'; import { WebMercatorViewport } from 'react-map-gl'; -import { chinaGeojson } from 'src/static/run_countries'; -import { chinaCities } from 'src/static/city'; +import { chinaGeojson } from '@/static/run_countries'; +import { chinaCities } from '@/static/city'; import { MUNICIPALITY_CITIES_ARR, NEED_FIX_MAP, RUN_TITLES } from './const'; +import { FeatureCollection, LineString } from 'geojson'; -const titleForShow = (run) => { +export type Coordinate = [number, number]; + +export interface Activity { + run_id: number; + name: string; + distance: number; + moving_time: string; + type: 'Run'; + start_date: string; + start_date_local: string; + location_country: string; + summary_polyline: string; + average_heartrate?: number; + average_speed: number; + streak: number; +} + +const titleForShow = (run: Activity): string => { const date = run.start_date_local.slice(0, 11); const distance = (run.distance / 1000.0).toFixed(2); let name = 'Run'; @@ -20,7 +38,7 @@ const titleForShow = (run) => { }`; }; -const formatPace = (d) => { +const formatPace = (d: number): string => { if (Number.isNaN(d)) return '0'; const pace = (1000.0 / 60.0) * (1.0 / d); const minutes = Math.floor(pace); @@ -28,7 +46,7 @@ const formatPace = (d) => { return `${minutes}'${seconds.toFixed(0).toString().padStart(2, '0')}"`; }; -const convertMovingTime2Sec = (moving_time) => { +const convertMovingTime2Sec = (moving_time: string): number => { if (!moving_time) { return 0; } @@ -41,7 +59,7 @@ const convertMovingTime2Sec = (moving_time) => { return totalSeconds; }; -const formatRunTime = (moving_time) => { +const formatRunTime = (moving_time: string): string => { const totalSeconds = convertMovingTime2Sec(moving_time); const seconds = totalSeconds % 60; const minutes = (totalSeconds - seconds) / 60; @@ -54,25 +72,33 @@ const formatRunTime = (moving_time) => { // for scroll to the map const scrollToMap = () => { const el = document.querySelector('.fl.w-100.w-70-l'); - const rect = el.getBoundingClientRect(); - window.scroll(rect.left + window.scrollX, rect.top + window.scrollY); + const rect = el?.getBoundingClientRect(); + if (rect) { + window.scroll(rect.left + window.scrollX, rect.top + window.scrollY); + } }; const pattern = /([\u4e00-\u9fa5]{2,}(市|自治州))/g; -const extractLocations = (str) => { +const extractLocations = (str: string): string[] => { const locations = []; let match; - + while ((match = pattern.exec(str)) !== null) { locations.push(match[0]); } - + return locations; }; const cities = chinaCities.map((c) => c.name); // what about oversea? -const locationForRun = (run) => { +const locationForRun = ( + run: Activity +): { + country: string; + province: string; + city: string; +} => { let location = run.location_country; let [city, province, country] = ['', '', '']; if (location) { @@ -82,9 +108,8 @@ const locationForRun = (run) => { const provinceMatch = location.match(/[\u4e00-\u9fa5]{2,}(省|自治区)/); if (cityMatch) { - [city] = cityMatch; - city = cities.find(value => cityMatch.includes(value)); - + city = cities.find((value) => cityMatch.includes(value)) as string; + if (!city) { city = ''; } @@ -118,7 +143,7 @@ const intComma = (x = '') => { return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); }; -const pathForRun = (run) => { +const pathForRun = (run: Activity): Coordinate[] => { try { const c = mapboxPolyline.decode(run.summary_polyline); // reverse lat long for mapbox @@ -133,16 +158,14 @@ const pathForRun = (run) => { } }; -const geoJsonForRuns = (runs) => ({ +const geoJsonForRuns = (runs: Activity[]): FeatureCollection => ({ type: 'FeatureCollection', features: runs.map((run) => { const points = pathForRun(run); - if (!points) { - return null; - } return { type: 'Feature', + properties: {}, geometry: { type: 'LineString', coordinates: points, @@ -153,7 +176,7 @@ const geoJsonForRuns = (runs) => ({ const geoJsonForMap = () => chinaGeojson; -const titleForRun = (run) => { +const titleForRun = (run: Activity): string => { const runDistance = run.distance / 1000; const runHour = +run.start_date_local.slice(11, 13); if (runDistance > 20 && runDistance < 40) { @@ -177,14 +200,21 @@ const titleForRun = (run) => { return RUN_TITLES.NIGHT_RUN_TITLE; }; -const applyToArray = (func, array) => func.apply(Math, array); -const getBoundsForGeoData = (geoData) => { +export interface IViewport { + longitude?: number; + latitude?: number; + zoom?: number; +} + +const getBoundsForGeoData = ( + geoData: FeatureCollection +): IViewport => { const { features } = geoData; - let points; + let points: Coordinate[] = []; // find first have data for (const f of features) { if (f.geometry.coordinates.length) { - points = f.geometry.coordinates; + points = f.geometry.coordinates as Coordinate[]; break; } } @@ -192,11 +222,11 @@ const getBoundsForGeoData = (geoData) => { return {}; } // Calculate corner values of bounds - const pointsLong = points.map((point) => point[0]); - const pointsLat = points.map((point) => point[1]); - const cornersLongLat = [ - [applyToArray(Math.min, pointsLong), applyToArray(Math.min, pointsLat)], - [applyToArray(Math.max, pointsLong), applyToArray(Math.max, pointsLat)], + const pointsLong = points.map((point) => point[0]) as number[]; + const pointsLat = points.map((point) => point[1]) as number[]; + const cornersLongLat: [Coordinate, Coordinate] = [ + [Math.min(...pointsLong), Math.min(...pointsLat)], + [Math.max(...pointsLong), Math.max(...pointsLat)], ]; const viewport = new WebMercatorViewport({ width: 800, @@ -209,22 +239,28 @@ const getBoundsForGeoData = (geoData) => { return { longitude, latitude, zoom }; }; -const filterYearRuns = (run, year) => { +const filterYearRuns = (run: Activity, year: string) => { if (run && run.start_date_local) { return run.start_date_local.slice(0, 4) === year; } return false; }; -const filterCityRuns = (run, city) => { +const filterCityRuns = (run: Activity, city: string) => { if (run && run.location_country) { return run.location_country.includes(city); } return false; }; -const filterTitleRuns = (run, title) => titleForRun(run) === title; +const filterTitleRuns = (run: Activity, title: string) => + titleForRun(run) === title; -const filterAndSortRuns = (activities, item, filterFunc, sortFunc) => { +const filterAndSortRuns = ( + activities: Activity[], + item: string, + filterFunc: (_run: Activity, _bvalue: string) => boolean, + sortFunc: (_a: Activity, _b: Activity) => number +) => { let s = activities; if (item !== 'Total') { s = activities.filter((run) => filterFunc(run, item)); @@ -232,10 +268,14 @@ const filterAndSortRuns = (activities, item, filterFunc, sortFunc) => { return s.sort(sortFunc); }; -const sortDateFunc = (a, b) => - new Date(b.start_date_local.replace(' ', 'T')) - - new Date(a.start_date_local.replace(' ', 'T')); -const sortDateFuncReverse = (a, b) => sortDateFunc(b, a); +const sortDateFunc = (a: Activity, b: Activity) => { + // @ts-ignore + return ( + new Date(b.start_date_local.replace(' ', 'T')) - + new Date(a.start_date_local.replace(' ', 'T')) + ); +}; +const sortDateFuncReverse = (a: Activity, b: Activity) => sortDateFunc(b, a); export { titleForShow, diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000000..748eeb7d8ec --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,113 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Projects */ + // "incremental": true, /* Enable incremental compilation */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "esnext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, + "lib": [ + "dom", + "esnext" + ] /* Specify a set of bundled library declaration files that describe the target runtime environment. */, + "jsx": "react" /* Specify what JSX code is generated. */, + // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ + // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + + /* Modules */ + "module": "esnext" /* Specify what module code is generated. */, + // "rootDir": "./", /* Specify the root folder within your source files. */ + "moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */, + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + "paths": { + "@/*": ["./src/*"], + "@assets/*": ["./assets/*"] + } /* Specify a set of entries that re-map imports to additional lookup locations. */, + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + "resolveJsonModule": true /* Enable importing .json files */, + // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */, + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, + + /* Type Checking */ + "strict": true /* Enable all strict type-checking options. */, + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ + // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ + // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + }, + "include": [ + "./src/**/*", + "./gatsby-node.ts", + "./gatsby-config.ts", + "./plugins/**/*" + ] +} diff --git a/yarn.lock b/yarn.lock index 4adf98477a7..d715f8facfb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -91,7 +91,7 @@ "@jridgewell/gen-mapping" "^0.3.2" jsesc "^2.5.1" -"@babel/helper-annotate-as-pure@^7.16.0", "@babel/helper-annotate-as-pure@^7.18.6": +"@babel/helper-annotate-as-pure@^7.18.6": version "7.18.6" resolved "https://registry.npmmirror.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz" integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== @@ -183,7 +183,7 @@ dependencies: "@babel/types" "^7.18.9" -"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.0.0-beta.49", "@babel/helper-module-imports@^7.16.0", "@babel/helper-module-imports@^7.18.6": +"@babel/helper-module-imports@^7.0.0-beta.49", "@babel/helper-module-imports@^7.18.6": version "7.18.6" resolved "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz" integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== @@ -301,7 +301,7 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.14.0", "@babel/parser@^7.15.5", "@babel/parser@^7.16.8", "@babel/parser@^7.18.10", "@babel/parser@^7.19.6", "@babel/parser@^7.7.0": +"@babel/parser@^7.14.0", "@babel/parser@^7.15.5", "@babel/parser@^7.16.8", "@babel/parser@^7.18.10", "@babel/parser@^7.19.6": version "7.19.6" resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.19.6.tgz" integrity sha512-h1IUp81s2JYJ3mRkdxJgs4UvmSsRvDrx5ICSJbPvtWYv5i1nTBGcBpnog+89rAFMwvvru6E5NUHdBe01UeSzYA== @@ -1036,7 +1036,7 @@ "@babel/parser" "^7.18.10" "@babel/types" "^7.18.10" -"@babel/traverse@^7.14.0", "@babel/traverse@^7.15.4", "@babel/traverse@^7.16.8", "@babel/traverse@^7.19.0", "@babel/traverse@^7.19.1", "@babel/traverse@^7.19.4", "@babel/traverse@^7.19.6", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.0": +"@babel/traverse@^7.14.0", "@babel/traverse@^7.15.4", "@babel/traverse@^7.16.8", "@babel/traverse@^7.19.0", "@babel/traverse@^7.19.1", "@babel/traverse@^7.19.4", "@babel/traverse@^7.19.6": version "7.19.6" resolved "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.19.6.tgz" integrity sha512-6l5HrUCzFM04mfbG09AagtYyR2P0B71B1wN7PfSPiksDPz2k5H9CBC1tcZpz2M8OxbKTPccByoOJ22rUKbpmQQ== @@ -1052,7 +1052,7 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.15.4", "@babel/types@^7.16.8", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.19.4", "@babel/types@^7.4.4", "@babel/types@^7.7.0": +"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.15.4", "@babel/types@^7.16.8", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.19.4", "@babel/types@^7.4.4": version "7.19.4" resolved "https://registry.npmmirror.com/@babel/types/-/types-7.19.4.tgz" integrity sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw== @@ -1066,40 +1066,6 @@ resolved "https://registry.npmmirror.com/@builder.io/partytown/-/partytown-0.5.4.tgz" integrity sha512-qnikpQgi30AS01aFlNQV6l8/qdZIcP76mp90ti+u4rucXHsn4afSKivQXApqxvrQG9+Ibv45STyvHizvxef/7A== -"@emotion/is-prop-valid@^1.1.0": - version "1.2.0" - resolved "https://registry.npmmirror.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz" - integrity sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg== - dependencies: - "@emotion/memoize" "^0.8.0" - -"@emotion/memoize@^0.8.0": - version "0.8.0" - resolved "https://registry.npmmirror.com/@emotion/memoize/-/memoize-0.8.0.tgz" - integrity sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA== - -"@emotion/stylis@^0.8.4": - version "0.8.5" - resolved "https://registry.npmmirror.com/@emotion/stylis/-/stylis-0.8.5.tgz" - integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ== - -"@emotion/unitless@^0.7.4": - version "0.7.5" - resolved "https://registry.npmmirror.com/@emotion/unitless/-/unitless-0.7.5.tgz" - integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== - -"@eslint-community/eslint-utils@^4.2.0": - version "4.4.0" - resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" - integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== - dependencies: - eslint-visitor-keys "^3.3.0" - -"@eslint-community/regexpp@^4.4.0": - version "4.5.1" - resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz" - integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== - "@eslint/eslintrc@^0.4.3": version "0.4.3" resolved "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz" @@ -1526,9 +1492,9 @@ integrity sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ== "@mapbox/mapbox-gl-language@^1.0.0": - version "1.0.0" - resolved "https://registry.npmmirror.com/@mapbox/mapbox-gl-language/-/mapbox-gl-language-1.0.0.tgz" - integrity sha512-G1m/BK7M9+u8tM23qg1gA9hyhjFplAfttLb1li6+hlBfhjRApzSqbYlX4pvtN4SftO7ALHNX7uPhpzpkl7c+5Q== + version "1.0.1" + resolved "https://registry.npmmirror.com/@mapbox/mapbox-gl-language/-/mapbox-gl-language-1.0.1.tgz#19c57da3163959f70c4057967cf599d2f49a7795" + integrity sha512-gL58ojl7gaWLfbSISoB2QJEfTK3j+NKvPH9og0r+c3bd5BNqhY19Eb4OPfDc5+dGmjW03LhtZBc4n2b7Xn8kjA== "@mapbox/mapbox-gl-supported@^1.5.0": version "1.5.0" @@ -2175,7 +2141,7 @@ dependencies: "@types/node" "*" -"@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.7", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": +"@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.7", "@types/json-schema@^7.0.8": version "7.0.11" resolved "https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.11.tgz" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== @@ -2204,6 +2170,13 @@ dependencies: "@types/geojson" "*" +"@types/mapbox__polyline@^1.0.2": + version "1.0.2" + resolved "https://registry.npmmirror.com/@types/mapbox__polyline/-/mapbox__polyline-1.0.2.tgz#788cf4d72326961eacf44cb1abca435860ec4673" + integrity sha512-Kr/oznVL3e8uvWM0+VPlVu2rVP+jKyVW/994HE9YJFBfcAcKqB4wMvqCdgXLG0SSrxxlKc5Nqaj7zt+KRl9oCA== + dependencies: + "@types/geojson" "*" + "@types/minimatch@*": version "5.1.2" resolved "https://registry.npmmirror.com/@types/minimatch/-/minimatch-5.1.2.tgz" @@ -2234,6 +2207,11 @@ resolved "https://registry.npmmirror.com/@types/node/-/node-18.11.3.tgz" integrity sha512-fNjDQzzOsZeKZu5NATgXUPsaFaTxeRgFXoosrHivTl8RGeV733OLawXsGfEk9a8/tySyZUyiZ6E8LcjPFZ2y1A== +"@types/node@^20.3.3": + version "20.4.3" + resolved "https://registry.npmmirror.com/@types/node/-/node-20.4.3.tgz#ca83a5a006e0d5709a3fe8966112f26436071d81" + integrity sha512-Yu3+r4Mn/iY6Mf0aihncZQ1qOjOUrCiodbHHY1hds5O+7BbKp9t+Li7zLO13zO8j9L2C6euz8xsYQP0rjGvVXw== + "@types/node@^8.5.7": version "8.10.66" resolved "https://registry.npmmirror.com/@types/node/-/node-8.10.66.tgz" @@ -2261,6 +2239,13 @@ dependencies: "@types/react" "*" +"@types/react-dom@^18.2.6": + version "18.2.7" + resolved "https://registry.npmmirror.com/@types/react-dom/-/react-dom-18.2.7.tgz#67222a08c0a6ae0a0da33c3532348277c70abb63" + integrity sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA== + dependencies: + "@types/react" "*" + "@types/react-helmet@^6.1.6": version "6.1.6" resolved "https://registry.npmjs.org/@types/react-helmet/-/react-helmet-6.1.6.tgz#7d1afd8cbf099616894e8240e9ef70e3c6d7506d" @@ -2277,6 +2262,15 @@ "@types/scheduler" "*" csstype "^3.0.2" +"@types/react@^18.2.14": + version "18.2.15" + resolved "https://registry.npmmirror.com/@types/react/-/react-18.2.15.tgz#14792b35df676c20ec3cf595b262f8c615a73066" + integrity sha512-oEjE7TQt1fFTFSbf8kkNuc798ahTUzn3Le67/PWjE8MAfYAD/qB7O8hSTcromLFqHCt9bcdOg5GXMokzTjJ5SA== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + "@types/responselike@*", "@types/responselike@^1.0.0": version "1.0.0" resolved "https://registry.npmmirror.com/@types/responselike/-/responselike-1.0.0.tgz" @@ -2297,11 +2291,6 @@ resolved "https://registry.npmmirror.com/@types/scheduler/-/scheduler-0.16.2.tgz" integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== -"@types/semver@^7.3.12": - version "7.3.13" - resolved "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz" - integrity sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw== - "@types/sharp@^0.30.5": version "0.30.5" resolved "https://registry.npmmirror.com/@types/sharp/-/sharp-0.30.5.tgz" @@ -2333,22 +2322,6 @@ semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/eslint-plugin@^5.59.2": - version "5.59.2" - resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.2.tgz" - integrity sha512-yVrXupeHjRxLDcPKL10sGQ/QlVrA8J5IYOEWVqk0lJaSZP7X5DfnP7Ns3cc74/blmbipQ1htFNVGsHX6wsYm0A== - dependencies: - "@eslint-community/regexpp" "^4.4.0" - "@typescript-eslint/scope-manager" "5.59.2" - "@typescript-eslint/type-utils" "5.59.2" - "@typescript-eslint/utils" "5.59.2" - debug "^4.3.4" - grapheme-splitter "^1.0.4" - ignore "^5.2.0" - natural-compare-lite "^1.4.0" - semver "^7.3.7" - tsutils "^3.21.0" - "@typescript-eslint/experimental-utils@4.33.0": version "4.33.0" resolved "https://registry.npmmirror.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz" @@ -2397,16 +2370,6 @@ "@typescript-eslint/types" "5.59.2" "@typescript-eslint/visitor-keys" "5.59.2" -"@typescript-eslint/type-utils@5.59.2": - version "5.59.2" - resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.2.tgz" - integrity sha512-b1LS2phBOsEy/T381bxkkywfQXkV1dWda/z0PhnIy3bC5+rQWQDS7fk9CSpcXBccPY27Z6vBEuaPBCKCgYezyQ== - dependencies: - "@typescript-eslint/typescript-estree" "5.59.2" - "@typescript-eslint/utils" "5.59.2" - debug "^4.3.4" - tsutils "^3.21.0" - "@typescript-eslint/types@4.33.0": version "4.33.0" resolved "https://registry.npmmirror.com/@typescript-eslint/types/-/types-4.33.0.tgz" @@ -2443,20 +2406,6 @@ semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/utils@5.59.2": - version "5.59.2" - resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.2.tgz" - integrity sha512-kSuF6/77TZzyGPhGO4uVp+f0SBoYxCDf+lW3GKhtKru/L8k/Hd7NFQxyWUeY7Z/KGB2C6Fe3yf2vVi4V9TsCSQ== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@types/json-schema" "^7.0.9" - "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.59.2" - "@typescript-eslint/types" "5.59.2" - "@typescript-eslint/typescript-estree" "5.59.2" - eslint-scope "^5.1.1" - semver "^7.3.7" - "@typescript-eslint/visitor-keys@4.33.0": version "4.33.0" resolved "https://registry.npmmirror.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz" @@ -2992,18 +2941,6 @@ axobject-query@^2.2.0: resolved "https://registry.npmmirror.com/axobject-query/-/axobject-query-2.2.0.tgz" integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA== -babel-eslint@^10.1.0: - version "10.1.0" - resolved "https://registry.npmmirror.com/babel-eslint/-/babel-eslint-10.1.0.tgz" - integrity sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.7.0" - "@babel/traverse" "^7.7.0" - "@babel/types" "^7.7.0" - eslint-visitor-keys "^1.0.0" - resolve "^1.12.0" - babel-extract-comments@^1.0.0: version "1.0.0" resolved "https://registry.npmmirror.com/babel-extract-comments/-/babel-extract-comments-1.0.0.tgz" @@ -3086,22 +3023,6 @@ babel-plugin-remove-graphql-queries@^4.25.0: "@babel/types" "^7.15.4" gatsby-core-utils "^3.25.0" -"babel-plugin-styled-components@>= 1.12.0": - version "2.0.7" - resolved "https://registry.npmmirror.com/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.7.tgz" - integrity sha512-i7YhvPgVqRKfoQ66toiZ06jPNA3p6ierpfUuEWxNF+fV27Uv5gxBkf8KZLHUCc1nFA9j6+80pYoIpqCeyW3/bA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.0" - "@babel/helper-module-imports" "^7.16.0" - babel-plugin-syntax-jsx "^6.18.0" - lodash "^4.17.11" - picomatch "^2.3.0" - -babel-plugin-syntax-jsx@^6.18.0: - version "6.18.0" - resolved "https://registry.npmmirror.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz" - integrity sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw== - babel-plugin-syntax-object-rest-spread@^6.8.0: version "6.13.0" resolved "https://registry.npmmirror.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz" @@ -3443,11 +3364,6 @@ camelcase@^6.2.0: resolved "https://registry.npmmirror.com/camelcase/-/camelcase-6.3.0.tgz" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -camelize@^1.0.0: - version "1.0.1" - resolved "https://registry.npmmirror.com/camelize/-/camelize-1.0.1.tgz" - integrity sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ== - caniuse-api@^3.0.0: version "3.0.0" resolved "https://registry.npmmirror.com/caniuse-api/-/caniuse-api-3.0.0.tgz" @@ -3591,11 +3507,6 @@ ci-info@2.0.0, ci-info@^2.0.0: resolved "https://registry.npmmirror.com/ci-info/-/ci-info-2.0.0.tgz" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== -classnames@^2.3.1: - version "2.3.2" - resolved "https://registry.npmmirror.com/classnames/-/classnames-2.3.2.tgz" - integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw== - cli-boxes@^2.2.0, cli-boxes@^2.2.1: version "2.2.1" resolved "https://registry.npmmirror.com/cli-boxes/-/cli-boxes-2.2.1.tgz" @@ -3960,11 +3871,6 @@ crypto-random-string@^2.0.0: resolved "https://registry.npmmirror.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz" integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== -css-color-keywords@^1.0.0: - version "1.0.0" - resolved "https://registry.npmmirror.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz" - integrity sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg== - css-declaration-sorter@^6.3.0: version "6.3.1" resolved "https://registry.npmmirror.com/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz" @@ -4021,15 +3927,6 @@ css-select@^5.1.0: domutils "^3.0.1" nth-check "^2.0.1" -css-to-react-native@^3.0.0: - version "3.0.0" - resolved "https://registry.npmmirror.com/css-to-react-native/-/css-to-react-native-3.0.0.tgz" - integrity sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ== - dependencies: - camelize "^1.0.0" - css-color-keywords "^1.0.0" - postcss-value-parser "^4.0.2" - css-tree@^1.1.2, css-tree@^1.1.3: version "1.1.3" resolved "https://registry.npmmirror.com/css-tree/-/css-tree-1.1.3.tgz" @@ -4147,7 +4044,7 @@ damerau-levenshtein@^1.0.8: resolved "https://registry.npmmirror.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz" integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== -date-fns@^2.25.0, date-fns@^2.28.0: +date-fns@^2.25.0: version "2.29.3" resolved "https://registry.npmmirror.com/date-fns/-/date-fns-2.29.3.tgz" integrity sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA== @@ -4901,7 +4798,7 @@ eslint-utils@^3.0.0: dependencies: eslint-visitor-keys "^2.0.0" -eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: +eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: version "1.3.0" resolved "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz" integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== @@ -6047,6 +5944,11 @@ geojson-vt@^3.2.1: resolved "https://registry.npmmirror.com/geojson-vt/-/geojson-vt-3.2.1.tgz" integrity sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg== +geojson@^0.5.0: + version "0.5.0" + resolved "https://registry.npmmirror.com/geojson/-/geojson-0.5.0.tgz#3cd6c96399be65b56ee55596116fe9191ce701c0" + integrity sha512-/Bx5lEn+qRF4TfQ5aLu6NH+UKtvIv7Lhc487y/c8BdludrCTpiWf9wyI0RTyqg49MFefIAvFDuEi5Dfd/zgNxQ== + get-caller-file@^2.0.1: version "2.0.5" resolved "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz" @@ -6294,11 +6196,6 @@ graphql-type-json@0.3.2: resolved "https://registry.npmmirror.com/graphql-type-json/-/graphql-type-json-0.3.2.tgz" integrity sha512-J+vjof74oMlCWXSvt0DOf2APEdZOCdubEvGDUAlqH//VBYcOYsGgRW7Xzorr44LvkjiuvecWc8fChxuZZbChtg== -graphql@15.0.0: - version "15.0.0" - resolved "https://registry.npmjs.org/graphql/-/graphql-15.0.0.tgz" - integrity sha512-ZyVO1xIF9F+4cxfkdhOJINM+51B06Friuv4M66W7HzUOeFd+vNzUn4vtswYINPi6sysjf1M2Ri/rwZALqgwbaQ== - graphql@^15.7.2: version "15.8.0" resolved "https://registry.npmmirror.com/graphql/-/graphql-15.8.0.tgz" @@ -6398,13 +6295,6 @@ header-case@^2.0.4: capital-case "^1.0.4" tslib "^2.0.3" -hoist-non-react-statics@^3.0.0: - version "3.3.2" - resolved "https://registry.npmmirror.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz" - integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== - dependencies: - react-is "^16.7.0" - hosted-git-info@^2.1.4: version "2.8.9" resolved "https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz" @@ -7373,7 +7263,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.npmmirror.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz" integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== -lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@~4.17.0: +lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@~4.17.0: version "4.17.21" resolved "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -7812,11 +7702,6 @@ napi-build-utils@^1.0.1: resolved "https://registry.npmmirror.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz" integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== -natural-compare-lite@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz" - integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== - natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz" @@ -8395,7 +8280,7 @@ picocolors@^1.0.0: resolved "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.0, picomatch@^2.3.1: +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -8666,7 +8551,7 @@ postcss-unique-selectors@^5.1.1: dependencies: postcss-selector-parser "^6.0.5" -postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: +postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: version "4.2.0" resolved "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== @@ -8974,16 +8859,11 @@ react-helmet@^6.1.0: react-fast-compare "^3.1.1" react-side-effect "^2.1.0" -react-is@^16.13.1, react-is@^16.7.0: +react-is@^16.13.1: version "16.13.1" resolved "https://registry.npmmirror.com/react-is/-/react-is-16.13.1.tgz" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-is@^18.2.0: - version "18.2.0" - resolved "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz" - integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== - react-lifecycles-compat@^3.0.4: version "3.0.4" resolved "https://registry.npmmirror.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz" @@ -9017,11 +8897,6 @@ react-server-dom-webpack@0.0.0-experimental-c8b778b7f-20220825: loose-envify "^1.1.0" neo-async "^2.6.1" -react-server-dom-webpack@^0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/react-server-dom-webpack/-/react-server-dom-webpack-0.0.1.tgz#385f0c886b5c014601dcda9754b37702fcdff183" - integrity sha512-XLR1T3SxiYe5CePB7apZg91V7zJqp55rAj1wb1rD0VQc8eA/Tt1mhCXaDKvUnLAxiOqUgRapl9CA3eud0UhEvg== - react-side-effect@^2.1.0: version "2.1.2" resolved "https://registry.npmmirror.com/react-side-effect/-/react-side-effect-2.1.2.tgz" @@ -9310,7 +9185,7 @@ resolve-url@^0.2.1: resolved "https://registry.npmmirror.com/resolve-url/-/resolve-url-0.2.1.tgz" integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== -resolve@^1.10.0, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.0: +resolve@^1.10.0, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.0: version "1.22.1" resolved "https://registry.npmmirror.com/resolve/-/resolve-1.22.1.tgz" integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== @@ -9613,11 +9488,6 @@ shallow-compare@^1.2.2: resolved "https://registry.npmmirror.com/shallow-compare/-/shallow-compare-1.2.2.tgz" integrity sha512-LUMFi+RppPlrHzbqmFnINTrazo0lPNwhcgzuAXVVcfy/mqPDrQmHAyz5bvV0gDAuRFrk804V0HpQ6u9sZ0tBeg== -shallowequal@^1.1.0: - version "1.1.0" - resolved "https://registry.npmmirror.com/shallowequal/-/shallowequal-1.1.0.tgz" - integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== - sharp@^0.30.7: version "0.30.7" resolved "https://registry.npmmirror.com/sharp/-/sharp-0.30.7.tgz" @@ -10101,22 +9971,6 @@ style-loader@^2.0.0: loader-utils "^2.0.0" schema-utils "^3.0.0" -styled-components@^5.3.5: - version "5.3.6" - resolved "https://registry.npmmirror.com/styled-components/-/styled-components-5.3.6.tgz" - integrity sha512-hGTZquGAaTqhGWldX7hhfzjnIYBZ0IXQXkCYdvF1Sq3DsUaLx6+NTHC5Jj1ooM2F68sBiVz3lvhfwQs/S3l6qg== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/traverse" "^7.4.5" - "@emotion/is-prop-valid" "^1.1.0" - "@emotion/stylis" "^0.8.4" - "@emotion/unitless" "^0.7.4" - babel-plugin-styled-components ">= 1.12.0" - css-to-react-native "^3.0.0" - hoist-non-react-statics "^3.0.0" - shallowequal "^1.1.0" - supports-color "^5.5.0" - stylehacks@^5.1.0: version "5.1.0" resolved "https://registry.npmmirror.com/stylehacks/-/stylehacks-5.1.0.tgz" @@ -10137,7 +9991,7 @@ supercluster@^7.1.0, supercluster@^7.1.4: dependencies: kdbush "^3.0.0" -supports-color@^5.3.0, supports-color@^5.5.0: +supports-color@^5.3.0: version "5.5.0" resolved "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== @@ -10495,10 +10349,10 @@ typedarray@^0.0.6: resolved "https://registry.npmmirror.com/typedarray/-/typedarray-0.0.6.tgz" integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== -typescript@^5.0.4: - version "5.0.4" - resolved "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz" - integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== +typescript@^5.1.6: + version "5.1.6" + resolved "https://registry.npmmirror.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" + integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== ua-parser-js@^0.7.30: version "0.7.32" @@ -10779,7 +10633,7 @@ webpack-virtual-modules@^0.3.2: dependencies: debug "^3.0.0" -webpack@^5.61.0, webpack@^5.73.0: +webpack@^5.61.0: version "5.74.0" resolved "https://registry.npmmirror.com/webpack/-/webpack-5.74.0.tgz" integrity sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==