mirror of
https://github.com/SrIzan10/hctv.git
synced 2026-06-06 00:56:56 +00:00
feat: initial chat and abstract auth away from next
This commit is contained in:
28
apps/chat/.gitignore
vendored
Normal file
28
apps/chat/.gitignore
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
# dev
|
||||
.yarn/
|
||||
!.yarn/releases
|
||||
.vscode/*
|
||||
!.vscode/launch.json
|
||||
!.vscode/*.code-snippets
|
||||
.idea/workspace.xml
|
||||
.idea/usage.statistics.xml
|
||||
.idea/shelf
|
||||
|
||||
# deps
|
||||
node_modules/
|
||||
|
||||
# env
|
||||
.env
|
||||
.env.production
|
||||
|
||||
# logs
|
||||
logs/
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
8
apps/chat/README.md
Normal file
8
apps/chat/README.md
Normal file
@@ -0,0 +1,8 @@
|
||||
```
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
```
|
||||
open http://localhost:3000
|
||||
```
|
||||
19
apps/chat/package.json
Normal file
19
apps/chat/package.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "@hctv/chat",
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "tsx watch src/index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hctv/db": "*",
|
||||
"@hono/node-server": "^1.14.0",
|
||||
"@hono/node-ws": "^1.1.0",
|
||||
"@oslojs/encoding": "^1.1.0",
|
||||
"hono": "^4.7.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.11.17",
|
||||
"tsx": "^4.7.1"
|
||||
}
|
||||
}
|
||||
15
apps/chat/src/3d.txt
Normal file
15
apps/chat/src/3d.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
,---, ___
|
||||
,--.' | ,--.'|_
|
||||
| | : | | :,'
|
||||
: : : : : ' : .---.
|
||||
: | |,--. ,---. .;__,' / /. ./|
|
||||
| : ' | / \| | | .-' . ' |
|
||||
| | /' : / / ':__,'| : /___/ \: |
|
||||
' : | | |. ' / ' : |__. \ ' .
|
||||
| | ' | :' ; :__ | | '.'|\ \ '
|
||||
| : :_:,'' | '.'| ; : ; \ \
|
||||
| | ,' | : : | , / \ \ |
|
||||
`--'' \ \ / ---`-' '---"
|
||||
`----'
|
||||
|
||||
This is hctv's chat backend. There's not much here, so go back to where you came from :)
|
||||
27
apps/chat/src/index.ts
Normal file
27
apps/chat/src/index.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { serve } from '@hono/node-server'
|
||||
import { createNodeWebSocket } from '@hono/node-ws'
|
||||
import { Hono } from 'hono'
|
||||
import { readFile } from 'node:fs/promises'
|
||||
|
||||
const threed = await readFile('./src/3d.txt', 'utf-8')
|
||||
|
||||
const app = new Hono()
|
||||
const { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({ app })
|
||||
|
||||
app.get('/', async (c) => {
|
||||
return c.text(threed)
|
||||
})
|
||||
|
||||
app.get(
|
||||
'/ws',
|
||||
upgradeWebSocket((c) => ({
|
||||
// https://hono.dev/helpers/websocket
|
||||
}))
|
||||
)
|
||||
|
||||
serve({
|
||||
fetch: app.fetch,
|
||||
port: 8000,
|
||||
}, (info) => {
|
||||
console.log(`Server is running on http://localhost:${info.port}`)
|
||||
})
|
||||
14
apps/chat/tsconfig.json
Normal file
14
apps/chat/tsconfig.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"module": "NodeNext",
|
||||
"strict": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"skipLibCheck": true,
|
||||
"types": [
|
||||
"node"
|
||||
],
|
||||
"jsx": "react-jsx",
|
||||
"jsxImportSource": "hono/jsx",
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,14 @@ const nextConfig = {
|
||||
reactStrictMode: false,
|
||||
output: 'standalone',
|
||||
outputFileTracingRoot: path.join(__dirname, '../../'),
|
||||
async rewrites() {
|
||||
return [
|
||||
{
|
||||
source: '/api/chat/:path*',
|
||||
destination: `http://localhost:8000/:path*`,
|
||||
},
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
export default nextConfig;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
"check-types": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hctv/auth": "*",
|
||||
"@hctv/db": "*",
|
||||
"@hookform/resolvers": "^3.9.1",
|
||||
"@livekit/components-react": "^2.7.0",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { validateRequest } from "@/lib/auth";
|
||||
import { validateRequest } from '@/lib/auth/validate';
|
||||
import fsP from 'fs/promises';
|
||||
import fs from 'fs';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { validateRequest } from "@/lib/auth";
|
||||
import { validateRequest } from '@/lib/auth/validate';
|
||||
import prisma from '@hctv/db';
|
||||
import { NextRequest } from "next/server";
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { lucia } from '@/lib/auth';
|
||||
import { lucia } from '@hctv/auth';
|
||||
import prisma from '@hctv/db';
|
||||
import { resolveUserPersonalChannel } from '@/lib/db/resolve';
|
||||
import type { WebSocket } from 'ws';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { validateRequest } from '@/lib/auth';
|
||||
import { validateRequest } from '@/lib/auth/validate';
|
||||
import prisma from '@hctv/db';
|
||||
import { NextRequest } from 'next/server';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { validateRequest } from '@/lib/auth';
|
||||
import { validateRequest } from '@/lib/auth/validate';
|
||||
import prisma from '@hctv/db';
|
||||
import type { NextRequest } from 'next/server';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { validateRequest } from '@/lib/auth';
|
||||
import { validateRequest } from '@/lib/auth/validate';
|
||||
import { redirect, RedirectType } from 'next/navigation';
|
||||
|
||||
export default async function Layout({ children }: { children: React.ReactNode }) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { slack, lucia } from '@/lib/auth';
|
||||
import { slack, lucia } from '@hctv/auth';
|
||||
import { cookies as nextCookies } from 'next/headers';
|
||||
import { decodeIdToken, OAuth2RequestError } from 'arctic';
|
||||
import { generateIdFromEntropySize } from 'lucia';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { generateState } from "arctic";
|
||||
import { slack } from "@/lib/auth";
|
||||
import { slack } from '@hctv/auth';
|
||||
import { cookies } from "next/headers";
|
||||
|
||||
export async function GET(): Promise<Response> {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { validateRequest } from "@/lib/auth";
|
||||
import { validateRequest } from '@/lib/auth/validate';
|
||||
import { redirect } from "next/navigation";
|
||||
import OnboardingClient from "./page.client";
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import LandingPage from '@/components/app/LandingPage/LandingPage';
|
||||
import { Card, CardContent } from '@/components/ui/card';
|
||||
import ConfusedDino from '@/components/ui/confuseddino';
|
||||
import { validateRequest } from '@/lib/auth';
|
||||
import { validateRequest } from '@/lib/auth/validate';
|
||||
import prisma from '@hctv/db';
|
||||
import { Avatar, AvatarImage, AvatarFallback } from '@radix-ui/react-avatar';
|
||||
import Image from 'next/image';
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Inter } from 'next/font/google';
|
||||
import './globals.css';
|
||||
import Navbar from '@/components/app/NavBar/NavBar';
|
||||
import { SessionProvider } from '@/lib/providers/SessionProvider';
|
||||
import { validateRequest } from '@/lib/auth';
|
||||
import { validateRequest } from '@/lib/auth/validate';
|
||||
import { Toaster } from '@/components/ui/sonner';
|
||||
import { ThemeProvider } from '@/lib/providers/ThemeProvider';
|
||||
import { SidebarProvider } from '@/components/ui/sidebar';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { validateRequest } from '@/lib/auth';
|
||||
import { validateRequest } from '@/lib/auth/validate';
|
||||
import prisma from '@hctv/db';
|
||||
import EditLivestreamDialog from './dialog';
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { PrismaAdapter } from '@lucia-auth/adapter-prisma';
|
||||
import { Lucia } from 'lucia';
|
||||
import prisma from '@hctv/db';
|
||||
import { cache } from 'react';
|
||||
import { cookies } from 'next/headers';
|
||||
import { Slack } from 'arctic';
|
||||
|
||||
const adapter = new PrismaAdapter(prisma.session, prisma.user);
|
||||
@@ -26,33 +24,6 @@ export const lucia = new Lucia(adapter, {
|
||||
};
|
||||
},
|
||||
});
|
||||
export const validateRequest = cache(async () => {
|
||||
const sessionId = (await cookies()).get(lucia.sessionCookieName)?.value ?? null;
|
||||
|
||||
if (!sessionId)
|
||||
return {
|
||||
user: null,
|
||||
session: null,
|
||||
};
|
||||
|
||||
const { user, session } = await lucia.validateSession(sessionId);
|
||||
try {
|
||||
if (session && session.fresh) {
|
||||
const sessionCookie = lucia.createSessionCookie(session.id);
|
||||
(await cookies()).set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
|
||||
}
|
||||
if (!session) {
|
||||
const sessionCookie = lucia.createBlankSessionCookie();
|
||||
(await cookies()).set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
|
||||
}
|
||||
} catch {
|
||||
// Next.js throws error attempting to set cookies when rendering page
|
||||
}
|
||||
return {
|
||||
user,
|
||||
session,
|
||||
};
|
||||
});
|
||||
|
||||
declare module 'lucia' {
|
||||
interface Register {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { validateRequest } from ".";
|
||||
import { validateRequest } from '@/lib/auth/validate';
|
||||
import prisma from '@hctv/db';
|
||||
|
||||
export async function getPersonalChannel(id?: string) {
|
||||
@@ -15,4 +15,4 @@ export async function getPersonalChannel(id?: string) {
|
||||
return null;
|
||||
}
|
||||
return db.personalChannel;
|
||||
}
|
||||
}
|
||||
|
||||
31
apps/web/src/lib/auth/validate.ts
Normal file
31
apps/web/src/lib/auth/validate.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { cookies } from "next/headers";
|
||||
import { cache } from "react";
|
||||
import { lucia } from '@hctv/auth';
|
||||
|
||||
export const validateRequest = cache(async () => {
|
||||
const sessionId = (await cookies()).get(lucia.sessionCookieName)?.value ?? null;
|
||||
|
||||
if (!sessionId)
|
||||
return {
|
||||
user: null,
|
||||
session: null,
|
||||
};
|
||||
|
||||
const { user, session } = await lucia.validateSession(sessionId);
|
||||
try {
|
||||
if (session && session.fresh) {
|
||||
const sessionCookie = lucia.createSessionCookie(session.id);
|
||||
(await cookies()).set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
|
||||
}
|
||||
if (!session) {
|
||||
const sessionCookie = lucia.createBlankSessionCookie();
|
||||
(await cookies()).set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
|
||||
}
|
||||
} catch {
|
||||
// Next.js throws error attempting to set cookies when rendering page
|
||||
}
|
||||
return {
|
||||
user,
|
||||
session,
|
||||
};
|
||||
});
|
||||
@@ -1,7 +1,7 @@
|
||||
'use server';
|
||||
|
||||
import { revalidatePath } from 'next/cache';
|
||||
import { validateRequest } from '../auth';
|
||||
import { validateRequest } from '@/lib/auth/validate';
|
||||
import prisma from '@hctv/db';
|
||||
import zodVerify from '../zodVerify';
|
||||
import { onboardSchema, streamInfoEditSchema } from './zod';
|
||||
|
||||
12
packages/auth/package.json
Normal file
12
packages/auth/package.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "@hctv/auth",
|
||||
"version": "0.0.0",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hctv/db": "*",
|
||||
"@lucia-auth/adapter-prisma": "^4.0.1",
|
||||
"arctic": "^3.1.1"
|
||||
}
|
||||
}
|
||||
39
packages/auth/src/index.ts
Normal file
39
packages/auth/src/index.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { PrismaAdapter } from '@lucia-auth/adapter-prisma';
|
||||
import { Lucia } from 'lucia';
|
||||
import prisma from '@hctv/db';
|
||||
import { Slack } from 'arctic';
|
||||
|
||||
const adapter = new PrismaAdapter(prisma.session, prisma.user);
|
||||
export const slack = new Slack(process.env.SLACK_ID!, process.env.SLACK_SECRET!, process.env.SLACK_REDIRECT_URI!);
|
||||
|
||||
export const lucia = new Lucia(adapter, {
|
||||
sessionCookie: {
|
||||
// this sets cookies with super long expiration
|
||||
// since Next.js doesn't allow Lucia to extend cookie expiration when rendering pages
|
||||
expires: false,
|
||||
attributes: {
|
||||
// set to `true` when using HTTPS
|
||||
secure: process.env.NODE_ENV === 'production',
|
||||
},
|
||||
},
|
||||
getUserAttributes: (attributes) => {
|
||||
return {
|
||||
slack_id: attributes.slack_id,
|
||||
pfpUrl: attributes.pfpUrl,
|
||||
hasOnboarded: attributes.hasOnboarded,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
declare module 'lucia' {
|
||||
interface Register {
|
||||
Lucia: typeof lucia;
|
||||
DatabaseUserAttributes: DatabaseUserAttributes;
|
||||
}
|
||||
}
|
||||
|
||||
interface DatabaseUserAttributes {
|
||||
slack_id: string;
|
||||
pfpUrl: string;
|
||||
hasOnboarded: boolean;
|
||||
}
|
||||
@@ -22,7 +22,7 @@
|
||||
"cache": false
|
||||
},
|
||||
"dd": {
|
||||
"persistent": true,
|
||||
"persistent": false,
|
||||
"cache": false
|
||||
},
|
||||
"db:generate": {
|
||||
|
||||
37
yarn.lock
37
yarn.lock
@@ -455,6 +455,18 @@
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.9.tgz#50dea3616bc8191fb8e112283b49eaff03e78429"
|
||||
integrity sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==
|
||||
|
||||
"@hono/node-server@^1.14.0":
|
||||
version "1.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@hono/node-server/-/node-server-1.14.0.tgz#b64f7e6b10dbc0fa0642e8a0a1c03c2abf2b391c"
|
||||
integrity sha512-YUCxJwgHRKSqjrdTk9e4VMGKN27MK5r4+MGPyZTgKH+IYbK+KtYbHeOcPGJ91KGGD6RIQiz2dAHxvjauNhOS8g==
|
||||
|
||||
"@hono/node-ws@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@hono/node-ws/-/node-ws-1.1.0.tgz#aefb18f31a2e67d71787a5838110f156fa819183"
|
||||
integrity sha512-uHaz1EPguJqsUmA+Jmhdi/DTRAMs2Fvcy7qno9E48rlK3WBtyGQw4u4DKlc+o18Nh1DGz2oA1n9hCzEyhVBeLw==
|
||||
dependencies:
|
||||
ws "^8.17.0"
|
||||
|
||||
"@hookform/resolvers@^3.9.1":
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@hookform/resolvers/-/resolvers-3.10.0.tgz#7bfd18113daca4e57e27e1205b7d5a2d371aa59a"
|
||||
@@ -1478,7 +1490,7 @@
|
||||
dependencies:
|
||||
undici-types "~6.20.0"
|
||||
|
||||
"@types/node@^20":
|
||||
"@types/node@^20", "@types/node@^20.11.17":
|
||||
version "20.17.25"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.17.25.tgz#3135ad0af2b46a7689aa5ffb3ecafe1f50171a29"
|
||||
integrity sha512-bT+r2haIlplJUYtlZrEanFHdPIZTeiMeh/fSOEbOOfWf9uTn+lg8g0KU6Q3iMgjd9FLuuMAgfCNSkjUbxL6E3Q==
|
||||
@@ -2549,7 +2561,7 @@ esbuild-register@3.6.0:
|
||||
dependencies:
|
||||
debug "^4.3.4"
|
||||
|
||||
"esbuild@>=0.12 <1":
|
||||
"esbuild@>=0.12 <1", esbuild@~0.25.0:
|
||||
version "0.25.1"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.25.1.tgz#a16b8d070b6ad4871935277bda6ccfe852e3fa2f"
|
||||
integrity sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==
|
||||
@@ -2959,7 +2971,7 @@ fs.realpath@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
|
||||
|
||||
fsevents@2.3.3, fsevents@~2.3.2:
|
||||
fsevents@2.3.3, fsevents@~2.3.2, fsevents@~2.3.3:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
|
||||
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
|
||||
@@ -3039,7 +3051,7 @@ get-symbol-description@^1.1.0:
|
||||
es-errors "^1.3.0"
|
||||
get-intrinsic "^1.2.6"
|
||||
|
||||
get-tsconfig@^4.10.0:
|
||||
get-tsconfig@^4.10.0, get-tsconfig@^4.7.5:
|
||||
version "4.10.0"
|
||||
resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.10.0.tgz#403a682b373a823612475a4c2928c7326fc0f6bb"
|
||||
integrity sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==
|
||||
@@ -3176,6 +3188,11 @@ hls.js@^1.5.11:
|
||||
resolved "https://registry.yarnpkg.com/hls.js/-/hls.js-1.5.20.tgz#7eb23bb5e2595311d4e2761038ca6882673de7e2"
|
||||
integrity sha512-uu0VXUK52JhihhnN/MVVo1lvqNNuhoxkonqgO3IpjvQiGpJBdIXMGkofjQb/j9zvV7a1SW8U9g1FslWx/1HOiQ==
|
||||
|
||||
hono@^4.7.5:
|
||||
version "4.7.5"
|
||||
resolved "https://registry.yarnpkg.com/hono/-/hono-4.7.5.tgz#5e28b48384971c16e011fe6f7b95668655d4b855"
|
||||
integrity sha512-fDOK5W2C1vZACsgLONigdZTRZxuBqFtcKh7bUQ5cVSbwI2RWjloJDcgFOVzbQrlI6pCmhlTsVYZ7zpLj4m4qMQ==
|
||||
|
||||
htmlparser2@^9.1.0:
|
||||
version "9.1.0"
|
||||
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-9.1.0.tgz#cdb498d8a75a51f739b61d3f718136c369bc8c23"
|
||||
@@ -5068,6 +5085,16 @@ tslib@2.8.1, tslib@^2.0.0, tslib@^2.0.1, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.8.
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"
|
||||
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
|
||||
|
||||
tsx@^4.7.1:
|
||||
version "4.19.3"
|
||||
resolved "https://registry.yarnpkg.com/tsx/-/tsx-4.19.3.tgz#2bdbcb87089374d933596f8645615142ed727666"
|
||||
integrity sha512-4H8vUNGNjQ4V2EOoGw005+c+dGuPSnhpPBPHBtsZdGZBk/iJb4kguGlPWaZTZ3q5nMtFOEsY0nRDlh9PJyd6SQ==
|
||||
dependencies:
|
||||
esbuild "~0.25.0"
|
||||
get-tsconfig "^4.7.5"
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.3"
|
||||
|
||||
turbo-darwin-64@2.4.4:
|
||||
version "2.4.4"
|
||||
resolved "https://registry.yarnpkg.com/turbo-darwin-64/-/turbo-darwin-64-2.4.4.tgz#2508d9b3b358bb91e8745be3e62284621a2b8721"
|
||||
@@ -5392,7 +5419,7 @@ wrappy@1:
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
|
||||
|
||||
ws@^8.18.1:
|
||||
ws@^8.17.0, ws@^8.18.1:
|
||||
version "8.18.1"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.1.tgz#ea131d3784e1dfdff91adb0a4a116b127515e3cb"
|
||||
integrity sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==
|
||||
|
||||
Reference in New Issue
Block a user