wip: github integration
This commit is contained in:
parent
57d183d652
commit
941c0ef71e
@ -62,6 +62,8 @@ spec:
|
||||
key: /handy-db
|
||||
- extract:
|
||||
key: /handy-master
|
||||
- extract:
|
||||
key: /handy-github
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
|
@ -11,6 +11,7 @@
|
||||
"dev": "lsof -ti tcp:3005 | xargs kill -9 && tsx --env-file=.env --env-file=.env.dev ./sources/main.ts",
|
||||
"test": "vitest run",
|
||||
"migrate": "dotenv -e .env.dev -- prisma migrate dev",
|
||||
"migrate:reset": "dotenv -e .env.dev -- prisma migrate reset",
|
||||
"generate": "prisma generate",
|
||||
"postinstall": "prisma generate",
|
||||
"db": "docker run -d -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=handy -v $(pwd)/.pgdata:/var/lib/postgresql/data -p 5432:5432 postgres",
|
||||
@ -43,6 +44,7 @@
|
||||
"fastify-type-provider-zod": "^4.0.2",
|
||||
"ioredis": "^5.6.1",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"octokit": "^5.0.3",
|
||||
"pino-pretty": "^13.0.0",
|
||||
"prisma": "^6.11.1",
|
||||
"prisma-json-types-generator": "^3.5.1",
|
||||
|
@ -0,0 +1,26 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Account" ADD COLUMN "githubUserId" TEXT;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "GithubUser" (
|
||||
"id" TEXT NOT NULL,
|
||||
"profile" JSONB NOT NULL,
|
||||
"token" BYTEA,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "GithubUser_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "GithubOrganization" (
|
||||
"id" TEXT NOT NULL,
|
||||
"profile" JSONB NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "GithubOrganization_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Account" ADD CONSTRAINT "Account_githubUserId_fkey" FOREIGN KEY ("githubUserId") REFERENCES "GithubUser"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
@ -20,13 +20,16 @@ datasource db {
|
||||
//
|
||||
|
||||
model Account {
|
||||
id String @id @default(cuid())
|
||||
publicKey String @unique
|
||||
seq Int @default(0)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
settings String?
|
||||
settingsVersion Int @default(0)
|
||||
id String @id @default(cuid())
|
||||
publicKey String @unique
|
||||
seq Int @default(0)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
settings String?
|
||||
settingsVersion Int @default(0)
|
||||
githubUserId String?
|
||||
githubUser GithubUser? @relation(fields: [githubUserId], references: [id])
|
||||
|
||||
Session Session[]
|
||||
AccountPushToken AccountPushToken[]
|
||||
TerminalAuthRequest TerminalAuthRequest[]
|
||||
@ -106,6 +109,28 @@ model SessionMessage {
|
||||
@@index([sessionId, seq])
|
||||
}
|
||||
|
||||
//
|
||||
// Github
|
||||
//
|
||||
|
||||
model GithubUser {
|
||||
id String @id
|
||||
/// [GitHubProfile]
|
||||
profile Json
|
||||
token Bytes?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
Account Account[]
|
||||
}
|
||||
|
||||
model GithubOrganization {
|
||||
id String @id
|
||||
/// [GitHubOrg]
|
||||
profile Json
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
//
|
||||
// Utility
|
||||
//
|
||||
|
@ -12,11 +12,11 @@ import { allocateSessionSeq, allocateUserSeq } from "@/services/seq";
|
||||
import { randomKeyNaked } from "@/utils/randomKeyNaked";
|
||||
import { AsyncLock } from "@/utils/lock";
|
||||
import { auth } from "@/modules/auth";
|
||||
import {
|
||||
EventRouter,
|
||||
ClientConnection,
|
||||
SessionScopedConnection,
|
||||
UserScopedConnection,
|
||||
import {
|
||||
EventRouter,
|
||||
ClientConnection,
|
||||
SessionScopedConnection,
|
||||
UserScopedConnection,
|
||||
MachineScopedConnection,
|
||||
RecipientFilter,
|
||||
buildNewSessionUpdate,
|
||||
@ -29,16 +29,18 @@ import {
|
||||
buildUsageEphemeral,
|
||||
buildMachineStatusEphemeral
|
||||
} from "@/modules/eventRouter";
|
||||
import {
|
||||
incrementWebSocketConnection,
|
||||
decrementWebSocketConnection,
|
||||
sessionAliveEventsCounter,
|
||||
import {
|
||||
incrementWebSocketConnection,
|
||||
decrementWebSocketConnection,
|
||||
sessionAliveEventsCounter,
|
||||
machineAliveEventsCounter,
|
||||
websocketEventsCounter,
|
||||
httpRequestsCounter,
|
||||
httpRequestDurationHistogram
|
||||
} from "@/modules/metrics";
|
||||
import { activityCache } from "@/modules/sessionCache";
|
||||
import { encryptBytes, encryptString } from "@/modules/encrypt";
|
||||
import { GitHubProfile } from "./types";
|
||||
|
||||
|
||||
declare module 'fastify' {
|
||||
@ -88,7 +90,7 @@ export async function startApi(): Promise<{ app: FastifyInstance; io: Server }>
|
||||
|
||||
// Increment request counter
|
||||
httpRequestsCounter.inc({ method, route, status });
|
||||
|
||||
|
||||
// Record request duration
|
||||
httpRequestDurationHistogram.observe({ method, route, status }, duration);
|
||||
});
|
||||
@ -239,6 +241,143 @@ export async function startApi(): Promise<{ app: FastifyInstance; io: Server }>
|
||||
return reply.send({ success: true });
|
||||
});
|
||||
|
||||
// GitHub OAuth parameters
|
||||
typed.get('/v1/connect/github/params', {
|
||||
preHandler: app.authenticate,
|
||||
schema: {
|
||||
response: {
|
||||
200: z.object({
|
||||
url: z.string()
|
||||
}),
|
||||
400: z.object({
|
||||
error: z.string()
|
||||
}),
|
||||
500: z.object({
|
||||
error: z.string()
|
||||
})
|
||||
}
|
||||
}
|
||||
}, async (request, reply) => {
|
||||
const clientId = process.env.GITHUB_CLIENT_ID;
|
||||
const redirectUri = process.env.GITHUB_REDIRECT_URL;
|
||||
|
||||
if (!clientId || !redirectUri) {
|
||||
return reply.code(400).send({ error: 'GitHub OAuth not configured' });
|
||||
}
|
||||
|
||||
// Generate ephemeral state token (5 minutes TTL)
|
||||
const state = await auth.createGithubToken(request.userId);
|
||||
|
||||
// Build complete OAuth URL
|
||||
const params = new URLSearchParams({
|
||||
client_id: clientId,
|
||||
redirect_uri: redirectUri,
|
||||
scope: 'user',
|
||||
state: state
|
||||
});
|
||||
|
||||
const url = `https://github.com/login/oauth/authorize?${params.toString()}`;
|
||||
|
||||
return reply.send({ url });
|
||||
});
|
||||
|
||||
// GitHub OAuth callback (GET for redirect from GitHub)
|
||||
typed.get('/v1/connect/github/callback', {
|
||||
schema: {
|
||||
querystring: z.object({
|
||||
code: z.string(),
|
||||
state: z.string()
|
||||
})
|
||||
}
|
||||
}, async (request, reply) => {
|
||||
const { code, state } = request.query;
|
||||
|
||||
// Verify the state token to get userId
|
||||
const tokenData = await auth.verifyGithubToken(state);
|
||||
if (!tokenData) {
|
||||
return reply.redirect('https://app.happy.engineering?error=invalid_state');
|
||||
}
|
||||
|
||||
const userId = tokenData.userId;
|
||||
const clientId = process.env.GITHUB_CLIENT_ID;
|
||||
const clientSecret = process.env.GITHUB_CLIENT_SECRET;
|
||||
|
||||
if (!clientId || !clientSecret) {
|
||||
return reply.redirect('https://app.happy.engineering?error=server_config');
|
||||
}
|
||||
|
||||
try {
|
||||
// Exchange code for access token
|
||||
const tokenResponse = await fetch('https://github.com/login/oauth/access_token', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
client_id: clientId,
|
||||
client_secret: clientSecret,
|
||||
code: code
|
||||
})
|
||||
});
|
||||
|
||||
const tokenResponseData = await tokenResponse.json() as {
|
||||
access_token?: string;
|
||||
error?: string;
|
||||
error_description?: string;
|
||||
};
|
||||
|
||||
if (tokenResponseData.error) {
|
||||
return reply.redirect(`https://app.happy.engineering?error=${encodeURIComponent(tokenResponseData.error)}`);
|
||||
}
|
||||
|
||||
const accessToken = tokenResponseData.access_token;
|
||||
|
||||
// Get user info from GitHub
|
||||
const userResponse = await fetch('https://api.github.com/user', {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${accessToken}`,
|
||||
'Accept': 'application/vnd.github.v3+json',
|
||||
}
|
||||
});
|
||||
|
||||
const userData = await userResponse.json() as GitHubProfile;
|
||||
|
||||
if (!userResponse.ok) {
|
||||
return reply.redirect('https://app.happy.engineering?error=github_user_fetch_failed');
|
||||
}
|
||||
|
||||
// Store GitHub user and connect to account
|
||||
const githubUser = await db.githubUser.upsert({
|
||||
where: { id: userData.id.toString() },
|
||||
update: {
|
||||
profile: userData,
|
||||
token: encryptString(['user', userId, 'github', 'token'], accessToken!)
|
||||
},
|
||||
create: {
|
||||
id: userData.id.toString(),
|
||||
profile: userData,
|
||||
token: encryptString(['user', userId, 'github', 'token'], accessToken!)
|
||||
}
|
||||
});
|
||||
|
||||
// Link GitHub user to account
|
||||
await db.account.update({
|
||||
where: { id: userId },
|
||||
data: { githubUserId: githubUser.id }
|
||||
});
|
||||
|
||||
log({ module: 'github-oauth' }, `GitHub account connected successfully for user ${userId}: ${userData.login}`);
|
||||
|
||||
// Redirect to app with success
|
||||
return reply.redirect(`https://app.happy.engineering?github=connected&user=${encodeURIComponent(userData.login)}`);
|
||||
|
||||
} catch (error) {
|
||||
log({ module: 'github-oauth' }, `Error in GitHub GET callback: ${error}`);
|
||||
return reply.redirect('https://app.happy.engineering?error=server_error');
|
||||
}
|
||||
});
|
||||
|
||||
// Account auth request
|
||||
typed.post('/v1/auth/account/request', {
|
||||
schema: {
|
||||
@ -331,11 +470,11 @@ export async function startApi(): Promise<{ app: FastifyInstance; io: Server }>
|
||||
// Check if OpenAI API key is configured on server
|
||||
const OPENAI_API_KEY = process.env.OPENAI_API_KEY;
|
||||
if (!OPENAI_API_KEY) {
|
||||
return reply.code(500).send({
|
||||
error: 'OpenAI API key not configured on server'
|
||||
return reply.code(500).send({
|
||||
error: 'OpenAI API key not configured on server'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Generate ephemeral token from OpenAI
|
||||
const response = await fetch('https://api.openai.com/v1/realtime/sessions', {
|
||||
method: 'POST',
|
||||
@ -348,11 +487,11 @@ export async function startApi(): Promise<{ app: FastifyInstance; io: Server }>
|
||||
voice: 'verse',
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`OpenAI API error: ${response.status}`);
|
||||
}
|
||||
|
||||
|
||||
const data = await response.json() as {
|
||||
client_secret: {
|
||||
value: string;
|
||||
@ -360,14 +499,14 @@ export async function startApi(): Promise<{ app: FastifyInstance; io: Server }>
|
||||
};
|
||||
id: string;
|
||||
};
|
||||
|
||||
|
||||
return reply.send({
|
||||
token: data.client_secret.value
|
||||
});
|
||||
} catch (error) {
|
||||
log({ module: 'openai', level: 'error' }, 'Failed to generate ephemeral token', error);
|
||||
return reply.code(500).send({
|
||||
error: 'Failed to generate ephemeral token'
|
||||
return reply.code(500).send({
|
||||
error: 'Failed to generate ephemeral token'
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -642,11 +781,11 @@ export async function startApi(): Promise<{ app: FastifyInstance; io: Server }>
|
||||
where: { id: request.userId },
|
||||
select: { settings: true, settingsVersion: true }
|
||||
});
|
||||
|
||||
|
||||
if (!user) {
|
||||
return reply.code(500).send({ error: 'Failed to get account settings' });
|
||||
}
|
||||
|
||||
|
||||
return reply.send({
|
||||
settings: user.settings,
|
||||
settingsVersion: user.settingsVersion
|
||||
@ -690,14 +829,14 @@ export async function startApi(): Promise<{ app: FastifyInstance; io: Server }>
|
||||
where: { id: userId },
|
||||
select: { settings: true, settingsVersion: true }
|
||||
});
|
||||
|
||||
|
||||
if (!currentUser) {
|
||||
return reply.code(500).send({
|
||||
success: false,
|
||||
error: 'Failed to update account settings'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Check current version
|
||||
if (currentUser.settingsVersion !== expectedVersion) {
|
||||
return reply.code(200).send({
|
||||
@ -1270,7 +1409,7 @@ export async function startApi(): Promise<{ app: FastifyInstance; io: Server }>
|
||||
|
||||
socket.on('disconnect', () => {
|
||||
websocketEventsCounter.inc({ event_type: 'disconnect' });
|
||||
|
||||
|
||||
// Cleanup connections
|
||||
eventRouter.removeConnection(userId, connection);
|
||||
decrementWebSocketConnection(connection.connectionType);
|
||||
@ -1319,7 +1458,7 @@ export async function startApi(): Promise<{ app: FastifyInstance; io: Server }>
|
||||
// Track metrics
|
||||
websocketEventsCounter.inc({ event_type: 'session-alive' });
|
||||
sessionAliveEventsCounter.inc();
|
||||
|
||||
|
||||
// Basic validation
|
||||
if (!data || typeof data.time !== 'number' || !data.sid) {
|
||||
return;
|
||||
@ -1364,7 +1503,7 @@ export async function startApi(): Promise<{ app: FastifyInstance; io: Server }>
|
||||
// Track metrics
|
||||
websocketEventsCounter.inc({ event_type: 'machine-alive' });
|
||||
machineAliveEventsCounter.inc();
|
||||
|
||||
|
||||
// Basic validation
|
||||
if (!data || typeof data.time !== 'number' || !data.machineId) {
|
||||
return;
|
||||
|
39
sources/app/types.ts
Normal file
39
sources/app/types.ts
Normal file
@ -0,0 +1,39 @@
|
||||
export interface GitHubProfile {
|
||||
id: number;
|
||||
login: string;
|
||||
type: string;
|
||||
site_admin: boolean;
|
||||
avatar_url: string;
|
||||
gravatar_id: string | null;
|
||||
name: string | null;
|
||||
company: string | null;
|
||||
blog: string | null;
|
||||
location: string | null;
|
||||
email: string | null;
|
||||
hireable: boolean | null;
|
||||
bio: string | null;
|
||||
twitter_username: string | null;
|
||||
public_repos: number;
|
||||
public_gists: number;
|
||||
followers: number;
|
||||
following: number;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
// Private user fields (only available when authenticated)
|
||||
private_gists?: number;
|
||||
total_private_repos?: number;
|
||||
owned_private_repos?: number;
|
||||
disk_usage?: number;
|
||||
collaborators?: number;
|
||||
two_factor_authentication?: boolean;
|
||||
plan?: {
|
||||
collaborators: number;
|
||||
name: string;
|
||||
space: number;
|
||||
private_repos: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface GitHubOrg {
|
||||
|
||||
}
|
8
sources/dbtypes.ts
Normal file
8
sources/dbtypes.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { GitHubProfile as GitHubProfileType, GitHubOrg as GitHubOrgType } from "./app/types";
|
||||
|
||||
declare global {
|
||||
namespace PrismaJson {
|
||||
type GitHubProfile = GitHubProfileType;
|
||||
type GitHubOrg = GitHubOrgType;
|
||||
}
|
||||
}
|
@ -8,6 +8,8 @@ import { startMetricsServer } from "@/app/metrics";
|
||||
import { activityCache } from "@/modules/sessionCache";
|
||||
import { auth } from "./modules/auth";
|
||||
import { startDatabaseMetricsUpdater } from "@/modules/metrics";
|
||||
import { initEncrypt } from "./modules/encrypt";
|
||||
import { initGithub } from "./modules/github";
|
||||
|
||||
async function main() {
|
||||
|
||||
@ -22,6 +24,8 @@ async function main() {
|
||||
await redis.ping();
|
||||
|
||||
// Initialize auth module
|
||||
await initEncrypt();
|
||||
await initGithub();
|
||||
await auth.init();
|
||||
|
||||
//
|
||||
|
@ -10,6 +10,8 @@ interface TokenCacheEntry {
|
||||
interface AuthTokens {
|
||||
generator: Awaited<ReturnType<typeof privacyKit.createPersistentTokenGenerator>>;
|
||||
verifier: Awaited<ReturnType<typeof privacyKit.createPersistentTokenVerifier>>;
|
||||
githubVerifier: Awaited<ReturnType<typeof privacyKit.createEphemeralTokenVerifier>>;
|
||||
githubGenerator: Awaited<ReturnType<typeof privacyKit.createEphemeralTokenGenerator>>;
|
||||
}
|
||||
|
||||
class AuthModule {
|
||||
@ -27,13 +29,25 @@ class AuthModule {
|
||||
service: 'handy',
|
||||
seed: process.env.HANDY_MASTER_SECRET!
|
||||
});
|
||||
|
||||
|
||||
const verifier = await privacyKit.createPersistentTokenVerifier({
|
||||
service: 'handy',
|
||||
publicKey: generator.publicKey
|
||||
});
|
||||
|
||||
this.tokens = { generator, verifier };
|
||||
|
||||
const githubVerifier = await privacyKit.createEphemeralTokenVerifier({
|
||||
service: 'github-happy',
|
||||
publicKey: generator.publicKey,
|
||||
});
|
||||
|
||||
const githubGenerator = await privacyKit.createEphemeralTokenGenerator({
|
||||
service: 'github-happy',
|
||||
seed: process.env.HANDY_MASTER_SECRET!,
|
||||
ttl: 5 * 60 * 1000 // 5 minutes
|
||||
});
|
||||
|
||||
this.tokens = { generator, verifier, githubVerifier, githubGenerator };
|
||||
|
||||
log({ module: 'auth' }, 'Auth module initialized');
|
||||
}
|
||||
@ -133,6 +147,35 @@ class AuthModule {
|
||||
};
|
||||
}
|
||||
|
||||
async createGithubToken(userId: string): Promise<string> {
|
||||
if (!this.tokens) {
|
||||
throw new Error('Auth module not initialized');
|
||||
}
|
||||
|
||||
const payload = { user: userId, purpose: 'github-oauth' };
|
||||
const token = await this.tokens.githubGenerator.new(payload);
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
async verifyGithubToken(token: string): Promise<{ userId: string } | null> {
|
||||
if (!this.tokens) {
|
||||
throw new Error('Auth module not initialized');
|
||||
}
|
||||
|
||||
try {
|
||||
const verified = await this.tokens.githubVerifier.verify(token);
|
||||
if (!verified) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return { userId: verified.user as string };
|
||||
} catch (error) {
|
||||
log({ module: 'auth', level: 'error' }, `GitHub token verification failed: ${error}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup old entries (optional - can be called periodically)
|
||||
cleanup(): void {
|
||||
// Note: Since tokens are cached "forever" as requested,
|
||||
|
26
sources/modules/encrypt.ts
Normal file
26
sources/modules/encrypt.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { KeyTree, crypto } from "privacy-kit";
|
||||
|
||||
let keyTree: KeyTree | null = null;
|
||||
|
||||
export async function initEncrypt() {
|
||||
keyTree = new KeyTree(await crypto.deriveSecureKey({
|
||||
key: process.env.HANDY_MASTER_SECRET!,
|
||||
usage: 'happy-server-tokens'
|
||||
}));
|
||||
}
|
||||
|
||||
export function encryptString(path: string[], string: string) {
|
||||
return keyTree!.symmetricEncrypt(path, string);
|
||||
}
|
||||
|
||||
export function encryptBytes(path: string[], bytes: Uint8Array) {
|
||||
return keyTree!.symmetricEncrypt(path, bytes);
|
||||
}
|
||||
|
||||
export function decryptString(path: string[], encrypted: Uint8Array) {
|
||||
return keyTree!.symmetricDecryptBuffer(path, encrypted);
|
||||
}
|
||||
|
||||
export function decryptBytes(path: string[], encrypted: Uint8Array) {
|
||||
return keyTree!.symmetricDecryptBuffer(path, encrypted);
|
||||
}
|
19
sources/modules/github.ts
Normal file
19
sources/modules/github.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { App } from "octokit";
|
||||
|
||||
let app: App | null = null;
|
||||
|
||||
export async function initGithub() {
|
||||
if (
|
||||
process.env.GITHUB_APP_ID &&
|
||||
process.env.GITHUB_PRIVATE_KEY &&
|
||||
process.env.GITHUB_CLIENT_ID &&
|
||||
process.env.GITHUB_CLIENT_SECRET &&
|
||||
process.env.GITHUB_REDIRECT_URL &&
|
||||
process.env.GITHUB_WEBHOOK_SECRET
|
||||
) {
|
||||
app = new App({
|
||||
appId: process.env.GITHUB_APP_ID,
|
||||
privateKey: process.env.GITHUB_PRIVATE_KEY,
|
||||
});
|
||||
}
|
||||
}
|
263
yarn.lock
263
yarn.lock
@ -381,6 +381,222 @@
|
||||
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.8.0.tgz#cee43d801fcef9644b11b8194857695acd5f815a"
|
||||
integrity sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==
|
||||
|
||||
"@octokit/app@^16.0.1":
|
||||
version "16.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/app/-/app-16.1.0.tgz#e0d7472fc2e7ae7b0ab3f1e4cca8c2aba5f052ad"
|
||||
integrity sha512-OdKHnm0CYLk8Setr47CATT4YnRTvWkpTYvE+B/l2B0mjszlfOIit3wqPHVslD2jfc1bD4UbO7Mzh6gjCuMZKsA==
|
||||
dependencies:
|
||||
"@octokit/auth-app" "^8.1.0"
|
||||
"@octokit/auth-unauthenticated" "^7.0.1"
|
||||
"@octokit/core" "^7.0.2"
|
||||
"@octokit/oauth-app" "^8.0.1"
|
||||
"@octokit/plugin-paginate-rest" "^13.0.0"
|
||||
"@octokit/types" "^14.0.0"
|
||||
"@octokit/webhooks" "^14.0.0"
|
||||
|
||||
"@octokit/auth-app@^8.1.0":
|
||||
version "8.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/auth-app/-/auth-app-8.1.0.tgz#19dacfe49ea62a1f40189ac222925e8a757b6a7c"
|
||||
integrity sha512-6bWhyvLXqCSfHiqlwzn9pScLZ+Qnvh/681GR/UEEPCMIVwfpRDBw0cCzy3/t2Dq8B7W2X/8pBgmw6MOiyE0DXQ==
|
||||
dependencies:
|
||||
"@octokit/auth-oauth-app" "^9.0.1"
|
||||
"@octokit/auth-oauth-user" "^6.0.0"
|
||||
"@octokit/request" "^10.0.2"
|
||||
"@octokit/request-error" "^7.0.0"
|
||||
"@octokit/types" "^14.0.0"
|
||||
toad-cache "^3.7.0"
|
||||
universal-github-app-jwt "^2.2.0"
|
||||
universal-user-agent "^7.0.0"
|
||||
|
||||
"@octokit/auth-oauth-app@^9.0.1":
|
||||
version "9.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/auth-oauth-app/-/auth-oauth-app-9.0.1.tgz#d8d2e950c95e9fcbe6f2fb98d4539ee8c9871766"
|
||||
integrity sha512-TthWzYxuHKLAbmxdFZwFlmwVyvynpyPmjwc+2/cI3cvbT7mHtsAW9b1LvQaNnAuWL+pFnqtxdmrU8QpF633i1g==
|
||||
dependencies:
|
||||
"@octokit/auth-oauth-device" "^8.0.1"
|
||||
"@octokit/auth-oauth-user" "^6.0.0"
|
||||
"@octokit/request" "^10.0.2"
|
||||
"@octokit/types" "^14.0.0"
|
||||
universal-user-agent "^7.0.0"
|
||||
|
||||
"@octokit/auth-oauth-device@^8.0.1":
|
||||
version "8.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/auth-oauth-device/-/auth-oauth-device-8.0.1.tgz#232ec13e299dd6bf199fe237527d04ec12decffb"
|
||||
integrity sha512-TOqId/+am5yk9zor0RGibmlqn4V0h8vzjxlw/wYr3qzkQxl8aBPur384D1EyHtqvfz0syeXji4OUvKkHvxk/Gw==
|
||||
dependencies:
|
||||
"@octokit/oauth-methods" "^6.0.0"
|
||||
"@octokit/request" "^10.0.2"
|
||||
"@octokit/types" "^14.0.0"
|
||||
universal-user-agent "^7.0.0"
|
||||
|
||||
"@octokit/auth-oauth-user@^6.0.0":
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/auth-oauth-user/-/auth-oauth-user-6.0.0.tgz#ba643060824536cd848c72d835061b1c00007286"
|
||||
integrity sha512-GV9IW134PHsLhtUad21WIeP9mlJ+QNpFd6V9vuPWmaiN25HEJeEQUcS4y5oRuqCm9iWDLtfIs+9K8uczBXKr6A==
|
||||
dependencies:
|
||||
"@octokit/auth-oauth-device" "^8.0.1"
|
||||
"@octokit/oauth-methods" "^6.0.0"
|
||||
"@octokit/request" "^10.0.2"
|
||||
"@octokit/types" "^14.0.0"
|
||||
universal-user-agent "^7.0.0"
|
||||
|
||||
"@octokit/auth-token@^6.0.0":
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-6.0.0.tgz#b02e9c08a2d8937df09a2a981f226ad219174c53"
|
||||
integrity sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==
|
||||
|
||||
"@octokit/auth-unauthenticated@^7.0.1":
|
||||
version "7.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/auth-unauthenticated/-/auth-unauthenticated-7.0.1.tgz#427b8a52e672318f84757307e766a448c741116b"
|
||||
integrity sha512-qVq1vdjLLZdE8kH2vDycNNjuJRCD1q2oet1nA/GXWaYlpDxlR7rdVhX/K/oszXslXiQIiqrQf+rdhDlA99JdTQ==
|
||||
dependencies:
|
||||
"@octokit/request-error" "^7.0.0"
|
||||
"@octokit/types" "^14.0.0"
|
||||
|
||||
"@octokit/core@^7.0.2":
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/core/-/core-7.0.3.tgz#0b5288995fed66920128d41cfeea34979d48a360"
|
||||
integrity sha512-oNXsh2ywth5aowwIa7RKtawnkdH6LgU1ztfP9AIUCQCvzysB+WeU8o2kyyosDPwBZutPpjZDKPQGIzzrfTWweQ==
|
||||
dependencies:
|
||||
"@octokit/auth-token" "^6.0.0"
|
||||
"@octokit/graphql" "^9.0.1"
|
||||
"@octokit/request" "^10.0.2"
|
||||
"@octokit/request-error" "^7.0.0"
|
||||
"@octokit/types" "^14.0.0"
|
||||
before-after-hook "^4.0.0"
|
||||
universal-user-agent "^7.0.0"
|
||||
|
||||
"@octokit/endpoint@^11.0.0":
|
||||
version "11.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-11.0.0.tgz#189fcc022721b4c49d0307eea6be3de1cfb53026"
|
||||
integrity sha512-hoYicJZaqISMAI3JfaDr1qMNi48OctWuOih1m80bkYow/ayPw6Jj52tqWJ6GEoFTk1gBqfanSoI1iY99Z5+ekQ==
|
||||
dependencies:
|
||||
"@octokit/types" "^14.0.0"
|
||||
universal-user-agent "^7.0.2"
|
||||
|
||||
"@octokit/graphql@^9.0.1":
|
||||
version "9.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-9.0.1.tgz#eb258fc9981403d2d751720832652c385b6c1613"
|
||||
integrity sha512-j1nQNU1ZxNFx2ZtKmL4sMrs4egy5h65OMDmSbVyuCzjOcwsHq6EaYjOTGXPQxgfiN8dJ4CriYHk6zF050WEULg==
|
||||
dependencies:
|
||||
"@octokit/request" "^10.0.2"
|
||||
"@octokit/types" "^14.0.0"
|
||||
universal-user-agent "^7.0.0"
|
||||
|
||||
"@octokit/oauth-app@^8.0.1":
|
||||
version "8.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/oauth-app/-/oauth-app-8.0.1.tgz#7cb889945c3ccacfd0ff9aa9f05e9748b439f7f3"
|
||||
integrity sha512-QnhMYEQpnYbEPn9cae+wXL2LuPMFglmfeuDJXXsyxIXdoORwkLK8y0cHhd/5du9MbO/zdG/BXixzB7EEwU63eQ==
|
||||
dependencies:
|
||||
"@octokit/auth-oauth-app" "^9.0.1"
|
||||
"@octokit/auth-oauth-user" "^6.0.0"
|
||||
"@octokit/auth-unauthenticated" "^7.0.1"
|
||||
"@octokit/core" "^7.0.2"
|
||||
"@octokit/oauth-authorization-url" "^8.0.0"
|
||||
"@octokit/oauth-methods" "^6.0.0"
|
||||
"@types/aws-lambda" "^8.10.83"
|
||||
universal-user-agent "^7.0.0"
|
||||
|
||||
"@octokit/oauth-authorization-url@^8.0.0":
|
||||
version "8.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/oauth-authorization-url/-/oauth-authorization-url-8.0.0.tgz#fdbab39a07d38faaad8621a5fdf04bc0c36d63e7"
|
||||
integrity sha512-7QoLPRh/ssEA/HuHBHdVdSgF8xNLz/Bc5m9fZkArJE5bb6NmVkDm3anKxXPmN1zh6b5WKZPRr3697xKT/yM3qQ==
|
||||
|
||||
"@octokit/oauth-methods@^6.0.0":
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/oauth-methods/-/oauth-methods-6.0.0.tgz#a138bbbec6762b52249f7c47d0c548fc1cf6ad7b"
|
||||
integrity sha512-Q8nFIagNLIZgM2odAraelMcDssapc+lF+y3OlcIPxyAU+knefO8KmozGqfnma1xegRDP4z5M73ABsamn72bOcA==
|
||||
dependencies:
|
||||
"@octokit/oauth-authorization-url" "^8.0.0"
|
||||
"@octokit/request" "^10.0.2"
|
||||
"@octokit/request-error" "^7.0.0"
|
||||
"@octokit/types" "^14.0.0"
|
||||
|
||||
"@octokit/openapi-types@^25.1.0":
|
||||
version "25.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-25.1.0.tgz#5a72a9dfaaba72b5b7db375fd05e90ca90dc9682"
|
||||
integrity sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA==
|
||||
|
||||
"@octokit/openapi-webhooks-types@12.0.3":
|
||||
version "12.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/openapi-webhooks-types/-/openapi-webhooks-types-12.0.3.tgz#fa44fb31fbb4c444c5fd640dbbf537f00c20617c"
|
||||
integrity sha512-90MF5LVHjBedwoHyJsgmaFhEN1uzXyBDRLEBe7jlTYx/fEhPAk3P3DAJsfZwC54m8hAIryosJOL+UuZHB3K3yA==
|
||||
|
||||
"@octokit/plugin-paginate-graphql@^6.0.0":
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-graphql/-/plugin-paginate-graphql-6.0.0.tgz#acdefd7e85ce24716e7ad7352f2df4d29d0e273b"
|
||||
integrity sha512-crfpnIoFiBtRkvPqOyLOsw12XsveYuY2ieP6uYDosoUegBJpSVxGwut9sxUgFFcll3VTOTqpUf8yGd8x1OmAkQ==
|
||||
|
||||
"@octokit/plugin-paginate-rest@^13.0.0":
|
||||
version "13.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-13.1.1.tgz#ca5bb1c7b85a583691263c1f788f607e9bcb74b3"
|
||||
integrity sha512-q9iQGlZlxAVNRN2jDNskJW/Cafy7/XE52wjZ5TTvyhyOD904Cvx//DNyoO3J/MXJ0ve3rPoNWKEg5iZrisQSuw==
|
||||
dependencies:
|
||||
"@octokit/types" "^14.1.0"
|
||||
|
||||
"@octokit/plugin-rest-endpoint-methods@^16.0.0":
|
||||
version "16.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-16.0.0.tgz#ba30ca387fc2ac8bd93cf9f951174736babebd97"
|
||||
integrity sha512-kJVUQk6/dx/gRNLWUnAWKFs1kVPn5O5CYZyssyEoNYaFedqZxsfYs7DwI3d67hGz4qOwaJ1dpm07hOAD1BXx6g==
|
||||
dependencies:
|
||||
"@octokit/types" "^14.1.0"
|
||||
|
||||
"@octokit/plugin-retry@^8.0.1":
|
||||
version "8.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/plugin-retry/-/plugin-retry-8.0.1.tgz#ee4a0487d31b97ad3deaf737faad68abeca3c227"
|
||||
integrity sha512-KUoYR77BjF5O3zcwDQHRRZsUvJwepobeqiSSdCJ8lWt27FZExzb0GgVxrhhfuyF6z2B2zpO0hN5pteni1sqWiw==
|
||||
dependencies:
|
||||
"@octokit/request-error" "^7.0.0"
|
||||
"@octokit/types" "^14.0.0"
|
||||
bottleneck "^2.15.3"
|
||||
|
||||
"@octokit/plugin-throttling@^11.0.1":
|
||||
version "11.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/plugin-throttling/-/plugin-throttling-11.0.1.tgz#31a0b5e759f0313514d9522a4103360f17ffc2e4"
|
||||
integrity sha512-S+EVhy52D/272L7up58dr3FNSMXWuNZolkL4zMJBNIfIxyZuUcczsQAU4b5w6dewJXnKYVgSHSV5wxitMSW1kw==
|
||||
dependencies:
|
||||
"@octokit/types" "^14.0.0"
|
||||
bottleneck "^2.15.3"
|
||||
|
||||
"@octokit/request-error@^7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-7.0.0.tgz#48ae2cd79008315605d00e83664891a10a5ddb97"
|
||||
integrity sha512-KRA7VTGdVyJlh0cP5Tf94hTiYVVqmt2f3I6mnimmaVz4UG3gQV/k4mDJlJv3X67iX6rmN7gSHCF8ssqeMnmhZg==
|
||||
dependencies:
|
||||
"@octokit/types" "^14.0.0"
|
||||
|
||||
"@octokit/request@^10.0.2":
|
||||
version "10.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/request/-/request-10.0.3.tgz#2ffdb88105ce20d25dcab8a592a7040ea48306c7"
|
||||
integrity sha512-V6jhKokg35vk098iBqp2FBKunk3kMTXlmq+PtbV9Gl3TfskWlebSofU9uunVKhUN7xl+0+i5vt0TGTG8/p/7HA==
|
||||
dependencies:
|
||||
"@octokit/endpoint" "^11.0.0"
|
||||
"@octokit/request-error" "^7.0.0"
|
||||
"@octokit/types" "^14.0.0"
|
||||
fast-content-type-parse "^3.0.0"
|
||||
universal-user-agent "^7.0.2"
|
||||
|
||||
"@octokit/types@^14.0.0", "@octokit/types@^14.1.0":
|
||||
version "14.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/types/-/types-14.1.0.tgz#3bf9b3a3e3b5270964a57cc9d98592ed44f840f2"
|
||||
integrity sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==
|
||||
dependencies:
|
||||
"@octokit/openapi-types" "^25.1.0"
|
||||
|
||||
"@octokit/webhooks-methods@^6.0.0":
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/webhooks-methods/-/webhooks-methods-6.0.0.tgz#34abf78aec6f826fe561cfe79d2ebb1950d1d25f"
|
||||
integrity sha512-MFlzzoDJVw/GcbfzVC1RLR36QqkTLUf79vLVO3D+xn7r0QgxnFoLZgtrzxiQErAjFUOdH6fas2KeQJ1yr/qaXQ==
|
||||
|
||||
"@octokit/webhooks@^14.0.0":
|
||||
version "14.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/webhooks/-/webhooks-14.1.3.tgz#2d0bed71b07745c0b33363d69e0ae0e440469a18"
|
||||
integrity sha512-gcK4FNaROM9NjA0mvyfXl0KPusk7a1BeA8ITlYEZVQCXF5gcETTd4yhAU0Kjzd8mXwYHppzJBWgdBVpIR9wUcQ==
|
||||
dependencies:
|
||||
"@octokit/openapi-webhooks-types" "12.0.3"
|
||||
"@octokit/request-error" "^7.0.0"
|
||||
"@octokit/webhooks-methods" "^6.0.0"
|
||||
|
||||
"@opentelemetry/api@^1.4.0":
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.9.0.tgz#d03eba68273dc0f7509e2a3d5cba21eae10379fe"
|
||||
@ -719,6 +935,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9"
|
||||
integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==
|
||||
|
||||
"@types/aws-lambda@^8.10.83":
|
||||
version "8.10.152"
|
||||
resolved "https://registry.yarnpkg.com/@types/aws-lambda/-/aws-lambda-8.10.152.tgz#f68424a8175f0a54a2a941e65b76c3f51f3bd89d"
|
||||
integrity sha512-soT/c2gYBnT5ygwiHPmd9a1bftj462NWVk2tKCc1PYHSIacB2UwbTS2zYG4jzag1mRDuzg/OjtxQjQ2NKRB6Rw==
|
||||
|
||||
"@types/body-parser@*":
|
||||
version "1.19.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4"
|
||||
@ -1029,11 +1250,21 @@ base64id@2.0.0, base64id@~2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6"
|
||||
integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==
|
||||
|
||||
before-after-hook@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-4.0.0.tgz#cf1447ab9160df6a40f3621da64d6ffc36050cb9"
|
||||
integrity sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==
|
||||
|
||||
bintrees@1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/bintrees/-/bintrees-1.0.2.tgz#49f896d6e858a4a499df85c38fb399b9aff840f8"
|
||||
integrity sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==
|
||||
|
||||
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==
|
||||
|
||||
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"
|
||||
@ -1431,6 +1662,11 @@ expect-type@^1.2.1:
|
||||
resolved "https://registry.yarnpkg.com/expect-type/-/expect-type-1.2.1.tgz#af76d8b357cf5fa76c41c09dafb79c549e75f71f"
|
||||
integrity sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==
|
||||
|
||||
fast-content-type-parse@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz#5590b6c807cc598be125e6740a9fde589d2b7afb"
|
||||
integrity sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==
|
||||
|
||||
fast-copy@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/fast-copy/-/fast-copy-3.0.2.tgz#59c68f59ccbcac82050ba992e0d5c389097c9d35"
|
||||
@ -1903,6 +2139,23 @@ obliterator@^2.0.4:
|
||||
resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-2.0.5.tgz#031e0145354b0c18840336ae51d41e7d6d2c76aa"
|
||||
integrity sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==
|
||||
|
||||
octokit@^5.0.3:
|
||||
version "5.0.3"
|
||||
resolved "https://registry.yarnpkg.com/octokit/-/octokit-5.0.3.tgz#1e4f110e28218ab9676c28da5f28ab403fe5b643"
|
||||
integrity sha512-+bwYsAIRmYv30NTmBysPIlgH23ekVDriB07oRxlPIAH5PI0yTMSxg5i5Xy0OetcnZw+nk/caD4szD7a9YZ3QyQ==
|
||||
dependencies:
|
||||
"@octokit/app" "^16.0.1"
|
||||
"@octokit/core" "^7.0.2"
|
||||
"@octokit/oauth-app" "^8.0.1"
|
||||
"@octokit/plugin-paginate-graphql" "^6.0.0"
|
||||
"@octokit/plugin-paginate-rest" "^13.0.0"
|
||||
"@octokit/plugin-rest-endpoint-methods" "^16.0.0"
|
||||
"@octokit/plugin-retry" "^8.0.1"
|
||||
"@octokit/plugin-throttling" "^11.0.1"
|
||||
"@octokit/request-error" "^7.0.0"
|
||||
"@octokit/types" "^14.0.0"
|
||||
"@octokit/webhooks" "^14.0.0"
|
||||
|
||||
on-exit-leak-free@^2.1.0:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz#fed195c9ebddb7d9e4c3842f93f281ac8dadd3b8"
|
||||
@ -2503,6 +2756,16 @@ undici-types@~7.8.0:
|
||||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.8.0.tgz#de00b85b710c54122e44fbfd911f8d70174cd294"
|
||||
integrity sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==
|
||||
|
||||
universal-github-app-jwt@^2.2.0:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/universal-github-app-jwt/-/universal-github-app-jwt-2.2.2.tgz#38537e5a7d154085a35f97601a5e30e9e17717df"
|
||||
integrity sha512-dcmbeSrOdTnsjGjUfAlqNDJrhxXizjAz94ija9Qw8YkZ1uu0d+GoZzyH+Jb9tIIqvGsadUfwg+22k5aDqqwzbw==
|
||||
|
||||
universal-user-agent@^7.0.0, universal-user-agent@^7.0.2:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-7.0.3.tgz#c05870a58125a2dc00431f2df815a77fe69736be"
|
||||
integrity sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==
|
||||
|
||||
url-join@4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.1.tgz#b642e21a2646808ffa178c4c5fda39844e12cde7"
|
||||
|
Loading…
Reference in New Issue
Block a user