mirror of
https://github.com/Steffo99/festa.git
synced 2024-12-22 14:44:21 +00:00
THINGS
This commit is contained in:
parent
e1409f3545
commit
6673b9fd15
23 changed files with 360 additions and 164 deletions
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
|
@ -9,7 +9,7 @@
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"runtimeArgs": [
|
"runtimeArgs": [
|
||||||
"run",
|
"run",
|
||||||
"dev",
|
"app:dev",
|
||||||
],
|
],
|
||||||
"runtimeExecutable": "yarn",
|
"runtimeExecutable": "yarn",
|
||||||
"skipFiles": [
|
"skipFiles": [
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
import { Trans, useTranslation } from "next-i18next"
|
|
||||||
import { LoginContext } from "../contexts/login"
|
|
||||||
import { useDefinedContext } from "../utils/definedContext"
|
|
||||||
import { InputSlug } from "./InputEventSlug"
|
|
||||||
import { LoginButton } from "./LoginButton"
|
|
||||||
import { LogoutLink } from "./LogoutLink"
|
|
||||||
import { TelegramUser } from "./TelegramUser"
|
|
||||||
|
|
||||||
|
|
||||||
export function Intro() {
|
|
||||||
const {t} = useTranslation("common")
|
|
||||||
const [login, _] = useDefinedContext(LoginContext)
|
|
||||||
|
|
||||||
const loginMessage = login ? <>
|
|
||||||
<Trans i18nKey="introTelegramLoggedIn">
|
|
||||||
introTelegramLoggedIn(1: <TelegramUser u={login}/>)
|
|
||||||
</Trans>
|
|
||||||
<br/>
|
|
||||||
<LogoutLink/>
|
|
||||||
</> : <>
|
|
||||||
{t("introTelegramLogin")}
|
|
||||||
</>
|
|
||||||
|
|
||||||
const input = login ? <>
|
|
||||||
<p>
|
|
||||||
{t("introCreateEvent")}
|
|
||||||
</p>
|
|
||||||
<form>
|
|
||||||
{window.location.protocol}//
|
|
||||||
{window.location.host}/events/
|
|
||||||
<InputSlug
|
|
||||||
placeholder={t("introCreateEventSlugPlaceholder")}
|
|
||||||
/>
|
|
||||||
<button aria-label="Continue" className="input-square input-positive">
|
|
||||||
→
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</> : <>
|
|
||||||
<LoginButton
|
|
||||||
botName="festaappbot"
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
|
|
||||||
return <>
|
|
||||||
<p>
|
|
||||||
{loginMessage}
|
|
||||||
</p>
|
|
||||||
{input}
|
|
||||||
</>
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
import * as React from 'react';
|
|
||||||
import {LoginContext} from "../contexts/login"
|
|
||||||
import OriginalTelegramLoginButton from 'react-telegram-login'
|
|
||||||
import { useDefinedContext } from '../utils/definedContext';
|
|
||||||
|
|
||||||
export function LoginButton(props: any) {
|
|
||||||
const [login, setLogin] = useDefinedContext(LoginContext)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="container-btn-telegram">
|
|
||||||
<OriginalTelegramLoginButton
|
|
||||||
dataOnauth={setLogin}
|
|
||||||
usePic={false}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -8,9 +8,11 @@ export function LogoutLink() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<small>
|
<small>
|
||||||
|
(
|
||||||
<a href="javascript:void(0)" onClick={() => setLogin(null)}>
|
<a href="javascript:void(0)" onClick={() => setLogin(null)}>
|
||||||
{t("introTelegramLogout")}
|
{t("introTelegramLogout")}
|
||||||
</a>
|
</a>
|
||||||
|
)
|
||||||
</small>
|
</small>
|
||||||
)
|
)
|
||||||
}
|
}
|
14
components/TelegramLoginButton.tsx
Normal file
14
components/TelegramLoginButton.tsx
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { default as OriginalTelegramLoginButton } from 'react-telegram-login'
|
||||||
|
|
||||||
|
|
||||||
|
export function TelegramLoginButton(props: any) {
|
||||||
|
return (
|
||||||
|
<div className="container-btn-telegram">
|
||||||
|
<OriginalTelegramLoginButton
|
||||||
|
usePic={false}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
41
components/TutorialTelegramLogin.tsx
Normal file
41
components/TutorialTelegramLogin.tsx
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
import { useTranslation } from "next-i18next"
|
||||||
|
import { useCallback } from "react"
|
||||||
|
import { LoginContext } from "../contexts/login"
|
||||||
|
import { useDefinedContext } from "../utils/definedContext"
|
||||||
|
import { TelegramLoginButton } from "./TelegramLoginButton"
|
||||||
|
import * as Telegram from "../utils/telegram"
|
||||||
|
import axios from "axios"
|
||||||
|
|
||||||
|
|
||||||
|
export function TutorialTelegramLogin() {
|
||||||
|
const { t } = useTranslation("common")
|
||||||
|
const [login, setLogin] = useDefinedContext(LoginContext)
|
||||||
|
|
||||||
|
const onLogin = useCallback(
|
||||||
|
async (data: Telegram.LoginData) => {
|
||||||
|
console.debug("[Telegram] Logged in successfully, now forwarding to the server...")
|
||||||
|
const response = await axios.post("/api/login/telegram", data)
|
||||||
|
console.info(response)
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!login) {
|
||||||
|
return <>
|
||||||
|
<div>
|
||||||
|
{t("introTelegramLogin")}
|
||||||
|
</div>
|
||||||
|
<TelegramLoginButton
|
||||||
|
dataOnauth={onLogin}
|
||||||
|
botName={process.env.NEXT_PUBLIC_TELEGRAM_USERNAME}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return <>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
}
|
17
package.json
17
package.json
|
@ -3,26 +3,33 @@
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"app:dev": "next dev",
|
||||||
"build": "next build",
|
"app:build": "next build",
|
||||||
"start": "next start",
|
"app:start": "next start",
|
||||||
"lint": "next lint"
|
"app:lint": "next lint",
|
||||||
|
"db:dev": "dotenv -e .env.local prisma db push --force-reset",
|
||||||
|
"db:generate": "dotenv -e .env.local prisma generate"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@prisma/client": "3.14.0",
|
"@prisma/client": "3.14.0",
|
||||||
|
"axios": "^0.27.2",
|
||||||
"classnames": "^2.3.1",
|
"classnames": "^2.3.1",
|
||||||
|
"cors": "^2.8.5",
|
||||||
|
"crypto-random-string": "^5.0.0",
|
||||||
"next": "12.1.6",
|
"next": "12.1.6",
|
||||||
"next-i18next": "^11.0.0",
|
"next-i18next": "^11.0.0",
|
||||||
"prisma": "^3.14.0",
|
"prisma": "^3.14.0",
|
||||||
"react": "18.1.0",
|
"react": "18.1.0",
|
||||||
"react-dom": "18.1.0",
|
"react-dom": "18.1.0",
|
||||||
"react-storage-hooks": "^4.0.1",
|
"react-storage-hooks": "^4.0.1",
|
||||||
"react-telegram-login": "^1.1.2"
|
"react-telegram-login": "^1.1.2",
|
||||||
|
"swr": "^1.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "17.0.35",
|
"@types/node": "17.0.35",
|
||||||
"@types/react": "18.0.9",
|
"@types/react": "18.0.9",
|
||||||
"@types/react-dom": "18.0.4",
|
"@types/react-dom": "18.0.4",
|
||||||
|
"dotenv-cli": "^5.1.0",
|
||||||
"eslint": "8.15.0",
|
"eslint": "8.15.0",
|
||||||
"eslint-config-next": "12.1.6",
|
"eslint-config-next": "12.1.6",
|
||||||
"typescript": "4.6.4"
|
"typescript": "4.6.4"
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
import '../styles/globals.css'
|
import '../styles/globals.css'
|
||||||
import '../styles/telegram.css'
|
|
||||||
import '../styles/postcard.css'
|
|
||||||
import "../styles/index.css"
|
|
||||||
import type { AppProps } from 'next/app'
|
import type { AppProps } from 'next/app'
|
||||||
import { LoginContext } from '../contexts/login'
|
import { LoginContext } from '../contexts/login'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
|
|
0
pages/api/.gitignore
vendored
0
pages/api/.gitignore
vendored
79
pages/api/login/telegram.ts
Normal file
79
pages/api/login/telegram.ts
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
import { NextApiRequest, NextApiResponse } from "next"
|
||||||
|
import { prisma } from "../../../utils/prismaClient"
|
||||||
|
import * as Telegram from "../../../utils/telegram"
|
||||||
|
import {default as cryptoRandomString} from "crypto-random-string"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
|
switch(req.method) {
|
||||||
|
case "POST":
|
||||||
|
const token = process.env.TELEGRAM_TOKEN
|
||||||
|
const validity_ms = parseInt(process.env.FESTA_TOKEN_VALIDITY_MS!) // Wrong typing?
|
||||||
|
const now = new Date()
|
||||||
|
|
||||||
|
if(!token) {
|
||||||
|
return res.status(503).json({error: "`TELEGRAM_TOKEN` was not set up"})
|
||||||
|
}
|
||||||
|
if(!validity_ms) {
|
||||||
|
return res.status(503).json({error: "`FESTA_TOKEN_VALIDITY_MS` was not set up"})
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
var lr: Telegram.LoginResponse = new Telegram.LoginResponse(req.body)
|
||||||
|
}
|
||||||
|
catch(_) {
|
||||||
|
return res.status(422).json({error: "Malformed data"})
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!lr.isRecent()) {
|
||||||
|
// Not sure?
|
||||||
|
return res.status(408).json({error: "Telegram login data is not recent"})
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!lr.isValid(token)) {
|
||||||
|
return res.status(401).json({error: "Telegram login data has been tampered"})
|
||||||
|
}
|
||||||
|
|
||||||
|
prisma.user.upsert({
|
||||||
|
where: {
|
||||||
|
id: lr.id,
|
||||||
|
},
|
||||||
|
update: {
|
||||||
|
id: lr.id,
|
||||||
|
firstName: lr.first_name,
|
||||||
|
lastName: lr.last_name,
|
||||||
|
username: lr.username,
|
||||||
|
photoUrl: lr.photo_url,
|
||||||
|
lastAuthDate: now,
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
id: lr.id,
|
||||||
|
firstName: lr.first_name,
|
||||||
|
lastName: lr.last_name,
|
||||||
|
username: lr.username,
|
||||||
|
photoUrl: lr.photo_url,
|
||||||
|
lastAuthDate: now,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const tokenString = cryptoRandomString({length: 16, type: "base64"})
|
||||||
|
const tokenExpiration = new Date(+ now + validity_ms)
|
||||||
|
|
||||||
|
prisma.token.create({
|
||||||
|
data: {
|
||||||
|
userId: lr.id,
|
||||||
|
token: tokenString,
|
||||||
|
expiresAt: tokenExpiration,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return res.status(200).json({
|
||||||
|
token: tokenString,
|
||||||
|
expiresAt: tokenExpiration.toISOString(),
|
||||||
|
})
|
||||||
|
|
||||||
|
default:
|
||||||
|
return res.status(405).json({error: "Invalid method"})
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,19 +2,42 @@ import type { NextPage, NextPageContext } from 'next'
|
||||||
import { useTranslation } from 'next-i18next'
|
import { useTranslation } from 'next-i18next'
|
||||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
|
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
|
||||||
import { Intro } from '../components/Intro';
|
import { Intro } from '../components/Intro';
|
||||||
import { LoginButton } from '../components/LoginButton';
|
import { TutorialTelegramLogin } from '../components/TutorialTelegramLogin';
|
||||||
|
import { LoginContext } from '../contexts/login';
|
||||||
|
import { useDefinedContext } from '../utils/definedContext';
|
||||||
|
|
||||||
export async function getStaticProps(context: NextPageContext) {
|
export async function getStaticProps(context: NextPageContext) {
|
||||||
return {props: {
|
return {
|
||||||
...(await serverSideTranslations(context.locale ?? "it-IT", ["common"]))
|
props: {
|
||||||
}}
|
...(await serverSideTranslations(context.locale ?? "it-IT", ["common"]))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Page: NextPage = () => {
|
const Page: NextPage = () => {
|
||||||
const {t} = useTranslation("common")
|
const { t } = useTranslation("common")
|
||||||
|
const [login, setLogin] = useDefinedContext(LoginContext)
|
||||||
|
|
||||||
|
if (!login) {
|
||||||
|
return (
|
||||||
|
<main className="page-index">
|
||||||
|
<hgroup>
|
||||||
|
<h1>
|
||||||
|
{t("siteTitle")}
|
||||||
|
</h1>
|
||||||
|
<h2>
|
||||||
|
{t("siteSubtitle")}
|
||||||
|
</h2>
|
||||||
|
</hgroup>
|
||||||
|
<div>
|
||||||
|
<TutorialTelegramLogin />
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="index">
|
<main className="page-index">
|
||||||
<hgroup>
|
<hgroup>
|
||||||
<h1>
|
<h1>
|
||||||
{t("siteTitle")}
|
{t("siteTitle")}
|
||||||
|
@ -23,10 +46,7 @@ const Page: NextPage = () => {
|
||||||
{t("siteSubtitle")}
|
{t("siteSubtitle")}
|
||||||
</h2>
|
</h2>
|
||||||
</hgroup>
|
</hgroup>
|
||||||
<div>
|
</main>
|
||||||
<Intro/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,14 @@ model User {
|
||||||
username String?
|
username String?
|
||||||
photoUrl String?
|
photoUrl String?
|
||||||
lastAuthDate DateTime
|
lastAuthDate DateTime
|
||||||
hash String
|
tokens Token[]
|
||||||
|
}
|
||||||
|
|
||||||
|
model Token {
|
||||||
|
userId BigInt
|
||||||
|
user User @relation(fields: [userId], references: [id])
|
||||||
|
token String @id
|
||||||
|
expiresAt DateTime
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A partecipant is a person who may or may not partecipate to the event.
|
/// A partecipant is a person who may or may not partecipate to the event.
|
||||||
|
|
|
@ -1 +1,9 @@
|
||||||
{}
|
{
|
||||||
|
"siteTitle": "Festa",
|
||||||
|
"siteSubtitle": "Organizza con facilità il tuo evento!",
|
||||||
|
"introTelegramLogin": "Per prima cosa, effettua il login con Telegram.",
|
||||||
|
"introTelegramLoggedIn": "Sei connesso come <1/>!",
|
||||||
|
"introTelegramLogout": "Non sei tu?",
|
||||||
|
"introCreateEvent": "Dai un nome al tuo primo evento:",
|
||||||
|
"introCreateEventSlugPlaceholder": "nome-evento-2022"
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
"siteTitle": "Festa",
|
|
||||||
"siteSubtitle": "Organizza il tuo evento ora!",
|
|
||||||
"introTelegramLogin": "Effettua il login con Telegram per iniziare a creare il tuo evento.",
|
|
||||||
"introTelegramLoggedIn": "Sei connesso come <1/>!",
|
|
||||||
"introTelegramLogout": "Non sei tu?",
|
|
||||||
"introCreateEvent": ""
|
|
||||||
}
|
|
|
@ -1,49 +1,24 @@
|
||||||
@media (prefers-color-scheme: light) {
|
* {
|
||||||
body {
|
box-sizing: border-box;
|
||||||
--background: #fafafa;
|
|
||||||
--foreground: black;
|
|
||||||
--border: darkgray;
|
|
||||||
|
|
||||||
--anchor: #4444ff;
|
|
||||||
--anchor-visited: #aa44ff;
|
|
||||||
--anchor-active: #ff4444;
|
|
||||||
|
|
||||||
--positive: #008800;
|
|
||||||
--negative: #880000;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
*::selection {
|
||||||
body {
|
background-color: var(--selection);
|
||||||
--background: #050505;
|
color: var(--foreground);
|
||||||
--foreground: white;
|
text-shadow: none;
|
||||||
--border: darkgray;
|
|
||||||
|
|
||||||
--anchor: #8888ff;
|
|
||||||
--anchor-visited: #aa88ff;
|
|
||||||
--anchor-active: #ff8888;
|
|
||||||
|
|
||||||
--positive: #88ff88;
|
|
||||||
--negative: #ff8888;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
body {
|
body {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
background-color: var(--background);
|
background-color: var(--background);
|
||||||
|
|
||||||
font-family: sans-serif;
|
|
||||||
color: var(--foreground);
|
color: var(--foreground);
|
||||||
|
font-family: sans-serif;
|
||||||
text-shadow: 1px 1px 1px var(--background);
|
text-shadow: 1px 1px 1px var(--background);
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1, h2, h3, h4, h5, h6 {
|
h1, h2, h3, h4, h5, h6 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
text-shadow: 2px 2px 2px var(--background);
|
text-shadow: 2px 2px 2px var(--background);
|
||||||
|
@ -66,7 +41,7 @@ input, button {
|
||||||
margin: 2px 4px;
|
margin: 2px 4px;
|
||||||
|
|
||||||
color: var(--foreground);
|
color: var(--foreground);
|
||||||
background-color: var(--background);
|
background-color: var(--interactable);
|
||||||
|
|
||||||
border-width: 2px;
|
border-width: 2px;
|
||||||
border-color: var(--border);
|
border-color: var(--border);
|
||||||
|
@ -103,4 +78,9 @@ input[type="submit"]:active, button:active {
|
||||||
.input-negative {
|
.input-negative {
|
||||||
border-color: var(--negative);
|
border-color: var(--negative);
|
||||||
color: var(--negative);
|
color: var(--negative);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@import "index.css";
|
||||||
|
@import "postcard.css";
|
||||||
|
@import "telegram.css";
|
||||||
|
@import "variables.css";
|
|
@ -1,4 +1,4 @@
|
||||||
.index {
|
.page-index {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
|
@ -10,21 +10,21 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 639px) {
|
@media only screen and (max-width: 639px) {
|
||||||
.index h1 {
|
.page-index h1 {
|
||||||
font-size: 5rem;
|
font-size: 5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.index h2 {
|
.page-index h2 {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (min-width: 640px) {
|
@media only screen and (min-width: 640px) {
|
||||||
.index h1 {
|
.page-index h1 {
|
||||||
font-size: 10rem;
|
font-size: 10rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.index h2 {
|
.page-index h2 {
|
||||||
font-size: 2.5rem;
|
font-size: 2.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,28 +1,3 @@
|
||||||
/* Taken from the Telegram widget button */
|
|
||||||
.container-btn-telegram > div {
|
.container-btn-telegram > div {
|
||||||
height: 40px;
|
height: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-telegram {
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: top;
|
|
||||||
font-weight: 500;
|
|
||||||
background-color: #54a9eb;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
margin: 0;
|
|
||||||
border: none;
|
|
||||||
color: #fff;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
font-size: 16px;
|
|
||||||
line-height: 20px;
|
|
||||||
padding: 9px 21px 11px;
|
|
||||||
border-radius: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatar-telegram-inline {
|
|
||||||
height: 1em;
|
|
||||||
border-radius: 20px;
|
|
||||||
margin-right: 3px;
|
|
||||||
}
|
|
||||||
|
|
33
styles/variables.css
Normal file
33
styles/variables.css
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
/* Light theme / unsupported */
|
||||||
|
body {
|
||||||
|
--background: #fafafa;
|
||||||
|
--foreground: black;
|
||||||
|
--border: gray;
|
||||||
|
--interactable: #fafafab5;
|
||||||
|
--selection: #7777ff;
|
||||||
|
|
||||||
|
--anchor: #4444ff;
|
||||||
|
--anchor-visited: #aa44ff;
|
||||||
|
--anchor-active: #ff4444;
|
||||||
|
|
||||||
|
--positive: #008800;
|
||||||
|
--negative: #880000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dark theme */
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
body {
|
||||||
|
--background: #050505;
|
||||||
|
--foreground: white;
|
||||||
|
--border: gray;
|
||||||
|
--interactable: #050505b5;
|
||||||
|
--selection: #3333dd;
|
||||||
|
|
||||||
|
--anchor: #8888ff;
|
||||||
|
--anchor-visited: #aa88ff;
|
||||||
|
--anchor-active: #ff8888;
|
||||||
|
|
||||||
|
--positive: #88ff88;
|
||||||
|
--negative: #ff8888;
|
||||||
|
}
|
||||||
|
}
|
3
utils/prismaClient.ts
Normal file
3
utils/prismaClient.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import { PrismaClient } from "@prisma/client";
|
||||||
|
|
||||||
|
export const prisma = new PrismaClient()
|
|
@ -74,6 +74,11 @@ export class LoginResponse implements LoginData {
|
||||||
* @param queryObj The query string object, from `context.query`.
|
* @param queryObj The query string object, from `context.query`.
|
||||||
*/
|
*/
|
||||||
constructor(ld: LoginData) {
|
constructor(ld: LoginData) {
|
||||||
|
if(!ld.id) throw new Error("Missing `id`")
|
||||||
|
if(!ld.first_name) throw new Error("Missing `first_name`")
|
||||||
|
if(!ld.auth_date) throw new Error("Missing `auth_date`")
|
||||||
|
if(!ld.hash) throw new Error("Missing `hash`")
|
||||||
|
|
||||||
this.id = ld.id
|
this.id = ld.id
|
||||||
this.first_name = ld.first_name
|
this.first_name = ld.first_name
|
||||||
this.last_name = ld.last_name
|
this.last_name = ld.last_name
|
||||||
|
|
107
yarn.lock
107
yarn.lock
|
@ -335,11 +335,24 @@ ast-types-flow@^0.0.7:
|
||||||
resolved "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad"
|
resolved "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad"
|
||||||
integrity sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==
|
integrity sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==
|
||||||
|
|
||||||
|
asynckit@^0.4.0:
|
||||||
|
version "0.4.0"
|
||||||
|
resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||||
|
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
|
||||||
|
|
||||||
axe-core@^4.3.5:
|
axe-core@^4.3.5:
|
||||||
version "4.4.2"
|
version "4.4.2"
|
||||||
resolved "https://registry.npmjs.org/axe-core/-/axe-core-4.4.2.tgz#dcf7fb6dea866166c3eab33d68208afe4d5f670c"
|
resolved "https://registry.npmjs.org/axe-core/-/axe-core-4.4.2.tgz#dcf7fb6dea866166c3eab33d68208afe4d5f670c"
|
||||||
integrity sha512-LVAaGp/wkkgYJcjmHsoKx4juT1aQvJyPcW09MLCjVTh3V2cc6PnyempiLMNH5iMdfIX/zdbjUx2KDjMLCTdPeA==
|
integrity sha512-LVAaGp/wkkgYJcjmHsoKx4juT1aQvJyPcW09MLCjVTh3V2cc6PnyempiLMNH5iMdfIX/zdbjUx2KDjMLCTdPeA==
|
||||||
|
|
||||||
|
axios@^0.27.2:
|
||||||
|
version "0.27.2"
|
||||||
|
resolved "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972"
|
||||||
|
integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==
|
||||||
|
dependencies:
|
||||||
|
follow-redirects "^1.14.9"
|
||||||
|
form-data "^4.0.0"
|
||||||
|
|
||||||
axobject-query@^2.2.0:
|
axobject-query@^2.2.0:
|
||||||
version "2.2.0"
|
version "2.2.0"
|
||||||
resolved "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be"
|
resolved "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be"
|
||||||
|
@ -408,6 +421,13 @@ color-name@~1.1.4:
|
||||||
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||||
|
|
||||||
|
combined-stream@^1.0.8:
|
||||||
|
version "1.0.8"
|
||||||
|
resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
|
||||||
|
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
|
||||||
|
dependencies:
|
||||||
|
delayed-stream "~1.0.0"
|
||||||
|
|
||||||
concat-map@0.0.1:
|
concat-map@0.0.1:
|
||||||
version "0.0.1"
|
version "0.0.1"
|
||||||
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||||
|
@ -423,7 +443,15 @@ core-js@^3:
|
||||||
resolved "https://registry.npmjs.org/core-js/-/core-js-3.22.7.tgz#8d6c37f630f6139b8732d10f2c114c3f1d00024f"
|
resolved "https://registry.npmjs.org/core-js/-/core-js-3.22.7.tgz#8d6c37f630f6139b8732d10f2c114c3f1d00024f"
|
||||||
integrity sha512-Jt8SReuDKVNZnZEzyEQT5eK6T2RRCXkfTq7Lo09kpm+fHjgGewSbNjV+Wt4yZMhPDdzz2x1ulI5z/w4nxpBseg==
|
integrity sha512-Jt8SReuDKVNZnZEzyEQT5eK6T2RRCXkfTq7Lo09kpm+fHjgGewSbNjV+Wt4yZMhPDdzz2x1ulI5z/w4nxpBseg==
|
||||||
|
|
||||||
cross-spawn@^7.0.2:
|
cors@^2.8.5:
|
||||||
|
version "2.8.5"
|
||||||
|
resolved "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29"
|
||||||
|
integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==
|
||||||
|
dependencies:
|
||||||
|
object-assign "^4"
|
||||||
|
vary "^1"
|
||||||
|
|
||||||
|
cross-spawn@^7.0.2, cross-spawn@^7.0.3:
|
||||||
version "7.0.3"
|
version "7.0.3"
|
||||||
resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
||||||
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
|
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
|
||||||
|
@ -432,6 +460,13 @@ cross-spawn@^7.0.2:
|
||||||
shebang-command "^2.0.0"
|
shebang-command "^2.0.0"
|
||||||
which "^2.0.1"
|
which "^2.0.1"
|
||||||
|
|
||||||
|
crypto-random-string@^5.0.0:
|
||||||
|
version "5.0.0"
|
||||||
|
resolved "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-5.0.0.tgz#12b4ca8ba936c36d757b65b71a7d85a69a02c18a"
|
||||||
|
integrity sha512-KWjTXWwxFd6a94m5CdRGW/t82Tr8DoBc9dNnPCAbFI1EBweN6v1tv8y4Y1m7ndkp/nkIBRxUxAzpaBnR2k3bcQ==
|
||||||
|
dependencies:
|
||||||
|
type-fest "^2.12.2"
|
||||||
|
|
||||||
csstype@^3.0.2:
|
csstype@^3.0.2:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz#4ddcac3718d787cf9df0d1b7d15033925c8f29f2"
|
resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz#4ddcac3718d787cf9df0d1b7d15033925c8f29f2"
|
||||||
|
@ -476,6 +511,11 @@ define-properties@^1.1.3, define-properties@^1.1.4:
|
||||||
has-property-descriptors "^1.0.0"
|
has-property-descriptors "^1.0.0"
|
||||||
object-keys "^1.1.1"
|
object-keys "^1.1.1"
|
||||||
|
|
||||||
|
delayed-stream@~1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
||||||
|
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
|
||||||
|
|
||||||
dir-glob@^3.0.1:
|
dir-glob@^3.0.1:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
|
resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
|
||||||
|
@ -497,6 +537,26 @@ doctrine@^3.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
esutils "^2.0.2"
|
esutils "^2.0.2"
|
||||||
|
|
||||||
|
dotenv-cli@^5.1.0:
|
||||||
|
version "5.1.0"
|
||||||
|
resolved "https://registry.npmjs.org/dotenv-cli/-/dotenv-cli-5.1.0.tgz#0d2942b089082da0157f9b26bd6c5c4dd51ef48e"
|
||||||
|
integrity sha512-NoEZAlKo9WVrG0b3i9mBxdD6INdDuGqdgR74t68t8084QcI077/1MnPerRW1odl+9uULhcdnQp2U0pYVppKHOA==
|
||||||
|
dependencies:
|
||||||
|
cross-spawn "^7.0.3"
|
||||||
|
dotenv "^16.0.0"
|
||||||
|
dotenv-expand "^8.0.1"
|
||||||
|
minimist "^1.2.5"
|
||||||
|
|
||||||
|
dotenv-expand@^8.0.1:
|
||||||
|
version "8.0.3"
|
||||||
|
resolved "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-8.0.3.tgz#29016757455bcc748469c83a19b36aaf2b83dd6e"
|
||||||
|
integrity sha512-SErOMvge0ZUyWd5B0NXMQlDkN+8r+HhVUsxgOO7IoPDOdDRD2JjExpN6y3KnFR66jsJMwSn1pqIivhU5rcJiNg==
|
||||||
|
|
||||||
|
dotenv@^16.0.0:
|
||||||
|
version "16.0.1"
|
||||||
|
resolved "https://registry.npmjs.org/dotenv/-/dotenv-16.0.1.tgz#8f8f9d94876c35dac989876a5d3a82a267fdce1d"
|
||||||
|
integrity sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==
|
||||||
|
|
||||||
emoji-regex@^9.2.2:
|
emoji-regex@^9.2.2:
|
||||||
version "9.2.2"
|
version "9.2.2"
|
||||||
resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72"
|
resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72"
|
||||||
|
@ -822,6 +882,20 @@ flatted@^3.1.0:
|
||||||
resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3"
|
resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3"
|
||||||
integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==
|
integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==
|
||||||
|
|
||||||
|
follow-redirects@^1.14.9:
|
||||||
|
version "1.15.1"
|
||||||
|
resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5"
|
||||||
|
integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==
|
||||||
|
|
||||||
|
form-data@^4.0.0:
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
|
||||||
|
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
|
||||||
|
dependencies:
|
||||||
|
asynckit "^0.4.0"
|
||||||
|
combined-stream "^1.0.8"
|
||||||
|
mime-types "^2.1.12"
|
||||||
|
|
||||||
fs.realpath@^1.0.0:
|
fs.realpath@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||||
|
@ -1234,6 +1308,18 @@ micromatch@^4.0.4:
|
||||||
braces "^3.0.2"
|
braces "^3.0.2"
|
||||||
picomatch "^2.3.1"
|
picomatch "^2.3.1"
|
||||||
|
|
||||||
|
mime-db@1.52.0:
|
||||||
|
version "1.52.0"
|
||||||
|
resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
|
||||||
|
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
|
||||||
|
|
||||||
|
mime-types@^2.1.12:
|
||||||
|
version "2.1.35"
|
||||||
|
resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
|
||||||
|
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
|
||||||
|
dependencies:
|
||||||
|
mime-db "1.52.0"
|
||||||
|
|
||||||
minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2:
|
minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2:
|
||||||
version "3.1.2"
|
version "3.1.2"
|
||||||
resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
||||||
|
@ -1241,7 +1327,7 @@ minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
brace-expansion "^1.1.7"
|
brace-expansion "^1.1.7"
|
||||||
|
|
||||||
minimist@^1.2.0, minimist@^1.2.6:
|
minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6:
|
||||||
version "1.2.6"
|
version "1.2.6"
|
||||||
resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
|
resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
|
||||||
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
|
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
|
||||||
|
@ -1307,7 +1393,7 @@ next@12.1.6:
|
||||||
"@next/swc-win32-ia32-msvc" "12.1.6"
|
"@next/swc-win32-ia32-msvc" "12.1.6"
|
||||||
"@next/swc-win32-x64-msvc" "12.1.6"
|
"@next/swc-win32-x64-msvc" "12.1.6"
|
||||||
|
|
||||||
object-assign@^4.1.1:
|
object-assign@^4, object-assign@^4.1.1:
|
||||||
version "4.1.1"
|
version "4.1.1"
|
||||||
resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||||
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
|
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
|
||||||
|
@ -1713,6 +1799,11 @@ supports-preserve-symlinks-flag@^1.0.0:
|
||||||
resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
|
resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
|
||||||
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
||||||
|
|
||||||
|
swr@^1.3.0:
|
||||||
|
version "1.3.0"
|
||||||
|
resolved "https://registry.npmjs.org/swr/-/swr-1.3.0.tgz#c6531866a35b4db37b38b72c45a63171faf9f4e8"
|
||||||
|
integrity sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw==
|
||||||
|
|
||||||
text-table@^0.2.0:
|
text-table@^0.2.0:
|
||||||
version "0.2.0"
|
version "0.2.0"
|
||||||
resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
||||||
|
@ -1759,6 +1850,11 @@ type-fest@^0.20.2:
|
||||||
resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
|
resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
|
||||||
integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
|
integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
|
||||||
|
|
||||||
|
type-fest@^2.12.2:
|
||||||
|
version "2.13.0"
|
||||||
|
resolved "https://registry.npmjs.org/type-fest/-/type-fest-2.13.0.tgz#d1ecee38af29eb2e863b22299a3d68ef30d2abfb"
|
||||||
|
integrity sha512-lPfAm42MxE4/456+QyIaaVBAwgpJb6xZ8PRu09utnhPdWwcyj9vgy6Sq0Z5yNbJ21EdxB5dRU/Qg8bsyAMtlcw==
|
||||||
|
|
||||||
typescript@4.6.4:
|
typescript@4.6.4:
|
||||||
version "4.6.4"
|
version "4.6.4"
|
||||||
resolved "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz#caa78bbc3a59e6a5c510d35703f6a09877ce45e9"
|
resolved "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz#caa78bbc3a59e6a5c510d35703f6a09877ce45e9"
|
||||||
|
@ -1786,6 +1882,11 @@ v8-compile-cache@^2.0.3:
|
||||||
resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
|
resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
|
||||||
integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
|
integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
|
||||||
|
|
||||||
|
vary@^1:
|
||||||
|
version "1.1.2"
|
||||||
|
resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
||||||
|
integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
|
||||||
|
|
||||||
void-elements@3.1.0:
|
void-elements@3.1.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09"
|
resolved "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09"
|
||||||
|
|
Loading…
Reference in a new issue