diff --git a/packages/console/package.json b/packages/console/package.json index 45cc76d2a..20ca61b73 100644 --- a/packages/console/package.json +++ b/packages/console/package.json @@ -17,7 +17,7 @@ }, "dependencies": { "@logto/phrases": "^0.1.0", - "@logto/react": "^0.1.2", + "@logto/react": "^0.1.3", "@logto/schemas": "^0.1.0", "@monaco-editor/react": "^4.3.1", "@silverhand/essentials": "^1.1.6", diff --git a/packages/console/src/App.tsx b/packages/console/src/App.tsx index 6f22cce83..94d8b23e6 100644 --- a/packages/console/src/App.tsx +++ b/packages/console/src/App.tsx @@ -7,6 +7,8 @@ import './scss/normalized.scss'; import AppContent from './components/AppContent'; import { getPath, sections } from './components/AppContent/components/Sidebar'; import Toast from './components/Toast'; +import { logtoApiResource } from './consts/api'; +import useSwrFetcher from './hooks/use-swr-fetcher'; import initI18n from './i18n/init'; import ApiResourceDetails from './pages/ApiResourceDetails'; import ApiResources from './pages/ApiResources'; @@ -18,7 +20,6 @@ import Connectors from './pages/Connectors'; import GetStarted from './pages/GetStarted'; import UserDetails from './pages/UserDetails'; import Users from './pages/Users'; -import { fetcher } from './swr'; const isBasenameNeeded = process.env.NODE_ENV !== 'development' || process.env.PORT === '5002'; @@ -27,6 +28,7 @@ void initI18n(); const Main = () => { const location = useLocation(); const navigate = useNavigate(); + const fetcher = useSwrFetcher(); useEffect(() => { if (location.pathname === '/') { @@ -35,44 +37,46 @@ const Main = () => { }, [location.pathname, navigate]); return ( - <LogtoProvider logtoConfig={{ endpoint: window.location.origin, clientId: 'foo' }}> - <SWRConfig value={{ fetcher }}> - <Toast /> - <Routes> - <Route path="callback" element={<Callback />} /> - <Route element={<AppContent theme="light" />}> - <Route path="get-started" element={<GetStarted />} /> - <Route path="applications"> - <Route index element={<Applications />} /> - <Route path=":id"> - <Route index element={<Navigate to="settings" />} /> - <Route path="settings" element={<ApplicationDetails />} /> - <Route path="advanced-settings" element={<ApplicationDetails />} /> - </Route> - </Route> - <Route path="api-resources"> - <Route index element={<ApiResources />} /> - <Route path=":id" element={<ApiResourceDetails />} /> - </Route> - <Route path="connectors"> - <Route index element={<Connectors />} /> - <Route path="social" element={<Connectors />} /> - <Route path=":connectorId" element={<ConnectorDetails />} /> - </Route> - <Route path="users"> - <Route index element={<Users />} /> - <Route path=":id" element={<UserDetails />} /> + <SWRConfig value={{ fetcher }}> + <Toast /> + <Routes> + <Route path="callback" element={<Callback />} /> + <Route element={<AppContent theme="light" />}> + <Route path="get-started" element={<GetStarted />} /> + <Route path="applications"> + <Route index element={<Applications />} /> + <Route path=":id"> + <Route index element={<Navigate to="settings" />} /> + <Route path="settings" element={<ApplicationDetails />} /> + <Route path="advanced-settings" element={<ApplicationDetails />} /> </Route> </Route> - </Routes> - </SWRConfig> - </LogtoProvider> + <Route path="api-resources"> + <Route index element={<ApiResources />} /> + <Route path=":id" element={<ApiResourceDetails />} /> + </Route> + <Route path="connectors"> + <Route index element={<Connectors />} /> + <Route path="social" element={<Connectors />} /> + <Route path=":connectorId" element={<ConnectorDetails />} /> + </Route> + <Route path="users"> + <Route index element={<Users />} /> + <Route path=":id" element={<UserDetails />} /> + </Route> + </Route> + </Routes> + </SWRConfig> ); }; const App = () => ( <BrowserRouter basename={isBasenameNeeded ? '/console' : ''}> - <Main /> + <LogtoProvider + config={{ endpoint: window.location.origin, clientId: 'foo', resources: [logtoApiResource] }} + > + <Main /> + </LogtoProvider> </BrowserRouter> ); diff --git a/packages/console/src/consts/api.ts b/packages/console/src/consts/api.ts new file mode 100644 index 000000000..3005203d2 --- /dev/null +++ b/packages/console/src/consts/api.ts @@ -0,0 +1 @@ +export const logtoApiResource = 'https://api.logto.io'; diff --git a/packages/console/src/consts/applications.ts b/packages/console/src/consts/applications.ts new file mode 100644 index 000000000..dfa0dcd53 --- /dev/null +++ b/packages/console/src/consts/applications.ts @@ -0,0 +1,7 @@ +import { ApplicationType } from '@logto/schemas'; + +export const applicationTypeI18nKey = Object.freeze({ + [ApplicationType.Native]: 'applications.type.native', + [ApplicationType.SPA]: 'applications.type.spa', + [ApplicationType.Traditional]: 'applications.type.traditional', +} as const); diff --git a/packages/console/src/hooks/use-api.ts b/packages/console/src/hooks/use-api.ts new file mode 100644 index 000000000..ef9d2116e --- /dev/null +++ b/packages/console/src/hooks/use-api.ts @@ -0,0 +1,60 @@ +import { useLogto } from '@logto/react'; +import { RequestErrorBody, RequestErrorMetadata } from '@logto/schemas'; +import { t } from 'i18next'; +import ky from 'ky'; +import { useMemo } from 'react'; +import { toast } from 'react-hot-toast'; + +import { logtoApiResource } from '@/consts/api'; + +export class RequestError extends Error { + metadata: RequestErrorMetadata; + + constructor(metadata: RequestErrorMetadata) { + super('Request error occurred.'); + this.metadata = metadata; + } +} + +const toastError = async (response: Response) => { + try { + const data = (await response.json()) as RequestErrorBody; + toast.error(data.message || t('admin_console.errors.unknown_server_error')); + } catch { + toast.error(t('admin_console.errors.unknown_server_error')); + } +}; + +const useApi = () => { + const { isAuthenticated, getAccessToken } = useLogto(); + + const api = useMemo( + () => + ky.create({ + hooks: { + beforeError: [ + (error) => { + const { response } = error; + + void toastError(response); + + return error; + }, + ], + beforeRequest: [ + async (request) => { + if (isAuthenticated) { + const accessToken = await getAccessToken(logtoApiResource); + request.headers.set('Authorization', `Bearer ${accessToken ?? ''}`); + } + }, + ], + }, + }), + [getAccessToken, isAuthenticated] + ); + + return api; +}; + +export default useApi; diff --git a/packages/console/src/hooks/use-swr-fetcher.ts b/packages/console/src/hooks/use-swr-fetcher.ts new file mode 100644 index 000000000..087acd4f7 --- /dev/null +++ b/packages/console/src/hooks/use-swr-fetcher.ts @@ -0,0 +1,26 @@ +import { RequestErrorMetadata } from '@logto/schemas'; +import { useCallback } from 'react'; +import { BareFetcher } from 'swr'; + +import useApi, { RequestError } from './use-api'; + +const useSwrFetcher = () => { + const api = useApi(); + const fetcher = useCallback<BareFetcher>( + async (resource, init) => { + const response = await api.get(resource, init); + + if (!response.ok) { + const metadata = (await response.json()) as RequestErrorMetadata; + throw new RequestError(metadata); + } + + return response.json(); + }, + [api] + ); + + return fetcher; +}; + +export default useSwrFetcher; diff --git a/packages/console/src/pages/ApiResourceDetails/components/DeleteForm/index.tsx b/packages/console/src/pages/ApiResourceDetails/components/DeleteForm/index.tsx index 838b21e50..1f5fd513e 100644 --- a/packages/console/src/pages/ApiResourceDetails/components/DeleteForm/index.tsx +++ b/packages/console/src/pages/ApiResourceDetails/components/DeleteForm/index.tsx @@ -7,8 +7,8 @@ import Button from '@/components/Button'; import Card from '@/components/Card'; import CardTitle from '@/components/CardTitle'; import TextInput from '@/components/TextInput'; +import useApi from '@/hooks/use-api'; import Close from '@/icons/Close'; -import api from '@/utilities/api'; import * as styles from './index.module.scss'; @@ -19,6 +19,7 @@ type Props = { }; const DeleteForm = ({ id, name, onClose }: Props) => { + const api = useApi(); const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); const navigate = useNavigate(); diff --git a/packages/console/src/pages/ApiResourceDetails/index.tsx b/packages/console/src/pages/ApiResourceDetails/index.tsx index 6bbb20cf6..b4ccec6fc 100644 --- a/packages/console/src/pages/ApiResourceDetails/index.tsx +++ b/packages/console/src/pages/ApiResourceDetails/index.tsx @@ -15,9 +15,8 @@ import FormField from '@/components/FormField'; import ImagePlaceholder from '@/components/ImagePlaceholder'; import TabNav, { TabNavLink } from '@/components/TabNav'; import TextInput from '@/components/TextInput'; +import useApi, { RequestError } from '@/hooks/use-api'; import * as modalStyles from '@/scss/modal.module.scss'; -import { RequestError } from '@/swr'; -import api from '@/utilities/api'; import DeleteForm from './components/DeleteForm'; import * as styles from './index.module.scss'; @@ -39,6 +38,7 @@ const ApiResourceDetails = () => { defaultValues: data, }); const [submitting, setSubmitting] = useState(false); + const api = useApi(); const [isDeleteFormOpen, setIsDeleteFormOpen] = useState(false); diff --git a/packages/console/src/pages/ApiResources/components/CreateForm/index.tsx b/packages/console/src/pages/ApiResources/components/CreateForm/index.tsx index 991246a13..9a0e8b9ef 100644 --- a/packages/console/src/pages/ApiResources/components/CreateForm/index.tsx +++ b/packages/console/src/pages/ApiResources/components/CreateForm/index.tsx @@ -7,8 +7,8 @@ import Card from '@/components/Card'; import CardTitle from '@/components/CardTitle'; import FormField from '@/components/FormField'; import TextInput from '@/components/TextInput'; +import useApi from '@/hooks/use-api'; import Close from '@/icons/Close'; -import api from '@/utilities/api'; import * as styles from './index.module.scss'; @@ -23,6 +23,7 @@ type Props = { const CreateForm = ({ onClose }: Props) => { const { handleSubmit, register } = useForm<FormData>(); + const api = useApi(); const onSubmit = handleSubmit(async (data) => { try { diff --git a/packages/console/src/pages/ApiResources/index.tsx b/packages/console/src/pages/ApiResources/index.tsx index 32df486b7..e9650d641 100644 --- a/packages/console/src/pages/ApiResources/index.tsx +++ b/packages/console/src/pages/ApiResources/index.tsx @@ -12,8 +12,8 @@ import CardTitle from '@/components/CardTitle'; import CopyToClipboard from '@/components/CopyToClipboard'; import ImagePlaceholder from '@/components/ImagePlaceholder'; import ItemPreview from '@/components/ItemPreview'; +import { RequestError } from '@/hooks/use-api'; import * as modalStyles from '@/scss/modal.module.scss'; -import { RequestError } from '@/swr'; import CreateForm from './components/CreateForm'; import * as styles from './index.module.scss'; diff --git a/packages/console/src/pages/ApplicationDetails/index.tsx b/packages/console/src/pages/ApplicationDetails/index.tsx index d06b45304..c70f2335a 100644 --- a/packages/console/src/pages/ApplicationDetails/index.tsx +++ b/packages/console/src/pages/ApplicationDetails/index.tsx @@ -13,7 +13,7 @@ import FormField from '@/components/FormField'; import ImagePlaceholder from '@/components/ImagePlaceholder'; import TabNav, { TabNavLink } from '@/components/TabNav'; import TextInput from '@/components/TextInput'; -import { RequestError } from '@/swr'; +import { RequestError } from '@/hooks/use-api'; import { applicationTypeI18nKey } from '@/types/applications'; import * as styles from './index.module.scss'; diff --git a/packages/console/src/pages/Applications/components/CreateForm/index.tsx b/packages/console/src/pages/Applications/components/CreateForm/index.tsx index 515921fb9..8a707ff6f 100644 --- a/packages/console/src/pages/Applications/components/CreateForm/index.tsx +++ b/packages/console/src/pages/Applications/components/CreateForm/index.tsx @@ -9,9 +9,9 @@ import CardTitle from '@/components/CardTitle'; import FormField from '@/components/FormField'; import RadioGroup, { Radio } from '@/components/RadioGroup'; import TextInput from '@/components/TextInput'; +import useApi from '@/hooks/use-api'; import Close from '@/icons/Close'; import { applicationTypeI18nKey } from '@/types/applications'; -import api from '@/utilities/api'; import TypeDescription from '../TypeDescription'; import * as styles from './index.module.scss'; @@ -37,6 +37,7 @@ const CreateForm = ({ onClose }: Props) => { field: { onChange, value, name, ref }, } = useController({ name: 'type', control, rules: { required: true } }); const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); + const api = useApi(); const onSubmit = handleSubmit(async (data) => { try { diff --git a/packages/console/src/pages/Applications/index.tsx b/packages/console/src/pages/Applications/index.tsx index 27c8da4b4..288e1e13e 100644 --- a/packages/console/src/pages/Applications/index.tsx +++ b/packages/console/src/pages/Applications/index.tsx @@ -13,8 +13,8 @@ import CardTitle from '@/components/CardTitle'; import CopyToClipboard from '@/components/CopyToClipboard'; import ImagePlaceholder from '@/components/ImagePlaceholder'; import ItemPreview from '@/components/ItemPreview'; +import { RequestError } from '@/hooks/use-api'; import * as modalStyles from '@/scss/modal.module.scss'; -import { RequestError } from '@/swr'; import { applicationTypeI18nKey } from '@/types/applications'; import CreateForm from './components/CreateForm'; diff --git a/packages/console/src/pages/Callback/index.tsx b/packages/console/src/pages/Callback/index.tsx index f6aa8fdb0..a92331a6c 100644 --- a/packages/console/src/pages/Callback/index.tsx +++ b/packages/console/src/pages/Callback/index.tsx @@ -1,4 +1,4 @@ -import { useLogto } from '@logto/react'; +import { useHandleSignInCallback, useLogto } from '@logto/react'; import React, { useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; @@ -6,6 +6,8 @@ const Callback = () => { const { isAuthenticated, isLoading } = useLogto(); const navigate = useNavigate(); + useHandleSignInCallback(); + // TO-DO: Error handling useEffect(() => { if (isAuthenticated && !isLoading) { diff --git a/packages/console/src/pages/ConnectorDetails/index.tsx b/packages/console/src/pages/ConnectorDetails/index.tsx index 4b22e531a..605af09ef 100644 --- a/packages/console/src/pages/ConnectorDetails/index.tsx +++ b/packages/console/src/pages/ConnectorDetails/index.tsx @@ -15,8 +15,7 @@ import ImagePlaceholder from '@/components/ImagePlaceholder'; import Markdown from '@/components/Markdown'; import Status from '@/components/Status'; import TabNav, { TabNavLink } from '@/components/TabNav'; -import { RequestError } from '@/swr'; -import api from '@/utilities/api'; +import useApi, { RequestError } from '@/hooks/use-api'; import SenderTester from './components/SenderTester'; import * as styles from './index.module.scss'; @@ -35,6 +34,7 @@ const ConnectorDetails = () => { connectorId && `/api/connectors/${connectorId}` ); const isLoading = !data && !error; + const api = useApi(); useEffect(() => { if (data) { diff --git a/packages/console/src/pages/Connectors/index.tsx b/packages/console/src/pages/Connectors/index.tsx index 421db13a0..0e56e4c2e 100644 --- a/packages/console/src/pages/Connectors/index.tsx +++ b/packages/console/src/pages/Connectors/index.tsx @@ -9,7 +9,7 @@ import Button from '@/components/Button'; import Card from '@/components/Card'; import CardTitle from '@/components/CardTitle'; import TabNav, { TabNavLink } from '@/components/TabNav'; -import { RequestError } from '@/swr'; +import { RequestError } from '@/hooks/use-api'; import ConnectorRow from './components/ConnectorRow'; import * as styles from './index.module.scss'; diff --git a/packages/console/src/pages/UserDetails/index.tsx b/packages/console/src/pages/UserDetails/index.tsx index 5725dcaed..091f1c9be 100644 --- a/packages/console/src/pages/UserDetails/index.tsx +++ b/packages/console/src/pages/UserDetails/index.tsx @@ -8,7 +8,7 @@ import BackLink from '@/components/BackLink'; import Card from '@/components/Card'; import CopyToClipboard from '@/components/CopyToClipboard'; import ImagePlaceholder from '@/components/ImagePlaceholder'; -import { RequestError } from '@/swr'; +import { RequestError } from '@/hooks/use-api'; import CreateSuccess from './components/CreateSuccess'; import * as styles from './index.module.scss'; diff --git a/packages/console/src/pages/Users/components/CreateForm/index.tsx b/packages/console/src/pages/Users/components/CreateForm/index.tsx index 0727986ef..b936b2881 100644 --- a/packages/console/src/pages/Users/components/CreateForm/index.tsx +++ b/packages/console/src/pages/Users/components/CreateForm/index.tsx @@ -7,8 +7,8 @@ import Card from '@/components/Card'; import CardTitle from '@/components/CardTitle'; import FormField from '@/components/FormField'; import TextInput from '@/components/TextInput'; +import useApi from '@/hooks/use-api'; import Close from '@/icons/Close'; -import api from '@/utilities/api'; import * as styles from './index.module.scss'; @@ -24,6 +24,7 @@ type Props = { const CreateForm = ({ onClose }: Props) => { const { handleSubmit, register } = useForm<FormData>(); + const api = useApi(); const onSubmit = handleSubmit(async (data) => { const createdUser = await api.post('/api/users', { json: data }).json<User>(); diff --git a/packages/console/src/pages/Users/index.tsx b/packages/console/src/pages/Users/index.tsx index 9c14f817a..fae11fa4d 100644 --- a/packages/console/src/pages/Users/index.tsx +++ b/packages/console/src/pages/Users/index.tsx @@ -10,8 +10,8 @@ import Card from '@/components/Card'; import CardTitle from '@/components/CardTitle'; import ImagePlaceholder from '@/components/ImagePlaceholder'; import ItemPreview from '@/components/ItemPreview'; +import { RequestError } from '@/hooks/use-api'; import * as modalStyles from '@/scss/modal.module.scss'; -import { RequestError } from '@/swr'; import CreateForm from './components/CreateForm'; import * as styles from './index.module.scss'; diff --git a/packages/console/src/swr/index.ts b/packages/console/src/swr/index.ts deleted file mode 100644 index 4cba5752d..000000000 --- a/packages/console/src/swr/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { RequestErrorMetadata } from '@logto/schemas'; -import { BareFetcher } from 'swr'; - -export class RequestError extends Error { - metadata: RequestErrorMetadata; - - constructor(metadata: RequestErrorMetadata) { - super('Request error occurred.'); - this.metadata = metadata; - } -} - -export const fetcher: BareFetcher = async (resource, init) => { - const response = await fetch(resource, init); - - if (!response.ok) { - const metadata = (await response.json()) as RequestErrorMetadata; - throw new RequestError(metadata); - } - - return response.json(); -}; diff --git a/packages/console/src/utilities/api.ts b/packages/console/src/utilities/api.ts deleted file mode 100644 index a9605060b..000000000 --- a/packages/console/src/utilities/api.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RequestErrorBody } from '@logto/schemas'; -import { t } from 'i18next'; -import ky from 'ky'; -import { toast } from 'react-hot-toast'; - -const toastError = async (response: Response) => { - try { - const data = (await response.json()) as RequestErrorBody; - toast.error(data.message || t('admin_console.errors.unknown_server_error')); - } catch { - toast.error(t('admin_console.errors.unknown_server_error')); - } -}; - -const api = ky.create({ - hooks: { - beforeError: [ - (error) => { - const { response } = error; - - void toastError(response); - - return error; - }, - ], - }, -}); - -export default api; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c77347418..cf5895004 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -21,7 +21,7 @@ importers: packages/console: specifiers: '@logto/phrases': ^0.1.0 - '@logto/react': ^0.1.2 + '@logto/react': ^0.1.3 '@logto/schemas': ^0.1.0 '@monaco-editor/react': ^4.3.1 '@parcel/core': ^2.3.2 @@ -63,7 +63,7 @@ importers: typescript: ^4.6.2 dependencies: '@logto/phrases': link:../phrases - '@logto/react': 0.1.2_react@17.0.2 + '@logto/react': 0.1.3_react@17.0.2 '@logto/schemas': link:../schemas '@monaco-editor/react': 4.3.1_e62f1489d5efe674a41c3f8d6971effe '@silverhand/essentials': 1.1.6 @@ -2222,19 +2222,19 @@ packages: write-file-atomic: 3.0.3 dev: true - /@logto/browser/0.1.2: - resolution: {integrity: sha512-sTJjnx00BXYEChCbbO/LPs0x0wE1bDSHniFi+u93cynyEHgoT5yjMnH4N39NhrpmRdkXxOxaIkXmyAT1nSmYzQ==} + /@logto/browser/0.1.3: + resolution: {integrity: sha512-SsXp7uWnDKSyYGbcCCUkTelcWs8OlUNO0gVnW1hvuAAgm62LAX6EfgsE4EIKCLN/JrcRfjbiJIr98QNfa0riWw==} requiresBuild: true dependencies: - '@logto/js': 0.1.2 + '@logto/js': 0.1.3 '@silverhand/essentials': 1.1.6 jose: 4.6.0 lodash.get: 4.4.2 superstruct: 0.15.4 dev: false - /@logto/js/0.1.2: - resolution: {integrity: sha512-kz7l++gfpXa1OaUaB5WvnHNXQKEJDFnBzVYAofPADnPftHEF0zYRuQDCa8PJMd6/ECKfL1XPLMlJMNP/5U2fqQ==} + /@logto/js/0.1.3: + resolution: {integrity: sha512-lxdZNX67w2rntiSHC5ovY2D7IHq8ldcT9AQDaP7ayjKTyIuWIJxW7u9f21BpuPpfBHAIhOsKjgqAvLPBXczjzw==} requiresBuild: true dependencies: '@silverhand/essentials': 1.1.6 @@ -2245,13 +2245,13 @@ packages: superstruct: 0.15.4 dev: false - /@logto/react/0.1.2_react@17.0.2: - resolution: {integrity: sha512-kxLOvxOv3IB8BjpbcoRFsBFX249wAfbOL0tfJlSWmOXrkPouai1bRItEFBHFKDI1zLJATVQRoJNQfaczJy/c0A==} + /@logto/react/0.1.3_react@17.0.2: + resolution: {integrity: sha512-cxa+LM+sb0azQY5tGe5smY4B5N6U/yE66GT6RL0CguHC6DXZ3j00wfzaRhwAtOXAl3QL2xULcZTwkI3sY69COw==} requiresBuild: true peerDependencies: react: '>=16.8.0' dependencies: - '@logto/browser': 0.1.2 + '@logto/browser': 0.1.3 '@silverhand/essentials': 1.1.6 react: 17.0.2 dev: false @@ -2366,8 +2366,8 @@ packages: '@octokit/types': 6.34.0 dev: true - /@octokit/core/3.5.1: - resolution: {integrity: sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==} + /@octokit/core/3.6.0: + resolution: {integrity: sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==} dependencies: '@octokit/auth-token': 2.5.0 '@octokit/graphql': 4.8.0 @@ -2406,29 +2406,29 @@ packages: resolution: {integrity: sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw==} dev: true - /@octokit/plugin-paginate-rest/2.17.0_@octokit+core@3.5.1: + /@octokit/plugin-paginate-rest/2.17.0_@octokit+core@3.6.0: resolution: {integrity: sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw==} peerDependencies: '@octokit/core': '>=2' dependencies: - '@octokit/core': 3.5.1 + '@octokit/core': 3.6.0 '@octokit/types': 6.34.0 dev: true - /@octokit/plugin-request-log/1.0.4_@octokit+core@3.5.1: + /@octokit/plugin-request-log/1.0.4_@octokit+core@3.6.0: resolution: {integrity: sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==} peerDependencies: '@octokit/core': '>=3' dependencies: - '@octokit/core': 3.5.1 + '@octokit/core': 3.6.0 dev: true - /@octokit/plugin-rest-endpoint-methods/5.13.0_@octokit+core@3.5.1: + /@octokit/plugin-rest-endpoint-methods/5.13.0_@octokit+core@3.6.0: resolution: {integrity: sha512-uJjMTkN1KaOIgNtUPMtIXDOjx6dGYysdIFhgA52x4xSadQCz3b/zJexvITDVpANnfKPW/+E0xkOvLntqMYpviA==} peerDependencies: '@octokit/core': '>=3' dependencies: - '@octokit/core': 3.5.1 + '@octokit/core': 3.6.0 '@octokit/types': 6.34.0 deprecation: 2.3.1 dev: true @@ -2457,10 +2457,10 @@ packages: /@octokit/rest/18.12.0: resolution: {integrity: sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==} dependencies: - '@octokit/core': 3.5.1 - '@octokit/plugin-paginate-rest': 2.17.0_@octokit+core@3.5.1 - '@octokit/plugin-request-log': 1.0.4_@octokit+core@3.5.1 - '@octokit/plugin-rest-endpoint-methods': 5.13.0_@octokit+core@3.5.1 + '@octokit/core': 3.6.0 + '@octokit/plugin-paginate-rest': 2.17.0_@octokit+core@3.6.0 + '@octokit/plugin-request-log': 1.0.4_@octokit+core@3.6.0 + '@octokit/plugin-rest-endpoint-methods': 5.13.0_@octokit+core@3.6.0 transitivePeerDependencies: - encoding dev: true @@ -6377,7 +6377,7 @@ packages: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 - mime-types: 2.1.34 + mime-types: 2.1.35 dev: true /form-data/3.0.1: @@ -9850,12 +9850,24 @@ packages: resolution: {integrity: sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==} engines: {node: '>= 0.6'} + /mime-db/1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: true + /mime-types/2.1.34: resolution: {integrity: sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==} engines: {node: '>= 0.6'} dependencies: mime-db: 1.51.0 + /mime-types/2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: true + /mime/1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} engines: {node: '>=4'} @@ -12263,7 +12275,7 @@ packages: is-typedarray: 1.0.0 isstream: 0.1.2 json-stringify-safe: 5.0.1 - mime-types: 2.1.34 + mime-types: 2.1.35 oauth-sign: 0.9.0 performance-now: 2.1.0 qs: 6.5.3