mirror of
https://github.com/SrIzan10/echospace.git
synced 2026-06-06 00:56:54 +00:00
feat: initial github integration
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {
|
const nextConfig = {
|
||||||
webpack: (config) => {
|
webpack: (config) => {
|
||||||
config.externals.push("@node-rs/argon2");
|
config.externals.push('@node-rs/argon2');
|
||||||
return config;
|
return config;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default nextConfig;
|
export default nextConfig;
|
||||||
|
|||||||
@@ -15,16 +15,20 @@
|
|||||||
"@hookform/resolvers": "^3.9.1",
|
"@hookform/resolvers": "^3.9.1",
|
||||||
"@lucia-auth/adapter-prisma": "^4.0.1",
|
"@lucia-auth/adapter-prisma": "^4.0.1",
|
||||||
"@node-rs/argon2": "^2.0.2",
|
"@node-rs/argon2": "^2.0.2",
|
||||||
|
"@octokit/app": "^15.1.1",
|
||||||
"@octokit/core": "^6.1.2",
|
"@octokit/core": "^6.1.2",
|
||||||
"@prisma/client": "^6.0.1",
|
"@prisma/client": "^6.0.1",
|
||||||
"@radix-ui/react-avatar": "^1.0.4",
|
"@radix-ui/react-avatar": "^1.0.4",
|
||||||
|
"@radix-ui/react-dialog": "^1.1.4",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.2",
|
"@radix-ui/react-dropdown-menu": "^2.1.2",
|
||||||
"@radix-ui/react-label": "^2.1.1",
|
"@radix-ui/react-label": "^2.1.1",
|
||||||
|
"@radix-ui/react-popover": "^1.1.4",
|
||||||
"@radix-ui/react-slot": "^1.1.1",
|
"@radix-ui/react-slot": "^1.1.1",
|
||||||
"@radix-ui/react-tabs": "^1.1.2",
|
"@radix-ui/react-tabs": "^1.1.2",
|
||||||
"arctic": "^2.3.1",
|
"arctic": "^2.3.1",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.0",
|
"clsx": "^2.1.0",
|
||||||
|
"cmdk": "1.0.0",
|
||||||
"ioredis": "^5.4.1",
|
"ioredis": "^5.4.1",
|
||||||
"lucia": "^3.1.1",
|
"lucia": "^3.1.1",
|
||||||
"lucide-react": "^0.368.0",
|
"lucide-react": "^0.368.0",
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "User" ADD COLUMN "installations" TEXT[];
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Project" ALTER COLUMN "github" DROP NOT NULL;
|
||||||
@@ -14,11 +14,12 @@ datasource db {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model User {
|
model User {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
githubId String @unique
|
githubId String @unique
|
||||||
username String
|
username String
|
||||||
projects Project[]
|
installations String[]
|
||||||
sessions Session[]
|
projects Project[]
|
||||||
|
sessions Session[]
|
||||||
}
|
}
|
||||||
|
|
||||||
model Session {
|
model Session {
|
||||||
@@ -32,7 +33,7 @@ model Project {
|
|||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
name String
|
name String
|
||||||
description String
|
description String
|
||||||
github String
|
github String?
|
||||||
customData String[]
|
customData String[]
|
||||||
rateLimitReq Int @default(5)
|
rateLimitReq Int @default(5)
|
||||||
rateLimitTime Int @default(60)
|
rateLimitTime Int @default(60)
|
||||||
|
|||||||
@@ -26,14 +26,9 @@ export default function CreateForm() {
|
|||||||
placeholder: 'A developer-centric user feedback platform.',
|
placeholder: 'A developer-centric user feedback platform.',
|
||||||
description: 'Describe the project a bit.',
|
description: 'Describe the project a bit.',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'github',
|
|
||||||
label: 'Github',
|
|
||||||
placeholder: 'https://github.com/SrIzan10/echospace',
|
|
||||||
},
|
|
||||||
]}
|
]}
|
||||||
submitText="Submit"
|
submitText="Submit"
|
||||||
submitClassname="w-full"
|
submitClassname="w-full !mt-5"
|
||||||
onActionComplete={(res) => {
|
onActionComplete={(res) => {
|
||||||
// @ts-ignore yea
|
// @ts-ignore yea
|
||||||
if (res && res.id) {
|
if (res && res.id) {
|
||||||
|
|||||||
@@ -9,6 +9,15 @@ export async function GET(request: Request): Promise<Response> {
|
|||||||
const url = new URL(request.url);
|
const url = new URL(request.url);
|
||||||
const code = url.searchParams.get('code');
|
const code = url.searchParams.get('code');
|
||||||
const state = url.searchParams.get('state');
|
const state = url.searchParams.get('state');
|
||||||
|
const setupAction = url.searchParams.get('setup_action');
|
||||||
|
if (setupAction === 'install') {
|
||||||
|
return new Response(null, {
|
||||||
|
status: 302,
|
||||||
|
headers: {
|
||||||
|
Location: '/',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
const storedState = (await cookies()).get('github_oauth_state')?.value ?? null;
|
const storedState = (await cookies()).get('github_oauth_state')?.value ?? null;
|
||||||
if (!code || !state || !storedState || state !== storedState) {
|
if (!code || !state || !storedState || state !== storedState) {
|
||||||
return new Response(null, {
|
return new Response(null, {
|
||||||
@@ -66,6 +75,7 @@ export async function GET(request: Request): Promise<Response> {
|
|||||||
console.error(e);
|
console.error(e);
|
||||||
if (e instanceof OAuth2RequestError) {
|
if (e instanceof OAuth2RequestError) {
|
||||||
// invalid code
|
// invalid code
|
||||||
|
console.error(e);
|
||||||
return new Response(null, {
|
return new Response(null, {
|
||||||
status: 400,
|
status: 400,
|
||||||
});
|
});
|
||||||
|
|||||||
90
src/app/(public)/auth/github/webhooks/route.ts
Normal file
90
src/app/(public)/auth/github/webhooks/route.ts
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
import { NextResponse } from 'next/server';
|
||||||
|
import crypto from 'crypto';
|
||||||
|
import prisma from '@/lib/db';
|
||||||
|
|
||||||
|
const WEBHOOK_SECRET = process.env.GITHUB_WEBHOOK_SECRET!;
|
||||||
|
|
||||||
|
export async function POST(request: Request) {
|
||||||
|
try {
|
||||||
|
const isValid = await validateRequest(request);
|
||||||
|
if (!isValid) {
|
||||||
|
return NextResponse.json({ error: 'Invalid signature' }, { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const event = request.headers.get('x-github-event');
|
||||||
|
// returns a string if valid, false if not, so we can parse it.
|
||||||
|
const payload = JSON.parse(isValid);
|
||||||
|
|
||||||
|
// handle installation events
|
||||||
|
if (event === 'installation') {
|
||||||
|
switch (payload.action) {
|
||||||
|
case 'created':
|
||||||
|
console.log('New installation:', payload.installation.id);
|
||||||
|
await updateInstallation(payload.sender.id, payload.installation.id);
|
||||||
|
break;
|
||||||
|
case 'deleted':
|
||||||
|
console.log('Installation deleted:', payload.installation.id);
|
||||||
|
await updateInstallation(payload.sender.id, payload.installation.id, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json({ success: true });
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Webhook error:', error);
|
||||||
|
return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function updateInstallation(userId: number, installationId: number, isAdding = true) {
|
||||||
|
const checkUserExists = await prisma.user.findUnique({
|
||||||
|
where: {
|
||||||
|
githubId: userId.toString(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!checkUserExists) return;
|
||||||
|
|
||||||
|
if (isAdding) {
|
||||||
|
await prisma.user.update({
|
||||||
|
where: {
|
||||||
|
githubId: userId.toString(),
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
installations: {
|
||||||
|
push: installationId.toString(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await prisma.user.update({
|
||||||
|
where: {
|
||||||
|
githubId: userId.toString(),
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
installations: {
|
||||||
|
// taking advantage of the prior user request to filter
|
||||||
|
set: checkUserExists.installations.filter((id) => id !== installationId.toString()),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function validateRequest(request: Request) {
|
||||||
|
const headers = request.headers;
|
||||||
|
const signature = headers.get('x-hub-signature-256');
|
||||||
|
const body = await request.text();
|
||||||
|
|
||||||
|
const hmac = crypto.createHmac('sha256', WEBHOOK_SECRET);
|
||||||
|
const digest = 'sha256=' + hmac.update(body).digest('hex');
|
||||||
|
if (
|
||||||
|
!crypto.timingSafeEqual(
|
||||||
|
new Uint8Array(Buffer.from(signature!)),
|
||||||
|
new Uint8Array(Buffer.from(digest))
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return body;
|
||||||
|
}
|
||||||
94
src/components/app/GithubRepoChooser/GithubRepoChooser.tsx
Normal file
94
src/components/app/GithubRepoChooser/GithubRepoChooser.tsx
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import * as React from 'react';
|
||||||
|
import { Check, ChevronsUpDown } from 'lucide-react';
|
||||||
|
|
||||||
|
import { cn } from '@/lib/utils';
|
||||||
|
import { Button } from '@/components/ui/button';
|
||||||
|
import {
|
||||||
|
Command,
|
||||||
|
CommandEmpty,
|
||||||
|
CommandGroup,
|
||||||
|
CommandInput,
|
||||||
|
CommandItem,
|
||||||
|
CommandList,
|
||||||
|
} from '@/components/ui/command';
|
||||||
|
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
|
||||||
|
import { getRepos } from './getRepos';
|
||||||
|
import { set } from 'zod';
|
||||||
|
|
||||||
|
export default function GithubRepoChooser(props: Props) {
|
||||||
|
const [open, setOpen] = React.useState(false);
|
||||||
|
const [value, setValue] = React.useState('');
|
||||||
|
const [repos, setRepos] = React.useState<string[]>([]);
|
||||||
|
const [isLoading, setIsLoading] = React.useState(true);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
setIsLoading(true);
|
||||||
|
getRepos().then((response) => {
|
||||||
|
if (response.success) {
|
||||||
|
setRepos(response.repos!);
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(props.selected);
|
||||||
|
setValue(props.selected ?? '');
|
||||||
|
}, []);
|
||||||
|
React.useEffect(() => {
|
||||||
|
props.onSelect(value);
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [value]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Popover open={open} onOpenChange={setOpen}>
|
||||||
|
<PopoverTrigger asChild>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
role="combobox"
|
||||||
|
aria-expanded={open}
|
||||||
|
className="w-full justify-between"
|
||||||
|
disabled={repos.length === 0}
|
||||||
|
>
|
||||||
|
{/* TODO: refactor whatever this is. */}
|
||||||
|
{isLoading
|
||||||
|
? 'Loading repositories (may take a while)...'
|
||||||
|
: value.length > 0
|
||||||
|
? repos.find((repo) => repo === value)
|
||||||
|
: repos.length === 0
|
||||||
|
? 'No repositories found'
|
||||||
|
: 'Select a repository'}
|
||||||
|
<ChevronsUpDown className="opacity-50 w-4 h-4" />
|
||||||
|
</Button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent className="w-full p-0" side="bottom">
|
||||||
|
<Command>
|
||||||
|
<CommandInput placeholder="Search repository..." />
|
||||||
|
<CommandList>
|
||||||
|
<CommandEmpty>No repos found.</CommandEmpty>
|
||||||
|
<CommandGroup>
|
||||||
|
{repos.map((repo) => (
|
||||||
|
<CommandItem
|
||||||
|
key={repo}
|
||||||
|
value={repo}
|
||||||
|
onSelect={(currentValue) => {
|
||||||
|
console.log(currentValue, value);
|
||||||
|
setValue(currentValue === value ? '' : currentValue);
|
||||||
|
setOpen(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{repo}
|
||||||
|
<Check className={cn('ml-auto', value === repo ? 'opacity-100' : 'opacity-0')} />
|
||||||
|
</CommandItem>
|
||||||
|
))}
|
||||||
|
</CommandGroup>
|
||||||
|
</CommandList>
|
||||||
|
</Command>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
onSelect: (repo: string) => void;
|
||||||
|
selected?: string;
|
||||||
|
}
|
||||||
41
src/components/app/GithubRepoChooser/getRepos.ts
Normal file
41
src/components/app/GithubRepoChooser/getRepos.ts
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
'use server';
|
||||||
|
|
||||||
|
import { validateRequest } from '@/lib/auth';
|
||||||
|
import { octokitApp } from '@/lib/octokitApp';
|
||||||
|
|
||||||
|
export async function getRepos() {
|
||||||
|
const { user } = await validateRequest();
|
||||||
|
if (!user) {
|
||||||
|
return { success: false, error: 'You must be logged in' };
|
||||||
|
}
|
||||||
|
|
||||||
|
const repoList: Array<{ name: string; pushed_at: string }> = [];
|
||||||
|
|
||||||
|
for (const installation of user.installations) {
|
||||||
|
const octokit = await octokitApp.getInstallationOctokit(Number(installation));
|
||||||
|
const { data: repos } = await octokit.request('GET /installation/repositories', {
|
||||||
|
per_page: 100,
|
||||||
|
});
|
||||||
|
if (repos.repositories.length >= 100) {
|
||||||
|
await octokit
|
||||||
|
.request('GET /installation/repositories', {
|
||||||
|
per_page: 100,
|
||||||
|
page: 2,
|
||||||
|
})
|
||||||
|
.then(({ data }) => repos.repositories.push(...data.repositories));
|
||||||
|
}
|
||||||
|
|
||||||
|
const repoData = repos.repositories.map((repo) => ({
|
||||||
|
name: repo.full_name,
|
||||||
|
pushed_at: repo.pushed_at ?? '1970-01-01T00:00:00Z',
|
||||||
|
}));
|
||||||
|
|
||||||
|
repoList.push(...repoData);
|
||||||
|
}
|
||||||
|
|
||||||
|
const sortedRepos = repoList
|
||||||
|
.sort((a, b) => new Date(b.pushed_at).getTime() - new Date(a.pushed_at).getTime())
|
||||||
|
.map((repo) => repo.name);
|
||||||
|
|
||||||
|
return { success: true, repos: sortedRepos };
|
||||||
|
}
|
||||||
@@ -4,7 +4,13 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/com
|
|||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
||||||
import type { Project } from '@prisma/client';
|
import type { Project } from '@prisma/client';
|
||||||
import { UniversalForm } from '../UniversalForm/UniversalForm';
|
import { UniversalForm } from '../UniversalForm/UniversalForm';
|
||||||
import { customData, editProject, ratelimitChange } from '@/lib/forms/actions';
|
import {
|
||||||
|
customData,
|
||||||
|
editProject,
|
||||||
|
githubSettings,
|
||||||
|
githubTestIssue,
|
||||||
|
ratelimitChange,
|
||||||
|
} from '@/lib/forms/actions';
|
||||||
import { bodyGen, bodyGenNoIdent } from '@/lib/bodyGen';
|
import { bodyGen, bodyGenNoIdent } from '@/lib/bodyGen';
|
||||||
import {
|
import {
|
||||||
Breadcrumb,
|
Breadcrumb,
|
||||||
@@ -14,9 +20,16 @@ import {
|
|||||||
BreadcrumbPage,
|
BreadcrumbPage,
|
||||||
BreadcrumbSeparator,
|
BreadcrumbSeparator,
|
||||||
} from '@/components/ui/breadcrumb';
|
} from '@/components/ui/breadcrumb';
|
||||||
|
import GithubRepoChooser from '../GithubRepoChooser/GithubRepoChooser';
|
||||||
|
import React from 'react';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import { useRouter } from 'next/navigation';
|
||||||
|
|
||||||
export default function ProjectSettings(project: Project) {
|
export default function ProjectSettings(project: Project) {
|
||||||
const url = `https://${window.location.hostname}/api/feedback/${project.id}`;
|
const router = useRouter();
|
||||||
|
const [ghRepo, setGhRepo] = React.useState('');
|
||||||
|
const apiUrl = `https://${window.location.hostname}/api/feedback/${project.id}`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full max-w-4xl mx-auto p-4">
|
<div className="w-full max-w-4xl mx-auto p-4">
|
||||||
<Breadcrumb className="pb-5">
|
<Breadcrumb className="pb-5">
|
||||||
@@ -109,8 +122,81 @@ export default function ProjectSettings(project: Project) {
|
|||||||
</div>
|
</div>
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|
||||||
<TabsContent value="github">
|
<TabsContent value="github" className="grid gap-4">
|
||||||
<h2>Soon™</h2>
|
<Card>
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle>GitHub Integration</CardTitle>
|
||||||
|
<CardDescription>Connect your project to GitHub</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<GithubRepoChooser
|
||||||
|
onSelect={(repo) => {
|
||||||
|
setGhRepo(`https://github.com/${repo}`);
|
||||||
|
}}
|
||||||
|
selected={project.github!.replace('https://github.com/', '')}
|
||||||
|
/>
|
||||||
|
<p className="text-muted-foreground text-xs mt-2">
|
||||||
|
Not the results you were expecting? You may have not allowed your user in the{' '}
|
||||||
|
<Link
|
||||||
|
href="https://github.com/apps/echospacedev/installations/new"
|
||||||
|
target="_blank"
|
||||||
|
className="text-primary"
|
||||||
|
>
|
||||||
|
installation settings
|
||||||
|
</Link>
|
||||||
|
.
|
||||||
|
</p>
|
||||||
|
<UniversalForm
|
||||||
|
fields={[
|
||||||
|
{
|
||||||
|
name: 'github',
|
||||||
|
label: 'GitHub Repository',
|
||||||
|
type: 'hidden',
|
||||||
|
value: ghRepo,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
label: 'ID',
|
||||||
|
type: 'hidden',
|
||||||
|
value: project.id,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
key={ghRepo}
|
||||||
|
schemaName={'githubSettings'}
|
||||||
|
action={githubSettings}
|
||||||
|
onActionComplete={() => router.refresh()}
|
||||||
|
/>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
<Card>
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle>Issue submission testing</CardTitle>
|
||||||
|
<CardDescription>Make sure your setup works!</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
{project.github ? (
|
||||||
|
<UniversalForm
|
||||||
|
fields={[
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
label: 'ID',
|
||||||
|
type: 'hidden',
|
||||||
|
value: project.id,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
schemaName={'githubTestIssue'}
|
||||||
|
action={githubTestIssue}
|
||||||
|
submitText="Create test issue"
|
||||||
|
submitClassname="!mt-0"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<p className="text-muted-foreground text-sm">
|
||||||
|
You need to connect your project to a GitHub repository before you can test issue
|
||||||
|
submission.
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|
||||||
<TabsContent value="api" className="space-y-5">
|
<TabsContent value="api" className="space-y-5">
|
||||||
@@ -123,20 +209,13 @@ export default function ProjectSettings(project: Project) {
|
|||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<h3 className="text-sm font-medium">Endpoint</h3>
|
<h3 className="text-sm font-medium">Endpoint</h3>
|
||||||
<code className="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm">
|
<code className="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm">
|
||||||
{url}
|
{apiUrl}
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<h3 className="text-sm font-medium">Method</h3>
|
<h3 className="text-sm font-medium">Method</h3>
|
||||||
<p className="text-sm">POST</p>
|
<p className="text-sm">POST</p>
|
||||||
</div>
|
</div>
|
||||||
{/* <div className="space-y-2">
|
|
||||||
<h3 className="text-sm font-medium">Headers</h3>
|
|
||||||
<code className="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm block whitespace-pre">
|
|
||||||
{`Content-Type: application/json
|
|
||||||
Authorization: Bearer YOUR_API_KEY`}
|
|
||||||
</code>
|
|
||||||
</div> */}
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<h3 className="text-sm font-medium">Body</h3>
|
<h3 className="text-sm font-medium">Body</h3>
|
||||||
<code className="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm block whitespace-pre">
|
<code className="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm block whitespace-pre">
|
||||||
@@ -148,7 +227,7 @@ export default function ProjectSettings(project: Project) {
|
|||||||
<code className="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm block whitespace-pre overflow-x-auto">
|
<code className="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm block whitespace-pre overflow-x-auto">
|
||||||
{stripIndents`curl -X POST \\
|
{stripIndents`curl -X POST \\
|
||||||
-d '${bodyGenNoIdent(project.customData)}' \\
|
-d '${bodyGenNoIdent(project.customData)}' \\
|
||||||
${url}`}
|
${apiUrl}`}
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
@@ -156,9 +235,7 @@ export default function ProjectSettings(project: Project) {
|
|||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>Rate limiting</CardTitle>
|
<CardTitle>Rate limiting</CardTitle>
|
||||||
<CardDescription>
|
<CardDescription>Manage your API rate limits.</CardDescription>
|
||||||
Manage your API rate limits.
|
|
||||||
</CardDescription>
|
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<UniversalForm
|
<UniversalForm
|
||||||
|
|||||||
@@ -15,7 +15,13 @@ import {
|
|||||||
import { Input } from '@/components/ui/input';
|
import { Input } from '@/components/ui/input';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import type { UniversalFormProps } from './types';
|
import type { UniversalFormProps } from './types';
|
||||||
import { customDataSchema, projectSettingsSchema, ratelimitChangeSchema } from './zod';
|
import {
|
||||||
|
customDataSchema,
|
||||||
|
githubSettingsSchema,
|
||||||
|
githubTestIssueSchema,
|
||||||
|
projectSettingsSchema,
|
||||||
|
ratelimitChangeSchema,
|
||||||
|
} from './zod';
|
||||||
import SubmitButton from '../SubmitButton/SubmitButton';
|
import SubmitButton from '../SubmitButton/SubmitButton';
|
||||||
import { useActionState } from 'react';
|
import { useActionState } from 'react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
@@ -27,6 +33,8 @@ export const schemaDb = [
|
|||||||
{ name: 'ratelimitChange', zod: ratelimitChangeSchema },
|
{ name: 'ratelimitChange', zod: ratelimitChangeSchema },
|
||||||
{ name: 'customData', zod: customDataSchema },
|
{ name: 'customData', zod: customDataSchema },
|
||||||
{ name: 'create', zod: createSchema },
|
{ name: 'create', zod: createSchema },
|
||||||
|
{ name: 'githubSettings', zod: githubSettingsSchema },
|
||||||
|
{ name: 'githubTestIssue', zod: githubTestIssueSchema },
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
export function UniversalForm<T extends z.ZodType>({
|
export function UniversalForm<T extends z.ZodType>({
|
||||||
|
|||||||
@@ -1,18 +1,39 @@
|
|||||||
import { z } from "zod";
|
import { z } from 'zod';
|
||||||
|
|
||||||
export const projectSettingsSchema = z.object({
|
export const projectSettingsSchema = z.object({
|
||||||
id: z.string().nonempty(),
|
id: z.string().nonempty(),
|
||||||
name: z.string().nonempty(),
|
name: z.string().nonempty(),
|
||||||
description: z.string().nonempty(),
|
description: z.string().nonempty(),
|
||||||
})
|
});
|
||||||
|
|
||||||
export const ratelimitChangeSchema = z.object({
|
export const ratelimitChangeSchema = z.object({
|
||||||
id: z.string().nonempty(),
|
id: z.string().nonempty(),
|
||||||
requests: z.string().nonempty().transform((val) => parseInt(val, 10)),
|
requests: z
|
||||||
duration: z.string().nonempty().transform((val) => parseInt(val, 10))
|
.string()
|
||||||
})
|
.nonempty()
|
||||||
|
.transform((val) => parseInt(val, 10)),
|
||||||
|
duration: z
|
||||||
|
.string()
|
||||||
|
.nonempty()
|
||||||
|
.transform((val) => parseInt(val, 10)),
|
||||||
|
});
|
||||||
|
|
||||||
export const customDataSchema = z.object({
|
export const customDataSchema = z.object({
|
||||||
id: z.string().nonempty(),
|
id: z.string().nonempty(),
|
||||||
data: z.string().nonempty()
|
data: z.string().nonempty(),
|
||||||
})
|
});
|
||||||
|
|
||||||
|
export const githubSettingsSchema = z.object({
|
||||||
|
id: z.string().nonempty(),
|
||||||
|
github: z
|
||||||
|
.string()
|
||||||
|
.regex(
|
||||||
|
/^https:\/\/github\.com\/[^\s\/]+\/[^\s\/]+[/]?$/,
|
||||||
|
'Github URL must be "https://github.com/user/repo"'
|
||||||
|
)
|
||||||
|
.nonempty(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const githubTestIssueSchema = z.object({
|
||||||
|
id: z.string().nonempty(),
|
||||||
|
});
|
||||||
153
src/components/ui/command.tsx
Normal file
153
src/components/ui/command.tsx
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { type DialogProps } from "@radix-ui/react-dialog"
|
||||||
|
import { Command as CommandPrimitive } from "cmdk"
|
||||||
|
import { Search } from "lucide-react"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
import { Dialog, DialogContent } from "@/components/ui/dialog"
|
||||||
|
|
||||||
|
const Command = React.forwardRef<
|
||||||
|
React.ElementRef<typeof CommandPrimitive>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof CommandPrimitive>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<CommandPrimitive
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
Command.displayName = CommandPrimitive.displayName
|
||||||
|
|
||||||
|
const CommandDialog = ({ children, ...props }: DialogProps) => {
|
||||||
|
return (
|
||||||
|
<Dialog {...props}>
|
||||||
|
<DialogContent className="overflow-hidden p-0 shadow-lg">
|
||||||
|
<Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
|
||||||
|
{children}
|
||||||
|
</Command>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const CommandInput = React.forwardRef<
|
||||||
|
React.ElementRef<typeof CommandPrimitive.Input>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<div className="flex items-center border-b px-3" cmdk-input-wrapper="">
|
||||||
|
<Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />
|
||||||
|
<CommandPrimitive.Input
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
|
||||||
|
CommandInput.displayName = CommandPrimitive.Input.displayName
|
||||||
|
|
||||||
|
const CommandList = React.forwardRef<
|
||||||
|
React.ElementRef<typeof CommandPrimitive.List>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<CommandPrimitive.List
|
||||||
|
ref={ref}
|
||||||
|
className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
|
||||||
|
CommandList.displayName = CommandPrimitive.List.displayName
|
||||||
|
|
||||||
|
const CommandEmpty = React.forwardRef<
|
||||||
|
React.ElementRef<typeof CommandPrimitive.Empty>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
|
||||||
|
>((props, ref) => (
|
||||||
|
<CommandPrimitive.Empty
|
||||||
|
ref={ref}
|
||||||
|
className="py-6 text-center text-sm"
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
|
||||||
|
CommandEmpty.displayName = CommandPrimitive.Empty.displayName
|
||||||
|
|
||||||
|
const CommandGroup = React.forwardRef<
|
||||||
|
React.ElementRef<typeof CommandPrimitive.Group>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<CommandPrimitive.Group
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
|
||||||
|
CommandGroup.displayName = CommandPrimitive.Group.displayName
|
||||||
|
|
||||||
|
const CommandSeparator = React.forwardRef<
|
||||||
|
React.ElementRef<typeof CommandPrimitive.Separator>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<CommandPrimitive.Separator
|
||||||
|
ref={ref}
|
||||||
|
className={cn("-mx-1 h-px bg-border", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
CommandSeparator.displayName = CommandPrimitive.Separator.displayName
|
||||||
|
|
||||||
|
const CommandItem = React.forwardRef<
|
||||||
|
React.ElementRef<typeof CommandPrimitive.Item>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<CommandPrimitive.Item
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"relative flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected='true']:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
|
||||||
|
CommandItem.displayName = CommandPrimitive.Item.displayName
|
||||||
|
|
||||||
|
const CommandShortcut = ({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.HTMLAttributes<HTMLSpanElement>) => {
|
||||||
|
return (
|
||||||
|
<span
|
||||||
|
className={cn(
|
||||||
|
"ml-auto text-xs tracking-widest text-muted-foreground",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
CommandShortcut.displayName = "CommandShortcut"
|
||||||
|
|
||||||
|
export {
|
||||||
|
Command,
|
||||||
|
CommandDialog,
|
||||||
|
CommandInput,
|
||||||
|
CommandList,
|
||||||
|
CommandEmpty,
|
||||||
|
CommandGroup,
|
||||||
|
CommandItem,
|
||||||
|
CommandShortcut,
|
||||||
|
CommandSeparator,
|
||||||
|
}
|
||||||
122
src/components/ui/dialog.tsx
Normal file
122
src/components/ui/dialog.tsx
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import * as DialogPrimitive from "@radix-ui/react-dialog"
|
||||||
|
import { X } from "lucide-react"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const Dialog = DialogPrimitive.Root
|
||||||
|
|
||||||
|
const DialogTrigger = DialogPrimitive.Trigger
|
||||||
|
|
||||||
|
const DialogPortal = DialogPrimitive.Portal
|
||||||
|
|
||||||
|
const DialogClose = DialogPrimitive.Close
|
||||||
|
|
||||||
|
const DialogOverlay = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DialogPrimitive.Overlay>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<DialogPrimitive.Overlay
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
|
||||||
|
|
||||||
|
const DialogContent = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DialogPrimitive.Content>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
|
||||||
|
>(({ className, children, ...props }, ref) => (
|
||||||
|
<DialogPortal>
|
||||||
|
<DialogOverlay />
|
||||||
|
<DialogPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
|
||||||
|
<X className="h-4 w-4" />
|
||||||
|
<span className="sr-only">Close</span>
|
||||||
|
</DialogPrimitive.Close>
|
||||||
|
</DialogPrimitive.Content>
|
||||||
|
</DialogPortal>
|
||||||
|
))
|
||||||
|
DialogContent.displayName = DialogPrimitive.Content.displayName
|
||||||
|
|
||||||
|
const DialogHeader = ({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
"flex flex-col space-y-1.5 text-center sm:text-left",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
DialogHeader.displayName = "DialogHeader"
|
||||||
|
|
||||||
|
const DialogFooter = ({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
DialogFooter.displayName = "DialogFooter"
|
||||||
|
|
||||||
|
const DialogTitle = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DialogPrimitive.Title>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<DialogPrimitive.Title
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"text-lg font-semibold leading-none tracking-tight",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
DialogTitle.displayName = DialogPrimitive.Title.displayName
|
||||||
|
|
||||||
|
const DialogDescription = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DialogPrimitive.Description>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<DialogPrimitive.Description
|
||||||
|
ref={ref}
|
||||||
|
className={cn("text-sm text-muted-foreground", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
DialogDescription.displayName = DialogPrimitive.Description.displayName
|
||||||
|
|
||||||
|
export {
|
||||||
|
Dialog,
|
||||||
|
DialogPortal,
|
||||||
|
DialogOverlay,
|
||||||
|
DialogClose,
|
||||||
|
DialogTrigger,
|
||||||
|
DialogContent,
|
||||||
|
DialogHeader,
|
||||||
|
DialogFooter,
|
||||||
|
DialogTitle,
|
||||||
|
DialogDescription,
|
||||||
|
}
|
||||||
31
src/components/ui/popover.tsx
Normal file
31
src/components/ui/popover.tsx
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import * as PopoverPrimitive from "@radix-ui/react-popover"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const Popover = PopoverPrimitive.Root
|
||||||
|
|
||||||
|
const PopoverTrigger = PopoverPrimitive.Trigger
|
||||||
|
|
||||||
|
const PopoverContent = React.forwardRef<
|
||||||
|
React.ElementRef<typeof PopoverPrimitive.Content>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
|
||||||
|
>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
|
||||||
|
<PopoverPrimitive.Portal>
|
||||||
|
<PopoverPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
align={align}
|
||||||
|
sideOffset={sideOffset}
|
||||||
|
className={cn(
|
||||||
|
"z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</PopoverPrimitive.Portal>
|
||||||
|
))
|
||||||
|
PopoverContent.displayName = PopoverPrimitive.Content.displayName
|
||||||
|
|
||||||
|
export { Popover, PopoverTrigger, PopoverContent }
|
||||||
@@ -28,6 +28,7 @@ export const lucia = new Lucia(adapter, {
|
|||||||
return {
|
return {
|
||||||
githubId: attributes.githubId,
|
githubId: attributes.githubId,
|
||||||
username: attributes.username,
|
username: attributes.username,
|
||||||
|
installations: attributes.installations,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -69,4 +70,5 @@ declare module 'lucia' {
|
|||||||
interface DatabaseUserAttributes {
|
interface DatabaseUserAttributes {
|
||||||
githubId: string;
|
githubId: string;
|
||||||
username: string;
|
username: string;
|
||||||
|
installations: string[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,5 @@ export const bodyGen = (customData: string[]) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const bodyGenNoIdent = (customData: string[]) => {
|
export const bodyGenNoIdent = (customData: string[]) => {
|
||||||
console.log(bodyGen(customData));
|
|
||||||
return JSON.stringify(JSON.parse(bodyGen(customData)));
|
return JSON.stringify(JSON.parse(bodyGen(customData)));
|
||||||
}
|
}
|
||||||
@@ -1,16 +1,24 @@
|
|||||||
'use server'
|
'use server';
|
||||||
|
|
||||||
import { customDataSchema, projectSettingsSchema, ratelimitChangeSchema } from "@/components/app/UniversalForm/zod";
|
import {
|
||||||
import { validateRequest } from "../auth";
|
customDataSchema,
|
||||||
import prisma from "../db";
|
githubSettingsSchema,
|
||||||
import zodVerify from "../zodVerify";
|
githubTestIssueSchema,
|
||||||
import { createSchema } from "./zod";
|
projectSettingsSchema,
|
||||||
|
ratelimitChangeSchema,
|
||||||
|
} from '@/components/app/UniversalForm/zod';
|
||||||
|
import { validateRequest } from '../auth';
|
||||||
|
import prisma from '../db';
|
||||||
|
import zodVerify from '../zodVerify';
|
||||||
|
import { createSchema } from './zod';
|
||||||
|
import { Octokit } from '@octokit/core';
|
||||||
|
import { octokitApp } from '../octokitApp';
|
||||||
|
|
||||||
export async function create(prev: any, formData: FormData) {
|
export async function create(prev: any, formData: FormData) {
|
||||||
const zod = await zodVerify(createSchema, formData);
|
const zod = await zodVerify(createSchema, formData);
|
||||||
const { user } = await validateRequest();
|
const { user } = await validateRequest();
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return { success: false, error: "You must be logged in" };
|
return { success: false, error: 'You must be logged in' };
|
||||||
}
|
}
|
||||||
if (!zod.success) {
|
if (!zod.success) {
|
||||||
return zod;
|
return zod;
|
||||||
@@ -24,7 +32,7 @@ export async function create(prev: any, formData: FormData) {
|
|||||||
id: user.id,
|
id: user.id,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
return { success: true, id: dbCreate.id };
|
return { success: true, id: dbCreate.id };
|
||||||
}
|
}
|
||||||
@@ -33,7 +41,7 @@ export async function editProject(prev: any, formData: FormData) {
|
|||||||
const zod = await zodVerify(projectSettingsSchema, formData);
|
const zod = await zodVerify(projectSettingsSchema, formData);
|
||||||
const { user } = await validateRequest();
|
const { user } = await validateRequest();
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return { success: false, error: "You must be logged in" };
|
return { success: false, error: 'You must be logged in' };
|
||||||
}
|
}
|
||||||
if (!zod.success) {
|
if (!zod.success) {
|
||||||
return zod;
|
return zod;
|
||||||
@@ -45,7 +53,7 @@ export async function editProject(prev: any, formData: FormData) {
|
|||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
...zod.data,
|
...zod.data,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
return { success: true, id: dbUpdate.id };
|
return { success: true, id: dbUpdate.id };
|
||||||
}
|
}
|
||||||
@@ -55,7 +63,7 @@ export async function ratelimitChange(prev: any, formData: FormData) {
|
|||||||
const zod = await zodVerify(ratelimitChangeSchema, formData);
|
const zod = await zodVerify(ratelimitChangeSchema, formData);
|
||||||
const { user } = await validateRequest();
|
const { user } = await validateRequest();
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return { success: false, error: "You must be logged in" };
|
return { success: false, error: 'You must be logged in' };
|
||||||
}
|
}
|
||||||
if (!zod.success) {
|
if (!zod.success) {
|
||||||
return zod;
|
return zod;
|
||||||
@@ -68,7 +76,7 @@ export async function ratelimitChange(prev: any, formData: FormData) {
|
|||||||
data: {
|
data: {
|
||||||
rateLimitReq: zod.data.requests,
|
rateLimitReq: zod.data.requests,
|
||||||
rateLimitTime: zod.data.duration,
|
rateLimitTime: zod.data.duration,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
return { success: true, id: dbUpdate.id };
|
return { success: true, id: dbUpdate.id };
|
||||||
}
|
}
|
||||||
@@ -77,7 +85,7 @@ export async function customData(prev: any, formData: FormData) {
|
|||||||
const zod = await zodVerify(customDataSchema, formData);
|
const zod = await zodVerify(customDataSchema, formData);
|
||||||
const { user } = await validateRequest();
|
const { user } = await validateRequest();
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return { success: false, error: "You must be logged in" };
|
return { success: false, error: 'You must be logged in' };
|
||||||
}
|
}
|
||||||
if (!zod.success) {
|
if (!zod.success) {
|
||||||
return zod;
|
return zod;
|
||||||
@@ -92,7 +100,86 @@ export async function customData(prev: any, formData: FormData) {
|
|||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
customData: splitted,
|
customData: splitted,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
return { success: true, id: dbUpdate.id };
|
return { success: true, id: dbUpdate.id };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function githubSettings(prev: any, formData: FormData) {
|
||||||
|
const zod = await zodVerify(githubSettingsSchema, formData);
|
||||||
|
const { user, session } = await validateRequest();
|
||||||
|
if (!user) {
|
||||||
|
return { success: false, error: 'You must be logged in' };
|
||||||
|
}
|
||||||
|
if (!zod.success) {
|
||||||
|
return zod;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dbUpdate = await prisma.project.update({
|
||||||
|
where: {
|
||||||
|
id: zod.data.id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
github: zod.data.github,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return { success: true, id: dbUpdate.id };
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function githubTestIssue(prev: any, formData: FormData) {
|
||||||
|
const zod = await zodVerify(githubTestIssueSchema, formData);
|
||||||
|
const { user } = await validateRequest();
|
||||||
|
if (!user) {
|
||||||
|
return { success: false, error: 'You must be logged in' };
|
||||||
|
}
|
||||||
|
if (!zod.success) {
|
||||||
|
return zod;
|
||||||
|
}
|
||||||
|
|
||||||
|
const project = await prisma.project.findUnique({
|
||||||
|
where: {
|
||||||
|
id: zod.data.id,
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
user: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!project) {
|
||||||
|
return { success: false, error: 'Project not found' };
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const [owner, repo] = project.github!.split('/').slice(-2);
|
||||||
|
let issueCreated = false;
|
||||||
|
|
||||||
|
for (const installationId of project.user.installations) {
|
||||||
|
if (issueCreated) break;
|
||||||
|
|
||||||
|
const installation = await octokitApp.getInstallationOctokit(Number(installationId));
|
||||||
|
const getRepo = await installation
|
||||||
|
.request('GET /repos/{owner}/{repo}', {
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
})
|
||||||
|
.catch(() => ({ status: 404 }));
|
||||||
|
if (getRepo.status === 200) {
|
||||||
|
const createIssue = await installation.request('POST /repos/{owner}/{repo}/issues', {
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
title: 'Test issue',
|
||||||
|
body: "### You are all set! 🎉\n\nIf you're reading this, the test issue has been created successfully!",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (createIssue.status === 201) {
|
||||||
|
issueCreated = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
return { success: false, error: e };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { success: true };
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,5 @@ import { z } from "zod";
|
|||||||
export const createSchema = z.object({
|
export const createSchema = z.object({
|
||||||
name: z.string().nonempty(),
|
name: z.string().nonempty(),
|
||||||
description: z.string().nonempty(),
|
description: z.string().nonempty(),
|
||||||
github: z.string().url().nonempty(),
|
|
||||||
});
|
});
|
||||||
export type createSchemaType = z.infer<typeof createSchema>;
|
export type createSchemaType = z.infer<typeof createSchema>;
|
||||||
11
src/lib/octokitApp.ts
Normal file
11
src/lib/octokitApp.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { App } from "@octokit/app";
|
||||||
|
import { readFileSync } from "fs";
|
||||||
|
|
||||||
|
export const octokitApp = new App({
|
||||||
|
appId: process.env.GITHUB_APP_ID!,
|
||||||
|
privateKey: readFileSync('./github-app.pem').toString(),
|
||||||
|
oauth: {
|
||||||
|
clientId: process.env.GITHUB_CLIENT_ID!,
|
||||||
|
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
||||||
|
},
|
||||||
|
});
|
||||||
388
yarn.lock
388
yarn.lock
@@ -912,12 +912,79 @@
|
|||||||
"@nodelib/fs.scandir" "2.1.5"
|
"@nodelib/fs.scandir" "2.1.5"
|
||||||
fastq "^1.6.0"
|
fastq "^1.6.0"
|
||||||
|
|
||||||
|
"@octokit/app@^15.1.1":
|
||||||
|
version "15.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@octokit/app/-/app-15.1.1.tgz#bbbae2b209928c8ca038122ec85bff67045628c7"
|
||||||
|
integrity sha512-fk8xrCSPTJGpyBdBNI+DcZ224dm0aApv4vi6X7/zTmANXlegKV2Td+dJ+fd7APPaPN7R+xttUsj2Fm+AFDSfMQ==
|
||||||
|
dependencies:
|
||||||
|
"@octokit/auth-app" "^7.0.0"
|
||||||
|
"@octokit/auth-unauthenticated" "^6.0.0"
|
||||||
|
"@octokit/core" "^6.1.2"
|
||||||
|
"@octokit/oauth-app" "^7.0.0"
|
||||||
|
"@octokit/plugin-paginate-rest" "^11.0.0"
|
||||||
|
"@octokit/types" "^13.0.0"
|
||||||
|
"@octokit/webhooks" "^13.0.0"
|
||||||
|
|
||||||
|
"@octokit/auth-app@^7.0.0":
|
||||||
|
version "7.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@octokit/auth-app/-/auth-app-7.1.3.tgz#b6b26e880895eaa4effc7d38a4679f05e100f593"
|
||||||
|
integrity sha512-GZdkOp2kZTIy5dG9oXqvzUAZiPvDx4C/lMlN6yQjtG9d/+hYa7W8WXTJoOrXE8UdfL9A/sZMl206dmtkl9lwVQ==
|
||||||
|
dependencies:
|
||||||
|
"@octokit/auth-oauth-app" "^8.1.0"
|
||||||
|
"@octokit/auth-oauth-user" "^5.1.0"
|
||||||
|
"@octokit/request" "^9.1.1"
|
||||||
|
"@octokit/request-error" "^6.1.1"
|
||||||
|
"@octokit/types" "^13.4.1"
|
||||||
|
toad-cache "^3.7.0"
|
||||||
|
universal-github-app-jwt "^2.2.0"
|
||||||
|
universal-user-agent "^7.0.0"
|
||||||
|
|
||||||
|
"@octokit/auth-oauth-app@^8.0.0", "@octokit/auth-oauth-app@^8.1.0":
|
||||||
|
version "8.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@octokit/auth-oauth-app/-/auth-oauth-app-8.1.1.tgz#6204affa6e86f535016799cadf2af9befe5e893c"
|
||||||
|
integrity sha512-5UtmxXAvU2wfcHIPPDWzVSAWXVJzG3NWsxb7zCFplCWEmMCArSZV0UQu5jw5goLQXbFyOr5onzEH37UJB3zQQg==
|
||||||
|
dependencies:
|
||||||
|
"@octokit/auth-oauth-device" "^7.0.0"
|
||||||
|
"@octokit/auth-oauth-user" "^5.0.1"
|
||||||
|
"@octokit/request" "^9.0.0"
|
||||||
|
"@octokit/types" "^13.0.0"
|
||||||
|
universal-user-agent "^7.0.0"
|
||||||
|
|
||||||
|
"@octokit/auth-oauth-device@^7.0.0", "@octokit/auth-oauth-device@^7.0.1":
|
||||||
|
version "7.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@octokit/auth-oauth-device/-/auth-oauth-device-7.1.1.tgz#7b4f8f97cbcadbe9894d48cde4406dbdef39875a"
|
||||||
|
integrity sha512-HWl8lYueHonuyjrKKIup/1tiy0xcmQCdq5ikvMO1YwkNNkxb6DXfrPjrMYItNLyCP/o2H87WuijuE+SlBTT8eg==
|
||||||
|
dependencies:
|
||||||
|
"@octokit/oauth-methods" "^5.0.0"
|
||||||
|
"@octokit/request" "^9.0.0"
|
||||||
|
"@octokit/types" "^13.0.0"
|
||||||
|
universal-user-agent "^7.0.0"
|
||||||
|
|
||||||
|
"@octokit/auth-oauth-user@^5.0.1", "@octokit/auth-oauth-user@^5.1.0":
|
||||||
|
version "5.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@octokit/auth-oauth-user/-/auth-oauth-user-5.1.1.tgz#4f1570c6ee15bb9ddc3dcca83308dcaa159e3848"
|
||||||
|
integrity sha512-rRkMz0ErOppdvEfnemHJXgZ9vTPhBuC6yASeFaB7I2yLMd7QpjfrL1mnvRPlyKo+M6eeLxrKanXJ9Qte29SRsw==
|
||||||
|
dependencies:
|
||||||
|
"@octokit/auth-oauth-device" "^7.0.1"
|
||||||
|
"@octokit/oauth-methods" "^5.0.0"
|
||||||
|
"@octokit/request" "^9.0.1"
|
||||||
|
"@octokit/types" "^13.0.0"
|
||||||
|
universal-user-agent "^7.0.0"
|
||||||
|
|
||||||
"@octokit/auth-token@^5.0.0":
|
"@octokit/auth-token@^5.0.0":
|
||||||
version "5.1.1"
|
version "5.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-5.1.1.tgz#3bbfe905111332a17f72d80bd0b51a3e2fa2cf07"
|
resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-5.1.1.tgz#3bbfe905111332a17f72d80bd0b51a3e2fa2cf07"
|
||||||
integrity sha512-rh3G3wDO8J9wSjfI436JUKzHIxq8NaiL0tVeB2aXmG6p/9859aUOAjA9pmSPNGGZxfwmaJ9ozOJImuNVJdpvbA==
|
integrity sha512-rh3G3wDO8J9wSjfI436JUKzHIxq8NaiL0tVeB2aXmG6p/9859aUOAjA9pmSPNGGZxfwmaJ9ozOJImuNVJdpvbA==
|
||||||
|
|
||||||
"@octokit/core@^6.1.2":
|
"@octokit/auth-unauthenticated@^6.0.0", "@octokit/auth-unauthenticated@^6.0.0-beta.1":
|
||||||
|
version "6.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@octokit/auth-unauthenticated/-/auth-unauthenticated-6.1.0.tgz#de0fe923bb06ed93aea526ab99972a98c546d0bf"
|
||||||
|
integrity sha512-zPSmfrUAcspZH/lOFQnVnvjQZsIvmfApQH6GzJrkIunDooU1Su2qt2FfMTSVPRp7WLTQyC20Kd55lF+mIYaohQ==
|
||||||
|
dependencies:
|
||||||
|
"@octokit/request-error" "^6.0.1"
|
||||||
|
"@octokit/types" "^13.0.0"
|
||||||
|
|
||||||
|
"@octokit/core@^6.0.0", "@octokit/core@^6.1.2":
|
||||||
version "6.1.2"
|
version "6.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/@octokit/core/-/core-6.1.2.tgz#20442d0a97c411612da206411e356014d1d1bd17"
|
resolved "https://registry.yarnpkg.com/@octokit/core/-/core-6.1.2.tgz#20442d0a97c411612da206411e356014d1d1bd17"
|
||||||
integrity sha512-hEb7Ma4cGJGEUNOAVmyfdB/3WirWMg5hDuNFVejGEDFqupeOysLc2sG6HJxY2etBp5YQu5Wtxwi020jS9xlUwg==
|
integrity sha512-hEb7Ma4cGJGEUNOAVmyfdB/3WirWMg5hDuNFVejGEDFqupeOysLc2sG6HJxY2etBp5YQu5Wtxwi020jS9xlUwg==
|
||||||
@@ -947,19 +1014,60 @@
|
|||||||
"@octokit/types" "^13.0.0"
|
"@octokit/types" "^13.0.0"
|
||||||
universal-user-agent "^7.0.0"
|
universal-user-agent "^7.0.0"
|
||||||
|
|
||||||
|
"@octokit/oauth-app@^7.0.0":
|
||||||
|
version "7.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@octokit/oauth-app/-/oauth-app-7.1.3.tgz#a0f256dd185e7c00bfbc3e6bc3c5aad66e42c609"
|
||||||
|
integrity sha512-EHXbOpBkSGVVGF1W+NLMmsnSsJRkcrnVmDKt0TQYRBb6xWfWzoi9sBD4DIqZ8jGhOWO/V8t4fqFyJ4vDQDn9bg==
|
||||||
|
dependencies:
|
||||||
|
"@octokit/auth-oauth-app" "^8.0.0"
|
||||||
|
"@octokit/auth-oauth-user" "^5.0.1"
|
||||||
|
"@octokit/auth-unauthenticated" "^6.0.0-beta.1"
|
||||||
|
"@octokit/core" "^6.0.0"
|
||||||
|
"@octokit/oauth-authorization-url" "^7.0.0"
|
||||||
|
"@octokit/oauth-methods" "^5.0.0"
|
||||||
|
"@types/aws-lambda" "^8.10.83"
|
||||||
|
universal-user-agent "^7.0.0"
|
||||||
|
|
||||||
|
"@octokit/oauth-authorization-url@^7.0.0":
|
||||||
|
version "7.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@octokit/oauth-authorization-url/-/oauth-authorization-url-7.1.1.tgz#0e17c2225eb66b58ec902d02b6f1315ffe9ff04b"
|
||||||
|
integrity sha512-ooXV8GBSabSWyhLUowlMIVd9l1s2nsOGQdlP2SQ4LnkEsGXzeCvbSbCPdZThXhEFzleGPwbapT0Sb+YhXRyjCA==
|
||||||
|
|
||||||
|
"@octokit/oauth-methods@^5.0.0":
|
||||||
|
version "5.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@octokit/oauth-methods/-/oauth-methods-5.1.2.tgz#fd31d2a69f4c91d1abc1ed1814dda5252c697e02"
|
||||||
|
integrity sha512-C5lglRD+sBlbrhCUTxgJAFjWgJlmTx5bQ7Ch0+2uqRjYv7Cfb5xpX4WuSC9UgQna3sqRGBL9EImX9PvTpMaQ7g==
|
||||||
|
dependencies:
|
||||||
|
"@octokit/oauth-authorization-url" "^7.0.0"
|
||||||
|
"@octokit/request" "^9.1.0"
|
||||||
|
"@octokit/request-error" "^6.1.0"
|
||||||
|
"@octokit/types" "^13.0.0"
|
||||||
|
|
||||||
"@octokit/openapi-types@^22.2.0":
|
"@octokit/openapi-types@^22.2.0":
|
||||||
version "22.2.0"
|
version "22.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-22.2.0.tgz#75aa7dcd440821d99def6a60b5f014207ae4968e"
|
resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-22.2.0.tgz#75aa7dcd440821d99def6a60b5f014207ae4968e"
|
||||||
integrity sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==
|
integrity sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==
|
||||||
|
|
||||||
"@octokit/request-error@^6.0.1":
|
"@octokit/openapi-webhooks-types@8.5.1":
|
||||||
|
version "8.5.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@octokit/openapi-webhooks-types/-/openapi-webhooks-types-8.5.1.tgz#de421dbd3efb586e908a152eed3f0ae50698a2f2"
|
||||||
|
integrity sha512-i3h1b5zpGSB39ffBbYdSGuAd0NhBAwPyA3QV3LYi/lx4lsbZiu7u2UHgXVUR6EpvOI8REOuVh1DZTRfHoJDvuQ==
|
||||||
|
|
||||||
|
"@octokit/plugin-paginate-rest@^11.0.0":
|
||||||
|
version "11.3.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.3.6.tgz#82f33c87464202423c2a89d5cc8c38761f4aa86b"
|
||||||
|
integrity sha512-zcvqqf/+TicbTCa/Z+3w4eBJcAxCFymtc0UAIsR3dEVoNilWld4oXdscQ3laXamTszUZdusw97K8+DrbFiOwjw==
|
||||||
|
dependencies:
|
||||||
|
"@octokit/types" "^13.6.2"
|
||||||
|
|
||||||
|
"@octokit/request-error@^6.0.1", "@octokit/request-error@^6.1.0", "@octokit/request-error@^6.1.1":
|
||||||
version "6.1.5"
|
version "6.1.5"
|
||||||
resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-6.1.5.tgz#907099e341c4e6179db623a0328d678024f54653"
|
resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-6.1.5.tgz#907099e341c4e6179db623a0328d678024f54653"
|
||||||
integrity sha512-IlBTfGX8Yn/oFPMwSfvugfncK2EwRLjzbrpifNaMY8o/HTEAFqCA1FZxjD9cWvSKBHgrIhc4CSBIzMxiLsbzFQ==
|
integrity sha512-IlBTfGX8Yn/oFPMwSfvugfncK2EwRLjzbrpifNaMY8o/HTEAFqCA1FZxjD9cWvSKBHgrIhc4CSBIzMxiLsbzFQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@octokit/types" "^13.0.0"
|
"@octokit/types" "^13.0.0"
|
||||||
|
|
||||||
"@octokit/request@^9.0.0":
|
"@octokit/request@^9.0.0", "@octokit/request@^9.0.1", "@octokit/request@^9.1.0", "@octokit/request@^9.1.1":
|
||||||
version "9.1.3"
|
version "9.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/@octokit/request/-/request-9.1.3.tgz#42b693bc06238f43af3c037ebfd35621c6457838"
|
resolved "https://registry.yarnpkg.com/@octokit/request/-/request-9.1.3.tgz#42b693bc06238f43af3c037ebfd35621c6457838"
|
||||||
integrity sha512-V+TFhu5fdF3K58rs1pGUJIDH5RZLbZm5BI+MNF+6o/ssFNT4vWlCh/tVpF3NxGtP15HUxTTMUbsG5llAuU2CZA==
|
integrity sha512-V+TFhu5fdF3K58rs1pGUJIDH5RZLbZm5BI+MNF+6o/ssFNT4vWlCh/tVpF3NxGtP15HUxTTMUbsG5llAuU2CZA==
|
||||||
@@ -969,13 +1077,27 @@
|
|||||||
"@octokit/types" "^13.1.0"
|
"@octokit/types" "^13.1.0"
|
||||||
universal-user-agent "^7.0.2"
|
universal-user-agent "^7.0.2"
|
||||||
|
|
||||||
"@octokit/types@^13.0.0", "@octokit/types@^13.1.0":
|
"@octokit/types@^13.0.0", "@octokit/types@^13.1.0", "@octokit/types@^13.4.1", "@octokit/types@^13.6.2":
|
||||||
version "13.6.2"
|
version "13.6.2"
|
||||||
resolved "https://registry.yarnpkg.com/@octokit/types/-/types-13.6.2.tgz#e10fc4d2bdd65d836d1ced223b03ad4cfdb525bd"
|
resolved "https://registry.yarnpkg.com/@octokit/types/-/types-13.6.2.tgz#e10fc4d2bdd65d836d1ced223b03ad4cfdb525bd"
|
||||||
integrity sha512-WpbZfZUcZU77DrSW4wbsSgTPfKcp286q3ItaIgvSbBpZJlu6mnYXAkjZz6LVZPXkEvLIM8McanyZejKTYUHipA==
|
integrity sha512-WpbZfZUcZU77DrSW4wbsSgTPfKcp286q3ItaIgvSbBpZJlu6mnYXAkjZz6LVZPXkEvLIM8McanyZejKTYUHipA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@octokit/openapi-types" "^22.2.0"
|
"@octokit/openapi-types" "^22.2.0"
|
||||||
|
|
||||||
|
"@octokit/webhooks-methods@^5.0.0":
|
||||||
|
version "5.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@octokit/webhooks-methods/-/webhooks-methods-5.1.0.tgz#13b6c08f89902c1ab0ddf31c6eeeec9c2772cfe6"
|
||||||
|
integrity sha512-yFZa3UH11VIxYnnoOYCVoJ3q4ChuSOk2IVBBQ0O3xtKX4x9bmKb/1t+Mxixv2iUhzMdOl1qeWJqEhouXXzB3rQ==
|
||||||
|
|
||||||
|
"@octokit/webhooks@^13.0.0":
|
||||||
|
version "13.4.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@octokit/webhooks/-/webhooks-13.4.1.tgz#608929916b0e0e5755fa5ca1de7484d2113bc6a9"
|
||||||
|
integrity sha512-I5YPUtfWidh+OzyrlDahJsUpkpGK0kCTmDRbuqGmlCUzOtxdEkX3R4d6Cd08ijQYwkVXQJanPdbKuZBeV2NMaA==
|
||||||
|
dependencies:
|
||||||
|
"@octokit/openapi-webhooks-types" "8.5.1"
|
||||||
|
"@octokit/request-error" "^6.0.1"
|
||||||
|
"@octokit/webhooks-methods" "^5.0.0"
|
||||||
|
|
||||||
"@oslojs/asn1@1.0.0":
|
"@oslojs/asn1@1.0.0":
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@oslojs/asn1/-/asn1-1.0.0.tgz#25edb31585b369efdc103e9a1eb822df9c235174"
|
resolved "https://registry.yarnpkg.com/@oslojs/asn1/-/asn1-1.0.0.tgz#25edb31585b369efdc103e9a1eb822df9c235174"
|
||||||
@@ -1059,6 +1181,13 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@prisma/debug" "6.0.1"
|
"@prisma/debug" "6.0.1"
|
||||||
|
|
||||||
|
"@radix-ui/primitive@1.0.1":
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.0.1.tgz#e46f9958b35d10e9f6dc71c497305c22e3e55dbd"
|
||||||
|
integrity sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
"@radix-ui/primitive@1.1.0":
|
"@radix-ui/primitive@1.1.0":
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.1.0.tgz#42ef83b3b56dccad5d703ae8c42919a68798bbe2"
|
resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.1.0.tgz#42ef83b3b56dccad5d703ae8c42919a68798bbe2"
|
||||||
@@ -1076,6 +1205,13 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@radix-ui/react-primitive" "2.0.0"
|
"@radix-ui/react-primitive" "2.0.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-arrow@1.1.1":
|
||||||
|
version "1.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-arrow/-/react-arrow-1.1.1.tgz#2103721933a8bfc6e53bbfbdc1aaad5fc8ba0dd7"
|
||||||
|
integrity sha512-NaVpZfmv8SKeZbn4ijN2V3jlHA9ngBG16VnIIm22nUR0Yk8KUALyBxT3KYEUnNuch9sTE8UTsS3whzBgKOL30w==
|
||||||
|
dependencies:
|
||||||
|
"@radix-ui/react-primitive" "2.0.1"
|
||||||
|
|
||||||
"@radix-ui/react-avatar@^1.0.4":
|
"@radix-ui/react-avatar@^1.0.4":
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-avatar/-/react-avatar-1.0.4.tgz#de9a5349d9e3de7bbe990334c4d2011acbbb9623"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-avatar/-/react-avatar-1.0.4.tgz#de9a5349d9e3de7bbe990334c4d2011acbbb9623"
|
||||||
@@ -1141,11 +1277,64 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.1.1.tgz#82074aa83a472353bb22e86f11bcbd1c61c4c71a"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.1.1.tgz#82074aa83a472353bb22e86f11bcbd1c61c4c71a"
|
||||||
integrity sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==
|
integrity sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==
|
||||||
|
|
||||||
|
"@radix-ui/react-dialog@1.0.5":
|
||||||
|
version "1.0.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz#71657b1b116de6c7a0b03242d7d43e01062c7300"
|
||||||
|
integrity sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/primitive" "1.0.1"
|
||||||
|
"@radix-ui/react-compose-refs" "1.0.1"
|
||||||
|
"@radix-ui/react-context" "1.0.1"
|
||||||
|
"@radix-ui/react-dismissable-layer" "1.0.5"
|
||||||
|
"@radix-ui/react-focus-guards" "1.0.1"
|
||||||
|
"@radix-ui/react-focus-scope" "1.0.4"
|
||||||
|
"@radix-ui/react-id" "1.0.1"
|
||||||
|
"@radix-ui/react-portal" "1.0.4"
|
||||||
|
"@radix-ui/react-presence" "1.0.1"
|
||||||
|
"@radix-ui/react-primitive" "1.0.3"
|
||||||
|
"@radix-ui/react-slot" "1.0.2"
|
||||||
|
"@radix-ui/react-use-controllable-state" "1.0.1"
|
||||||
|
aria-hidden "^1.1.1"
|
||||||
|
react-remove-scroll "2.5.5"
|
||||||
|
|
||||||
|
"@radix-ui/react-dialog@^1.1.4":
|
||||||
|
version "1.1.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-dialog/-/react-dialog-1.1.4.tgz#d68e977acfcc0d044b9dab47b6dd2c179d2b3191"
|
||||||
|
integrity sha512-Ur7EV1IwQGCyaAuyDRiOLA5JIUZxELJljF+MbM/2NC0BYwfuRrbpS30BiQBJrVruscgUkieKkqXYDOoByaxIoA==
|
||||||
|
dependencies:
|
||||||
|
"@radix-ui/primitive" "1.1.1"
|
||||||
|
"@radix-ui/react-compose-refs" "1.1.1"
|
||||||
|
"@radix-ui/react-context" "1.1.1"
|
||||||
|
"@radix-ui/react-dismissable-layer" "1.1.3"
|
||||||
|
"@radix-ui/react-focus-guards" "1.1.1"
|
||||||
|
"@radix-ui/react-focus-scope" "1.1.1"
|
||||||
|
"@radix-ui/react-id" "1.1.0"
|
||||||
|
"@radix-ui/react-portal" "1.1.3"
|
||||||
|
"@radix-ui/react-presence" "1.1.2"
|
||||||
|
"@radix-ui/react-primitive" "2.0.1"
|
||||||
|
"@radix-ui/react-slot" "1.1.1"
|
||||||
|
"@radix-ui/react-use-controllable-state" "1.1.0"
|
||||||
|
aria-hidden "^1.1.1"
|
||||||
|
react-remove-scroll "^2.6.1"
|
||||||
|
|
||||||
"@radix-ui/react-direction@1.1.0":
|
"@radix-ui/react-direction@1.1.0":
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-direction/-/react-direction-1.1.0.tgz#a7d39855f4d077adc2a1922f9c353c5977a09cdc"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-direction/-/react-direction-1.1.0.tgz#a7d39855f4d077adc2a1922f9c353c5977a09cdc"
|
||||||
integrity sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==
|
integrity sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==
|
||||||
|
|
||||||
|
"@radix-ui/react-dismissable-layer@1.0.5":
|
||||||
|
version "1.0.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz#3f98425b82b9068dfbab5db5fff3df6ebf48b9d4"
|
||||||
|
integrity sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/primitive" "1.0.1"
|
||||||
|
"@radix-ui/react-compose-refs" "1.0.1"
|
||||||
|
"@radix-ui/react-primitive" "1.0.3"
|
||||||
|
"@radix-ui/react-use-callback-ref" "1.0.1"
|
||||||
|
"@radix-ui/react-use-escape-keydown" "1.0.3"
|
||||||
|
|
||||||
"@radix-ui/react-dismissable-layer@1.1.1":
|
"@radix-ui/react-dismissable-layer@1.1.1":
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.1.tgz#cbdcb739c5403382bdde5f9243042ba643883396"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.1.tgz#cbdcb739c5403382bdde5f9243042ba643883396"
|
||||||
@@ -1157,6 +1346,17 @@
|
|||||||
"@radix-ui/react-use-callback-ref" "1.1.0"
|
"@radix-ui/react-use-callback-ref" "1.1.0"
|
||||||
"@radix-ui/react-use-escape-keydown" "1.1.0"
|
"@radix-ui/react-use-escape-keydown" "1.1.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-dismissable-layer@1.1.3":
|
||||||
|
version "1.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.3.tgz#4ee0f0f82d53bf5bd9db21665799bb0d1bad5ed8"
|
||||||
|
integrity sha512-onrWn/72lQoEucDmJnr8uczSNTujT0vJnA/X5+3AkChVPowr8n1yvIKIabhWyMQeMvvmdpsvcyDqx3X1LEXCPg==
|
||||||
|
dependencies:
|
||||||
|
"@radix-ui/primitive" "1.1.1"
|
||||||
|
"@radix-ui/react-compose-refs" "1.1.1"
|
||||||
|
"@radix-ui/react-primitive" "2.0.1"
|
||||||
|
"@radix-ui/react-use-callback-ref" "1.1.0"
|
||||||
|
"@radix-ui/react-use-escape-keydown" "1.1.0"
|
||||||
|
|
||||||
"@radix-ui/react-dropdown-menu@^2.1.2":
|
"@radix-ui/react-dropdown-menu@^2.1.2":
|
||||||
version "2.1.2"
|
version "2.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.2.tgz#acc49577130e3c875ef0133bd1e271ea3392d924"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.2.tgz#acc49577130e3c875ef0133bd1e271ea3392d924"
|
||||||
@@ -1170,11 +1370,28 @@
|
|||||||
"@radix-ui/react-primitive" "2.0.0"
|
"@radix-ui/react-primitive" "2.0.0"
|
||||||
"@radix-ui/react-use-controllable-state" "1.1.0"
|
"@radix-ui/react-use-controllable-state" "1.1.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-focus-guards@1.0.1":
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz#1ea7e32092216b946397866199d892f71f7f98ad"
|
||||||
|
integrity sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
"@radix-ui/react-focus-guards@1.1.1":
|
"@radix-ui/react-focus-guards@1.1.1":
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz#8635edd346304f8b42cae86b05912b61aef27afe"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz#8635edd346304f8b42cae86b05912b61aef27afe"
|
||||||
integrity sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==
|
integrity sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==
|
||||||
|
|
||||||
|
"@radix-ui/react-focus-scope@1.0.4":
|
||||||
|
version "1.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz#2ac45fce8c5bb33eb18419cdc1905ef4f1906525"
|
||||||
|
integrity sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-compose-refs" "1.0.1"
|
||||||
|
"@radix-ui/react-primitive" "1.0.3"
|
||||||
|
"@radix-ui/react-use-callback-ref" "1.0.1"
|
||||||
|
|
||||||
"@radix-ui/react-focus-scope@1.1.0":
|
"@radix-ui/react-focus-scope@1.1.0":
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz#ebe2891a298e0a33ad34daab2aad8dea31caf0b2"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz#ebe2891a298e0a33ad34daab2aad8dea31caf0b2"
|
||||||
@@ -1184,6 +1401,23 @@
|
|||||||
"@radix-ui/react-primitive" "2.0.0"
|
"@radix-ui/react-primitive" "2.0.0"
|
||||||
"@radix-ui/react-use-callback-ref" "1.1.0"
|
"@radix-ui/react-use-callback-ref" "1.1.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-focus-scope@1.1.1":
|
||||||
|
version "1.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.1.tgz#5c602115d1db1c4fcfa0fae4c3b09bb8919853cb"
|
||||||
|
integrity sha512-01omzJAYRxXdG2/he/+xy+c8a8gCydoQ1yOxnWNcRhrrBW5W+RQJ22EK1SaO8tb3WoUsuEw7mJjBozPzihDFjA==
|
||||||
|
dependencies:
|
||||||
|
"@radix-ui/react-compose-refs" "1.1.1"
|
||||||
|
"@radix-ui/react-primitive" "2.0.1"
|
||||||
|
"@radix-ui/react-use-callback-ref" "1.1.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-id@1.0.1":
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.0.1.tgz#73cdc181f650e4df24f0b6a5b7aa426b912c88c0"
|
||||||
|
integrity sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-use-layout-effect" "1.0.1"
|
||||||
|
|
||||||
"@radix-ui/react-id@1.1.0":
|
"@radix-ui/react-id@1.1.0":
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.1.0.tgz#de47339656594ad722eb87f94a6b25f9cffae0ed"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.1.0.tgz#de47339656594ad722eb87f94a6b25f9cffae0ed"
|
||||||
@@ -1222,6 +1456,27 @@
|
|||||||
aria-hidden "^1.1.1"
|
aria-hidden "^1.1.1"
|
||||||
react-remove-scroll "2.6.0"
|
react-remove-scroll "2.6.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-popover@^1.1.4":
|
||||||
|
version "1.1.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-popover/-/react-popover-1.1.4.tgz#d83104e5fb588870a673b55f3387da4844e5836e"
|
||||||
|
integrity sha512-aUACAkXx8LaFymDma+HQVji7WhvEhpFJ7+qPz17Nf4lLZqtreGOFRiNQWQmhzp7kEWg9cOyyQJpdIMUMPc/CPw==
|
||||||
|
dependencies:
|
||||||
|
"@radix-ui/primitive" "1.1.1"
|
||||||
|
"@radix-ui/react-compose-refs" "1.1.1"
|
||||||
|
"@radix-ui/react-context" "1.1.1"
|
||||||
|
"@radix-ui/react-dismissable-layer" "1.1.3"
|
||||||
|
"@radix-ui/react-focus-guards" "1.1.1"
|
||||||
|
"@radix-ui/react-focus-scope" "1.1.1"
|
||||||
|
"@radix-ui/react-id" "1.1.0"
|
||||||
|
"@radix-ui/react-popper" "1.2.1"
|
||||||
|
"@radix-ui/react-portal" "1.1.3"
|
||||||
|
"@radix-ui/react-presence" "1.1.2"
|
||||||
|
"@radix-ui/react-primitive" "2.0.1"
|
||||||
|
"@radix-ui/react-slot" "1.1.1"
|
||||||
|
"@radix-ui/react-use-controllable-state" "1.1.0"
|
||||||
|
aria-hidden "^1.1.1"
|
||||||
|
react-remove-scroll "^2.6.1"
|
||||||
|
|
||||||
"@radix-ui/react-popper@1.2.0":
|
"@radix-ui/react-popper@1.2.0":
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-1.2.0.tgz#a3e500193d144fe2d8f5d5e60e393d64111f2a7a"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-1.2.0.tgz#a3e500193d144fe2d8f5d5e60e393d64111f2a7a"
|
||||||
@@ -1238,6 +1493,30 @@
|
|||||||
"@radix-ui/react-use-size" "1.1.0"
|
"@radix-ui/react-use-size" "1.1.0"
|
||||||
"@radix-ui/rect" "1.1.0"
|
"@radix-ui/rect" "1.1.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-popper@1.2.1":
|
||||||
|
version "1.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-1.2.1.tgz#2fc66cfc34f95f00d858924e3bee54beae2dff0a"
|
||||||
|
integrity sha512-3kn5Me69L+jv82EKRuQCXdYyf1DqHwD2U/sxoNgBGCB7K9TRc3bQamQ+5EPM9EvyPdli0W41sROd+ZU1dTCztw==
|
||||||
|
dependencies:
|
||||||
|
"@floating-ui/react-dom" "^2.0.0"
|
||||||
|
"@radix-ui/react-arrow" "1.1.1"
|
||||||
|
"@radix-ui/react-compose-refs" "1.1.1"
|
||||||
|
"@radix-ui/react-context" "1.1.1"
|
||||||
|
"@radix-ui/react-primitive" "2.0.1"
|
||||||
|
"@radix-ui/react-use-callback-ref" "1.1.0"
|
||||||
|
"@radix-ui/react-use-layout-effect" "1.1.0"
|
||||||
|
"@radix-ui/react-use-rect" "1.1.0"
|
||||||
|
"@radix-ui/react-use-size" "1.1.0"
|
||||||
|
"@radix-ui/rect" "1.1.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-portal@1.0.4":
|
||||||
|
version "1.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.0.4.tgz#df4bfd353db3b1e84e639e9c63a5f2565fb00e15"
|
||||||
|
integrity sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-primitive" "1.0.3"
|
||||||
|
|
||||||
"@radix-ui/react-portal@1.1.2":
|
"@radix-ui/react-portal@1.1.2":
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.1.2.tgz#51eb46dae7505074b306ebcb985bf65cc547d74e"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.1.2.tgz#51eb46dae7505074b306ebcb985bf65cc547d74e"
|
||||||
@@ -1246,6 +1525,23 @@
|
|||||||
"@radix-ui/react-primitive" "2.0.0"
|
"@radix-ui/react-primitive" "2.0.0"
|
||||||
"@radix-ui/react-use-layout-effect" "1.1.0"
|
"@radix-ui/react-use-layout-effect" "1.1.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-portal@1.1.3":
|
||||||
|
version "1.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.1.3.tgz#b0ea5141103a1671b715481b13440763d2ac4440"
|
||||||
|
integrity sha512-NciRqhXnGojhT93RPyDaMPfLH3ZSl4jjIFbZQ1b/vxvZEdHsBZ49wP9w8L3HzUQwep01LcWtkUvm0OVB5JAHTw==
|
||||||
|
dependencies:
|
||||||
|
"@radix-ui/react-primitive" "2.0.1"
|
||||||
|
"@radix-ui/react-use-layout-effect" "1.1.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-presence@1.0.1":
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.0.1.tgz#491990ba913b8e2a5db1b06b203cb24b5cdef9ba"
|
||||||
|
integrity sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-compose-refs" "1.0.1"
|
||||||
|
"@radix-ui/react-use-layout-effect" "1.0.1"
|
||||||
|
|
||||||
"@radix-ui/react-presence@1.1.1":
|
"@radix-ui/react-presence@1.1.1":
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.1.1.tgz#98aba423dba5e0c687a782c0669dcd99de17f9b1"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.1.1.tgz#98aba423dba5e0c687a782c0669dcd99de17f9b1"
|
||||||
@@ -1362,6 +1658,14 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz#bce938ca413675bc937944b0d01ef6f4a6dc5bf1"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz#bce938ca413675bc937944b0d01ef6f4a6dc5bf1"
|
||||||
integrity sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==
|
integrity sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==
|
||||||
|
|
||||||
|
"@radix-ui/react-use-controllable-state@1.0.1":
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz#ecd2ced34e6330caf89a82854aa2f77e07440286"
|
||||||
|
integrity sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-use-callback-ref" "1.0.1"
|
||||||
|
|
||||||
"@radix-ui/react-use-controllable-state@1.1.0":
|
"@radix-ui/react-use-controllable-state@1.1.0":
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz#1321446857bb786917df54c0d4d084877aab04b0"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz#1321446857bb786917df54c0d4d084877aab04b0"
|
||||||
@@ -1369,6 +1673,14 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@radix-ui/react-use-callback-ref" "1.1.0"
|
"@radix-ui/react-use-callback-ref" "1.1.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-use-escape-keydown@1.0.3":
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz#217b840c250541609c66f67ed7bab2b733620755"
|
||||||
|
integrity sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-use-callback-ref" "1.0.1"
|
||||||
|
|
||||||
"@radix-ui/react-use-escape-keydown@1.1.0":
|
"@radix-ui/react-use-escape-keydown@1.1.0":
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz#31a5b87c3b726504b74e05dac1edce7437b98754"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz#31a5b87c3b726504b74e05dac1edce7437b98754"
|
||||||
@@ -1453,6 +1765,11 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
tslib "^2.4.0"
|
tslib "^2.4.0"
|
||||||
|
|
||||||
|
"@types/aws-lambda@^8.10.83":
|
||||||
|
version "8.10.146"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/aws-lambda/-/aws-lambda-8.10.146.tgz#05f9968d8cd9719a0a86526baf889c25761f60b8"
|
||||||
|
integrity sha512-3BaDXYTh0e6UCJYL/jwV/3+GRslSc08toAiZSmleYtkAUyV5rtvdPYxrG/88uqvTuT6sb27WE9OS90ZNTIuQ0g==
|
||||||
|
|
||||||
"@types/json5@^0.0.29":
|
"@types/json5@^0.0.29":
|
||||||
version "0.0.29"
|
version "0.0.29"
|
||||||
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
|
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
|
||||||
@@ -1993,6 +2310,14 @@ cluster-key-slot@^1.1.0:
|
|||||||
resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz#88ddaa46906e303b5de30d3153b7d9fe0a0c19ac"
|
resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz#88ddaa46906e303b5de30d3153b7d9fe0a0c19ac"
|
||||||
integrity sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==
|
integrity sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==
|
||||||
|
|
||||||
|
cmdk@1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/cmdk/-/cmdk-1.0.0.tgz#0a095fdafca3dfabed82d1db78a6262fb163ded9"
|
||||||
|
integrity sha512-gDzVf0a09TvoJ5jnuPvygTB77+XdOSwEmJ88L6XPFPlv7T3RxbP9jgenfylrAMD0+Le1aO0nVjQUzl2g+vjz5Q==
|
||||||
|
dependencies:
|
||||||
|
"@radix-ui/react-dialog" "1.0.5"
|
||||||
|
"@radix-ui/react-primitive" "1.0.3"
|
||||||
|
|
||||||
code-block-writer@^12.0.0:
|
code-block-writer@^12.0.0:
|
||||||
version "12.0.0"
|
version "12.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/code-block-writer/-/code-block-writer-12.0.0.tgz#4dd58946eb4234105aff7f0035977b2afdc2a770"
|
resolved "https://registry.yarnpkg.com/code-block-writer/-/code-block-writer-12.0.0.tgz#4dd58946eb4234105aff7f0035977b2afdc2a770"
|
||||||
@@ -4240,6 +4565,14 @@ react-is@^16.13.1:
|
|||||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||||
|
|
||||||
|
react-remove-scroll-bar@^2.3.3, react-remove-scroll-bar@^2.3.7:
|
||||||
|
version "2.3.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz#99c20f908ee467b385b68a3469b4a3e750012223"
|
||||||
|
integrity sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==
|
||||||
|
dependencies:
|
||||||
|
react-style-singleton "^2.2.2"
|
||||||
|
tslib "^2.0.0"
|
||||||
|
|
||||||
react-remove-scroll-bar@^2.3.6:
|
react-remove-scroll-bar@^2.3.6:
|
||||||
version "2.3.6"
|
version "2.3.6"
|
||||||
resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz#3e585e9d163be84a010180b18721e851ac81a29c"
|
resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz#3e585e9d163be84a010180b18721e851ac81a29c"
|
||||||
@@ -4248,6 +4581,17 @@ react-remove-scroll-bar@^2.3.6:
|
|||||||
react-style-singleton "^2.2.1"
|
react-style-singleton "^2.2.1"
|
||||||
tslib "^2.0.0"
|
tslib "^2.0.0"
|
||||||
|
|
||||||
|
react-remove-scroll@2.5.5:
|
||||||
|
version "2.5.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz#1e31a1260df08887a8a0e46d09271b52b3a37e77"
|
||||||
|
integrity sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==
|
||||||
|
dependencies:
|
||||||
|
react-remove-scroll-bar "^2.3.3"
|
||||||
|
react-style-singleton "^2.2.1"
|
||||||
|
tslib "^2.1.0"
|
||||||
|
use-callback-ref "^1.3.0"
|
||||||
|
use-sidecar "^1.1.2"
|
||||||
|
|
||||||
react-remove-scroll@2.6.0:
|
react-remove-scroll@2.6.0:
|
||||||
version "2.6.0"
|
version "2.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.6.0.tgz#fb03a0845d7768a4f1519a99fdb84983b793dc07"
|
resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.6.0.tgz#fb03a0845d7768a4f1519a99fdb84983b793dc07"
|
||||||
@@ -4259,6 +4603,17 @@ react-remove-scroll@2.6.0:
|
|||||||
use-callback-ref "^1.3.0"
|
use-callback-ref "^1.3.0"
|
||||||
use-sidecar "^1.1.2"
|
use-sidecar "^1.1.2"
|
||||||
|
|
||||||
|
react-remove-scroll@^2.6.1:
|
||||||
|
version "2.6.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.6.2.tgz#2518d2c5112e71ea8928f1082a58459b5c7a2a97"
|
||||||
|
integrity sha512-KmONPx5fnlXYJQqC62Q+lwIeAk64ws/cUw6omIumRzMRPqgnYqhSSti99nbj0Ry13bv7dF+BKn7NB+OqkdZGTw==
|
||||||
|
dependencies:
|
||||||
|
react-remove-scroll-bar "^2.3.7"
|
||||||
|
react-style-singleton "^2.2.1"
|
||||||
|
tslib "^2.1.0"
|
||||||
|
use-callback-ref "^1.3.3"
|
||||||
|
use-sidecar "^1.1.2"
|
||||||
|
|
||||||
react-style-singleton@^2.2.1:
|
react-style-singleton@^2.2.1:
|
||||||
version "2.2.1"
|
version "2.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.1.tgz#f99e420492b2d8f34d38308ff660b60d0b1205b4"
|
resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.1.tgz#f99e420492b2d8f34d38308ff660b60d0b1205b4"
|
||||||
@@ -4268,6 +4623,14 @@ react-style-singleton@^2.2.1:
|
|||||||
invariant "^2.2.4"
|
invariant "^2.2.4"
|
||||||
tslib "^2.0.0"
|
tslib "^2.0.0"
|
||||||
|
|
||||||
|
react-style-singleton@^2.2.2:
|
||||||
|
version "2.2.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.3.tgz#4265608be69a4d70cfe3047f2c6c88b2c3ace388"
|
||||||
|
integrity sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==
|
||||||
|
dependencies:
|
||||||
|
get-nonce "^1.0.0"
|
||||||
|
tslib "^2.0.0"
|
||||||
|
|
||||||
react@^19.0.0-rc.1:
|
react@^19.0.0-rc.1:
|
||||||
version "19.0.0-rc.1"
|
version "19.0.0-rc.1"
|
||||||
resolved "https://registry.yarnpkg.com/react/-/react-19.0.0-rc.1.tgz#469cc8ae6bdba224dcaab10ad6c4d90843f21352"
|
resolved "https://registry.yarnpkg.com/react/-/react-19.0.0-rc.1.tgz#469cc8ae6bdba224dcaab10ad6c4d90843f21352"
|
||||||
@@ -4941,6 +5304,11 @@ to-regex-range@^5.0.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
is-number "^7.0.0"
|
is-number "^7.0.0"
|
||||||
|
|
||||||
|
toad-cache@^3.7.0:
|
||||||
|
version "3.7.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/toad-cache/-/toad-cache-3.7.0.tgz#b9b63304ea7c45ec34d91f1d2fa513517025c441"
|
||||||
|
integrity sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==
|
||||||
|
|
||||||
ts-api-utils@^1.3.0:
|
ts-api-utils@^1.3.0:
|
||||||
version "1.4.3"
|
version "1.4.3"
|
||||||
resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.4.3.tgz#bfc2215fe6528fecab2b0fba570a2e8a4263b064"
|
resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.4.3.tgz#bfc2215fe6528fecab2b0fba570a2e8a4263b064"
|
||||||
@@ -5089,6 +5457,11 @@ undici-types@~5.26.4:
|
|||||||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
|
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
|
||||||
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
|
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
|
||||||
|
|
||||||
|
universal-github-app-jwt@^2.2.0:
|
||||||
|
version "2.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/universal-github-app-jwt/-/universal-github-app-jwt-2.2.0.tgz#dc6c8929e76f1996a766ba2a08fb420f73365d77"
|
||||||
|
integrity sha512-G5o6f95b5BggDGuUfKDApKaCgNYy2x7OdHY0zSMF081O0EJobw+1130VONhrA7ezGSV2FNOGyM+KQpQZAr9bIQ==
|
||||||
|
|
||||||
universal-user-agent@^7.0.0, universal-user-agent@^7.0.2:
|
universal-user-agent@^7.0.0, universal-user-agent@^7.0.2:
|
||||||
version "7.0.2"
|
version "7.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-7.0.2.tgz#52e7d0e9b3dc4df06cc33cb2b9fd79041a54827e"
|
resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-7.0.2.tgz#52e7d0e9b3dc4df06cc33cb2b9fd79041a54827e"
|
||||||
@@ -5121,6 +5494,13 @@ use-callback-ref@^1.3.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
tslib "^2.0.0"
|
tslib "^2.0.0"
|
||||||
|
|
||||||
|
use-callback-ref@^1.3.3:
|
||||||
|
version "1.3.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.3.3.tgz#98d9fab067075841c5b2c6852090d5d0feabe2bf"
|
||||||
|
integrity sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==
|
||||||
|
dependencies:
|
||||||
|
tslib "^2.0.0"
|
||||||
|
|
||||||
use-sidecar@^1.1.2:
|
use-sidecar@^1.1.2:
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.2.tgz#2f43126ba2d7d7e117aa5855e5d8f0276dfe73c2"
|
resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.2.tgz#2f43126ba2d7d7e117aa5855e5d8f0276dfe73c2"
|
||||||
|
|||||||
Reference in New Issue
Block a user