From e1e9a7063e1bb29a5b5af21930b5152b2e8fb4dd Mon Sep 17 00:00:00 2001 From: Nabarun Gogoi Date: Tue, 30 Jan 2024 19:50:53 +0530 Subject: [PATCH] Implement Github authentication to show repositories list (#45) * Use react-oauth-popup for github authentication popup * Fetch auth token and use in app to fetch list of repositories * Get client id and secret from config * Use GitHub search API for fetching repos * Use debounce for searching repos and projects --- README.md | 4 + packages/backend/environments/local.toml | 4 + packages/backend/package.json | 3 +- packages/backend/src/config.ts | 6 + packages/backend/src/index.ts | 13 +- packages/backend/src/resolvers.ts | 15 +- packages/backend/src/schema.gql | 5 + packages/frontend/.env | 2 + packages/frontend/package.json | 3 + .../components/projects/ProjectSearchBar.tsx | 17 +- .../projects/create/ConnectAccount.tsx | 44 +- .../projects/create/ProjectRepoCard.tsx | 12 +- .../projects/create/RepositoryList.tsx | 144 +++++-- .../projects/project/settings/GitTabPanel.tsx | 12 +- .../project/settings/RepoConnectedSection.tsx | 8 +- .../src/pages/projects/create/index.tsx | 19 +- packages/frontend/src/types/project.ts | 16 + packages/gql-client/src/client.ts | 15 +- packages/gql-client/src/mutations.ts | 7 + packages/gql-client/src/types.ts | 6 + yarn.lock | 378 +++++++++++++++++- 21 files changed, 647 insertions(+), 86 deletions(-) diff --git a/README.md b/README.md index 2fe198be..4ca3a392 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,10 @@ yarn db:load:fixtures ``` +- Set `githubOauth.clientId` and `githubOauth.clientSecret` in backend [config file](packages/backend/environments/local.toml) + - Client id and secret will be available after creating Github OAuth app + - https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app + - Start the server ```bash diff --git a/packages/backend/environments/local.toml b/packages/backend/environments/local.toml index b1f8d7df..de0d96b8 100644 --- a/packages/backend/environments/local.toml +++ b/packages/backend/environments/local.toml @@ -5,3 +5,7 @@ [database] dbPath = "db/snowball" + +[githubOauth] + clientId = "" + clientSecret = "" diff --git a/packages/backend/package.json b/packages/backend/package.json index ffd680dc..68a9540e 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -5,6 +5,7 @@ "dependencies": { "@graphql-tools/schema": "^10.0.2", "@graphql-tools/utils": "^10.0.12", + "@octokit/oauth-app": "^6.1.0", "@types/debug": "^4.1.5", "@types/express": "^4.17.21", "@types/node": "^20.11.0", @@ -36,8 +37,8 @@ "@types/fs-extra": "^11.0.4", "@typescript-eslint/eslint-plugin": "^6.18.1", "@typescript-eslint/parser": "^6.18.1", - "copyfiles": "^2.4.1", "better-sqlite3": "^9.2.2", + "copyfiles": "^2.4.1", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-config-semistandard": "^15.0.1", diff --git a/packages/backend/src/config.ts b/packages/backend/src/config.ts index 68451e2b..412492a6 100644 --- a/packages/backend/src/config.ts +++ b/packages/backend/src/config.ts @@ -8,7 +8,13 @@ export interface DatabaseConfig { dbPath: string; } +export interface GithubOauthConfig { + clientId: string; + clientSecret: string; +} + export interface Config { server: ServerConfig; database: DatabaseConfig; + githubOauth: GithubOauthConfig; } diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index 6f3bc8c9..d2ec61d2 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -3,6 +3,8 @@ import debug from 'debug'; import fs from 'fs'; import path from 'path'; +import { OAuthApp } from '@octokit/oauth-app'; + import { Database } from './database'; import { createAndStartServer } from './server'; import { createResolvers } from './resolvers'; @@ -14,13 +16,20 @@ const log = debug('snowball:server'); export const main = async (): Promise => { // TODO: get config path using cli - const { server, database } = await getConfig(DEFAULT_CONFIG_FILE_PATH); + const { server, database, githubOauth } = await getConfig(DEFAULT_CONFIG_FILE_PATH); const db = new Database(database); await db.init(); + // TODO: Move to Service class + const app = new OAuthApp({ + clientType: 'oauth-app', + clientId: githubOauth.clientId, + clientSecret: githubOauth.clientSecret + }); + const typeDefs = fs.readFileSync(path.join(__dirname, 'schema.gql')).toString(); - const resolvers = await createResolvers(db); + const resolvers = await createResolvers(db, app); await createAndStartServer(typeDefs, resolvers, server); }; diff --git a/packages/backend/src/resolvers.ts b/packages/backend/src/resolvers.ts index b2f73907..e84ce91b 100644 --- a/packages/backend/src/resolvers.ts +++ b/packages/backend/src/resolvers.ts @@ -1,13 +1,15 @@ import debug from 'debug'; import assert from 'assert'; +import { OAuthApp } from '@octokit/oauth-app'; + import { Database } from './database'; import { deploymentToGqlType, projectMemberToGqlType, projectToGqlType, environmentVariableToGqlType, isUserOwner } from './utils'; import { Environment } from './entity/Deployment'; const log = debug('snowball:database'); -export const createResolvers = async (db: Database): Promise => { +export const createResolvers = async (db: Database, app: OAuthApp): Promise => { return { Query: { // TODO: add custom type for context @@ -203,6 +205,17 @@ export const createResolvers = async (db: Database): Promise => { log(err); return false; } + }, + + authenticateGithub: async (_: any, { code }: { code: string }) => { + // TOO: Move to Service class + const { authentication: { token } } = await app.createToken({ + code + }); + + // TODO: Save bearer token in DB for user + + return { token }; } } }; diff --git a/packages/backend/src/schema.gql b/packages/backend/src/schema.gql index 64357655..b98cd38b 100644 --- a/packages/backend/src/schema.gql +++ b/packages/backend/src/schema.gql @@ -126,6 +126,10 @@ type Query { domains(projectId: String!): [Domain!] } +type AuthResult { + token: String! +} + type Mutation { removeMember(memberId: String!): Boolean! addEnvironmentVariables(projectId: String!, environmentVariables: [AddEnvironmentVariableInput!]): Boolean! @@ -136,6 +140,7 @@ type Mutation { rollbackDeployment(projectId: String!, deploymentId: String!): Boolean! addDomain(projectId: String!, domainDetails: AddDomainInput!): Boolean! updateDomain(domainId: String!, domainDetails: UpdateDomainInput!): Boolean! + authenticateGithub(code: String!): AuthResult! } input AddEnvironmentVariableInput { diff --git a/packages/frontend/.env b/packages/frontend/.env index 5b03837d..1c7a146a 100644 --- a/packages/frontend/.env +++ b/packages/frontend/.env @@ -1 +1,3 @@ REACT_APP_GQL_SERVER_URL = 'http://localhost:8000/graphql' + +REACT_APP_GITHUB_CLIENT_ID = 4720362b6740b00652b6 diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 150949eb..5ce472e1 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -17,17 +17,20 @@ "eslint-config-react-app": "^7.0.1", "gql-client": "^1.0.0", "luxon": "^3.4.4", + "octokit": "^3.1.2", "react": "^18.2.0", "react-day-picker": "^8.9.1", "react-dom": "^18.2.0", "react-dropdown": "^1.11.0", "react-hook-form": "^7.49.0", "react-hot-toast": "^2.4.1", + "react-oauth-popup": "^1.0.5", "react-router-dom": "^6.20.1", "react-scripts": "5.0.1", "react-tabs": "^6.0.2", "react-timer-hook": "^3.0.7", "typescript": "^4.9.5", + "usehooks-ts": "^2.10.0", "vertical-stepper-nav": "^1.0.2", "web-vitals": "^2.1.4" }, diff --git a/packages/frontend/src/components/projects/ProjectSearchBar.tsx b/packages/frontend/src/components/projects/ProjectSearchBar.tsx index 41c8c958..494c0369 100644 --- a/packages/frontend/src/components/projects/ProjectSearchBar.tsx +++ b/packages/frontend/src/components/projects/ProjectSearchBar.tsx @@ -1,6 +1,7 @@ -import React, { useCallback, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { useCombobox } from 'downshift'; import { Project } from 'gql-client'; +import { useDebounce } from 'usehooks-ts'; import { List, @@ -30,12 +31,6 @@ const ProjectSearchBar = ({ onChange }: ProjectsSearchProps) => { highlightedIndex, inputValue, } = useCombobox({ - onInputValueChange({ inputValue }) { - if (inputValue) { - // TODO: Use debounce - fetchProjects(inputValue); - } - }, items, itemToString(item) { return item ? item.name : ''; @@ -52,6 +47,8 @@ const ProjectSearchBar = ({ onChange }: ProjectsSearchProps) => { }, }); + const debouncedInputValue = useDebounce(inputValue, 500); + const fetchProjects = useCallback( async (inputValue: string) => { const { searchProjects } = await client.searchProjects(inputValue); @@ -60,6 +57,12 @@ const ProjectSearchBar = ({ onChange }: ProjectsSearchProps) => { [client], ); + useEffect(() => { + if (debouncedInputValue) { + fetchProjects(debouncedInputValue); + } + }, [fetchProjects, debouncedInputValue]); + return (
diff --git a/packages/frontend/src/components/projects/create/ConnectAccount.tsx b/packages/frontend/src/components/projects/create/ConnectAccount.tsx index 105125fe..76889ecc 100644 --- a/packages/frontend/src/components/projects/create/ConnectAccount.tsx +++ b/packages/frontend/src/components/projects/create/ConnectAccount.tsx @@ -1,6 +1,29 @@ +import { Button } from '@material-tailwind/react'; import React from 'react'; +import OauthPopup from 'react-oauth-popup'; + +import { useGQLClient } from '../../../context/GQLClientContext'; + +const SCOPES = 'repo user'; +const GITHUB_OAUTH_URL = `https://github.com/login/oauth/authorize?client_id=${ + process.env.REACT_APP_GITHUB_CLIENT_ID +}&scope=${encodeURIComponent(SCOPES)}`; + +interface ConnectAccountInterface { + onToken: (token: string) => void; +} + +const ConnectAccount = ({ onToken }: ConnectAccountInterface) => { + const client = useGQLClient(); + + const handleCode = async (code: string) => { + // Pass code to backend and get access token + const { + authenticateGithub: { token }, + } = await client.authenticateGithub(code); + onToken(token); + }; -const ConnectAccount = () => { return (
^
@@ -11,13 +34,18 @@ const ConnectAccount = () => { under the account

-
- - +
+ {}} + title="Snowball" + width={1000} + height={1000} + > + + +
); diff --git a/packages/frontend/src/components/projects/create/ProjectRepoCard.tsx b/packages/frontend/src/components/projects/create/ProjectRepoCard.tsx index a9855464..38e4da89 100644 --- a/packages/frontend/src/components/projects/create/ProjectRepoCard.tsx +++ b/packages/frontend/src/components/projects/create/ProjectRepoCard.tsx @@ -3,10 +3,10 @@ import React from 'react'; import { Chip, IconButton } from '@material-tailwind/react'; import { relativeTime } from '../../../utils/time'; -import { RepositoryDetails } from '../../../types/project'; +import { GitRepositoryDetails } from '../../../types/project'; interface ProjectRepoCardProps { - repository: RepositoryDetails; + repository: GitRepositoryDetails; onClick: () => void; } @@ -22,10 +22,8 @@ const ProjectRepoCard: React.FC = ({
^
- - {repository.user}/{repository.title} - - {repository.private ? ( + {repository.full_name} + {repository.visibility === 'private' ? ( = ({ '' )}
-

{relativeTime(repository.updatedAt)}

+

{repository.updated_at && relativeTime(repository.updated_at)}

{'>'} diff --git a/packages/frontend/src/components/projects/create/RepositoryList.tsx b/packages/frontend/src/components/projects/create/RepositoryList.tsx index df7745b0..d9d17f1f 100644 --- a/packages/frontend/src/components/projects/create/RepositoryList.tsx +++ b/packages/frontend/src/components/projects/create/RepositoryList.tsx @@ -1,61 +1,133 @@ -import React, { useCallback, useMemo, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import { Octokit } from 'octokit'; +import assert from 'assert'; +import { useDebounce } from 'usehooks-ts'; import { Button, Typography, Option, Select } from '@material-tailwind/react'; import SearchBar from '../../SearchBar'; import ProjectRepoCard from './ProjectRepoCard'; -import repositoryDetails from '../../../assets/repositories.json'; -import { RepositoryDetails } from '../../../types/project'; +import { GitOrgDetails, GitRepositoryDetails } from '../../../types/project'; const DEFAULT_SEARCHED_REPO = ''; -const DEFAULT_SELECTED_USER = 'All accounts'; +const REPOS_PER_PAGE = 5; interface RepositoryListProps { - repoSelectionHandler: (repo: RepositoryDetails) => void; + repoSelectionHandler: (repo: GitRepositoryDetails) => void; + token: string; } -const RepositoryList = ({ repoSelectionHandler }: RepositoryListProps) => { +const RepositoryList = ({ + repoSelectionHandler, + token, +}: RepositoryListProps) => { const [searchedRepo, setSearchedRepo] = useState(DEFAULT_SEARCHED_REPO); - const [selectedUser, setSelectedUser] = useState(DEFAULT_SELECTED_USER); + const [selectedAccount, setSelectedAccount] = useState(''); + const [orgs, setOrgs] = useState([]); + // TODO: Add new type for Git user when required + const [gitUser, setGitUser] = useState(); - const filteredRepos = useMemo(() => { - return repositoryDetails.filter((repo) => { - const titleMatch = - !searchedRepo || - repo.title.toLowerCase().includes(searchedRepo.toLowerCase()); - const userMatch = - selectedUser === DEFAULT_SELECTED_USER || selectedUser === repo.user; - return titleMatch && userMatch; - }); - }, [searchedRepo, selectedUser]); + const [repositoryDetails, setRepositoryDetails] = useState< + GitRepositoryDetails[] + >([]); + + const octokit = useMemo(() => { + // TODO: Create github/octokit context + return new Octokit({ auth: token }); + }, [token]); + + useEffect(() => { + const fetchUserAndOrgs = async () => { + const user = await octokit.rest.users.getAuthenticated(); + const orgs = await octokit.rest.orgs.listForAuthenticatedUser(); + setOrgs(orgs.data); + setGitUser(user.data); + setSelectedAccount(user.data.login); + }; + + if (token) { + fetchUserAndOrgs(); + } + }, [octokit]); + + const debouncedSearchedRepo = useDebounce(searchedRepo, 500); + + useEffect(() => { + const fetchRepos = async () => { + if (!selectedAccount || !gitUser) { + return; + } + + // Check search input and use GitHub search API + if (debouncedSearchedRepo) { + let query = `${debouncedSearchedRepo} in:name fork:true`; + + // Check if selected account is an organization + if (selectedAccount === gitUser.login) { + query = query + ` user:${selectedAccount}`; + } else { + query = query + ` org:${selectedAccount}`; + } + + const result = await octokit.rest.search.repos({ + q: query, + per_page: REPOS_PER_PAGE, + }); + + setRepositoryDetails(result.data.items); + return; + } + + if (selectedAccount === gitUser.login) { + const result = await octokit.rest.repos.listForAuthenticatedUser({ + per_page: REPOS_PER_PAGE, + affiliation: 'owner', + }); + setRepositoryDetails(result.data); + return; + } + + const selectedOrg = orgs.find((org) => org.login === selectedAccount); + assert(selectedOrg, 'Selected org not found in list'); + + const result = await octokit.rest.repos.listForOrg({ + org: selectedOrg.login, + per_page: REPOS_PER_PAGE, + type: 'all', + }); + + setRepositoryDetails(result.data); + }; + + fetchRepos(); + }, [selectedAccount, gitUser, orgs, debouncedSearchedRepo]); const handleResetFilters = useCallback(() => { + assert(gitUser, 'Git user is not available'); setSearchedRepo(DEFAULT_SEARCHED_REPO); - setSelectedUser(DEFAULT_SELECTED_USER); - }, []); + setSelectedAccount(gitUser.login); + }, [gitUser]); - const users = useMemo(() => { - return [ - DEFAULT_SELECTED_USER, - ...Array.from(new Set(repositoryDetails.map((repo) => repo.user))), - ]; - }, []); + const accounts = useMemo(() => { + if (!octokit || !gitUser) { + return []; + } + + return [gitUser, ...orgs]; + }, [octokit, orgs, gitUser]); return (
+ {/* TODO: Fix selection of Git user at start */} @@ -68,8 +140,8 @@ const RepositoryList = ({ repoSelectionHandler }: RepositoryListProps) => { />
- {Boolean(filteredRepos.length) ? ( - filteredRepos.map((repo, key) => { + {Boolean(repositoryDetails.length) ? ( + repositoryDetails.map((repo, key) => { return ( { const [gitSelect, setGitSelect] = useState('none'); - const [linkedRepo, setLinkedRepo] = useState(); + const [linkedRepo, setLinkedRepo] = useState(); const [webhooksArray, setWebhooksArray] = useState>([]); const gitSelectionHandler = (git: GitSelect) => { setGitSelect(git); }; - const repoSelectionHandler = (repoDetails: RepositoryDetails) => { + const repoSelectionHandler = (repoDetails: GitRepositoryDetails) => { setLinkedRepo(repoDetails); }; @@ -54,7 +54,11 @@ const GitTabPanel = () => { (GitSelect.NONE === gitSelect ? ( ) : ( - + ))}
diff --git a/packages/frontend/src/components/projects/project/settings/RepoConnectedSection.tsx b/packages/frontend/src/components/projects/project/settings/RepoConnectedSection.tsx index f4228dae..95b88bc8 100644 --- a/packages/frontend/src/components/projects/project/settings/RepoConnectedSection.tsx +++ b/packages/frontend/src/components/projects/project/settings/RepoConnectedSection.tsx @@ -2,13 +2,13 @@ import React, { useState } from 'react'; import { Button, Typography } from '@material-tailwind/react'; -import { RepositoryDetails } from '../../../../types/project'; +import { GitRepositoryDetails } from '../../../../types/project'; import ConfirmDialog from '../../../shared/ConfirmDialog'; const RepoConnectedSection = ({ linkedRepo, }: { - linkedRepo: RepositoryDetails; + linkedRepo: GitRepositoryDetails; }) => { const [disconnectRepoDialogOpen, setDisconnectRepoDialogOpen] = useState(false); @@ -17,9 +17,7 @@ const RepoConnectedSection = ({
^
- - {linkedRepo.user}/{linkedRepo.title} - + {linkedRepo.full_name} Connected just now
diff --git a/packages/frontend/src/pages/projects/create/index.tsx b/packages/frontend/src/pages/projects/create/index.tsx index 9c2d9104..8ec221da 100644 --- a/packages/frontend/src/pages/projects/create/index.tsx +++ b/packages/frontend/src/pages/projects/create/index.tsx @@ -1,13 +1,20 @@ -import React from 'react'; +import React, { useCallback, useState } from 'react'; import templateDetails from '../../../assets/templates.json'; import TemplateCard from '../../../components/projects/create/TemplateCard'; import RepositoryList from '../../../components/projects/create/RepositoryList'; import ConnectAccount from '../../../components/projects/create/ConnectAccount'; -const IS_GIT_AUTH = true; - const NewProject = () => { + const [isGitAuth, setIsGitAuth] = useState(false); + const [gitToken, setGitToken] = useState(''); + // TODO: Get DB user details for checking if already authenticated to Github + + const handleToken = useCallback((token: string) => { + setGitToken(token); + setIsGitAuth(true); + }, []); + return ( <>
Start with template
@@ -17,10 +24,10 @@ const NewProject = () => { })}
Import a repository
- {IS_GIT_AUTH ? ( - {}} /> + {isGitAuth ? ( + {}} /> ) : ( - + )} ); diff --git a/packages/frontend/src/types/project.ts b/packages/frontend/src/types/project.ts index 25ac7f76..ff626bcb 100644 --- a/packages/frontend/src/types/project.ts +++ b/packages/frontend/src/types/project.ts @@ -25,6 +25,13 @@ export enum Status { ERROR = 'Error', } +export interface GitOrgDetails { + id: number; + login: string; + avatar_url: string; +} + +// TODO: Use GitRepositoryDetails export interface RepositoryDetails { title: string; updatedAt: string; @@ -33,6 +40,15 @@ export interface RepositoryDetails { branch: string[]; } +export interface GitRepositoryDetails { + id: number; + name: string; + full_name: string; + owner: GitOrgDetails | null; + visibility?: string; + updated_at?: string | null; +} + export enum GitSelect { GITHUB = 'github', GITEA = 'gitea', diff --git a/packages/gql-client/src/client.ts b/packages/gql-client/src/client.ts index f061bafb..1b1483a4 100644 --- a/packages/gql-client/src/client.ts +++ b/packages/gql-client/src/client.ts @@ -1,8 +1,8 @@ import { ApolloClient, DefaultOptions, InMemoryCache, NormalizedCacheObject } from '@apollo/client'; import { getUser, getOrganizations, getDeployments, getProjectMembers, searchProjects, getEnvironmentVariables, getProject, getDomains, getProjectsInOrganization } from './queries'; -import { AddEnvironmentVariableInput, AddEnvironmentVariablesResponse, GetDeploymentsResponse, GetEnvironmentVariablesResponse, GetOrganizationsResponse, GetProjectMembersResponse, SearchProjectsResponse, GetUserResponse, RemoveMemberResponse, UpdateDeploymentToProdResponse, GetProjectResponse, UpdateProjectResponse, UpdateProjectInput, RedeployToProdResponse, DeleteProjectResponse, GetProjectsInOrganizationResponse, RollbackDeploymentResponse, AddDomainInput, AddDomainResponse, GetDomainsResponse, UpdateDomainInput, UpdateDomainResponse } from './types'; -import { removeMember, addEnvironmentVariables, updateDeploymentToProd, updateProjectMutation, redeployToProd, deleteProject, addDomain, rollbackDeployment, updateDomainMutation } from './mutations'; +import { AddEnvironmentVariableInput, AddEnvironmentVariablesResponse, GetDeploymentsResponse, GetEnvironmentVariablesResponse, GetOrganizationsResponse, GetProjectMembersResponse, SearchProjectsResponse, GetUserResponse, RemoveMemberResponse, UpdateDeploymentToProdResponse, GetProjectResponse, UpdateProjectResponse, UpdateProjectInput, RedeployToProdResponse, DeleteProjectResponse, GetProjectsInOrganizationResponse, RollbackDeploymentResponse, AddDomainInput, AddDomainResponse, GetDomainsResponse, UpdateDomainInput, UpdateDomainResponse, AuthenticateGithubResponse } from './types'; +import { removeMember, addEnvironmentVariables, updateDeploymentToProd, updateProjectMutation, redeployToProd, deleteProject, addDomain, rollbackDeployment, updateDomainMutation, authenticateGithub } from './mutations'; export interface GraphQLConfig { gqlEndpoint: string; @@ -227,4 +227,15 @@ export class GQLClient { return data; } + + async authenticateGithub (code: string): Promise { + const { data } = await this.client.mutate({ + mutation: authenticateGithub, + variables: { + code + } + }); + + return data; + } } diff --git a/packages/gql-client/src/mutations.ts b/packages/gql-client/src/mutations.ts index 5a59dce0..006b488c 100644 --- a/packages/gql-client/src/mutations.ts +++ b/packages/gql-client/src/mutations.ts @@ -51,3 +51,10 @@ mutation ($projectId: String!, $domainDetails: AddDomainInput!) { addDomain(projectId: $projectId, domainDetails: $domainDetails) } `; + +export const authenticateGithub = gql` +mutation ($code: String!) { + authenticateGithub(code: $code) { + token + } +}`; diff --git a/packages/gql-client/src/types.ts b/packages/gql-client/src/types.ts index d77e446d..e47a1a31 100644 --- a/packages/gql-client/src/types.ts +++ b/packages/gql-client/src/types.ts @@ -222,3 +222,9 @@ export type AddDomainInput = { export type AddDomainResponse = { addDomain: true } + +export type AuthenticateGithubResponse = { + authenticateGithub: { + token: string + } +} diff --git a/yarn.lock b/yarn.lock index d5ad4af6..a8096960 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2299,11 +2299,87 @@ resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-17.1.3.tgz#5b3446868bb747f55930636165969c26ad72f77b" integrity sha512-eTuTpBHFvA5NFJh/iosmqCL4JOAjDrwXLSMgfKrZKjiApHMG1T/5Hb+PrsNpt+WnGp94ur7c4Dtx4xD5vlpAEw== +"@octokit/app@^14.0.2": + version "14.0.2" + resolved "https://registry.yarnpkg.com/@octokit/app/-/app-14.0.2.tgz#b47c52020221351fb58640f113eb38b2ad3998fe" + integrity sha512-NCSCktSx+XmjuSUVn2dLfqQ9WIYePGP95SDJs4I9cn/0ZkeXcPkaoCLl64Us3dRKL2ozC7hArwze5Eu+/qt1tg== + dependencies: + "@octokit/auth-app" "^6.0.0" + "@octokit/auth-unauthenticated" "^5.0.0" + "@octokit/core" "^5.0.0" + "@octokit/oauth-app" "^6.0.0" + "@octokit/plugin-paginate-rest" "^9.0.0" + "@octokit/types" "^12.0.0" + "@octokit/webhooks" "^12.0.4" + +"@octokit/auth-app@^6.0.0": + version "6.0.3" + resolved "https://registry.yarnpkg.com/@octokit/auth-app/-/auth-app-6.0.3.tgz#4c0ba68e8d3b1a55c34d1e68ea0ca92ef018bb7a" + integrity sha512-9N7IlBAKEJR3tJgPSubCxIDYGXSdc+2xbkjYpk9nCyqREnH8qEMoMhiEB1WgoA9yTFp91El92XNXAi+AjuKnfw== + dependencies: + "@octokit/auth-oauth-app" "^7.0.0" + "@octokit/auth-oauth-user" "^4.0.0" + "@octokit/request" "^8.0.2" + "@octokit/request-error" "^5.0.0" + "@octokit/types" "^12.0.0" + deprecation "^2.3.1" + lru-cache "^10.0.0" + universal-github-app-jwt "^1.1.2" + universal-user-agent "^6.0.0" + +"@octokit/auth-oauth-app@^7.0.0": + version "7.0.1" + resolved "https://registry.yarnpkg.com/@octokit/auth-oauth-app/-/auth-oauth-app-7.0.1.tgz#30fd8fcb4608ca52c29c265a3fc7032897796c8e" + integrity sha512-RE0KK0DCjCHXHlQBoubwlLijXEKfhMhKm9gO56xYvFmP1QTMb+vvwRPmQLLx0V+5AvV9N9I3lr1WyTzwL3rMDg== + dependencies: + "@octokit/auth-oauth-device" "^6.0.0" + "@octokit/auth-oauth-user" "^4.0.0" + "@octokit/request" "^8.0.2" + "@octokit/types" "^12.0.0" + "@types/btoa-lite" "^1.0.0" + btoa-lite "^1.0.0" + universal-user-agent "^6.0.0" + +"@octokit/auth-oauth-device@^6.0.0": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@octokit/auth-oauth-device/-/auth-oauth-device-6.0.1.tgz#38e5f7f8997c5e8b774f283463ecf4a7e42d7cee" + integrity sha512-yxU0rkL65QkjbqQedgVx3gmW7YM5fF+r5uaSj9tM/cQGVqloXcqP2xK90eTyYvl29arFVCW8Vz4H/t47mL0ELw== + dependencies: + "@octokit/oauth-methods" "^4.0.0" + "@octokit/request" "^8.0.0" + "@octokit/types" "^12.0.0" + universal-user-agent "^6.0.0" + +"@octokit/auth-oauth-user@^4.0.0": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@octokit/auth-oauth-user/-/auth-oauth-user-4.0.1.tgz#c8267883935c83f78318c726ff91d7e98de05517" + integrity sha512-N94wWW09d0hleCnrO5wt5MxekatqEJ4zf+1vSe8MKMrhZ7gAXKFOKrDEZW2INltvBWJCyDUELgGRv8gfErH1Iw== + dependencies: + "@octokit/auth-oauth-device" "^6.0.0" + "@octokit/oauth-methods" "^4.0.0" + "@octokit/request" "^8.0.2" + "@octokit/types" "^12.0.0" + btoa-lite "^1.0.0" + universal-user-agent "^6.0.0" + "@octokit/auth-token@^3.0.0": version "3.0.4" resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-3.0.4.tgz#70e941ba742bdd2b49bdb7393e821dea8520a3db" integrity sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ== +"@octokit/auth-token@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-4.0.0.tgz#40d203ea827b9f17f42a29c6afb93b7745ef80c7" + integrity sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA== + +"@octokit/auth-unauthenticated@^5.0.0": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@octokit/auth-unauthenticated/-/auth-unauthenticated-5.0.1.tgz#d8032211728333068b2e07b53997c29e59a03507" + integrity sha512-oxeWzmBFxWd+XolxKTc4zr+h3mt+yofn4r7OfoIkR/Cj/o70eEGmPsFbueyJE2iBAGpjgTnEOKM3pnuEGVmiqg== + dependencies: + "@octokit/request-error" "^5.0.0" + "@octokit/types" "^12.0.0" + "@octokit/core@^4.2.1": version "4.2.4" resolved "https://registry.yarnpkg.com/@octokit/core/-/core-4.2.4.tgz#d8769ec2b43ff37cc3ea89ec4681a20ba58ef907" @@ -2317,6 +2393,19 @@ before-after-hook "^2.2.0" universal-user-agent "^6.0.0" +"@octokit/core@^5.0.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@octokit/core/-/core-5.1.0.tgz#81dacf0197ed7855e6413f128bd6dd9e121e7d2f" + integrity sha512-BDa2VAMLSh3otEiaMJ/3Y36GU4qf6GI+VivQ/P41NC6GHcdxpKlqV0ikSZ5gdQsmS3ojXeRx5vasgNTinF0Q4g== + dependencies: + "@octokit/auth-token" "^4.0.0" + "@octokit/graphql" "^7.0.0" + "@octokit/request" "^8.0.2" + "@octokit/request-error" "^5.0.0" + "@octokit/types" "^12.0.0" + before-after-hook "^2.2.0" + universal-user-agent "^6.0.0" + "@octokit/endpoint@^7.0.0": version "7.0.6" resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-7.0.6.tgz#791f65d3937555141fb6c08f91d618a7d645f1e2" @@ -2326,6 +2415,14 @@ is-plain-object "^5.0.0" universal-user-agent "^6.0.0" +"@octokit/endpoint@^9.0.0": + version "9.0.4" + resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-9.0.4.tgz#8afda5ad1ffc3073d08f2b450964c610b821d1ea" + integrity sha512-DWPLtr1Kz3tv8L0UvXTDP1fNwM0S+z6EJpRcvH66orY6Eld4XBMCSYsaWp4xIm61jTWxK68BrR7ibO+vSDnZqw== + dependencies: + "@octokit/types" "^12.0.0" + universal-user-agent "^6.0.0" + "@octokit/graphql@^5.0.0": version "5.0.6" resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-5.0.6.tgz#9eac411ac4353ccc5d3fca7d76736e6888c5d248" @@ -2335,16 +2432,65 @@ "@octokit/types" "^9.0.0" universal-user-agent "^6.0.0" +"@octokit/graphql@^7.0.0": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-7.0.2.tgz#3df14b9968192f9060d94ed9e3aa9780a76e7f99" + integrity sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q== + dependencies: + "@octokit/request" "^8.0.1" + "@octokit/types" "^12.0.0" + universal-user-agent "^6.0.0" + +"@octokit/oauth-app@^6.0.0", "@octokit/oauth-app@^6.1.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@octokit/oauth-app/-/oauth-app-6.1.0.tgz#22c276f6ad2364c6999837bfdd5d9c1092838726" + integrity sha512-nIn/8eUJ/BKUVzxUXd5vpzl1rwaVxMyYbQkNZjHrF7Vk/yu98/YDF/N2KeWO7uZ0g3b5EyiFXFkZI8rJ+DH1/g== + dependencies: + "@octokit/auth-oauth-app" "^7.0.0" + "@octokit/auth-oauth-user" "^4.0.0" + "@octokit/auth-unauthenticated" "^5.0.0" + "@octokit/core" "^5.0.0" + "@octokit/oauth-authorization-url" "^6.0.2" + "@octokit/oauth-methods" "^4.0.0" + "@types/aws-lambda" "^8.10.83" + universal-user-agent "^6.0.0" + +"@octokit/oauth-authorization-url@^6.0.2": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@octokit/oauth-authorization-url/-/oauth-authorization-url-6.0.2.tgz#cc82ca29cc5e339c9921672f39f2b3f5c8eb6ef2" + integrity sha512-CdoJukjXXxqLNK4y/VOiVzQVjibqoj/xHgInekviUJV73y/BSIcwvJ/4aNHPBPKcPWFnd4/lO9uqRV65jXhcLA== + +"@octokit/oauth-methods@^4.0.0": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@octokit/oauth-methods/-/oauth-methods-4.0.1.tgz#90d22c662387056307778d7e5c4763ff559636c4" + integrity sha512-1NdTGCoBHyD6J0n2WGXg9+yDLZrRNZ0moTEex/LSPr49m530WNKcCfXDghofYptr3st3eTii+EHoG5k/o+vbtw== + dependencies: + "@octokit/oauth-authorization-url" "^6.0.2" + "@octokit/request" "^8.0.2" + "@octokit/request-error" "^5.0.0" + "@octokit/types" "^12.0.0" + btoa-lite "^1.0.0" + "@octokit/openapi-types@^18.0.0": version "18.1.1" resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-18.1.1.tgz#09bdfdabfd8e16d16324326da5148010d765f009" integrity sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw== +"@octokit/openapi-types@^19.1.0": + version "19.1.0" + resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-19.1.0.tgz#75ec7e64743870fc73e1ab4bc6ec252ecdd624dc" + integrity sha512-6G+ywGClliGQwRsjvqVYpklIfa7oRPA0vyhPQG/1Feh+B+wU0vGH1JiJ5T25d3g1JZYBHzR2qefLi9x8Gt+cpw== + "@octokit/plugin-enterprise-rest@6.0.1": version "6.0.1" resolved "https://registry.yarnpkg.com/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz#e07896739618dab8da7d4077c658003775f95437" integrity sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw== +"@octokit/plugin-paginate-graphql@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-graphql/-/plugin-paginate-graphql-4.0.0.tgz#b26024fa454039c18b948f13bf754ff86b89e8b9" + integrity sha512-7HcYW5tP7/Z6AETAPU14gp5H5KmCPT3hmJrS/5tO7HIgbwenYmgw4OY9Ma54FDySuxMwD+wsJlxtuGWwuZuItA== + "@octokit/plugin-paginate-rest@^6.1.2": version "6.1.2" resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz#f86456a7a1fe9e58fec6385a85cf1b34072341f8" @@ -2353,11 +2499,25 @@ "@octokit/tsconfig" "^1.0.2" "@octokit/types" "^9.2.3" +"@octokit/plugin-paginate-rest@^9.0.0": + version "9.1.5" + resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.1.5.tgz#1705bcef4dcde1f4015ee58a63dc61b68648f480" + integrity sha512-WKTQXxK+bu49qzwv4qKbMMRXej1DU2gq017euWyKVudA6MldaSSQuxtz+vGbhxV4CjxpUxjZu6rM2wfc1FiWVg== + dependencies: + "@octokit/types" "^12.4.0" + "@octokit/plugin-request-log@^1.0.4": version "1.0.4" resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz#5e50ed7083a613816b1e4a28aeec5fb7f1462e85" integrity sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA== +"@octokit/plugin-rest-endpoint-methods@^10.0.0": + version "10.2.0" + resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.2.0.tgz#eeaa4de97a2ae26404dea30ce3e17b11928e027c" + integrity sha512-ePbgBMYtGoRNXDyKGvr9cyHjQ163PbwD0y1MkDJCpkO2YH4OeXX40c4wYHKikHGZcpGPbcRLuy0unPUuafco8Q== + dependencies: + "@octokit/types" "^12.3.0" + "@octokit/plugin-rest-endpoint-methods@^7.1.2": version "7.2.3" resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.2.3.tgz#37a84b171a6cb6658816c82c4082ac3512021797" @@ -2365,6 +2525,23 @@ dependencies: "@octokit/types" "^10.0.0" +"@octokit/plugin-retry@^6.0.0": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@octokit/plugin-retry/-/plugin-retry-6.0.1.tgz#3257404f7cc418e1c1f13a7f2012c1db848b7693" + integrity sha512-SKs+Tz9oj0g4p28qkZwl/topGcb0k0qPNX/i7vBKmDsjoeqnVfFUquqrE/O9oJY7+oLzdCtkiWSXLpLjvl6uog== + dependencies: + "@octokit/request-error" "^5.0.0" + "@octokit/types" "^12.0.0" + bottleneck "^2.15.3" + +"@octokit/plugin-throttling@^8.0.0": + version "8.1.3" + resolved "https://registry.yarnpkg.com/@octokit/plugin-throttling/-/plugin-throttling-8.1.3.tgz#7fb0e001c0cb9383c6be07740b8ec326ed990f6b" + integrity sha512-pfyqaqpc0EXh5Cn4HX9lWYsZ4gGbjnSmUILeu4u2gnuM50K/wIk9s1Pxt3lVeVwekmITgN/nJdoh43Ka+vye8A== + dependencies: + "@octokit/types" "^12.2.0" + bottleneck "^2.15.3" + "@octokit/request-error@^3.0.0": version "3.0.3" resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-3.0.3.tgz#ef3dd08b8e964e53e55d471acfe00baa892b9c69" @@ -2374,6 +2551,15 @@ deprecation "^2.0.0" once "^1.4.0" +"@octokit/request-error@^5.0.0": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-5.0.1.tgz#277e3ce3b540b41525e07ba24c5ef5e868a72db9" + integrity sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ== + dependencies: + "@octokit/types" "^12.0.0" + deprecation "^2.0.0" + once "^1.4.0" + "@octokit/request@^6.0.0": version "6.2.8" resolved "https://registry.yarnpkg.com/@octokit/request/-/request-6.2.8.tgz#aaf480b32ab2b210e9dadd8271d187c93171d8eb" @@ -2386,6 +2572,16 @@ node-fetch "^2.6.7" universal-user-agent "^6.0.0" +"@octokit/request@^8.0.0", "@octokit/request@^8.0.1", "@octokit/request@^8.0.2": + version "8.1.6" + resolved "https://registry.yarnpkg.com/@octokit/request/-/request-8.1.6.tgz#a76a859c30421737a3918b40973c2ff369009571" + integrity sha512-YhPaGml3ncZC1NfXpP3WZ7iliL1ap6tLkAp6MvbK2fTTPytzVUyUesBBogcdMm86uRYO5rHaM1xIWxigWZ17MQ== + dependencies: + "@octokit/endpoint" "^9.0.0" + "@octokit/request-error" "^5.0.0" + "@octokit/types" "^12.0.0" + universal-user-agent "^6.0.0" + "@octokit/rest@19.0.11": version "19.0.11" resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-19.0.11.tgz#2ae01634fed4bd1fca5b642767205ed3fd36177c" @@ -2408,6 +2604,13 @@ dependencies: "@octokit/openapi-types" "^18.0.0" +"@octokit/types@^12.0.0", "@octokit/types@^12.2.0", "@octokit/types@^12.3.0", "@octokit/types@^12.4.0": + version "12.4.0" + resolved "https://registry.yarnpkg.com/@octokit/types/-/types-12.4.0.tgz#8f97b601e91ce6b9776ed8152217e77a71be7aac" + integrity sha512-FLWs/AvZllw/AGVs+nJ+ELCDZZJk+kY0zMen118xhL2zD0s1etIUHm1odgjP7epxYU1ln7SZxEUWYop5bhsdgQ== + dependencies: + "@octokit/openapi-types" "^19.1.0" + "@octokit/types@^9.0.0", "@octokit/types@^9.2.3": version "9.3.2" resolved "https://registry.yarnpkg.com/@octokit/types/-/types-9.3.2.tgz#3f5f89903b69f6a2d196d78ec35f888c0013cac5" @@ -2415,6 +2618,26 @@ dependencies: "@octokit/openapi-types" "^18.0.0" +"@octokit/webhooks-methods@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@octokit/webhooks-methods/-/webhooks-methods-4.0.0.tgz#d1697930ba3d8e6b6d0f8a2c996bb440d2e1df1b" + integrity sha512-M8mwmTXp+VeolOS/kfRvsDdW+IO0qJ8kYodM/sAysk093q6ApgmBXwK1ZlUvAwXVrp/YVHp6aArj4auAxUAOFw== + +"@octokit/webhooks-types@7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@octokit/webhooks-types/-/webhooks-types-7.1.0.tgz#d533dea253416e02dd6c2bfab25e533295bd5d3f" + integrity sha512-y92CpG4kFFtBBjni8LHoV12IegJ+KFxLgKRengrVjKmGE5XMeCuGvlfRe75lTRrgXaG6XIWJlFpIDTlkoJsU8w== + +"@octokit/webhooks@^12.0.4": + version "12.0.11" + resolved "https://registry.yarnpkg.com/@octokit/webhooks/-/webhooks-12.0.11.tgz#4c7887390f506518420b96821c6304187ce59db1" + integrity sha512-YEQOb7v0TZ662nh5jsbY1CMgJyMajCEagKrHWC30LTCwCtnuIrLtEpE20vq4AtH0SuZI90+PtV66/Bnnw0jkvg== + dependencies: + "@octokit/request-error" "^5.0.0" + "@octokit/webhooks-methods" "^4.0.0" + "@octokit/webhooks-types" "7.1.0" + aggregate-error "^3.1.0" + "@pkgjs/parseargs@^0.11.0": version "0.11.0" resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" @@ -2828,6 +3051,11 @@ resolved "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz" integrity sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw== +"@types/aws-lambda@^8.10.83": + version "8.10.131" + resolved "https://registry.yarnpkg.com/@types/aws-lambda/-/aws-lambda-8.10.131.tgz#76fcd36e6a4a4666c7ea7503bf0e3e86c0a9cdb2" + integrity sha512-IWmFpqnVDvskYWnNSiu/qlRn80XlIOU0Gy5rKCl/NjhnI95pV8qIHs6L5b+bpHhyzuOSzjLgBcwgFSXrC1nZWA== + "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": version "7.20.5" resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz" @@ -2884,6 +3112,11 @@ dependencies: "@types/node" "*" +"@types/btoa-lite@^1.0.0": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/btoa-lite/-/btoa-lite-1.0.2.tgz#82bb6aab00abf7cff3ca2825abe010c0cd536ae5" + integrity sha512-ZYbcE2x7yrvNFJiU7xJGrpF/ihpkM7zKgw8bha3LNJSesvTtUNxbpzaT7WXBIryf6jovisrxTBvymxMeLLj1Mg== + "@types/connect-history-api-fallback@^1.3.5": version "1.5.4" resolved "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz" @@ -3052,6 +3285,13 @@ dependencies: "@types/node" "*" +"@types/jsonwebtoken@^9.0.0": + version "9.0.5" + resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.5.tgz#0bd9b841c9e6c5a937c17656e2368f65da025588" + integrity sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA== + dependencies: + "@types/node" "*" + "@types/long@^4.0.0": version "4.0.2" resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" @@ -3954,7 +4194,7 @@ agentkeepalive@^4.2.1: dependencies: humanize-ms "^1.2.1" -aggregate-error@^3.0.0: +aggregate-error@^3.0.0, aggregate-error@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== @@ -4686,6 +4926,11 @@ boolbase@^1.0.0, boolbase@~1.0.0: resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== +bottleneck@^2.15.3: + version "2.19.5" + resolved "https://registry.yarnpkg.com/bottleneck/-/bottleneck-2.19.5.tgz#5df0b90f59fd47656ebe63c78a98419205cadd91" + integrity sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw== + bplist-parser@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz" @@ -4737,6 +4982,16 @@ bser@2.1.1: dependencies: node-int64 "^0.4.0" +btoa-lite@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337" + integrity sha512-gvW7InbIyF8AicrqWoptdW08pUxuhq8BEgowNajy9RhiE86fmGAGl+bLKo6oB8QP0CkqHLowfN0oJdKC/J6LbA== + +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== + buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" @@ -5911,7 +6166,7 @@ depd@~1.1.2: resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== -deprecation@^2.0.0: +deprecation@^2.0.0, deprecation@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== @@ -6153,6 +6408,13 @@ eastasianwidth@^0.2.0: resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== +ecdsa-sig-formatter@1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" + integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== + dependencies: + safe-buffer "^5.0.1" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" @@ -9269,6 +9531,22 @@ jsonpointer@^5.0.0: resolved "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz" integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== +jsonwebtoken@^9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3" + integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ== + dependencies: + jws "^3.2.2" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.1.1" + semver "^7.5.4" + "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.5: version "3.3.5" resolved "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz" @@ -9279,6 +9557,23 @@ jsonpointer@^5.0.0: object.assign "^4.1.4" object.values "^1.1.6" +jwa@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" + integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jws@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" + integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== + dependencies: + jwa "^1.4.1" + safe-buffer "^5.0.1" + keyv@^4.5.3: version "4.5.4" resolved "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz" @@ -9538,11 +9833,41 @@ lodash.debounce@^4.0.8: resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== + +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== + lodash.ismatch@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" integrity sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g== +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw== + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== + lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz" @@ -9553,6 +9878,11 @@ lodash.merge@^4.6.2: resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== + lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz" @@ -9605,6 +9935,11 @@ lower-case@^2.0.2: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.13.1.tgz#267a81fbd0881327c46a81c5922606a2cfe336c4" integrity sha512-CHqbAq7NFlW3RSnoWXLJBxCWaZVBrfa9UEHId2M3AW8iEBurbqduNexEUCGc3SHc6iCYXNJCDi903LajSVAEPQ== +lru-cache@^10.0.0, "lru-cache@^9.1.1 || ^10.0.0": + version "10.1.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.1.0.tgz#2098d41c2dc56500e6c88584aa656c84de7d0484" + integrity sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" @@ -9624,11 +9959,6 @@ lru-cache@^7.4.4, lru-cache@^7.5.1, lru-cache@^7.7.1: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== -"lru-cache@^9.1.1 || ^10.0.0": - version "10.1.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.1.0.tgz#2098d41c2dc56500e6c88584aa656c84de7d0484" - integrity sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag== - luxon@^3.4.4: version "3.4.4" resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.4.4.tgz#cf20dc27dc532ba41a169c43fdcc0063601577af" @@ -10530,6 +10860,22 @@ obuf@^1.0.0, obuf@^1.1.2: resolved "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== +octokit@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/octokit/-/octokit-3.1.2.tgz#e574e4f2f5f8712e10412ce81fb56a74c93d4cfa" + integrity sha512-MG5qmrTL5y8KYwFgE1A4JWmgfQBaIETE/lOlfwNYx1QOtCQHGVxkRJmdUJltFc1HVn73d61TlMhMyNTOtMl+ng== + dependencies: + "@octokit/app" "^14.0.2" + "@octokit/core" "^5.0.0" + "@octokit/oauth-app" "^6.0.0" + "@octokit/plugin-paginate-graphql" "^4.0.0" + "@octokit/plugin-paginate-rest" "^9.0.0" + "@octokit/plugin-rest-endpoint-methods" "^10.0.0" + "@octokit/plugin-retry" "^6.0.0" + "@octokit/plugin-throttling" "^8.0.0" + "@octokit/request-error" "^5.0.0" + "@octokit/types" "^12.0.0" + on-finished@2.4.1: version "2.4.1" resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" @@ -11896,6 +12242,11 @@ react-is@^18.0.0, react-is@^18.2.0: resolved "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz" integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== +react-oauth-popup@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/react-oauth-popup/-/react-oauth-popup-1.0.5.tgz#e84f33995840ab66143b3d5e6f0e70f571e957a8" + integrity sha512-UyJ3ohmpaXReUeir7mUZaADmUtpATEmJ9EBwGO/CfDQAGFsHZ+W1MrSVy2t0Hl8v+mgN6Ts/cnRhftSccGK3sg== + react-refresh@^0.11.0: version "0.11.0" resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz" @@ -13857,6 +14208,14 @@ unique-string@^2.0.0: dependencies: crypto-random-string "^2.0.0" +universal-github-app-jwt@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/universal-github-app-jwt/-/universal-github-app-jwt-1.1.2.tgz#8c1867a394d7d9d42cda34f11d1bcb023797d8df" + integrity sha512-t1iB2FmLFE+yyJY9+3wMx0ejB+MQpEVkH0gQv7dR6FZyltyq+ZZO0uDpbopxhrZ3SLEO4dCEkIujOMldEQ2iOA== + dependencies: + "@types/jsonwebtoken" "^9.0.0" + jsonwebtoken "^9.0.2" + universal-user-agent@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.1.tgz#15f20f55da3c930c57bddbf1734c6654d5fd35aa" @@ -13920,6 +14279,11 @@ url-parse@^1.5.3: querystringify "^2.1.1" requires-port "^1.0.0" +usehooks-ts@^2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/usehooks-ts/-/usehooks-ts-2.10.0.tgz#ccd0d63168e4db95b061e26e585b0068d3fad0ed" + integrity sha512-hN22L5pqcsM1LwL6Q3p1QfxI9K+wuP4lrBXyCQ4Vi5Zo94YhphqRh2l7G7uhqPzLunAObLUAoSKzo64lisNyWQ== + util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"