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
This commit is contained in:
Nabarun Gogoi 2024-01-30 19:50:53 +05:30 committed by Ashwin Phatak
parent 2f8d21baf5
commit e1e9a7063e
21 changed files with 647 additions and 86 deletions

View File

@ -30,6 +30,10 @@
yarn db:load:fixtures 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 - Start the server
```bash ```bash

View File

@ -5,3 +5,7 @@
[database] [database]
dbPath = "db/snowball" dbPath = "db/snowball"
[githubOauth]
clientId = ""
clientSecret = ""

View File

@ -5,6 +5,7 @@
"dependencies": { "dependencies": {
"@graphql-tools/schema": "^10.0.2", "@graphql-tools/schema": "^10.0.2",
"@graphql-tools/utils": "^10.0.12", "@graphql-tools/utils": "^10.0.12",
"@octokit/oauth-app": "^6.1.0",
"@types/debug": "^4.1.5", "@types/debug": "^4.1.5",
"@types/express": "^4.17.21", "@types/express": "^4.17.21",
"@types/node": "^20.11.0", "@types/node": "^20.11.0",
@ -36,8 +37,8 @@
"@types/fs-extra": "^11.0.4", "@types/fs-extra": "^11.0.4",
"@typescript-eslint/eslint-plugin": "^6.18.1", "@typescript-eslint/eslint-plugin": "^6.18.1",
"@typescript-eslint/parser": "^6.18.1", "@typescript-eslint/parser": "^6.18.1",
"copyfiles": "^2.4.1",
"better-sqlite3": "^9.2.2", "better-sqlite3": "^9.2.2",
"copyfiles": "^2.4.1",
"eslint": "^8.56.0", "eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-config-semistandard": "^15.0.1", "eslint-config-semistandard": "^15.0.1",

View File

@ -8,7 +8,13 @@ export interface DatabaseConfig {
dbPath: string; dbPath: string;
} }
export interface GithubOauthConfig {
clientId: string;
clientSecret: string;
}
export interface Config { export interface Config {
server: ServerConfig; server: ServerConfig;
database: DatabaseConfig; database: DatabaseConfig;
githubOauth: GithubOauthConfig;
} }

View File

@ -3,6 +3,8 @@ import debug from 'debug';
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import { OAuthApp } from '@octokit/oauth-app';
import { Database } from './database'; import { Database } from './database';
import { createAndStartServer } from './server'; import { createAndStartServer } from './server';
import { createResolvers } from './resolvers'; import { createResolvers } from './resolvers';
@ -14,13 +16,20 @@ const log = debug('snowball:server');
export const main = async (): Promise<void> => { export const main = async (): Promise<void> => {
// TODO: get config path using cli // TODO: get config path using cli
const { server, database } = await getConfig<Config>(DEFAULT_CONFIG_FILE_PATH); const { server, database, githubOauth } = await getConfig<Config>(DEFAULT_CONFIG_FILE_PATH);
const db = new Database(database); const db = new Database(database);
await db.init(); 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 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); await createAndStartServer(typeDefs, resolvers, server);
}; };

View File

@ -1,13 +1,15 @@
import debug from 'debug'; import debug from 'debug';
import assert from 'assert'; import assert from 'assert';
import { OAuthApp } from '@octokit/oauth-app';
import { Database } from './database'; import { Database } from './database';
import { deploymentToGqlType, projectMemberToGqlType, projectToGqlType, environmentVariableToGqlType, isUserOwner } from './utils'; import { deploymentToGqlType, projectMemberToGqlType, projectToGqlType, environmentVariableToGqlType, isUserOwner } from './utils';
import { Environment } from './entity/Deployment'; import { Environment } from './entity/Deployment';
const log = debug('snowball:database'); const log = debug('snowball:database');
export const createResolvers = async (db: Database): Promise<any> => { export const createResolvers = async (db: Database, app: OAuthApp): Promise<any> => {
return { return {
Query: { Query: {
// TODO: add custom type for context // TODO: add custom type for context
@ -203,6 +205,17 @@ export const createResolvers = async (db: Database): Promise<any> => {
log(err); log(err);
return false; 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 };
} }
} }
}; };

View File

@ -126,6 +126,10 @@ type Query {
domains(projectId: String!): [Domain!] domains(projectId: String!): [Domain!]
} }
type AuthResult {
token: String!
}
type Mutation { type Mutation {
removeMember(memberId: String!): Boolean! removeMember(memberId: String!): Boolean!
addEnvironmentVariables(projectId: String!, environmentVariables: [AddEnvironmentVariableInput!]): Boolean! addEnvironmentVariables(projectId: String!, environmentVariables: [AddEnvironmentVariableInput!]): Boolean!
@ -136,6 +140,7 @@ type Mutation {
rollbackDeployment(projectId: String!, deploymentId: String!): Boolean! rollbackDeployment(projectId: String!, deploymentId: String!): Boolean!
addDomain(projectId: String!, domainDetails: AddDomainInput!): Boolean! addDomain(projectId: String!, domainDetails: AddDomainInput!): Boolean!
updateDomain(domainId: String!, domainDetails: UpdateDomainInput!): Boolean! updateDomain(domainId: String!, domainDetails: UpdateDomainInput!): Boolean!
authenticateGithub(code: String!): AuthResult!
} }
input AddEnvironmentVariableInput { input AddEnvironmentVariableInput {

View File

@ -1 +1,3 @@
REACT_APP_GQL_SERVER_URL = 'http://localhost:8000/graphql' REACT_APP_GQL_SERVER_URL = 'http://localhost:8000/graphql'
REACT_APP_GITHUB_CLIENT_ID = 4720362b6740b00652b6

View File

@ -17,17 +17,20 @@
"eslint-config-react-app": "^7.0.1", "eslint-config-react-app": "^7.0.1",
"gql-client": "^1.0.0", "gql-client": "^1.0.0",
"luxon": "^3.4.4", "luxon": "^3.4.4",
"octokit": "^3.1.2",
"react": "^18.2.0", "react": "^18.2.0",
"react-day-picker": "^8.9.1", "react-day-picker": "^8.9.1",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-dropdown": "^1.11.0", "react-dropdown": "^1.11.0",
"react-hook-form": "^7.49.0", "react-hook-form": "^7.49.0",
"react-hot-toast": "^2.4.1", "react-hot-toast": "^2.4.1",
"react-oauth-popup": "^1.0.5",
"react-router-dom": "^6.20.1", "react-router-dom": "^6.20.1",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"react-tabs": "^6.0.2", "react-tabs": "^6.0.2",
"react-timer-hook": "^3.0.7", "react-timer-hook": "^3.0.7",
"typescript": "^4.9.5", "typescript": "^4.9.5",
"usehooks-ts": "^2.10.0",
"vertical-stepper-nav": "^1.0.2", "vertical-stepper-nav": "^1.0.2",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
}, },

View File

@ -1,6 +1,7 @@
import React, { useCallback, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import { useCombobox } from 'downshift'; import { useCombobox } from 'downshift';
import { Project } from 'gql-client'; import { Project } from 'gql-client';
import { useDebounce } from 'usehooks-ts';
import { import {
List, List,
@ -30,12 +31,6 @@ const ProjectSearchBar = ({ onChange }: ProjectsSearchProps) => {
highlightedIndex, highlightedIndex,
inputValue, inputValue,
} = useCombobox({ } = useCombobox({
onInputValueChange({ inputValue }) {
if (inputValue) {
// TODO: Use debounce
fetchProjects(inputValue);
}
},
items, items,
itemToString(item) { itemToString(item) {
return item ? item.name : ''; return item ? item.name : '';
@ -52,6 +47,8 @@ const ProjectSearchBar = ({ onChange }: ProjectsSearchProps) => {
}, },
}); });
const debouncedInputValue = useDebounce<string>(inputValue, 500);
const fetchProjects = useCallback( const fetchProjects = useCallback(
async (inputValue: string) => { async (inputValue: string) => {
const { searchProjects } = await client.searchProjects(inputValue); const { searchProjects } = await client.searchProjects(inputValue);
@ -60,6 +57,12 @@ const ProjectSearchBar = ({ onChange }: ProjectsSearchProps) => {
[client], [client],
); );
useEffect(() => {
if (debouncedInputValue) {
fetchProjects(debouncedInputValue);
}
}, [fetchProjects, debouncedInputValue]);
return ( return (
<div className="relative"> <div className="relative">
<SearchBar {...getInputProps()} /> <SearchBar {...getInputProps()} />

View File

@ -1,6 +1,29 @@
import { Button } from '@material-tailwind/react';
import React from '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 ( return (
<div className="bg-gray-100 flex flex-col p-4 justify-end items-center text-center text-sm h-60 rounded-2xl"> <div className="bg-gray-100 flex flex-col p-4 justify-end items-center text-center text-sm h-60 rounded-2xl">
<div>^</div> <div>^</div>
@ -11,13 +34,18 @@ const ConnectAccount = () => {
under the account under the account
</p> </p>
</div> </div>
<div> <div className="mt-2 flex">
<button className="bg-gray-300 rounded-full mx-2"> <OauthPopup
Connect to Github url={GITHUB_OAUTH_URL}
</button> onCode={handleCode}
<button className="bg-gray-300 rounded-full mx-2"> onClose={() => {}}
Connect to Gitea title="Snowball"
</button> width={1000}
height={1000}
>
<Button className="rounded-full mx-2">Connect to Github</Button>
</OauthPopup>
<Button className="rounded-full mx-2">Connect to Gitea</Button>
</div> </div>
</div> </div>
); );

View File

@ -3,10 +3,10 @@ import React from 'react';
import { Chip, IconButton } from '@material-tailwind/react'; import { Chip, IconButton } from '@material-tailwind/react';
import { relativeTime } from '../../../utils/time'; import { relativeTime } from '../../../utils/time';
import { RepositoryDetails } from '../../../types/project'; import { GitRepositoryDetails } from '../../../types/project';
interface ProjectRepoCardProps { interface ProjectRepoCardProps {
repository: RepositoryDetails; repository: GitRepositoryDetails;
onClick: () => void; onClick: () => void;
} }
@ -22,10 +22,8 @@ const ProjectRepoCard: React.FC<ProjectRepoCardProps> = ({
<div>^</div> <div>^</div>
<div className="grow"> <div className="grow">
<div> <div>
<span className="text-black"> <span className="text-black">{repository.full_name}</span>
{repository.user}/{repository.title} {repository.visibility === 'private' ? (
</span>
{repository.private ? (
<Chip <Chip
className="normal-case inline ml-6 bg-[#FED7AA] text-[#EA580C] font-normal" className="normal-case inline ml-6 bg-[#FED7AA] text-[#EA580C] font-normal"
size="sm" size="sm"
@ -36,7 +34,7 @@ const ProjectRepoCard: React.FC<ProjectRepoCardProps> = ({
'' ''
)} )}
</div> </div>
<p>{relativeTime(repository.updatedAt)}</p> <p>{repository.updated_at && relativeTime(repository.updated_at)}</p>
</div> </div>
<div className="hidden group-hover:block"> <div className="hidden group-hover:block">
<IconButton size="sm">{'>'}</IconButton> <IconButton size="sm">{'>'}</IconButton>

View File

@ -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 { Button, Typography, Option, Select } from '@material-tailwind/react';
import SearchBar from '../../SearchBar'; import SearchBar from '../../SearchBar';
import ProjectRepoCard from './ProjectRepoCard'; import ProjectRepoCard from './ProjectRepoCard';
import repositoryDetails from '../../../assets/repositories.json'; import { GitOrgDetails, GitRepositoryDetails } from '../../../types/project';
import { RepositoryDetails } from '../../../types/project';
const DEFAULT_SEARCHED_REPO = ''; const DEFAULT_SEARCHED_REPO = '';
const DEFAULT_SELECTED_USER = 'All accounts'; const REPOS_PER_PAGE = 5;
interface RepositoryListProps { 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 [searchedRepo, setSearchedRepo] = useState(DEFAULT_SEARCHED_REPO);
const [selectedUser, setSelectedUser] = useState(DEFAULT_SELECTED_USER); const [selectedAccount, setSelectedAccount] = useState('');
const [orgs, setOrgs] = useState<GitOrgDetails[]>([]);
// TODO: Add new type for Git user when required
const [gitUser, setGitUser] = useState<GitOrgDetails>();
const filteredRepos = useMemo(() => { const [repositoryDetails, setRepositoryDetails] = useState<
return repositoryDetails.filter((repo) => { GitRepositoryDetails[]
const titleMatch = >([]);
!searchedRepo ||
repo.title.toLowerCase().includes(searchedRepo.toLowerCase()); const octokit = useMemo(() => {
const userMatch = // TODO: Create github/octokit context
selectedUser === DEFAULT_SELECTED_USER || selectedUser === repo.user; return new Octokit({ auth: token });
return titleMatch && userMatch; }, [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<string>(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,
}); });
}, [searchedRepo, selectedUser]);
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(() => { const handleResetFilters = useCallback(() => {
assert(gitUser, 'Git user is not available');
setSearchedRepo(DEFAULT_SEARCHED_REPO); setSearchedRepo(DEFAULT_SEARCHED_REPO);
setSelectedUser(DEFAULT_SELECTED_USER); setSelectedAccount(gitUser.login);
}, []); }, [gitUser]);
const users = useMemo(() => { const accounts = useMemo(() => {
return [ if (!octokit || !gitUser) {
DEFAULT_SELECTED_USER, return [];
...Array.from(new Set(repositoryDetails.map((repo) => repo.user))), }
];
}, []); return [gitUser, ...orgs];
}, [octokit, orgs, gitUser]);
return ( return (
<div className="p-4"> <div className="p-4">
<div className="flex gap-2 mb-2"> <div className="flex gap-2 mb-2">
<div className="basis-1/3"> <div className="basis-1/3">
{/* TODO: Fix selection of Git user at start */}
<Select <Select
value={selectedUser} value={selectedAccount}
onChange={(value) => setSelectedUser(value!)} onChange={(value) => setSelectedAccount(value!)}
> >
{users.map((user, key) => ( {accounts.map((account) => (
<Option <Option key={account.id} value={account.login}>
className={user === selectedUser ? 'hidden' : ''} ^ {account.login}
key={key}
value={user}
>
^ {user}
</Option> </Option>
))} ))}
</Select> </Select>
@ -68,8 +140,8 @@ const RepositoryList = ({ repoSelectionHandler }: RepositoryListProps) => {
/> />
</div> </div>
</div> </div>
{Boolean(filteredRepos.length) ? ( {Boolean(repositoryDetails.length) ? (
filteredRepos.map((repo, key) => { repositoryDetails.map((repo, key) => {
return ( return (
<ProjectRepoCard <ProjectRepoCard
repository={repo} repository={repo}

View File

@ -7,19 +7,19 @@ import { Button, Input, Switch, Typography } from '@material-tailwind/react';
import RepositoryList from '../../create/RepositoryList'; import RepositoryList from '../../create/RepositoryList';
import RepoConnectedSection from './RepoConnectedSection'; import RepoConnectedSection from './RepoConnectedSection';
import GitSelectionSection from './GitSelectionSection'; import GitSelectionSection from './GitSelectionSection';
import { GitSelect, RepositoryDetails } from '../../../../types/project'; import { GitRepositoryDetails, GitSelect } from '../../../../types/project';
import WebhookCard from './WebhookCard'; import WebhookCard from './WebhookCard';
const GitTabPanel = () => { const GitTabPanel = () => {
const [gitSelect, setGitSelect] = useState('none'); const [gitSelect, setGitSelect] = useState('none');
const [linkedRepo, setLinkedRepo] = useState<RepositoryDetails>(); const [linkedRepo, setLinkedRepo] = useState<GitRepositoryDetails>();
const [webhooksArray, setWebhooksArray] = useState<Array<string>>([]); const [webhooksArray, setWebhooksArray] = useState<Array<string>>([]);
const gitSelectionHandler = (git: GitSelect) => { const gitSelectionHandler = (git: GitSelect) => {
setGitSelect(git); setGitSelect(git);
}; };
const repoSelectionHandler = (repoDetails: RepositoryDetails) => { const repoSelectionHandler = (repoDetails: GitRepositoryDetails) => {
setLinkedRepo(repoDetails); setLinkedRepo(repoDetails);
}; };
@ -54,7 +54,11 @@ const GitTabPanel = () => {
(GitSelect.NONE === gitSelect ? ( (GitSelect.NONE === gitSelect ? (
<GitSelectionSection gitSelectionHandler={gitSelectionHandler} /> <GitSelectionSection gitSelectionHandler={gitSelectionHandler} />
) : ( ) : (
<RepositoryList repoSelectionHandler={repoSelectionHandler} /> <RepositoryList
repoSelectionHandler={repoSelectionHandler}
// TODO: Pass Github access token after authentication
token=""
/>
))} ))}
<div className="flex justify-between mt-4"> <div className="flex justify-between mt-4">

View File

@ -2,13 +2,13 @@ import React, { useState } from 'react';
import { Button, Typography } from '@material-tailwind/react'; import { Button, Typography } from '@material-tailwind/react';
import { RepositoryDetails } from '../../../../types/project'; import { GitRepositoryDetails } from '../../../../types/project';
import ConfirmDialog from '../../../shared/ConfirmDialog'; import ConfirmDialog from '../../../shared/ConfirmDialog';
const RepoConnectedSection = ({ const RepoConnectedSection = ({
linkedRepo, linkedRepo,
}: { }: {
linkedRepo: RepositoryDetails; linkedRepo: GitRepositoryDetails;
}) => { }) => {
const [disconnectRepoDialogOpen, setDisconnectRepoDialogOpen] = const [disconnectRepoDialogOpen, setDisconnectRepoDialogOpen] =
useState(false); useState(false);
@ -17,9 +17,7 @@ const RepoConnectedSection = ({
<div className="flex gap-4"> <div className="flex gap-4">
<div>^</div> <div>^</div>
<div className="grow"> <div className="grow">
<Typography variant="small"> <Typography variant="small">{linkedRepo.full_name}</Typography>
{linkedRepo.user}/{linkedRepo.title}
</Typography>
<Typography variant="small">Connected just now</Typography> <Typography variant="small">Connected just now</Typography>
</div> </div>
<div> <div>

View File

@ -1,13 +1,20 @@
import React from 'react'; import React, { useCallback, useState } from 'react';
import templateDetails from '../../../assets/templates.json'; import templateDetails from '../../../assets/templates.json';
import TemplateCard from '../../../components/projects/create/TemplateCard'; import TemplateCard from '../../../components/projects/create/TemplateCard';
import RepositoryList from '../../../components/projects/create/RepositoryList'; import RepositoryList from '../../../components/projects/create/RepositoryList';
import ConnectAccount from '../../../components/projects/create/ConnectAccount'; import ConnectAccount from '../../../components/projects/create/ConnectAccount';
const IS_GIT_AUTH = true;
const NewProject = () => { 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 ( return (
<> <>
<h5 className="mt-4 ml-4">Start with template</h5> <h5 className="mt-4 ml-4">Start with template</h5>
@ -17,10 +24,10 @@ const NewProject = () => {
})} })}
</div> </div>
<h5 className="mt-4 ml-4">Import a repository</h5> <h5 className="mt-4 ml-4">Import a repository</h5>
{IS_GIT_AUTH ? ( {isGitAuth ? (
<RepositoryList repoSelectionHandler={() => {}} /> <RepositoryList token={gitToken} repoSelectionHandler={() => {}} />
) : ( ) : (
<ConnectAccount /> <ConnectAccount onToken={handleToken} />
)} )}
</> </>
); );

View File

@ -25,6 +25,13 @@ export enum Status {
ERROR = 'Error', ERROR = 'Error',
} }
export interface GitOrgDetails {
id: number;
login: string;
avatar_url: string;
}
// TODO: Use GitRepositoryDetails
export interface RepositoryDetails { export interface RepositoryDetails {
title: string; title: string;
updatedAt: string; updatedAt: string;
@ -33,6 +40,15 @@ export interface RepositoryDetails {
branch: string[]; branch: string[];
} }
export interface GitRepositoryDetails {
id: number;
name: string;
full_name: string;
owner: GitOrgDetails | null;
visibility?: string;
updated_at?: string | null;
}
export enum GitSelect { export enum GitSelect {
GITHUB = 'github', GITHUB = 'github',
GITEA = 'gitea', GITEA = 'gitea',

View File

@ -1,8 +1,8 @@
import { ApolloClient, DefaultOptions, InMemoryCache, NormalizedCacheObject } from '@apollo/client'; import { ApolloClient, DefaultOptions, InMemoryCache, NormalizedCacheObject } from '@apollo/client';
import { getUser, getOrganizations, getDeployments, getProjectMembers, searchProjects, getEnvironmentVariables, getProject, getDomains, getProjectsInOrganization } from './queries'; 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 { 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 } from './mutations'; import { removeMember, addEnvironmentVariables, updateDeploymentToProd, updateProjectMutation, redeployToProd, deleteProject, addDomain, rollbackDeployment, updateDomainMutation, authenticateGithub } from './mutations';
export interface GraphQLConfig { export interface GraphQLConfig {
gqlEndpoint: string; gqlEndpoint: string;
@ -227,4 +227,15 @@ export class GQLClient {
return data; return data;
} }
async authenticateGithub (code: string): Promise<AuthenticateGithubResponse> {
const { data } = await this.client.mutate({
mutation: authenticateGithub,
variables: {
code
}
});
return data;
}
} }

View File

@ -51,3 +51,10 @@ mutation ($projectId: String!, $domainDetails: AddDomainInput!) {
addDomain(projectId: $projectId, domainDetails: $domainDetails) addDomain(projectId: $projectId, domainDetails: $domainDetails)
} }
`; `;
export const authenticateGithub = gql`
mutation ($code: String!) {
authenticateGithub(code: $code) {
token
}
}`;

View File

@ -222,3 +222,9 @@ export type AddDomainInput = {
export type AddDomainResponse = { export type AddDomainResponse = {
addDomain: true addDomain: true
} }
export type AuthenticateGithubResponse = {
authenticateGithub: {
token: string
}
}

378
yarn.lock
View File

@ -2299,11 +2299,87 @@
resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-17.1.3.tgz#5b3446868bb747f55930636165969c26ad72f77b" 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== 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": "@octokit/auth-token@^3.0.0":
version "3.0.4" version "3.0.4"
resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-3.0.4.tgz#70e941ba742bdd2b49bdb7393e821dea8520a3db" resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-3.0.4.tgz#70e941ba742bdd2b49bdb7393e821dea8520a3db"
integrity sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ== 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": "@octokit/core@^4.2.1":
version "4.2.4" version "4.2.4"
resolved "https://registry.yarnpkg.com/@octokit/core/-/core-4.2.4.tgz#d8769ec2b43ff37cc3ea89ec4681a20ba58ef907" resolved "https://registry.yarnpkg.com/@octokit/core/-/core-4.2.4.tgz#d8769ec2b43ff37cc3ea89ec4681a20ba58ef907"
@ -2317,6 +2393,19 @@
before-after-hook "^2.2.0" before-after-hook "^2.2.0"
universal-user-agent "^6.0.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": "@octokit/endpoint@^7.0.0":
version "7.0.6" version "7.0.6"
resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-7.0.6.tgz#791f65d3937555141fb6c08f91d618a7d645f1e2" resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-7.0.6.tgz#791f65d3937555141fb6c08f91d618a7d645f1e2"
@ -2326,6 +2415,14 @@
is-plain-object "^5.0.0" is-plain-object "^5.0.0"
universal-user-agent "^6.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": "@octokit/graphql@^5.0.0":
version "5.0.6" version "5.0.6"
resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-5.0.6.tgz#9eac411ac4353ccc5d3fca7d76736e6888c5d248" resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-5.0.6.tgz#9eac411ac4353ccc5d3fca7d76736e6888c5d248"
@ -2335,16 +2432,65 @@
"@octokit/types" "^9.0.0" "@octokit/types" "^9.0.0"
universal-user-agent "^6.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": "@octokit/openapi-types@^18.0.0":
version "18.1.1" version "18.1.1"
resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-18.1.1.tgz#09bdfdabfd8e16d16324326da5148010d765f009" resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-18.1.1.tgz#09bdfdabfd8e16d16324326da5148010d765f009"
integrity sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw== 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": "@octokit/plugin-enterprise-rest@6.0.1":
version "6.0.1" version "6.0.1"
resolved "https://registry.yarnpkg.com/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz#e07896739618dab8da7d4077c658003775f95437" resolved "https://registry.yarnpkg.com/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz#e07896739618dab8da7d4077c658003775f95437"
integrity sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw== 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": "@octokit/plugin-paginate-rest@^6.1.2":
version "6.1.2" version "6.1.2"
resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz#f86456a7a1fe9e58fec6385a85cf1b34072341f8" 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/tsconfig" "^1.0.2"
"@octokit/types" "^9.2.3" "@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": "@octokit/plugin-request-log@^1.0.4":
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz#5e50ed7083a613816b1e4a28aeec5fb7f1462e85" resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz#5e50ed7083a613816b1e4a28aeec5fb7f1462e85"
integrity sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA== 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": "@octokit/plugin-rest-endpoint-methods@^7.1.2":
version "7.2.3" version "7.2.3"
resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.2.3.tgz#37a84b171a6cb6658816c82c4082ac3512021797" resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.2.3.tgz#37a84b171a6cb6658816c82c4082ac3512021797"
@ -2365,6 +2525,23 @@
dependencies: dependencies:
"@octokit/types" "^10.0.0" "@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": "@octokit/request-error@^3.0.0":
version "3.0.3" version "3.0.3"
resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-3.0.3.tgz#ef3dd08b8e964e53e55d471acfe00baa892b9c69" resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-3.0.3.tgz#ef3dd08b8e964e53e55d471acfe00baa892b9c69"
@ -2374,6 +2551,15 @@
deprecation "^2.0.0" deprecation "^2.0.0"
once "^1.4.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": "@octokit/request@^6.0.0":
version "6.2.8" version "6.2.8"
resolved "https://registry.yarnpkg.com/@octokit/request/-/request-6.2.8.tgz#aaf480b32ab2b210e9dadd8271d187c93171d8eb" resolved "https://registry.yarnpkg.com/@octokit/request/-/request-6.2.8.tgz#aaf480b32ab2b210e9dadd8271d187c93171d8eb"
@ -2386,6 +2572,16 @@
node-fetch "^2.6.7" node-fetch "^2.6.7"
universal-user-agent "^6.0.0" 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": "@octokit/rest@19.0.11":
version "19.0.11" version "19.0.11"
resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-19.0.11.tgz#2ae01634fed4bd1fca5b642767205ed3fd36177c" resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-19.0.11.tgz#2ae01634fed4bd1fca5b642767205ed3fd36177c"
@ -2408,6 +2604,13 @@
dependencies: dependencies:
"@octokit/openapi-types" "^18.0.0" "@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": "@octokit/types@^9.0.0", "@octokit/types@^9.2.3":
version "9.3.2" version "9.3.2"
resolved "https://registry.yarnpkg.com/@octokit/types/-/types-9.3.2.tgz#3f5f89903b69f6a2d196d78ec35f888c0013cac5" resolved "https://registry.yarnpkg.com/@octokit/types/-/types-9.3.2.tgz#3f5f89903b69f6a2d196d78ec35f888c0013cac5"
@ -2415,6 +2618,26 @@
dependencies: dependencies:
"@octokit/openapi-types" "^18.0.0" "@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": "@pkgjs/parseargs@^0.11.0":
version "0.11.0" version "0.11.0"
resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" 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" resolved "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz"
integrity sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw== 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": "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14":
version "7.20.5" version "7.20.5"
resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz" resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz"
@ -2884,6 +3112,11 @@
dependencies: dependencies:
"@types/node" "*" "@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": "@types/connect-history-api-fallback@^1.3.5":
version "1.5.4" version "1.5.4"
resolved "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz" resolved "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz"
@ -3052,6 +3285,13 @@
dependencies: dependencies:
"@types/node" "*" "@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": "@types/long@^4.0.0":
version "4.0.2" version "4.0.2"
resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a"
@ -3954,7 +4194,7 @@ agentkeepalive@^4.2.1:
dependencies: dependencies:
humanize-ms "^1.2.1" humanize-ms "^1.2.1"
aggregate-error@^3.0.0: aggregate-error@^3.0.0, aggregate-error@^3.1.0:
version "3.1.0" version "3.1.0"
resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a"
integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== 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" resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz"
integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== 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: bplist-parser@^0.2.0:
version "0.2.0" version "0.2.0"
resolved "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz" resolved "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz"
@ -4737,6 +4982,16 @@ bser@2.1.1:
dependencies: dependencies:
node-int64 "^0.4.0" 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: buffer-from@^1.0.0:
version "1.1.2" version "1.1.2"
resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" 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" resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz"
integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==
deprecation@^2.0.0: deprecation@^2.0.0, deprecation@^2.3.1:
version "2.3.1" version "2.3.1"
resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919"
integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==
@ -6153,6 +6408,13 @@ eastasianwidth@^0.2.0:
resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== 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: ee-first@1.1.1:
version "1.1.1" version "1.1.1"
resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" 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" resolved "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz"
integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== 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: "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.5:
version "3.3.5" version "3.3.5"
resolved "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz" 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.assign "^4.1.4"
object.values "^1.1.6" 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: keyv@^4.5.3:
version "4.5.4" version "4.5.4"
resolved "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz" 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" resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz"
integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== 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: lodash.ismatch@^4.4.0:
version "4.4.0" version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37"
integrity sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g== 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: lodash.memoize@^4.1.2:
version "4.1.2" version "4.1.2"
resolved "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz" 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" resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== 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: lodash.sortby@^4.7.0:
version "4.7.0" version "4.7.0"
resolved "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz" 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" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.13.1.tgz#267a81fbd0881327c46a81c5922606a2cfe336c4"
integrity sha512-CHqbAq7NFlW3RSnoWXLJBxCWaZVBrfa9UEHId2M3AW8iEBurbqduNexEUCGc3SHc6iCYXNJCDi903LajSVAEPQ== 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: lru-cache@^5.1.1:
version "5.1.1" version "5.1.1"
resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" 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" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89"
integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== 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: luxon@^3.4.4:
version "3.4.4" version "3.4.4"
resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.4.4.tgz#cf20dc27dc532ba41a169c43fdcc0063601577af" 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" resolved "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz"
integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== 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: on-finished@2.4.1:
version "2.4.1" version "2.4.1"
resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" 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" resolved "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz"
integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== 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: react-refresh@^0.11.0:
version "0.11.0" version "0.11.0"
resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz" resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz"
@ -13857,6 +14208,14 @@ unique-string@^2.0.0:
dependencies: dependencies:
crypto-random-string "^2.0.0" 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: universal-user-agent@^6.0.0:
version "6.0.1" version "6.0.1"
resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.1.tgz#15f20f55da3c930c57bddbf1734c6654d5fd35aa" 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" querystringify "^2.1.1"
requires-port "^1.0.0" 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: util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
version "1.0.2" version "1.0.2"
resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"