feat: add check update

This commit is contained in:
Yifei Zhang 2023-03-23 16:01:00 +00:00
parent e55520e93c
commit 29de957395
13 changed files with 201 additions and 5257 deletions

View File

@ -26,6 +26,7 @@ import { copyToClipboard, downloadAs, isIOS, selectOrCopy } from "../utils";
import Locale from "../locales"; import Locale from "../locales";
import dynamic from "next/dynamic"; import dynamic from "next/dynamic";
import { REPO_URL } from "../constant";
export function Loading(props: { noLogo?: boolean }) { export function Loading(props: { noLogo?: boolean }) {
return ( return (
@ -466,10 +467,7 @@ export function Home() {
/> />
</div> </div>
<div className={styles["sidebar-action"]}> <div className={styles["sidebar-action"]}>
<a <a href={REPO_URL} target="_blank">
href="https://github.com/Yidadaa/ChatGPT-Next-Web"
target="_blank"
>
<IconButton icon={<GithubIcon />} /> <IconButton icon={<GithubIcon />} />
</a> </a>
</div> </div>

View File

@ -1,4 +1,4 @@
import { useState } from "react"; import { useState, useEffect } from "react";
import EmojiPicker, { Theme as EmojiTheme } from "emoji-picker-react"; import EmojiPicker, { Theme as EmojiTheme } from "emoji-picker-react";
@ -15,6 +15,9 @@ import { SubmitKey, useChatStore, Theme, ALL_MODELS } from "../store";
import { Avatar } from "./home"; import { Avatar } from "./home";
import Locale, { changeLang, getLang } from "../locales"; import Locale, { changeLang, getLang } from "../locales";
import { checkUpstreamLatestCommitId, getCurrentCommitId } from "../utils";
import Link from "next/link";
import { UPDATE_URL } from "../constant";
function SettingItem(props: { function SettingItem(props: {
title: string; title: string;
@ -45,6 +48,23 @@ export function Settings(props: { closeSettings: () => void }) {
] ]
); );
const currentId = getCurrentCommitId();
const [checkingUpdate, setCheckingUpdate] = useState(false);
const [remoteId, setRemoteId] = useState<string>();
const hasNewVersion = currentId !== remoteId;
function checkUpdate(force = false) {
setCheckingUpdate(true);
checkUpstreamLatestCommitId(force).then((id) => {
setRemoteId(id);
setCheckingUpdate(false);
});
}
useEffect(() => {
checkUpdate();
}, []);
return ( return (
<> <>
<div className={styles["window-header"]}> <div className={styles["window-header"]}>
@ -109,6 +129,31 @@ export function Settings(props: { closeSettings: () => void }) {
</Popover> </Popover>
</SettingItem> </SettingItem>
<SettingItem
title={Locale.Settings.Update.Version(currentId)}
subTitle={
checkingUpdate
? Locale.Settings.Update.IsChecking
: hasNewVersion
? Locale.Settings.Update.FoundUpdate(remoteId ?? "ERROR")
: Locale.Settings.Update.IsLatest
}
>
{checkingUpdate ? (
<div />
) : hasNewVersion ? (
<Link href={UPDATE_URL} target="_blank" className="link">
{Locale.Settings.Update.GoToUpdate}
</Link>
) : (
<IconButton
icon={<ResetIcon></ResetIcon>}
text={Locale.Settings.Update.CheckUpdate}
onClick={() => checkUpdate(true)}
/>
)}
</SettingItem>
<SettingItem title={Locale.Settings.SendKey}> <SettingItem title={Locale.Settings.SendKey}>
<select <select
value={config.submitKey} value={config.submitKey}

3
app/constant.ts Normal file
View File

@ -0,0 +1,3 @@
export const REPO_URL = "https://github.com/Yidadaa/ChatGPT-Next-Web";
export const UPDATE_URL =
"https://github.com/Yidadaa/ChatGPT-Next-Web#%E4%BF%9D%E6%8C%81%E6%9B%B4%E6%96%B0-keep-updated";

View File

@ -4,9 +4,11 @@ import "./styles/prism.scss";
export const metadata = { export const metadata = {
title: "ChatGPT Next Web", title: "ChatGPT Next Web",
description: "Your personal ChatGPT Chat Bot.", description: "Your personal ChatGPT Chat Bot."
}; };
const COMMIT_ID = process.env.COMMIT_ID
export default function RootLayout({ export default function RootLayout({
children, children,
}: { }: {
@ -19,7 +21,14 @@ export default function RootLayout({
name="viewport" name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
/> />
<meta name="version" content={COMMIT_ID} />
<link rel="manifest" href="/site.webmanifest"></link> <link rel="manifest" href="/site.webmanifest"></link>
<link rel="preconnect" href="https://fonts.googleapis.com"></link>
<link rel="preconnect" href="https://fonts.gstatic.com"></link>
<link
href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;400;700;900&display=swap"
rel="stylesheet"
></link>
</head> </head>
<body>{children}</body> <body>{children}</body>
</html> </html>

View File

@ -43,6 +43,14 @@ const cn = {
}, },
}, },
Avatar: "头像", Avatar: "头像",
Update: {
Version: (x: string) => `当前版本:${x}`,
IsLatest: "已是最新版本",
CheckUpdate: "检查更新",
IsChecking: "正在检查更新...",
FoundUpdate: (x: string) => `发现新版本:${x}`,
GoToUpdate: "前往更新",
},
SendKey: "发送键", SendKey: "发送键",
Theme: "主题", Theme: "主题",
TightBorder: "紧凑边框", TightBorder: "紧凑边框",

View File

@ -46,6 +46,14 @@ const en: LocaleType = {
}, },
}, },
Avatar: "Avatar", Avatar: "Avatar",
Update: {
Version: (x: string) => `Version: ${x}`,
IsLatest: "Latest version",
CheckUpdate: "Check Update",
IsChecking: "Checking update...",
FoundUpdate: (x: string) => `Found new version: ${x}`,
GoToUpdate: "Update",
},
SendKey: "Send Key", SendKey: "Send Key",
Theme: "Theme", Theme: "Theme",
TightBorder: "Tight Border", TightBorder: "Tight Border",

View File

@ -83,6 +83,8 @@ body {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
user-select: none; user-select: none;
font-family: "Noto Sans SC", "SF Pro SC", "SF Pro Text", "SF Pro Icons",
"PingFang SC", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
} }
::-webkit-scrollbar { ::-webkit-scrollbar {
@ -192,3 +194,14 @@ div.math {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
.link {
font-size: 12px;
color: var(--primary);
text-decoration: none;
padding: 5px 10px;
&:hover {
text-decoration: underline;
}
}

View File

@ -96,8 +96,6 @@
margin: 0; margin: 0;
color: var(--color-fg-default); color: var(--color-fg-default);
background-color: var(--color-canvas-default); background-color: var(--color-canvas-default);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans",
Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
font-size: 14px; font-size: 14px;
line-height: 1.5; line-height: 1.5;
word-wrap: break-word; word-wrap: break-word;
@ -319,7 +317,7 @@
cursor: pointer; cursor: pointer;
} }
.markdown-body details:not([open])>*:not(summary) { .markdown-body details:not([open]) > *:not(summary) {
display: none !important; display: none !important;
} }
@ -489,11 +487,11 @@
content: ""; content: "";
} }
.markdown-body>*:first-child { .markdown-body > *:first-child {
margin-top: 0 !important; margin-top: 0 !important;
} }
.markdown-body>*:last-child { .markdown-body > *:last-child {
margin-bottom: 0 !important; margin-bottom: 0 !important;
} }
@ -529,11 +527,11 @@
margin-bottom: 16px; margin-bottom: 16px;
} }
.markdown-body blockquote> :first-child { .markdown-body blockquote > :first-child {
margin-top: 0; margin-top: 0;
} }
.markdown-body blockquote> :last-child { .markdown-body blockquote > :last-child {
margin-bottom: 0; margin-bottom: 0;
} }
@ -632,7 +630,7 @@
list-style-type: decimal; list-style-type: decimal;
} }
.markdown-body div>ol:not([type]) { .markdown-body div > ol:not([type]) {
list-style-type: decimal; list-style-type: decimal;
} }
@ -644,11 +642,11 @@
margin-bottom: 0; margin-bottom: 0;
} }
.markdown-body li>p { .markdown-body li > p {
margin-top: 16px; margin-top: 16px;
} }
.markdown-body li+li { .markdown-body li + li {
margin-top: 0.25em; margin-top: 0.25em;
} }
@ -711,7 +709,7 @@
overflow: hidden; overflow: hidden;
} }
.markdown-body span.frame>span { .markdown-body span.frame > span {
display: block; display: block;
float: left; float: left;
width: auto; width: auto;
@ -739,7 +737,7 @@
clear: both; clear: both;
} }
.markdown-body span.align-center>span { .markdown-body span.align-center > span {
display: block; display: block;
margin: 13px auto 0; margin: 13px auto 0;
overflow: hidden; overflow: hidden;
@ -757,7 +755,7 @@
clear: both; clear: both;
} }
.markdown-body span.align-right>span { .markdown-body span.align-right > span {
display: block; display: block;
margin: 13px 0 0; margin: 13px 0 0;
overflow: hidden; overflow: hidden;
@ -787,7 +785,7 @@
overflow: hidden; overflow: hidden;
} }
.markdown-body span.float-right>span { .markdown-body span.float-right > span {
display: block; display: block;
margin: 13px auto 0; margin: 13px auto 0;
overflow: hidden; overflow: hidden;
@ -821,7 +819,7 @@
font-size: 100%; font-size: 100%;
} }
.markdown-body pre>code { .markdown-body pre > code {
padding: 0; padding: 0;
margin: 0; margin: 0;
word-break: normal; word-break: normal;
@ -1085,7 +1083,7 @@
cursor: pointer; cursor: pointer;
} }
.markdown-body .task-list-item+.task-list-item { .markdown-body .task-list-item + .task-list-item {
margin-top: 4px; margin-top: 4px;
} }
@ -1107,7 +1105,9 @@
} }
.markdown-body .contains-task-list:hover .task-list-item-convert-container, .markdown-body .contains-task-list:hover .task-list-item-convert-container,
.markdown-body .contains-task-list:focus-within .task-list-item-convert-container { .markdown-body
.contains-task-list:focus-within
.task-list-item-convert-container {
display: block; display: block;
width: auto; width: auto;
height: 24px; height: 24px;

View File

@ -56,3 +56,42 @@ export function selectOrCopy(el: HTMLElement, content: string) {
return true; return true;
} }
let currentId: string;
export function getCurrentCommitId() {
if (currentId) {
return currentId;
}
if (document) {
const meta = document.head.querySelector(
"meta[name='version']"
) as HTMLMetaElement;
currentId = meta?.content ?? "";
} else {
currentId = process.env.COMMIT_ID ?? "";
}
return currentId;
}
let remoteId: string;
export async function checkUpstreamLatestCommitId(force = false) {
if (!force && remoteId) {
return remoteId;
}
const owner = "Yidadaa";
const repo = "ChatGPT-Next-Web";
const url = `https://api.github.com/repos/${owner}/${repo}/commits?per_page=1`;
try {
const data = await (await fetch(url)).json();
const sha = data[0].sha as string;
remoteId = sha.substring(0, 7);
return remoteId;
} catch (error) {
console.error("[Fetch Upstream Commit Id]", error);
return getCurrentCommitId();
}
}

View File

@ -11,7 +11,7 @@ const nextConfig = {
}); // 针对 SVG 的处理规则 }); // 针对 SVG 的处理规则
return config; return config;
}, }
}; };
module.exports = nextConfig; module.exports = nextConfig;

5221
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,11 @@
{ {
"name": "chatgpt-next-web", "name": "chatgpt-next-web",
"version": "0.1.0", "version": "1.1",
"private": true, "private": false,
"scripts": { "scripts": {
"dev": "next dev", "dev": "cross-env COMMIT_ID=$(git rev-parse --short HEAD) next dev",
"local:dev": "./dev/proxychains.exe -f ./scripts/proxychains.conf yarn dev", "build": "cross-env COMMIT_ID=$(git rev-parse --short HEAD) next build",
"local:start": "./dev/proxychains.exe -f ./scripts/proxychains.conf yarn start", "start": "cross-env COMMIT_ID=$(git rev-parse --short HEAD) next start",
"build": "next build",
"start": "next start",
"lint": "next lint" "lint": "next lint"
}, },
"dependencies": { "dependencies": {
@ -17,10 +15,12 @@
"@types/react-dom": "^18.0.11", "@types/react-dom": "^18.0.11",
"@types/react-katex": "^3.0.0", "@types/react-katex": "^3.0.0",
"@vercel/analytics": "^0.1.11", "@vercel/analytics": "^0.1.11",
"cross-env": "^7.0.3",
"emoji-picker-react": "^4.4.7", "emoji-picker-react": "^4.4.7",
"eslint": "8.35.0", "eslint": "8.35.0",
"eslint-config-next": "13.2.3", "eslint-config-next": "13.2.3",
"eventsource-parser": "^0.1.0", "eventsource-parser": "^0.1.0",
"git-rev-sync": "^3.0.2",
"next": "^13.2.3", "next": "^13.2.3",
"openai": "^3.2.1", "openai": "^3.2.1",
"react": "^18.2.0", "react": "^18.2.0",

View File

@ -1817,7 +1817,14 @@ cosmiconfig@^7.0.1:
path-type "^4.0.0" path-type "^4.0.0"
yaml "^1.10.0" yaml "^1.10.0"
cross-spawn@^7.0.2, cross-spawn@^7.0.3: cross-env@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf"
integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==
dependencies:
cross-spawn "^7.0.1"
cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
version "7.0.3" version "7.0.3"
resolved "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" resolved "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
@ -2126,7 +2133,7 @@ escalade@^3.1.1:
resolved "https://registry.npmmirror.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" resolved "https://registry.npmmirror.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
escape-string-regexp@^1.0.5: escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5:
version "1.0.5" version "1.0.5"
resolved "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" resolved "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
@ -2514,6 +2521,15 @@ get-tsconfig@^4.2.0:
resolved "https://registry.npmmirror.com/get-tsconfig/-/get-tsconfig-4.4.0.tgz#64eee64596668a81b8fce18403f94f245ee0d4e5" resolved "https://registry.npmmirror.com/get-tsconfig/-/get-tsconfig-4.4.0.tgz#64eee64596668a81b8fce18403f94f245ee0d4e5"
integrity sha512-0Gdjo/9+FzsYhXCEFueo2aY1z1tpXrxWZzP7k8ul9qt1U5o8rYJwTJYmaeHdrVosYIVYkOy2iwCJ9FdpocJhPQ== integrity sha512-0Gdjo/9+FzsYhXCEFueo2aY1z1tpXrxWZzP7k8ul9qt1U5o8rYJwTJYmaeHdrVosYIVYkOy2iwCJ9FdpocJhPQ==
git-rev-sync@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/git-rev-sync/-/git-rev-sync-3.0.2.tgz#9763c730981187c3419b75dd270088cc5f0e161b"
integrity sha512-Nd5RiYpyncjLv0j6IONy0lGzAqdRXUaBctuGBbrEA2m6Bn4iDrN/9MeQTXuiquw8AEKL9D2BW0nw5m/lQvxqnQ==
dependencies:
escape-string-regexp "1.0.5"
graceful-fs "4.1.15"
shelljs "0.8.5"
glob-parent@^5.1.2, glob-parent@~5.1.2: glob-parent@^5.1.2, glob-parent@~5.1.2:
version "5.1.2" version "5.1.2"
resolved "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" resolved "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
@ -2540,7 +2556,7 @@ glob@7.1.7:
once "^1.3.0" once "^1.3.0"
path-is-absolute "^1.0.0" path-is-absolute "^1.0.0"
glob@^7.1.3: glob@^7.0.0, glob@^7.1.3:
version "7.2.3" version "7.2.3"
resolved "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" resolved "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
@ -2611,6 +2627,11 @@ gopd@^1.0.1:
dependencies: dependencies:
get-intrinsic "^1.1.3" get-intrinsic "^1.1.3"
graceful-fs@4.1.15:
version "4.1.15"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==
graceful-fs@^4.2.4: graceful-fs@^4.2.4:
version "4.2.10" version "4.2.10"
resolved "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" resolved "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
@ -2778,6 +2799,11 @@ internal-slot@^1.0.3, internal-slot@^1.0.4:
has "^1.0.3" has "^1.0.3"
side-channel "^1.0.4" side-channel "^1.0.4"
interpret@^1.0.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==
is-alphabetical@^2.0.0: is-alphabetical@^2.0.0:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-2.0.1.tgz#01072053ea7c1036df3c7d19a6daaec7f19e789b" resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-2.0.1.tgz#01072053ea7c1036df3c7d19a6daaec7f19e789b"
@ -3983,6 +4009,13 @@ readdirp@~3.6.0:
dependencies: dependencies:
picomatch "^2.2.1" picomatch "^2.2.1"
rechoir@^0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
integrity sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==
dependencies:
resolve "^1.1.6"
refractor@^4.7.0: refractor@^4.7.0:
version "4.8.1" version "4.8.1"
resolved "https://registry.yarnpkg.com/refractor/-/refractor-4.8.1.tgz#fbdd889333a3d86c9c864479622855c9b38e9d42" resolved "https://registry.yarnpkg.com/refractor/-/refractor-4.8.1.tgz#fbdd889333a3d86c9c864479622855c9b38e9d42"
@ -4130,7 +4163,7 @@ resolve-from@^4.0.0:
resolved "https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" resolved "https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
resolve@^1.14.2, resolve@^1.22.1: resolve@^1.1.6, resolve@^1.14.2, resolve@^1.22.1:
version "1.22.1" version "1.22.1"
resolved "https://registry.npmmirror.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" resolved "https://registry.npmmirror.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
@ -4223,6 +4256,15 @@ shebang-regex@^3.0.0:
resolved "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" resolved "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
shelljs@0.8.5:
version "0.8.5"
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c"
integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==
dependencies:
glob "^7.0.0"
interpret "^1.0.0"
rechoir "^0.6.2"
side-channel@^1.0.4: side-channel@^1.0.4:
version "1.0.4" version "1.0.4"
resolved "https://registry.npmmirror.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" resolved "https://registry.npmmirror.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"