1
Fork 0
mirror of https://github.com/Steffo99/festa.git synced 2024-12-22 22:54:22 +00:00
This commit is contained in:
Steffo 2022-05-28 05:45:05 +02:00
parent e1409f3545
commit 6673b9fd15
Signed by: steffo
GPG key ID: 6965406171929D01
23 changed files with 360 additions and 164 deletions

2
.vscode/launch.json vendored
View file

@ -9,7 +9,7 @@
"request": "launch", "request": "launch",
"runtimeArgs": [ "runtimeArgs": [
"run", "run",
"dev", "app:dev",
], ],
"runtimeExecutable": "yarn", "runtimeExecutable": "yarn",
"skipFiles": [ "skipFiles": [

View file

@ -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}
</>
}

View file

@ -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>
)
}

View file

@ -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>
) )
} }

View 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>
)
}

View 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>
</>
}
}

View file

@ -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"

View file

@ -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'

View file

View 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"})
}
}

View file

@ -2,19 +2,25 @@ 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 {
props: {
...(await serverSideTranslations(context.locale ?? "it-IT", ["common"])) ...(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 ( return (
<div className="index"> <main className="page-index">
<hgroup> <hgroup>
<h1> <h1>
{t("siteTitle")} {t("siteTitle")}
@ -24,9 +30,23 @@ const Page: NextPage = () => {
</h2> </h2>
</hgroup> </hgroup>
<div> <div>
<Intro/> <TutorialTelegramLogin />
</div>
</div> </div>
</main>
)
}
return (
<main className="page-index">
<hgroup>
<h1>
{t("siteTitle")}
</h1>
<h2>
{t("siteSubtitle")}
</h2>
</hgroup>
</main>
) )
} }

View file

@ -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.

View file

@ -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"
}

View file

@ -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": ""
}

View file

@ -1,33 +1,12 @@
@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;
@ -35,15 +14,11 @@ body {
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);
@ -104,3 +79,8 @@ input[type="submit"]:active, button:active {
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";

View file

@ -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;
} }
} }

View file

@ -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
View 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
View file

@ -0,0 +1,3 @@
import { PrismaClient } from "@prisma/client";
export const prisma = new PrismaClient()

View file

@ -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
View file

@ -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"