From ec49754781ead471cd9c63b0b4733ba0f955fa8d Mon Sep 17 00:00:00 2001 From: Daniel Zhang Date: Thu, 11 Apr 2024 22:47:32 -0400 Subject: [PATCH 1/6] fix: add x overflow clip to main wrapper --- .gitignore | 2 ++ src/app/client.tsx | 2 +- src/app/page.tsx | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index a5127e3..61b733c 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,5 @@ yarn-error.log* # typescript *.tsbuildinfo + +pnpm-lock.yaml \ No newline at end of file diff --git a/src/app/client.tsx b/src/app/client.tsx index 938a370..bf447f2 100644 --- a/src/app/client.tsx +++ b/src/app/client.tsx @@ -21,7 +21,7 @@ export default function Client({ users }: Props) { const router = useRouter(); return ( - + {/* */} diff --git a/src/app/page.tsx b/src/app/page.tsx index af6f18e..3e112d7 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -9,7 +9,7 @@ const REDIRECT_AUTH_URL = process.env.NEXT_PUBLIC_REDIRECT_AUTH_URL ?? "/unauthorized"; export default async function Home() { - await hasPermission(["canAccessAdmin", "canManageUsers"], REDIRECT_AUTH_URL); + // await hasPermission(["canAccessAdmin", "canManageUsers"], REDIRECT_AUTH_URL); const users = await prisma.user.findMany({ include: { From 6249b0ca4ff731a7b5c89cfdaf0c6b736f4eb7ab Mon Sep 17 00:00:00 2001 From: Daniel Zhang Date: Thu, 11 Apr 2024 22:50:27 -0400 Subject: [PATCH 2/6] fix: undo temporary permission bypass --- src/app/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/page.tsx b/src/app/page.tsx index 3e112d7..af6f18e 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -9,7 +9,7 @@ const REDIRECT_AUTH_URL = process.env.NEXT_PUBLIC_REDIRECT_AUTH_URL ?? "/unauthorized"; export default async function Home() { - // await hasPermission(["canAccessAdmin", "canManageUsers"], REDIRECT_AUTH_URL); + await hasPermission(["canAccessAdmin", "canManageUsers"], REDIRECT_AUTH_URL); const users = await prisma.user.findMany({ include: { From 2a6e4e4c9eb0e69c07e9ae926b5b7a1853a111db Mon Sep 17 00:00:00 2001 From: ashlyn <68078477+4shlyn@users.noreply.github.com> Date: Wed, 24 Apr 2024 15:20:37 -0400 Subject: [PATCH 3/6] added NavBar component --- src/components/NavBar.tsx | 116 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/components/NavBar.tsx diff --git a/src/components/NavBar.tsx b/src/components/NavBar.tsx new file mode 100644 index 0000000..23a4eb1 --- /dev/null +++ b/src/components/NavBar.tsx @@ -0,0 +1,116 @@ +/** + * NavBar Component + * @returns JSX.Element + */ +import { useState } from "react"; +export default function NavBar(): JSX.Element { + const [isNavOpen, setIsNavOpen] = useState(false); + + return ( +
+ + +
+); +} From da5f38b40015264e4afe00dae41b4b8c38be9c3e Mon Sep 17 00:00:00 2001 From: ashlyn <68078477+4shlyn@users.noreply.github.com> Date: Wed, 24 Apr 2024 15:21:17 -0400 Subject: [PATCH 4/6] added Navbar to client --- src/app/client.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/client.tsx b/src/app/client.tsx index bf447f2..bf16ad8 100644 --- a/src/app/client.tsx +++ b/src/app/client.tsx @@ -12,6 +12,7 @@ import { import { useEffect, useState } from "react"; import { trpc } from "./_trpc/client"; import { useRouter } from "next/navigation"; +import NavBar from "@/components/NavBar"; type Props = { users: UserWithMailingList[]; @@ -23,7 +24,7 @@ export default function Client({ users }: Props) { return ( - + {/* */} Date: Wed, 24 Apr 2024 15:21:50 -0400 Subject: [PATCH 5/6] Added Navbar (git wasn't working, had to manually add) --- src/app/hiring/responses/client.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/hiring/responses/client.tsx b/src/app/hiring/responses/client.tsx index 9b13dbb..638c8bc 100644 --- a/src/app/hiring/responses/client.tsx +++ b/src/app/hiring/responses/client.tsx @@ -8,6 +8,7 @@ import { ObjectTable, } from "eclipse-components"; import { useRouter } from "next/navigation"; +import NavBar from "@/components/NavBar"; type Props = { applications: HiringApplication[]; @@ -19,7 +20,7 @@ export default function Client({ applications }: Props) { return ( - + Date: Wed, 3 Jul 2024 10:06:52 -0700 Subject: [PATCH 6/6] FEAT: Added Download CSV Button, fixed responses page --- .dockerignore | 3 + .env.example | 45 + .eslintrc.cjs | 34 + .gitignore | 43 + Dockerfile | 25 + LICENSE | 21 + README.md | 69 + bun.lockb | Bin 0 -> 95268 bytes docker-compose.yml | 16 + next.config.js | 24 + package-lock.json | 3862 +++++++++++++++++ package.json | 52 + postcss.config.cjs | 8 + prettier.config.js | 6 + .../20231216071101_inint/migration.sql | 13 + .../20240216030149_add_auth/migration.sql | 20 + .../migration.sql | 31 + .../migration.sql | 23 + .../migration.sql | 15 + .../migrations/20240223234508_/migration.sql | 10 + .../migration.sql | 18 + .../migration.sql | 2 + .../migration.sql | 9 + .../migration.sql | 10 + .../migration.sql | 21 + .../migration.sql | 33 + .../migration.sql | 3 + .../migration.sql | 29 + .../migration.sql | 11 + prisma/migrations/migration_lock.toml | 3 + prisma/schema.prisma | 117 + public/.gitkeep | 0 src/app/Providers.tsx | 11 + src/app/_trpc/Provider.tsx | 24 + src/app/_trpc/client.ts | 5 + src/app/_trpc/serverClient.ts | 10 + src/app/api/trpc/[trpc]/route.ts | 13 + src/app/client.tsx | 64 + src/app/error/layout.tsx | 22 + src/app/error/page.tsx | 30 + src/app/favicon.ico | Bin 0 -> 23600 bytes src/app/hiring/responses/[id]/client.tsx | 80 + src/app/hiring/responses/[id]/loading.tsx | 11 + src/app/hiring/responses/[id]/page.tsx | 37 + src/app/hiring/responses/client.tsx | 60 + src/app/hiring/responses/loading.tsx | 11 + src/app/hiring/responses/page.tsx | 24 + src/app/layout.tsx | 28 + src/app/loading.tsx | 11 + src/app/page.tsx | 20 + src/app/unauthorized/layout.tsx | 22 + src/app/unauthorized/page.tsx | 30 + src/components/ErrorMessage.tsx | 13 + src/components/Loading.tsx | 39 + src/components/MainWrapper.tsx | 17 + src/components/NavBar.tsx | 116 + src/components/PageHead.tsx | 16 + src/lib/crypto.ts | 42 + src/lib/prisma.ts | 15 + src/lib/responses.ts | 81 + src/lib/server/index.ts | 9 + src/lib/server/trpc.ts | 6 + src/lib/server/utils/zod.ts | 13 + src/lib/user/getSessionUser.ts | 19 + src/lib/user/hasPermission.ts | 54 + src/lib/utils/cn.ts | 4 + src/styles/globals.css | 6 + src/styles/stars.module.scss | 37 + src/types/debugTypes.d.ts | 9 + src/types/next-auth.d.ts | 21 + src/types/types.ts | 34 + tailwind.config.ts | 32 + tsconfig.json | 42 + 73 files changed, 5714 insertions(+) create mode 100644 .dockerignore create mode 100644 .env.example create mode 100644 .eslintrc.cjs create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 README.md create mode 100755 bun.lockb create mode 100644 docker-compose.yml create mode 100644 next.config.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 postcss.config.cjs create mode 100644 prettier.config.js create mode 100644 prisma/migrations/20231216071101_inint/migration.sql create mode 100644 prisma/migrations/20240216030149_add_auth/migration.sql create mode 100644 prisma/migrations/20240218002138_add_mailing_list/migration.sql create mode 100644 prisma/migrations/20240218002616_deduplicate_mailinglist/migration.sql create mode 100644 prisma/migrations/20240223233815_add_hiring_application/migration.sql create mode 100644 prisma/migrations/20240223234508_/migration.sql create mode 100644 prisma/migrations/20240227004733_update_application_table/migration.sql create mode 100644 prisma/migrations/20240227021057_make_portfolio_optional/migration.sql create mode 100644 prisma/migrations/20240227021146_store_resume_name/migration.sql create mode 100644 prisma/migrations/20240227022100_rename_school_column/migration.sql create mode 100644 prisma/migrations/20240303030415_add_permissions_table/migration.sql create mode 100644 prisma/migrations/20240303031139_update_permissions_table/migration.sql create mode 100644 prisma/migrations/20240307001403_add_timestamps_to_hiring_application/migration.sql create mode 100644 prisma/migrations/20240307001706_track_login_attempts/migration.sql create mode 100644 prisma/migrations/20240307002135_track_login_result/migration.sql create mode 100644 prisma/migrations/migration_lock.toml create mode 100644 prisma/schema.prisma create mode 100644 public/.gitkeep create mode 100644 src/app/Providers.tsx create mode 100644 src/app/_trpc/Provider.tsx create mode 100644 src/app/_trpc/client.ts create mode 100644 src/app/_trpc/serverClient.ts create mode 100644 src/app/api/trpc/[trpc]/route.ts create mode 100644 src/app/client.tsx create mode 100644 src/app/error/layout.tsx create mode 100644 src/app/error/page.tsx create mode 100644 src/app/favicon.ico create mode 100644 src/app/hiring/responses/[id]/client.tsx create mode 100644 src/app/hiring/responses/[id]/loading.tsx create mode 100644 src/app/hiring/responses/[id]/page.tsx create mode 100644 src/app/hiring/responses/client.tsx create mode 100644 src/app/hiring/responses/loading.tsx create mode 100644 src/app/hiring/responses/page.tsx create mode 100644 src/app/layout.tsx create mode 100644 src/app/loading.tsx create mode 100644 src/app/page.tsx create mode 100644 src/app/unauthorized/layout.tsx create mode 100644 src/app/unauthorized/page.tsx create mode 100644 src/components/ErrorMessage.tsx create mode 100644 src/components/Loading.tsx create mode 100644 src/components/MainWrapper.tsx create mode 100644 src/components/NavBar.tsx create mode 100644 src/components/PageHead.tsx create mode 100644 src/lib/crypto.ts create mode 100644 src/lib/prisma.ts create mode 100644 src/lib/responses.ts create mode 100644 src/lib/server/index.ts create mode 100644 src/lib/server/trpc.ts create mode 100644 src/lib/server/utils/zod.ts create mode 100644 src/lib/user/getSessionUser.ts create mode 100644 src/lib/user/hasPermission.ts create mode 100644 src/lib/utils/cn.ts create mode 100644 src/styles/globals.css create mode 100644 src/styles/stars.module.scss create mode 100644 src/types/debugTypes.d.ts create mode 100644 src/types/next-auth.d.ts create mode 100644 src/types/types.ts create mode 100644 tailwind.config.ts create mode 100644 tsconfig.json diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..cc1708a --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +dist +node_modules +.db diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..e2d2e00 --- /dev/null +++ b/.env.example @@ -0,0 +1,45 @@ +# Since the ".env" file is gitignored, you can use the ".env.example" file to +# build a new ".env" file when you clone the repo. Keep this file up-to-date +# when you add new variables to `.env`. + +# This file will be committed to version control, so make sure not to have any +# secrets in it. If you are cloning this repo, create a copy of this file named +# ".env" and populate it with your secrets. + +## +## Application Configuration +## +TZ='America/Toronto' +NODE_ENV='development' + +## +## Since this is prefixed with "NEXT_PUBLIC_", these variables will be available to the client (public) +## +NEXT_PUBLIC_REDIRECT_AUTH_URL="https://auth.eclipseexpos.org" + + +## +## Prisma Configuration (DATABASE_URL) +## +## This runs on the default port: 3306 +## +DATABASE_URL="postgresql://postgres:change-me@127.0.0.1/application" + + +## +## MYSQL Database Configuration +## +MYSQL_DATABASE='application' +MYSQL_ROOT_HOST="%" +MYSQL_PASSWORD="change-me" + +## +## PostgreSQL Database Configuration +## +DB_PATH='./.db' + +## +## Twilio Send Grid Configuration +## +SENDGRID_API_KEY = "" +SENDGRID_SENDER_ID = "" diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..8923a93 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,34 @@ +/** @type {import("eslint").Linter.Config} */ +const config = { + parser: "@typescript-eslint/parser", + parserOptions: { + project: true, + }, + plugins: ["@typescript-eslint"], + extends: [ + "plugin:@next/next/recommended", + "plugin:@typescript-eslint/stylistic-type-checked", + ], + rules: { + // These opinionated rules are enabled in stylistic-type-checked above. + // Feel free to reconfigure them to your own preference. + "@typescript-eslint/consistent-type-imports": [ + "warn", + { + prefer: "type-imports", + fixStyle: "inline-type-imports", + }, + ], + "@typescript-eslint/consistent-type-definitions": ["error", "type"], + "@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }], + "@typescript-eslint/require-await": "off", + "@typescript-eslint/no-misused-promises": [ + "error", + { + checksVoidReturn: { attributes: false }, + }, + ], + }, +}; + +module.exports = config; diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a5127e3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,43 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# database +/prisma/db.sqlite +/prisma/db.sqlite-journal +/.db + +# next.js +/.next/ +/out/ +next-env.d.ts + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# local env files +# do not commit any .env files to git, except for the .env.example file. https://create.t3.gg/en/usage/env-variables#using-environment-variables +.env +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1880795 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ +FROM node:lts-alpine + +WORKDIR /usr/app + +COPY package*.json ./ + +RUN npm ci + +COPY . . + +EXPOSE 3000 + + +ENV TZ=${TZ:-America/Toronto} +RUN apk add -U tzdata +RUN cp /usr/share/zoneinfo/${TZ} /etc/localtime + + +RUN npm i -g prisma + +RUN prisma generate + +RUN npm run build + +CMD ["npm", "start"] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..762236b --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Simpson Computer Technologies Research + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..5b7773d --- /dev/null +++ b/README.md @@ -0,0 +1,69 @@ +# admin.eclipseexpos.org + +## Contributing + +### Prerequisites + +- [Node.js](https://nodejs.org/en/) +- [npm](https://www.npmjs.com/) +- [Docker](https://www.docker.com/) + +### Installation + +1. Clone the repo + + ```sh + git clone https://github.com/Eclipse-Expos/admin.eclipseexpos.org.git + ``` + +2. Install NPM packages + + ```sh + npm install + ``` + +3. Run the database container + + ```sh + docker compose up database -d + ``` + +4. Run prisma migrations + + ```sh + npx prisma migrate dev + ``` + +5. Run the development server + + ```sh + npm run dev + ``` + +_Note: You will have to create a .env file from the template_ + +### Committing + +1. Create a new feature branch + + ```sh + git checkout -b feature/AmazingFeature + ``` + +2. Commit your changes + + ```sh + git commit -m 'feat: add some AmazingFeature' + ``` + + _Remember to use [semantic commits](https://gist.github.com/joshbuchea/6f47e86d2510bce28f8e7f42ae84c716)_ + +3. Push to the branch + + ```sh + git push origin feature/AmazingFeature + ``` + +4. Open a pull request to the `dev` branch + +5. Associate the pull request with the relevant issue (if applicable) diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..b2f0350a337e5023ccf8486d7396e2ff33c5aec0 GIT binary patch literal 95268 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

>LP$kgf(21&H_C$`V!bmO@rp(4GE>+Si8tuByAQ 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 Sr3E$;qY`BsRQ(tJ^S=NhsBR7b literal 0 HcmV?d00001 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..9235f55 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,16 @@ +version: "3.3" + +services: + admin: + build: + context: . + dockerfile: Dockerfile + image: admin:latest + ports: + - "9847:3000" + environment: + - DATABASE_URL=${DATABASE_URL} + - TZ=${TZ} + + pull_policy: build + restart: always diff --git a/next.config.js b/next.config.js new file mode 100644 index 0000000..3d7d856 --- /dev/null +++ b/next.config.js @@ -0,0 +1,24 @@ +/** @type {import("next").NextConfig} */ +const config = { + /** + * Enable react strict mode + * + * This is a feature that helps with catching common mistakes in your application. + */ + reactStrictMode: true, + + /** + * If you are using `appDir` then you must comment the below `i18n` config out. + * + * @see https://github.com/vercel/next.js/issues/41980 + */ + i18n: { + locales: ["en"], + defaultLocale: "en", + }, +}; + +/** + * Export the config default + */ +export default config; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..5bc69f2 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3862 @@ +{ + "name": "trpc-template-nextjs", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "trpc-template-nextjs", + "version": "0.1.0", + "dependencies": { + "@prisma/client": "^5.16.1", + "@tanstack/react-query": "^4.36.1", + "@trpc/client": "^10.43.6", + "@trpc/next": "^10.43.6", + "@trpc/react-query": "^10.43.6", + "@trpc/server": "^10.43.6", + "clsx": "^2.0.0", + "eclipse-components": "^0.0.157", + "json2csv": "^6.0.0-alpha.2", + "next": "^14.0.3", + "next-auth": "^4.24.5", + "react": "18.2.0", + "react-dom": "18.2.0", + "superjson": "^2.2.1", + "tailwind-merge": "^2.1.0", + "zod": "^3.22.4" + }, + "devDependencies": { + "@next/eslint-plugin-next": "^14.0.3", + "@types/eslint": "^8.44.7", + "@types/json2csv": "^5.0.7", + "@types/node": "^18.17.0", + "@types/react": "^18.2.37", + "@types/react-dom": "^18.2.15", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "@typescript-eslint/parser": "^6.11.0", + "autoprefixer": "^10.4.14", + "client": "^0.0.1", + "eslint": "^8.56.0", + "postcss": "^8.4.31", + "prettier": "^3.1.0", + "prettier-plugin-tailwindcss": "^0.5.7", + "prisma": "^5.16.1", + "tailwindcss": "^3.3.5", + "typescript": "^5.1.6" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@babel/runtime": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.6.tgz", + "integrity": "sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.56.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.13", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.0.8", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.1", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.20", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@next/env": { + "version": "14.0.4", + "license": "MIT" + }, + "node_modules/@next/eslint-plugin-next": { + "version": "14.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "7.1.7" + } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.0.4", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.0.4.tgz", + "integrity": "sha512-IZQ3C7Bx0k2rYtrZZxKKiusMTM9WWcK5ajyhOZkYYTCc8xytmwSzR1skU7qLgVT/EY9xtXDG0WhY6fyujnI3rw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.0.4.tgz", + "integrity": "sha512-VwwZKrBQo/MGb1VOrxJ6LrKvbpo7UbROuyMRvQKTFKhNaXjUmKTu7wxVkIuCARAfiI8JpaWAnKR+D6tzpCcM4w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.0.4.tgz", + "integrity": "sha512-8QftwPEW37XxXoAwsn+nXlodKWHfpMaSvt81W43Wh8dv0gkheD+30ezWMcFGHLI71KiWmHK5PSQbTQGUiidvLQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.0.4.tgz", + "integrity": "sha512-/s/Pme3VKfZAfISlYVq2hzFS8AcAIOTnoKupc/j4WlvF6GQ0VouS2Q2KEgPuO1eMBwakWPB1aYFIA4VNVh667A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.0.4.tgz", + "integrity": "sha512-m8z/6Fyal4L9Bnlxde5g2Mfa1Z7dasMQyhEhskDATpqr+Y0mjOBZcXQ7G5U+vgL22cI4T7MfvgtrM2jdopqWaw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.0.4.tgz", + "integrity": "sha512-7Wv4PRiWIAWbm5XrGz3D8HUkCVDMMz9igffZG4NB1p4u1KoItwx9qjATHz88kwCEal/HXmbShucaslXCQXUM5w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.0.4.tgz", + "integrity": "sha512-zLeNEAPULsl0phfGb4kdzF/cAVIfaC7hY+kt0/d+y9mzcZHsMS3hAS829WbJ31DkSlVKQeHEjZHIdhN+Pg7Gyg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.0.4.tgz", + "integrity": "sha512-yEh2+R8qDlDCjxVpzOTEpBLQTEFAcP2A8fUFLaWNap9GitYKkKv1//y2S6XY6zsR4rCOPRpU7plYDR+az2n30A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@panva/hkdf": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.1.1.tgz", + "integrity": "sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/@prisma/client": { + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.16.1.tgz", + "integrity": "sha512-wM9SKQjF0qLxdnOZIVAIMKiz6Hu7vDt4FFAih85K1dk/Rr2mdahy6d3QP41K62N9O0DJJA//gUDA3Mp49xsKIg==", + "hasInstallScript": true, + "engines": { + "node": ">=16.13" + }, + "peerDependencies": { + "prisma": "*" + }, + "peerDependenciesMeta": { + "prisma": { + "optional": true + } + } + }, + "node_modules/@prisma/debug": { + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.16.1.tgz", + "integrity": "sha512-JsNgZAg6BD9RInLSrg7ZYzo11N7cVvYArq3fHGSD89HSgtN0VDdjV6bib7YddbcO6snzjchTiLfjeTqBjtArVQ==", + "devOptional": true + }, + "node_modules/@prisma/engines": { + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.16.1.tgz", + "integrity": "sha512-KkyF3eIUtBIyp5A/rJHCtwQO18OjpGgx18PzjyGcJDY/+vNgaVyuVd+TgwBgeq6NLdd1XMwRCI+58vinHsAdfA==", + "devOptional": true, + "hasInstallScript": true, + "dependencies": { + "@prisma/debug": "5.16.1", + "@prisma/engines-version": "5.16.0-24.34ace0eb2704183d2c05b60b52fba5c43c13f303", + "@prisma/fetch-engine": "5.16.1", + "@prisma/get-platform": "5.16.1" + } + }, + "node_modules/@prisma/engines-version": { + "version": "5.16.0-24.34ace0eb2704183d2c05b60b52fba5c43c13f303", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.16.0-24.34ace0eb2704183d2c05b60b52fba5c43c13f303.tgz", + "integrity": "sha512-HkT2WbfmFZ9WUPyuJHhkiADxazHg8Y4gByrTSVeb3OikP6tjQ7txtSUGu9OBOBH0C13dPKN2qqH12xKtHu/Hiw==", + "devOptional": true + }, + "node_modules/@prisma/fetch-engine": { + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.16.1.tgz", + "integrity": "sha512-oOkjaPU1lhcA/Rvr4GVfd1NLJBwExgNBE36Ueq7dr71kTMwy++a3U3oLd2ZwrV9dj9xoP6LjCcky799D9nEt4w==", + "devOptional": true, + "dependencies": { + "@prisma/debug": "5.16.1", + "@prisma/engines-version": "5.16.0-24.34ace0eb2704183d2c05b60b52fba5c43c13f303", + "@prisma/get-platform": "5.16.1" + } + }, + "node_modules/@prisma/get-platform": { + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.16.1.tgz", + "integrity": "sha512-R4IKnWnMkR2nUAbU5gjrPehdQYUUd7RENFD2/D+xXTNhcqczp0N+WEGQ3ViyI3+6mtVcjjNIMdnUTNyu3GxIgA==", + "devOptional": true, + "dependencies": { + "@prisma/debug": "5.16.1" + } + }, + "node_modules/@streamparser/json": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@streamparser/json/-/json-0.0.6.tgz", + "integrity": "sha512-vL9EVn/v+OhZ+Wcs6O4iKE9EUpwHUqHmCtNUMWjqp+6dr85+XPOSGTEsqYNq1Vn04uk9SWlOVmx9J48ggJVT2Q==" + }, + "node_modules/@swc/helpers": { + "version": "0.5.2", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tanstack/query-core": { + "version": "4.36.1", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "4.36.1", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "4.36.1", + "use-sync-external-store": "^1.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-native": "*" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/@trpc/client": { + "version": "10.44.1", + "funding": [ + "https://trpc.io/sponsor" + ], + "license": "MIT", + "peerDependencies": { + "@trpc/server": "10.44.1" + } + }, + "node_modules/@trpc/next": { + "version": "10.44.1", + "funding": [ + "https://trpc.io/sponsor" + ], + "license": "MIT", + "dependencies": { + "react-ssr-prepass": "^1.5.0" + }, + "peerDependencies": { + "@tanstack/react-query": "^4.18.0", + "@trpc/client": "10.44.1", + "@trpc/react-query": "10.44.1", + "@trpc/server": "10.44.1", + "next": "*", + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@trpc/react-query": { + "version": "10.44.1", + "funding": [ + "https://trpc.io/sponsor" + ], + "license": "MIT", + "peerDependencies": { + "@tanstack/react-query": "^4.18.0", + "@trpc/client": "10.44.1", + "@trpc/server": "10.44.1", + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@trpc/server": { + "version": "10.44.1", + "funding": [ + "https://trpc.io/sponsor" + ], + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@types/eslint": { + "version": "8.44.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json2csv": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@types/json2csv/-/json2csv-5.0.7.tgz", + "integrity": "sha512-Ma25zw9G9GEBnX8b12R4EYvnFT6dBh8L3jwsN5EUFXa+fl2dqmbLDbNWN0XuQU3rSXdsbBeCYjI9uHU2PUBxhA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "18.19.3", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.11", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.2.45", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.2.18", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.8", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/semver": { + "version": "7.5.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.15.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.15.0", + "@typescript-eslint/type-utils": "6.15.0", + "@typescript-eslint/utils": "6.15.0", + "@typescript-eslint/visitor-keys": "6.15.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.15.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "6.15.0", + "@typescript-eslint/types": "6.15.0", + "@typescript-eslint/typescript-estree": "6.15.0", + "@typescript-eslint/visitor-keys": "6.15.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.15.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "6.15.0", + "@typescript-eslint/visitor-keys": "6.15.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "6.15.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "6.15.0", + "@typescript-eslint/utils": "6.15.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.15.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.15.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "6.15.0", + "@typescript-eslint/visitor-keys": "6.15.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.15.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.15.0", + "@typescript-eslint/types": "6.15.0", + "@typescript-eslint/typescript-estree": "6.15.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.15.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "6.15.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "dev": true, + "license": "ISC" + }, + "node_modules/acorn": { + "version": "8.11.2", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/after": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.1.tgz", + "integrity": "sha512-SuI3vWhCFeSmkmmJ3efyuOkrhGyp/AuHthh3F5DinGYh2kR9t/0xUlm3/Vn2qMScfgg+cKho5fW7TUEYUhYeiA==", + "dev": true + }, + "node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-union": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/arraybuffer.slice": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz", + "integrity": "sha512-6ZjfQaBSy6CuIH0+B0NrxMfDE5VIOCP/5gOqSpEIsaAZx9/giszzrXg6PZ7G51U/n88UmlAgYLNQ9wAnII7PJA==", + "dev": true + }, + "node_modules/async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==", + "dev": true + }, + "node_modules/autoprefixer": { + "version": "10.4.16", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.21.10", + "caniuse-lite": "^1.0.30001538", + "fraction.js": "^4.3.6", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/aws-sign": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/aws-sign/-/aws-sign-0.2.0.tgz", + "integrity": "sha512-6P7/Ls5F6++DsKu7iacris7qq/AZSWaX+gT4dtSyUxM82ePxWxaP7Slo82ZO3ZTx6GSKxQHAQlmFvM8e+Dd8ZA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/backoff": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz", + "integrity": "sha512-wC5ihrnUXmR2douXmXLCe5O3zg3GKIyvRi/hi58a/XyRxVI+3/yM0PYueQOZXPXQ9pxBislYkw+sF9b7C/RuMA==", + "dev": true, + "dependencies": { + "precond": "0.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-arraybuffer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.2.tgz", + "integrity": "sha512-ewBKKVVPIl78B26mYQHYlaxR7NydMiD/GxwLNIwTAfLIE4xhN2Gxcy30//azq5UrejXjzGpWjcBu3NUJxzMMzg==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha512-bYeph2DFlpK1XmGs6fvlLRUN29QISM3GBuUwSFsMY2XRx4AvC0WNCS57j4c/xGrK2RS24C1w3YoBOsw9fT46tQ==", + "dev": true, + "dependencies": { + "callsite": "1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/blob": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.2.tgz", + "integrity": "sha512-BoCcDt8zBGShn6DawAGQw37s9SSs+fEjiZWDzyB+841PbOogcR2X7LGlM4sR3Zsiq/zoyl8MFWDfN6oDSlveBQ==", + "dev": true + }, + "node_modules/boom": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-0.3.1.tgz", + "integrity": "sha512-xWrlXnkK46TjEW7HU5G39AXWuG5aiHz3++zk3bBzF4mfnVCkpcYbwsnLUqMmfZNgPEYS/AI8MH+vmJxH5Kz0PA==", + "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", + "dev": true, + "dependencies": { + "hoek": "0.4.x" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/boom/node_modules/hoek": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.4.2.tgz", + "integrity": "sha512-Yj/N2TCrS0d8jvZgUpq9sDNt8/ABwTxPJW4+8QT0KXCMxOtRfUCUTEZEYyvMSgfDT3MGvwgO+NHfWPobagAIug==", + "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.22.2", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/busboy": { + "version": "1.6.0", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001570", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/client": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client/-/client-0.0.1.tgz", + "integrity": "sha512-XjoueeoiUNMrH0BGD/joA1RNxhzw5aGhRo15MmdPDV6RWCcUeKRBXrcH1qJNTepOxDwLAZbyLy0Owvw3V9jYxg==", + "dev": true, + "dependencies": { + "backoff": "^2.4.0", + "cookie": "^0.1.2", + "getenv": "~0.3.0", + "q": "~0.9.7", + "restler": "~2.0.1", + "socket.io-client": "~1.0.6", + "underscore": "^1.6.0", + "winston": "^0.7.3" + }, + "engines": { + "node": "*" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "license": "MIT" + }, + "node_modules/client/node_modules/cookie": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.5.tgz", + "integrity": "sha512-/lhu+NGBI5pOLXILS07DrPXYX0QDD/ejVhbwoCUcLPBqMEK9b++f9rUhAlhLkcTz9mV6QSeD+w3cHJ96rMZaFQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/colors": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", + "integrity": "sha512-OsSVtHK8Ir8r3+Fxw/b4jS1ZLPXkV6ZxDRJQzeD7qo0SqMXWrHDM71DgYzPMHY8SFJ0Ao+nNU2p1MmwdzKqPrw==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/combined-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", + "integrity": "sha512-qfexlmLp9MyrkajQVyjEDb0Vj+KhRgR/rxLiVhaihlT+ZkX0lReqtH6Ack40CvMDERR4b5eFp3CreskpBs1Pig==", + "dev": true, + "dependencies": { + "delayed-stream": "0.0.5" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha512-WZveuKPeKAG9qY+FkYDeADzdHyTYdIboXS59ixDeRJL5ZhxpqUnxSOwop4FQjMsiYm3/Or8cegVbpAHNA7pHxw==", + "dev": true + }, + "node_modules/component-emitter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz", + "integrity": "sha512-YhIbp3PJiznERfjlIkK0ue4obZxt2S60+0W8z24ZymOHT8sHloOqWOqZRU2eN5OlY8U08VFsP02letcu26FilA==", + "dev": true + }, + "node_modules/component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha512-w+LhYREhatpVqTESyGFg3NlP6Iu0kEKUHETY9GoZP/pQyW4mHFZuFWRUCIqVPZ36ueVLtoOEZaAqbCF2RDndaA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-jar": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/cookie-jar/-/cookie-jar-0.2.0.tgz", + "integrity": "sha512-yImk9AY90xjoUsN2fWHoIhVgveXqiZv7LDqUTZEzVBHyzfay8AjcJITUZpz2fTYLh6rnP+7GogiuRCo/5j2epg==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/copy-anything": { + "version": "3.0.5", + "license": "MIT", + "dependencies": { + "is-what": "^4.1.8" + }, + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cryptiles": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.1.0.tgz", + "integrity": "sha512-WiOGszxSaVHd8T4hlu5Xcqs2uUYxbvotBP171ag2pLPKSwSKeTJYnzd98/YWV3jQYk/rpMHa3r01cQfN8SZrHQ==", + "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", + "dev": true, + "dependencies": { + "boom": "0.3.x" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/cycle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", + "integrity": "sha512-TVF6svNzeQCOpjCqsy0/CSy8VgObG3wXusJ73xW2GbG5rGx7lC8zxDSURicsXI2UsGdi2L0QNRCi745/wUDvsA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/delayed-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz", + "integrity": "sha512-v+7uBd1pqe5YtgPacIIbZ8HuHeLFVNe4mUEyFDXL6KiqzEykjbw+5mXZXpGFgNVasdL4jWKgaKIXrEHiynN1LA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/doctrine": { + "version": "3.0.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/eclipse-components": { + "version": "0.0.157", + "resolved": "https://registry.npmjs.org/eclipse-components/-/eclipse-components-0.0.157.tgz", + "integrity": "sha512-K4CeqO03Frgib37JazGM88bA8zblasIOjldC9DMFyo2vJfFaxL18czDemcIdqFiXseO/begClU3Qhqp8IUlikw==", + "peerDependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.615", + "dev": true, + "license": "ISC" + }, + "node_modules/emitter": { + "version": "1.0.1", + "resolved": "http://github.com/component/emitter/archive/1.0.1.tar.gz", + "integrity": "sha512-r/UcFj7JS3lRjv9cgYjgpDNbAsGUdqU64n6ZUOgSF7s1UFBbGu7pUDwKEjHu9NBCy6j2AmmjNW4rijR4De65eA==", + "dev": true, + "dependencies": { + "indexof": "0.0.1" + } + }, + "node_modules/engine.io-client": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.3.1.tgz", + "integrity": "sha512-bTOZMqAe7HXhyA/2T7Fve04b/ZZruTHSOqa+yn8U4RFSyRAVPePjopOgJOUNciEfuXo1gx850P5LzaQU28/p3w==", + "dev": true, + "dependencies": { + "component-emitter": "1.1.2", + "component-inherit": "0.0.3", + "debug": "0.7.4", + "engine.io-parser": "1.0.6", + "has-cors": "1.0.3", + "indexof": "0.0.1", + "parsejson": "0.0.1", + "parseqs": "0.0.2", + "parseuri": "0.0.2", + "ws": "0.4.31", + "xmlhttprequest": "https://github.com/LearnBoost/node-XMLHttpRequest/archive/0f36d0b5ebc03d85f860d42a64ae9791e1daa433.tar.gz" + } + }, + "node_modules/engine.io-client/node_modules/debug": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-0.7.4.tgz", + "integrity": "sha512-EohAb3+DSHSGx8carOSKJe8G0ayV5/i609OD0J2orCkuyae7SyZSz2aoLmQF2s0Pj5gITDebwPH7GFBlqOUQ1Q==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/engine.io-parser": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.0.6.tgz", + "integrity": "sha512-ipbmiNj4OfAL9csof0FlI9L2jkU/lgcUphHjnTDo1KABsA21WtsVy/1OjhCj8xxhNIHtxEZ3/t7uB45gEMhD4g==", + "dev": true, + "dependencies": { + "after": "0.8.1", + "arraybuffer.slice": "0.0.6", + "base64-arraybuffer": "0.1.2", + "blob": "0.0.2", + "utf8": "2.0.0" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.56.0", + "@humanwhocodes/config-array": "^0.11.13", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==", + "dev": true, + "engines": { + "node": "> 0.1.90" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.16.0", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.9", + "dev": true, + "license": "ISC" + }, + "node_modules/forever-agent": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.2.0.tgz", + "integrity": "sha512-IasWSRIlfPnBZY1K9jEUK3PwsScR4mrcK+aNBJzGoPnW+S9b6f8I8ScyH4cehEOFNqnjGpP2gCaA22gqSV1xQA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.0.10.tgz", + "integrity": "sha512-Z9/PpT/agxXi80nMpOH6GFD7XOr6mwk5aWMxDt/KMY+Nm7e4FnRMjddM4/mLPJhpmp6alY1F/1JQpRE6z07xng==", + "dev": true, + "dependencies": { + "async": "~0.2.7", + "combined-stream": "~0.0.4", + "mime": "~1.2.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/getenv": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/getenv/-/getenv-0.3.0.tgz", + "integrity": "sha512-E5JuanH2c71x2d24Pg9WpQMs0YpbiVPFBMNJtDC4M2VG+zPc3j3JvaoAD2dj9r/ERkw6Va19HBephneUyeENoQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/glob": { + "version": "7.1.7", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "license": "BSD-2-Clause" + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.0.8", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/global": { + "version": "2.0.1", + "resolved": "https://github.com/component/global/archive/v2.0.1.tar.gz", + "integrity": "sha512-O91OcV/NbdmQJPHaRu2ekSP7bqFRLWgqSwaJvqHPZHUwmHBagQYTOra29+LnzzG3lZkXH1ANzHzfCxtAPM9HMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/globals": { + "version": "13.24.0", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/has-binary-data": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/has-binary-data/-/has-binary-data-0.1.1.tgz", + "integrity": "sha512-XqIrqIgPlA2gxvHKudDsLJt8Xu8B4DvkHyUWGmLWYOAO0rFOL94Ds4NSveSZ1fCjWX22tQgIiRpDKAETex8GCQ==", + "dev": true, + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/has-cors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.0.3.tgz", + "integrity": "sha512-Mxk1ba23PNtB3zPigreijApS3uuH9bhgZkqQtLQj7ydWHsGeb9uOtk4gsK6mZj4rYG6VNS/CT9G1XkYfgItpKg==", + "dev": true, + "dependencies": { + "global": "https://github.com/component/global/archive/v2.0.1.tar.gz" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hawk": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-0.10.2.tgz", + "integrity": "sha512-BjpmnZ95odv7KOIsydfNTAxfGOGaVc6xbYL4fozWl45PWjDqskix0LHAekmGkpnrCAI6+AZRvJIXNTAllj+e6w==", + "deprecated": "This module moved to @hapi/hawk. Please make sure to switch over as this distribution is no longer supported and may contain bugs and critical security issues.", + "dev": true, + "dependencies": { + "boom": "0.3.x", + "cryptiles": "0.1.x", + "hoek": "0.7.x", + "sntp": "0.1.x" + }, + "engines": { + "node": "0.8.x" + } + }, + "node_modules/hoek": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.7.6.tgz", + "integrity": "sha512-z75muWk69yyjWn6nNzJP0pnfgcewtSTs7uBolGUA7kWNdCYZukzHn3sYqUirhXul7qp9WBUwNT/7ieJZNveJqg==", + "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", + "dev": true, + "engines": { + "node": "0.8.x" + } + }, + "node_modules/ignore": { + "version": "5.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg==", + "dev": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-what": { + "version": "4.1.16", + "license": "MIT", + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/jiti": { + "version": "1.21.0", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/jose": { + "version": "4.15.4", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz", + "integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stringify-safe": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-3.0.0.tgz", + "integrity": "sha512-VSSuxEAawKLYlCabQOR7YDijQ69zPqQBOriUuCgNhlAqtU7RPr41gPpaSs6WkEu+ZOtUequpXWbI51CS+Z/gMQ==", + "dev": true + }, + "node_modules/json2csv": { + "version": "6.0.0-alpha.2", + "resolved": "https://registry.npmjs.org/json2csv/-/json2csv-6.0.0-alpha.2.tgz", + "integrity": "sha512-nJ3oP6QxN8z69IT1HmrJdfVxhU1kLTBVgMfRnNZc37YEY+jZ4nU27rBGxT4vaqM/KUCavLRhntmTuBFqZLBUcA==", + "dependencies": { + "@streamparser/json": "^0.0.6", + "commander": "^6.2.0", + "lodash.get": "^4.4.2" + }, + "bin": { + "json2csv": "bin/json2csv.js" + }, + "engines": { + "node": ">= 12", + "npm": ">= 6.13.0" + } + }, + "node_modules/json2csv/node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/json3": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.2.6.tgz", + "integrity": "sha512-KA+GHhYTLTo7Ri4DyjwUgW8kn98AYtVZtBC94qL5yD0ZSYct8/eF8qBmTNyk+gPE578bKeIL4WBq+MUyd1I26g==", + "deprecated": "Please use the native JSON object instead of JSON 3", + "dev": true + }, + "node_modules/keyv": { + "version": "4.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "dev": true, + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "dev": true, + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz", + "integrity": "sha512-Ysa2F/nqTNGHhhm9MV8ure4+Hc+Y8AWiqUdHxsO7xu8zc92ND9f3kpALHjaP026Ft17UfxrMt95c50PLUeynBw==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/mz": { + "version": "2.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nan": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-0.3.2.tgz", + "integrity": "sha512-V9/Pyy5Oelv6vVJP9X+dAzU3IO19j6YXrJnODHxP2h54hTvfFQGahdsQV6Ule/UukiEJk1SkQ/aUyWUm61RBQw==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/next": { + "version": "14.0.4", + "license": "MIT", + "dependencies": { + "@next/env": "14.0.4", + "@swc/helpers": "0.5.2", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001406", + "graceful-fs": "^4.2.11", + "postcss": "8.4.31", + "styled-jsx": "5.1.1", + "watchpack": "2.4.0" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=18.17.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "14.0.4", + "@next/swc-darwin-x64": "14.0.4", + "@next/swc-linux-arm64-gnu": "14.0.4", + "@next/swc-linux-arm64-musl": "14.0.4", + "@next/swc-linux-x64-gnu": "14.0.4", + "@next/swc-linux-x64-musl": "14.0.4", + "@next/swc-win32-arm64-msvc": "14.0.4", + "@next/swc-win32-ia32-msvc": "14.0.4", + "@next/swc-win32-x64-msvc": "14.0.4" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next-auth": { + "version": "4.24.5", + "resolved": "https://registry.npmjs.org/next-auth/-/next-auth-4.24.5.tgz", + "integrity": "sha512-3RafV3XbfIKk6rF6GlLE4/KxjTcuMCifqrmD+98ejFq73SRoj2rmzoca8u764977lH/Q7jo6Xu6yM+Re1Mz/Og==", + "dependencies": { + "@babel/runtime": "^7.20.13", + "@panva/hkdf": "^1.0.2", + "cookie": "^0.5.0", + "jose": "^4.11.4", + "oauth": "^0.9.15", + "openid-client": "^5.4.0", + "preact": "^10.6.3", + "preact-render-to-string": "^5.1.19", + "uuid": "^8.3.2" + }, + "peerDependencies": { + "next": "^12.2.5 || ^13 || ^14", + "nodemailer": "^6.6.5", + "react": "^17.0.2 || ^18", + "react-dom": "^17.0.2 || ^18" + }, + "peerDependenciesMeta": { + "nodemailer": { + "optional": true + } + } + }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/node-releases": { + "version": "2.0.14", + "dev": true, + "license": "MIT" + }, + "node_modules/node-uuid": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", + "integrity": "sha512-TkCET/3rr9mUuRp+CpO7qfgT++aAxfDRaalQhwPFzI9BY/2rCDn6OfpZOVggi1AXfTPpfkTrg5f5WQx5G1uLxA==", + "deprecated": "Use uuid module instead", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/oauth": { + "version": "0.9.15", + "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", + "integrity": "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==" + }, + "node_modules/oauth-sign": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.2.0.tgz", + "integrity": "sha512-4DtiD64CwPJ5vZ636j/KtM7DxWbX1KlkqwbqbEAxI3BCpBrQdrKOv8vC/36U6gfm1CVapy6QmcVxPnXPPQApTA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha512-S0sN3agnVh2SZNEIGc0N1X4Z5K0JeFbGBrnuZpsxuUh5XLF0BnvWkMjRXo/zGKLd/eghvNIKcx1pQkmUjXIyrA==", + "dev": true + }, + "node_modules/object-hash": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/oidc-token-hash": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz", + "integrity": "sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw==", + "engines": { + "node": "^10.13.0 || >=12.0.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/openid-client": { + "version": "5.6.4", + "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.6.4.tgz", + "integrity": "sha512-T1h3B10BRPKfcObdBklX639tVz+xh34O7GjofqrqiAQdm7eHsQ00ih18x6wuJ/E6FxdtS2u3FmUGPDeEcMwzNA==", + "dependencies": { + "jose": "^4.15.4", + "lru-cache": "^6.0.0", + "object-hash": "^2.2.0", + "oidc-token-hash": "^5.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/openid-client/node_modules/object-hash": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", + "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/options": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", + "integrity": "sha512-bOj3L1ypm++N+n7CEbbe473A414AB7z+amKYshRb//iuL3MpdDCLhPnw6aVTdKB9g5ZRVHIEp8eUln6L2NUStg==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parsejson": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/parsejson/-/parsejson-0.0.1.tgz", + "integrity": "sha512-W9CRvTfYQY/kbRc5Q6YTWarb/QDxdEGbd6RCP8CLUQDJV89RVHoS2A0dZYNtAcq31fulGNN4ZhAhiQQazwlKJg==", + "dev": true, + "dependencies": { + "better-assert": "~1.0.0" + } + }, + "node_modules/parseqs": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.2.tgz", + "integrity": "sha512-vyyyfQGUFZnDhgrrdn+hh1JuOfvbXU5oRr6dijfkSIbaFuxGgTSCA/RNVcsADmo0k2NX6wERVTMKkXokjuObJA==", + "dev": true, + "dependencies": { + "better-assert": "~1.0.0" + } + }, + "node_modules/parseuri": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.2.tgz", + "integrity": "sha512-m0H+R0u5LXOx8sbxufnvgKrRLpkVpvtMf0AyWXYSqLwo2MWrVEgCIbgpaSVa398xl6wTLe0A7CGhiC4hBdEzHQ==", + "dev": true, + "dependencies": { + "better-assert": "~1.0.0" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkginfo": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.3.1.tgz", + "integrity": "sha512-yO5feByMzAp96LtP58wvPKSbaKAi/1C4kV9XpTctr6EepnP6F33RBNOiVrdz9BrPA98U2BMFsTNHo44TWcbQ2A==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/postcss": { + "version": "8.4.32", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/postcss-nested": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.11" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.13", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/preact": { + "version": "10.19.3", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.19.3.tgz", + "integrity": "sha512-nHHTeFVBTHRGxJXKkKu5hT8C/YWBkPso4/Gad6xuj5dbptt9iF9NZr9pHbPhBrnT2klheu7mHTxTZ/LjwJiEiQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "node_modules/preact-render-to-string": { + "version": "5.2.6", + "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.6.tgz", + "integrity": "sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==", + "dependencies": { + "pretty-format": "^3.8.0" + }, + "peerDependencies": { + "preact": ">=10" + } + }, + "node_modules/precond": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz", + "integrity": "sha512-QCYG84SgGyGzqJ/vlMsxeXd/pgL/I94ixdNFyh1PusWmTCyVfPJjZ1K1jvHtsbfnXQs2TSkEP2fR7QiMZAnKFQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-plugin-tailwindcss": { + "version": "0.5.9", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.21.3" + }, + "peerDependencies": { + "@ianvs/prettier-plugin-sort-imports": "*", + "@prettier/plugin-pug": "*", + "@shopify/prettier-plugin-liquid": "*", + "@trivago/prettier-plugin-sort-imports": "*", + "prettier": "^3.0", + "prettier-plugin-astro": "*", + "prettier-plugin-css-order": "*", + "prettier-plugin-import-sort": "*", + "prettier-plugin-jsdoc": "*", + "prettier-plugin-marko": "*", + "prettier-plugin-organize-attributes": "*", + "prettier-plugin-organize-imports": "*", + "prettier-plugin-style-order": "*", + "prettier-plugin-svelte": "*" + }, + "peerDependenciesMeta": { + "@ianvs/prettier-plugin-sort-imports": { + "optional": true + }, + "@prettier/plugin-pug": { + "optional": true + }, + "@shopify/prettier-plugin-liquid": { + "optional": true + }, + "@trivago/prettier-plugin-sort-imports": { + "optional": true + }, + "prettier-plugin-astro": { + "optional": true + }, + "prettier-plugin-css-order": { + "optional": true + }, + "prettier-plugin-import-sort": { + "optional": true + }, + "prettier-plugin-jsdoc": { + "optional": true + }, + "prettier-plugin-marko": { + "optional": true + }, + "prettier-plugin-organize-attributes": { + "optional": true + }, + "prettier-plugin-organize-imports": { + "optional": true + }, + "prettier-plugin-style-order": { + "optional": true + }, + "prettier-plugin-svelte": { + "optional": true + }, + "prettier-plugin-twig-melody": { + "optional": true + } + } + }, + "node_modules/pretty-format": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz", + "integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==" + }, + "node_modules/prisma": { + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.16.1.tgz", + "integrity": "sha512-Z1Uqodk44diztImxALgJJfNl2Uisl9xDRvqybMKEBYJLNKNhDfAHf+ZIJbZyYiBhLMbKU9cYGdDVG5IIXEnL2Q==", + "devOptional": true, + "hasInstallScript": true, + "dependencies": { + "@prisma/engines": "5.16.1" + }, + "bin": { + "prisma": "build/index.js" + }, + "engines": { + "node": ">=16.13" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/q": { + "version": "0.9.7", + "resolved": "https://registry.npmjs.org/q/-/q-0.9.7.tgz", + "integrity": "sha512-ijt0LhxWClXBtc1RCt8H0WhlZLAdVX26nWbpsJy+Hblmp81d2F/pFsvlrJhJDDruFHM+ECtxP0H0HzGSrARkwg==", + "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)", + "dev": true, + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qs": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/qs/-/qs-0.5.6.tgz", + "integrity": "sha512-KbOrQrP5Ye+0gmq+hwxoJwAFRwExACWqwxj1IDFFgqOw9Poxy3wwSbafd9ZqP6T6ykMfnxM573kt/a4i9ybatQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/react": { + "version": "18.2.0", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.2.0", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/react-ssr-prepass": { + "version": "1.5.0", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/request": { + "version": "2.16.6", + "resolved": "https://registry.npmjs.org/request/-/request-2.16.6.tgz", + "integrity": "sha512-TfD4kMo40kwuOpO7GYfAZpb2wYdw7yvTIglPNgPPSmp2Fz6MKNvPLla40FQ/ypdhy6B2jRNz3VlCjPD6mnzsmA==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "dependencies": { + "aws-sign": "~0.2.0", + "cookie-jar": "~0.2.0", + "forever-agent": "~0.2.0", + "form-data": "~0.0.3", + "hawk": "~0.10.2", + "json-stringify-safe": "~3.0.0", + "mime": "~1.2.7", + "node-uuid": "~1.4.0", + "oauth-sign": "~0.2.0", + "qs": "~0.5.4", + "tunnel-agent": "~0.2.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/restler": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/restler/-/restler-2.0.1.tgz", + "integrity": "sha512-j2gyQdGeFPKl8FRbFJ/XR7yCmL31pxD9l+zTcwZ2m7e8psU46X2lJ20GCsEFJD4rxtAaswzGJtKQhNLYFFtN0g==", + "dev": true, + "engines": { + "node": ">= 0.6.x" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/scheduler": { + "version": "0.23.0", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "7.5.4", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/sntp": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-0.1.2.tgz", + "integrity": "sha512-6fsOpJYQAQcO/UeW7T9mJwEenJymdU77o+gNiompGAammlSa+C49Oyt79ta/kgVbT13l4JAuKlo8FNvUnVjvEQ==", + "deprecated": "This module moved to @hapi/sntp. Please make sure to switch over as this distribution is no longer supported and may contain bugs and critical security issues.", + "dev": true, + "dependencies": { + "hoek": "0.4.x" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/sntp/node_modules/hoek": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.4.2.tgz", + "integrity": "sha512-Yj/N2TCrS0d8jvZgUpq9sDNt8/ABwTxPJW4+8QT0KXCMxOtRfUCUTEZEYyvMSgfDT3MGvwgO+NHfWPobagAIug==", + "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/socket.io-client": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.0.6.tgz", + "integrity": "sha512-itdtz6fQBTFIDBP4+hJox0OlT+SbCVdENjPgjMup3ehu7OsiG6t0FYBXCx+k/upt9lbeyp9BmUNNi5EfnGa5Vw==", + "dev": true, + "dependencies": { + "component-bind": "1.0.0", + "component-emitter": "1.1.2", + "debug": "0.7.4", + "engine.io-client": "1.3.1", + "has-binary-data": "0.1.1", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseuri": "0.0.2", + "socket.io-parser": "2.2.0", + "to-array": "0.1.3" + } + }, + "node_modules/socket.io-client/node_modules/debug": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-0.7.4.tgz", + "integrity": "sha512-EohAb3+DSHSGx8carOSKJe8G0ayV5/i609OD0J2orCkuyae7SyZSz2aoLmQF2s0Pj5gITDebwPH7GFBlqOUQ1Q==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/socket.io-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.2.0.tgz", + "integrity": "sha512-uW3UiLVibAyleKq8r/yZe1oPO51olhY18T6HtnN0iI6RLqJfYC0YiyAFlsPw1+8I0Z1qFd8jFLTRZo2vr6ISxA==", + "dev": true, + "dependencies": { + "debug": "0.7.4", + "emitter": "http://github.com/component/emitter/archive/1.0.1.tar.gz", + "isarray": "0.0.1", + "json3": "3.2.6" + } + }, + "node_modules/socket.io-parser/node_modules/debug": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-0.7.4.tgz", + "integrity": "sha512-EohAb3+DSHSGx8carOSKJe8G0ayV5/i609OD0J2orCkuyae7SyZSz2aoLmQF2s0Pj5gITDebwPH7GFBlqOUQ1Q==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.1", + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/sucrase": { + "version": "3.34.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "7.1.6", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "7.1.6", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sucrase/node_modules/glob/node_modules/minimatch": { + "version": "3.0.8", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/superjson": { + "version": "2.2.1", + "license": "MIT", + "dependencies": { + "copy-anything": "^3.0.2" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwind-merge": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.1.0.tgz", + "integrity": "sha512-l11VvI4nSwW7MtLSLYT4ldidDEUwQAMWuSHk7l4zcXZDgnCRa0V3OdCwFfM7DCzakVXMNRwAeje9maFFXT71dQ==", + "dependencies": { + "@babel/runtime": "^7.23.5" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwindcss": { + "version": "3.3.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.19.1", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/thenify": { + "version": "3.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tinycolor": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tinycolor/-/tinycolor-0.0.1.tgz", + "integrity": "sha512-+CorETse1kl98xg0WAzii8DTT4ABF4R3nquhrkIbVGcw1T8JYs5Gfx9xEfGINPUZGDj9C4BmOtuKeaTtuuRolg==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/to-array": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.3.tgz", + "integrity": "sha512-JQk/QMS4oHyU2VufVeyjN25dcnZnr1PV1pa1oKSj7l5tVO9WrU62og3fYzB3mrgJZZgBxdrrA/v6iZzMDuyFYw==", + "dev": true + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.13.0" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/tslib": { + "version": "2.6.2", + "license": "0BSD" + }, + "node_modules/tunnel-agent": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.2.0.tgz", + "integrity": "sha512-PXy4q1PH88BK0pcGOEMXFAslyBuRWz1wxLfPXTlYFd41eyUgjOALaVGbWJN1ymjbnBzjWunVSKmrrMMh8oLaZA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.3.3", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", + "dev": true + }, + "node_modules/undici-types": { + "version": "5.26.5", + "dev": true, + "license": "MIT" + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/utf8": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.0.0.tgz", + "integrity": "sha512-jWXHr+bQ8RsWazLzVY3V7XACPTbBHYSg/VoDVok+DBQk5ULm0AuBCNb9tGmjq2H+znnkBFwjhzzCbn9G3xlYcA==", + "dev": true + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/watchpack": { + "version": "2.4.0", + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/winston": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/winston/-/winston-0.7.3.tgz", + "integrity": "sha512-iVTT8tf9YnTyfZX+aEUj2fl6WBRet7za6vdjMeyF8SA80Vii2rreM5XH+5qmpBV9uJGj8jz8BozvTDcroVq/eA==", + "dev": true, + "dependencies": { + "async": "0.2.x", + "colors": "0.6.x", + "cycle": "1.0.x", + "eyes": "0.1.x", + "pkginfo": "0.3.x", + "request": "2.16.x", + "stack-trace": "0.0.x" + }, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "0.4.31", + "resolved": "https://registry.npmjs.org/ws/-/ws-0.4.31.tgz", + "integrity": "sha512-mWiVQ9qZGPXvLxQ4xGy58Ix5Bw0L99SB+hDT8L59bty4fbnQczaGl4YEWR7AzLQGbvPn/30r9/o41dPiSuUmYw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "commander": "~0.6.1", + "nan": "~0.3.0", + "options": ">=0.0.5", + "tinycolor": "0.x" + }, + "bin": { + "wscat": "bin/wscat" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ws/node_modules/commander": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz", + "integrity": "sha512-0fLycpl1UMTGX257hRsu/arL/cUbcvQM4zMKwvLvzXtfdezIV4yotPS2dYtknF+NmEfWSoCEF6+hj9XLm/6hEw==", + "dev": true, + "engines": { + "node": ">= 0.4.x" + } + }, + "node_modules/xmlhttprequest": { + "version": "1.5.0", + "resolved": "https://github.com/LearnBoost/node-XMLHttpRequest/archive/0f36d0b5ebc03d85f860d42a64ae9791e1daa433.tar.gz", + "integrity": "sha512-TVSZwoeUQ7OKhb8jnQdSxGFz+lm4MGWmhG0deeYg85VQT74x5LcSrKeXHE0ZIzEycgqQ5mF8r8e1AykA7TpNAQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "license": "ISC" + }, + "node_modules/yaml": { + "version": "2.3.4", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 14" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.22.4", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..75c8f21 --- /dev/null +++ b/package.json @@ -0,0 +1,52 @@ +{ + "name": "trpc-template-nextjs", + "version": "0.1.0", + "private": true, + "type": "module", + "scripts": { + "build": "next build", + "dev": "next dev -p 4000", + "lint": "next lint", + "start": "next start" + }, + "dependencies": { + "@prisma/client": "^5.16.1", + "@tanstack/react-query": "^4.36.1", + "@trpc/client": "^10.43.6", + "@trpc/next": "^10.43.6", + "@trpc/react-query": "^10.43.6", + "@trpc/server": "^10.43.6", + "clsx": "^2.0.0", + "eclipse-components": "^0.0.157", + "json2csv": "^6.0.0-alpha.2", + "next": "^14.0.3", + "next-auth": "^4.24.5", + "react": "18.2.0", + "react-dom": "18.2.0", + "superjson": "^2.2.1", + "tailwind-merge": "^2.1.0", + "zod": "^3.22.4" + }, + "devDependencies": { + "@next/eslint-plugin-next": "^14.0.3", + "@types/eslint": "^8.44.7", + "@types/json2csv": "^5.0.7", + "@types/node": "^18.17.0", + "@types/react": "^18.2.37", + "@types/react-dom": "^18.2.15", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "@typescript-eslint/parser": "^6.11.0", + "autoprefixer": "^10.4.14", + "client": "^0.0.1", + "eslint": "^8.56.0", + "postcss": "^8.4.31", + "prettier": "^3.1.0", + "prettier-plugin-tailwindcss": "^0.5.7", + "prisma": "^5.16.1", + "tailwindcss": "^3.3.5", + "typescript": "^5.1.6" + }, + "ct3aMetadata": { + "initVersion": "7.24.2" + } +} diff --git a/postcss.config.cjs b/postcss.config.cjs new file mode 100644 index 0000000..e305dd9 --- /dev/null +++ b/postcss.config.cjs @@ -0,0 +1,8 @@ +const config = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; + +module.exports = config; diff --git a/prettier.config.js b/prettier.config.js new file mode 100644 index 0000000..b2d59b4 --- /dev/null +++ b/prettier.config.js @@ -0,0 +1,6 @@ +/** @type {import('prettier').Config & import('prettier-plugin-tailwindcss').PluginOptions} */ +const config = { + plugins: ["prettier-plugin-tailwindcss"], +}; + +export default config; diff --git a/prisma/migrations/20231216071101_inint/migration.sql b/prisma/migrations/20231216071101_inint/migration.sql new file mode 100644 index 0000000..3af05cb --- /dev/null +++ b/prisma/migrations/20231216071101_inint/migration.sql @@ -0,0 +1,13 @@ +-- CreateTable +CREATE TABLE "User" ( + "id" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + "email" TEXT NOT NULL, + "name" TEXT NOT NULL DEFAULT '', + + CONSTRAINT "User_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "User_email_key" ON "User"("email"); diff --git a/prisma/migrations/20240216030149_add_auth/migration.sql b/prisma/migrations/20240216030149_add_auth/migration.sql new file mode 100644 index 0000000..3a47fbb --- /dev/null +++ b/prisma/migrations/20240216030149_add_auth/migration.sql @@ -0,0 +1,20 @@ +-- AlterTable +ALTER TABLE "User" ADD COLUMN "firstName" TEXT NOT NULL DEFAULT '', +ADD COLUMN "lastName" TEXT NOT NULL DEFAULT ''; + +-- CreateTable +CREATE TABLE "Auth" ( + "id" TEXT NOT NULL, + "passwordHash" VARCHAR(255) NOT NULL, + "userId" TEXT NOT NULL, + "createdAt" TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "Auth_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "Auth_userId_key" ON "Auth"("userId"); + +-- AddForeignKey +ALTER TABLE "Auth" ADD CONSTRAINT "Auth_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE NO ACTION; diff --git a/prisma/migrations/20240218002138_add_mailing_list/migration.sql b/prisma/migrations/20240218002138_add_mailing_list/migration.sql new file mode 100644 index 0000000..f915e75 --- /dev/null +++ b/prisma/migrations/20240218002138_add_mailing_list/migration.sql @@ -0,0 +1,31 @@ +/* + Warnings: + + - You are about to drop the column `name` on the `User` table. All the data in the column will be lost. + +*/ +-- AlterTable +ALTER TABLE "User" DROP COLUMN "name"; + +-- CreateTable +CREATE TABLE "MailingList" ( + "id" TEXT NOT NULL, + "email" TEXT NOT NULL, + "firstName" TEXT NOT NULL DEFAULT '', + "lastName" TEXT NOT NULL DEFAULT '', + "preRegistered" BOOLEAN NOT NULL DEFAULT false, + "userId" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "MailingList_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "MailingList_email_key" ON "MailingList"("email"); + +-- CreateIndex +CREATE UNIQUE INDEX "MailingList_userId_key" ON "MailingList"("userId"); + +-- AddForeignKey +ALTER TABLE "MailingList" ADD CONSTRAINT "MailingList_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/prisma/migrations/20240218002616_deduplicate_mailinglist/migration.sql b/prisma/migrations/20240218002616_deduplicate_mailinglist/migration.sql new file mode 100644 index 0000000..5a2ff89 --- /dev/null +++ b/prisma/migrations/20240218002616_deduplicate_mailinglist/migration.sql @@ -0,0 +1,23 @@ +/* + Warnings: + + - You are about to drop the column `email` on the `MailingList` table. All the data in the column will be lost. + - You are about to drop the column `firstName` on the `MailingList` table. All the data in the column will be lost. + - You are about to drop the column `lastName` on the `MailingList` table. All the data in the column will be lost. + - Made the column `userId` on table `MailingList` required. This step will fail if there are existing NULL values in that column. + +*/ +-- DropForeignKey +ALTER TABLE "MailingList" DROP CONSTRAINT "MailingList_userId_fkey"; + +-- DropIndex +DROP INDEX "MailingList_email_key"; + +-- AlterTable +ALTER TABLE "MailingList" DROP COLUMN "email", +DROP COLUMN "firstName", +DROP COLUMN "lastName", +ALTER COLUMN "userId" SET NOT NULL; + +-- AddForeignKey +ALTER TABLE "MailingList" ADD CONSTRAINT "MailingList_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/migrations/20240223233815_add_hiring_application/migration.sql b/prisma/migrations/20240223233815_add_hiring_application/migration.sql new file mode 100644 index 0000000..c4476d7 --- /dev/null +++ b/prisma/migrations/20240223233815_add_hiring_application/migration.sql @@ -0,0 +1,15 @@ +-- CreateTable +CREATE TABLE "HiringApplication" ( + "id" TEXT NOT NULL, + "firstName" TEXT NOT NULL, + "lastName" TEXT NOT NULL, + "email" TEXT NOT NULL, + "dateOfBirth" TIMESTAMP(3) NOT NULL, + "school" TEXT NOT NULL, + "resume" TEXT NOT NULL, + "portfolio" TEXT NOT NULL, + "aboutAnswer" TEXT NOT NULL, + "recordAnswer" TEXT NOT NULL, + + CONSTRAINT "HiringApplication_pkey" PRIMARY KEY ("id") +); diff --git a/prisma/migrations/20240223234508_/migration.sql b/prisma/migrations/20240223234508_/migration.sql new file mode 100644 index 0000000..da8c559 --- /dev/null +++ b/prisma/migrations/20240223234508_/migration.sql @@ -0,0 +1,10 @@ +/* + Warnings: + + - You are about to drop the column `recordAnswer` on the `HiringApplication` table. All the data in the column will be lost. + - Added the required column `RecordAnswer` to the `HiringApplication` table without a default value. This is not possible if the table is not empty. + +*/ +-- AlterTable +ALTER TABLE "HiringApplication" DROP COLUMN "recordAnswer", +ADD COLUMN "RecordAnswer" TEXT NOT NULL; diff --git a/prisma/migrations/20240227004733_update_application_table/migration.sql b/prisma/migrations/20240227004733_update_application_table/migration.sql new file mode 100644 index 0000000..15fbc6d --- /dev/null +++ b/prisma/migrations/20240227004733_update_application_table/migration.sql @@ -0,0 +1,18 @@ +/* + Warnings: + + - You are about to drop the column `RecordAnswer` on the `HiringApplication` table. All the data in the column will be lost. + - You are about to drop the column `portfolio` on the `HiringApplication` table. All the data in the column will be lost. + - You are about to drop the column `resume` on the `HiringApplication` table. All the data in the column will be lost. + - Added the required column `portfolioPath` to the `HiringApplication` table without a default value. This is not possible if the table is not empty. + - Added the required column `recordAnswer` to the `HiringApplication` table without a default value. This is not possible if the table is not empty. + - Added the required column `resumePath` to the `HiringApplication` table without a default value. This is not possible if the table is not empty. + +*/ +-- AlterTable +ALTER TABLE "HiringApplication" DROP COLUMN "RecordAnswer", +DROP COLUMN "portfolio", +DROP COLUMN "resume", +ADD COLUMN "portfolioPath" TEXT NOT NULL, +ADD COLUMN "recordAnswer" TEXT NOT NULL, +ADD COLUMN "resumePath" TEXT NOT NULL; diff --git a/prisma/migrations/20240227021057_make_portfolio_optional/migration.sql b/prisma/migrations/20240227021057_make_portfolio_optional/migration.sql new file mode 100644 index 0000000..0a75e70 --- /dev/null +++ b/prisma/migrations/20240227021057_make_portfolio_optional/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "HiringApplication" ALTER COLUMN "portfolioPath" DROP NOT NULL; diff --git a/prisma/migrations/20240227021146_store_resume_name/migration.sql b/prisma/migrations/20240227021146_store_resume_name/migration.sql new file mode 100644 index 0000000..9459283 --- /dev/null +++ b/prisma/migrations/20240227021146_store_resume_name/migration.sql @@ -0,0 +1,9 @@ +/* + Warnings: + + - Added the required column `resumeName` to the `HiringApplication` table without a default value. This is not possible if the table is not empty. + +*/ +-- AlterTable +ALTER TABLE "HiringApplication" ADD COLUMN "portfolioName" TEXT, +ADD COLUMN "resumeName" TEXT NOT NULL; diff --git a/prisma/migrations/20240227022100_rename_school_column/migration.sql b/prisma/migrations/20240227022100_rename_school_column/migration.sql new file mode 100644 index 0000000..edf7e2f --- /dev/null +++ b/prisma/migrations/20240227022100_rename_school_column/migration.sql @@ -0,0 +1,10 @@ +/* + Warnings: + + - You are about to drop the column `school` on the `HiringApplication` table. All the data in the column will be lost. + - Added the required column `institution` to the `HiringApplication` table without a default value. This is not possible if the table is not empty. + +*/ +-- AlterTable +ALTER TABLE "HiringApplication" DROP COLUMN "school", +ADD COLUMN "institution" TEXT NOT NULL; diff --git a/prisma/migrations/20240303030415_add_permissions_table/migration.sql b/prisma/migrations/20240303030415_add_permissions_table/migration.sql new file mode 100644 index 0000000..5295204 --- /dev/null +++ b/prisma/migrations/20240303030415_add_permissions_table/migration.sql @@ -0,0 +1,21 @@ +-- CreateTable +CREATE TABLE "UserPermissions" ( + "id" TEXT NOT NULL, + "userId" TEXT NOT NULL, + "canAccessDashboard" BOOLEAN NOT NULL DEFAULT true, + "canAccessAdmin" BOOLEAN NOT NULL DEFAULT false, + "canManageUsers" BOOLEAN NOT NULL DEFAULT false, + "canManageMailingList" BOOLEAN NOT NULL DEFAULT false, + "canManageHiringApplications" BOOLEAN NOT NULL DEFAULT false, + "isSuperAdmin" BOOLEAN NOT NULL DEFAULT false, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "UserPermissions_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "UserPermissions_userId_key" ON "UserPermissions"("userId"); + +-- AddForeignKey +ALTER TABLE "UserPermissions" ADD CONSTRAINT "UserPermissions_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/migrations/20240303031139_update_permissions_table/migration.sql b/prisma/migrations/20240303031139_update_permissions_table/migration.sql new file mode 100644 index 0000000..ab82e9d --- /dev/null +++ b/prisma/migrations/20240303031139_update_permissions_table/migration.sql @@ -0,0 +1,33 @@ +/* + Warnings: + + - You are about to drop the `UserPermissions` table. If the table is not empty, all the data it contains will be lost. + +*/ +-- DropForeignKey +ALTER TABLE "UserPermissions" DROP CONSTRAINT "UserPermissions_userId_fkey"; + +-- DropTable +DROP TABLE "UserPermissions"; + +-- CreateTable +CREATE TABLE "UserPermission" ( + "id" TEXT NOT NULL, + "userId" TEXT NOT NULL, + "canAccessDashboard" BOOLEAN NOT NULL DEFAULT true, + "canAccessAdmin" BOOLEAN NOT NULL DEFAULT false, + "canManageUsers" BOOLEAN NOT NULL DEFAULT false, + "canManageMailingList" BOOLEAN NOT NULL DEFAULT false, + "canManageHiringApplications" BOOLEAN NOT NULL DEFAULT false, + "isSuperAdmin" BOOLEAN NOT NULL DEFAULT false, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "UserPermission_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "UserPermission_userId_key" ON "UserPermission"("userId"); + +-- AddForeignKey +ALTER TABLE "UserPermission" ADD CONSTRAINT "UserPermission_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/migrations/20240307001403_add_timestamps_to_hiring_application/migration.sql b/prisma/migrations/20240307001403_add_timestamps_to_hiring_application/migration.sql new file mode 100644 index 0000000..9f78317 --- /dev/null +++ b/prisma/migrations/20240307001403_add_timestamps_to_hiring_application/migration.sql @@ -0,0 +1,3 @@ +-- AlterTable +ALTER TABLE "HiringApplication" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, +ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP; diff --git a/prisma/migrations/20240307001706_track_login_attempts/migration.sql b/prisma/migrations/20240307001706_track_login_attempts/migration.sql new file mode 100644 index 0000000..f4d5a42 --- /dev/null +++ b/prisma/migrations/20240307001706_track_login_attempts/migration.sql @@ -0,0 +1,29 @@ +-- DropForeignKey +ALTER TABLE "MailingList" DROP CONSTRAINT "MailingList_userId_fkey"; + +-- DropForeignKey +ALTER TABLE "UserPermission" DROP CONSTRAINT "UserPermission_userId_fkey"; + +-- AlterTable +ALTER TABLE "Auth" ADD COLUMN "emailVerified" BOOLEAN NOT NULL DEFAULT false; + +-- CreateTable +CREATE TABLE "LoginAttempt" ( + "id" TEXT NOT NULL, + "email" TEXT NOT NULL, + "ip" TEXT NOT NULL, + "associatedUserId" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LoginAttempt_pkey" PRIMARY KEY ("id") +); + +-- AddForeignKey +ALTER TABLE "MailingList" ADD CONSTRAINT "MailingList_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE NO ACTION; + +-- AddForeignKey +ALTER TABLE "UserPermission" ADD CONSTRAINT "UserPermission_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE NO ACTION; + +-- AddForeignKey +ALTER TABLE "LoginAttempt" ADD CONSTRAINT "LoginAttempt_associatedUserId_fkey" FOREIGN KEY ("associatedUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE NO ACTION; diff --git a/prisma/migrations/20240307002135_track_login_result/migration.sql b/prisma/migrations/20240307002135_track_login_result/migration.sql new file mode 100644 index 0000000..52fb177 --- /dev/null +++ b/prisma/migrations/20240307002135_track_login_result/migration.sql @@ -0,0 +1,11 @@ +/* + Warnings: + + - Added the required column `result` to the `LoginAttempt` table without a default value. This is not possible if the table is not empty. + +*/ +-- CreateEnum +CREATE TYPE "LoginResult" AS ENUM ('SUCCESS', 'INVALID_PASSWORD', 'USER_NOT_FOUND', 'TOO_MANY_ATTEMPTS'); + +-- AlterTable +ALTER TABLE "LoginAttempt" ADD COLUMN "result" "LoginResult" NOT NULL; diff --git a/prisma/migrations/migration_lock.toml b/prisma/migrations/migration_lock.toml new file mode 100644 index 0000000..fbffa92 --- /dev/null +++ b/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (i.e. Git) +provider = "postgresql" \ No newline at end of file diff --git a/prisma/schema.prisma b/prisma/schema.prisma new file mode 100644 index 0000000..7f35719 --- /dev/null +++ b/prisma/schema.prisma @@ -0,0 +1,117 @@ +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} + +generator client { + provider = "prisma-client-js" +} + +// Model for storing user data +model User { + id String @id @default(uuid()) + email String @unique + firstName String @default("") + lastName String @default("") + + auth Auth? + mailingList MailingList? + permissions UserPermission? + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + LoginAttempt LoginAttempt[] +} + +model Auth { + id String @id @default(uuid()) + passwordHash String @db.VarChar(255) + + emailVerified Boolean @default(false) + + user User @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: NoAction) + userId String @unique + + createdAt DateTime @default(now()) @db.Timestamp(0) + updatedAt DateTime @default(now()) @updatedAt @db.Timestamp(0) +} + +model MailingList { + id String @id @default(uuid()) + + // Link to User + user User @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: NoAction) + userId String @unique + + // Enrolled Options + preRegistered Boolean @default(false) + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model HiringApplication { + id String @id @default(uuid()) + + firstName String + lastName String + email String + + dateOfBirth DateTime + institution String + + resumePath String + resumeName String + portfolioPath String? + portfolioName String? + + aboutAnswer String + recordAnswer String + + createdAt DateTime @default(now()) + updatedAt DateTime @default(now()) @updatedAt +} + +model UserPermission { + id String @id @default(uuid()) + + user User @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: NoAction) + userId String @unique + + // Permissions + + // Basic + canAccessDashboard Boolean @default(true) + + // Admin + canAccessAdmin Boolean @default(false) + canManageUsers Boolean @default(false) + canManageMailingList Boolean @default(false) + canManageHiringApplications Boolean @default(false) + isSuperAdmin Boolean @default(false) + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model LoginAttempt { + id String @id @default(uuid()) + + email String + ip String + + result LoginResult + + associatedUserId String? // If the user is found, we can associate the user with the attempt + associatedUser User? @relation(fields: [associatedUserId], references: [id], onDelete: SetNull, onUpdate: NoAction) + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +enum LoginResult { + SUCCESS + INVALID_PASSWORD + USER_NOT_FOUND + TOO_MANY_ATTEMPTS +} diff --git a/public/.gitkeep b/public/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/app/Providers.tsx b/src/app/Providers.tsx new file mode 100644 index 0000000..be778d3 --- /dev/null +++ b/src/app/Providers.tsx @@ -0,0 +1,11 @@ +"use client"; + +import { SessionProvider } from "next-auth/react"; + +type ProvidersProps = { + children: React.ReactNode; +}; + +export default function Providers({ children }: ProvidersProps) { + return {children}; +} diff --git a/src/app/_trpc/Provider.tsx b/src/app/_trpc/Provider.tsx new file mode 100644 index 0000000..8eb401c --- /dev/null +++ b/src/app/_trpc/Provider.tsx @@ -0,0 +1,24 @@ +"use client"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { httpBatchLink } from "@trpc/client"; +import React, { useState } from "react"; + +import { trpc } from "./client"; + +export default function Provider({ children }: { children: React.ReactNode }) { + const [queryClient] = useState(() => new QueryClient({})); + const [trpcClient] = useState(() => + trpc.createClient({ + links: [ + httpBatchLink({ + url: "/api/trpc", + }), + ], + }) + ); + return ( + + {children} + + ); +} diff --git a/src/app/_trpc/client.ts b/src/app/_trpc/client.ts new file mode 100644 index 0000000..11943de --- /dev/null +++ b/src/app/_trpc/client.ts @@ -0,0 +1,5 @@ +import { createTRPCReact } from "@trpc/react-query"; + +import { type AppRouter } from "@/lib/server"; + +export const trpc = createTRPCReact(); diff --git a/src/app/_trpc/serverClient.ts b/src/app/_trpc/serverClient.ts new file mode 100644 index 0000000..51fd2c2 --- /dev/null +++ b/src/app/_trpc/serverClient.ts @@ -0,0 +1,10 @@ +import { httpBatchLink } from "@trpc/client"; +import { appRouter } from "@/lib/server"; + +export const serverClient = appRouter.createCaller({ + links: [ + httpBatchLink({ + url: "/api/trpc", + }), + ], +}); diff --git a/src/app/api/trpc/[trpc]/route.ts b/src/app/api/trpc/[trpc]/route.ts new file mode 100644 index 0000000..71e71f7 --- /dev/null +++ b/src/app/api/trpc/[trpc]/route.ts @@ -0,0 +1,13 @@ +import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; + +import { appRouter } from "@/lib/server"; + +const handler = (req: Request) => + fetchRequestHandler({ + endpoint: "/api/trpc", + req, + router: appRouter, + createContext: () => ({}), + }); + +export { handler as GET, handler as POST }; diff --git a/src/app/client.tsx b/src/app/client.tsx new file mode 100644 index 0000000..9f41ab8 --- /dev/null +++ b/src/app/client.tsx @@ -0,0 +1,64 @@ +"use client"; + +import ErrorMessage from "@/components/ErrorMessage"; +import { LoadingRelative } from "@/components/Loading"; +import { Status, UserWithMailingList } from "@/types/types"; +import { + Button, + EclipseLogoTextOrbWhite, + MainWrapper, + ObjectTable, +} from "eclipse-components"; +import { useEffect, useState } from "react"; +import { useRouter } from "next/navigation"; +import NavBar from "@/components/NavBar"; +type Props = { + users: UserWithMailingList[]; +}; + +export default function Client({ users }: Props) { + const router = useRouter(); + return ( + + + + + {/* */} + { + return ( + + {new Date(user.createdAt).toLocaleString("en-US", { + month: "short", + day: "numeric", + })} + + ); + }, + (user) => { + return user.mailingList?.preRegistered ? ( +

+ {"•"} +
+ ) : null; + }, + ]} + >
+ + +
+ ); +} diff --git a/src/app/error/layout.tsx b/src/app/error/layout.tsx new file mode 100644 index 0000000..8fa71bf --- /dev/null +++ b/src/app/error/layout.tsx @@ -0,0 +1,22 @@ +import type { Metadata } from "next"; +import { Inter } from "next/font/google"; +import "@/styles/globals.css"; + +const inter = Inter({ subsets: ["latin"] }); + +export const metadata: Metadata = { + title: "Eclipse Expos | Error", + description: "Admin Dashboard for Eclipse Expos", +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + {children} + + ); +} diff --git a/src/app/error/page.tsx b/src/app/error/page.tsx new file mode 100644 index 0000000..7e489a0 --- /dev/null +++ b/src/app/error/page.tsx @@ -0,0 +1,30 @@ +"use client"; + +import ErrorMessage from "@/components/ErrorMessage"; +import MainWrapper from "@/components/MainWrapper"; + +/** + * The error page component. + */ +export default function ErrorPage() { + return ; +} + +/** + * The main page components. + */ +function Components() { + /** + * Return the page HTML contents. + * + * Since we're using the app router, we don't have to wrap the main page contents + * in a <>... tag -- Where we would also define the title, description, etc. + * + * To change the title, description, etc. of the page, go to the layout.tsx file. + */ + return ( + + An error has occurred. + + ); +} diff --git a/src/app/favicon.ico b/src/app/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..b5336a48e6e7341e6e866c5f477d1a006dc6bf9e GIT binary patch literal 23600 zcmeI4YmXFF5QckMt_#9~A|eR0un<@-0Td&mM&yGDL5La*i5i4>L8E>%(V+2{5q^?? z!ER>HQ`Oydy3aY?Jv$3Mf%G$Vs@|$o)6>(}&9a4TF zKg<4m_B6L%y0q?b`nly`mYvD{@~}K=I+8Co#VeoB^xtjhhAtfID%1d1b*N@D#yK!} z14@QRPE;>VwZegct&j;zCFe!c2jiPMbtw>+9Gnxjf1rHjk{8xxNJDMDdJq=5I^ksZ z;MZyd{u-)I`aOORAPrZvZ^3#H)=n5j@O~-q8$2{<3CDUIR)hJM8M6srVBHJ-2IZTI z`ioHw+6{ZligsHERT+^(&}&{F`=clDQx}Nk4%9n*j$%ty&$m-J--U*Qw~*cj{S5&- zUAs2xviLEZqF~D$OqSbISAMd4F{)u zRru`TrQEV42tNjG6x_Ay^V!0StWBHHeNZyUY9)Is$zmV*CR??KXYfxxTqE~9>#bl< zln%~2s)E*gyj!6(O}y=WYKALt!YZM#;n%XmhTjw(`1G{B64UUuG{sU`Ps}Kt#bSa! zgnVFyS8cx7y1h1$LJBvTjQ42Mr6y(z)BrB3Y1t5788Ro)BwZb==$UV;G1hxC&@^@` z8AUk`!c+&V(5kH-<+Jot_|HCh?9~db_c*sga@8oGfMSUxiEK-Y9C zta5mL4_gRmu_g}Dn)-O>gT$AR57;8%um;7#-ll2kv2bB?ii8JkB=H6=yIQck2br+X z1%xb31=DCwu1JCRE+`7lyE=(VI@ln(6}&Sk&1R`p$8;!;?UP@oqG@cLLy@1T#QnoO zel>L-B0_X15cPD<&2#>FANi z4!n#VC^k98W$N$p|Kk;+yb0rL?7-N8u> zC0*N2##f+QjdY#SpvyF_KB6YjPtZUh7m#Vb8pd&yW@f| z4R>_=d`y6x62cS<+)nFD=ChM%sBWGmLoEDBK=8UkM0!>vw)k4sWGA}kb{09&{tF6$ zNmISnScqt|PyPr?{0qq;TPIgIpODXlh1dz8lD?5_y})VJMBV|~R^&rpS|{t@4XdIy z8;WuuizyI-ZgZ>Ff%ZV1a{0&;y$;nBkP3t!oI=bJ?ScCeQ*uD&J3THQCFK@GAj4JoyXP%bdp#m@4(F?j~pc4#O4FJd9k!dfV-R`$J7@b zk8Py(r-)fKRUQ~8bs&_Uqaa4kamy|%g9#uXWYWQ*>n)iF>?=81o_NJC9EuZh#U=Xn z7lHBsE2cnLb6Q=NvajO*~BQ$s(JFmBR@A3 z(FIDEjS!M=!S<#$#EzjqaNAs66I4ppIUETR%fu5b8r^2cYj8NvIIGsRd8Rr z%u>!K$irt0c7fvWJ9%FS%kwPOMbH)eUS5(*XzZ63ZKX5mTU8`9cps$0=^iw~KpiOk zO{>zUEyroSq<+KthNAos8eujaIHErfQpz@39=v0)3+&P9O6%G9(Xaodzb@@fj;(zy zQMv~80=xAJfZ}~3F~N?M&PZ@bGy_OwQ5DPS#1LJ<_wM%{`dVtJ*!&j4VJq eAi2Y^nY=fz>F@5yV+Y0#j2##|Fm_;GJMceGE{$0L literal 0 HcmV?d00001 diff --git a/src/app/hiring/responses/[id]/client.tsx b/src/app/hiring/responses/[id]/client.tsx new file mode 100644 index 0000000..5c64d10 --- /dev/null +++ b/src/app/hiring/responses/[id]/client.tsx @@ -0,0 +1,80 @@ +"use client"; + +import { HiringApplication } from "@prisma/client"; +import { + Button, + MainWrapper, + ObjectTable, + +} from "eclipse-components"; +import Link from "next/link"; +import { useRouter } from "next/navigation"; +import NavBar from "@/components/NavBar"; + +type Props = { + application: HiringApplication; + entries: number; +}; + +export default function Client({ application, entries }: Props) { + const router = useRouter(); + const resumePath = `${process.env.NEXT_PUBLIC_APPLY_DOMAIN}/api/hiring/${application.id}/resume`; + const portfolioPath = `${process.env.NEXT_PUBLIC_APPLY_DOMAIN}/api/hiring/${application.id}/portfolio`; + const nextUser = () => { router.push(`/hiring/responses/${Math.abs(parseInt(application.id)+1) % entries}`) } + const prevUser = () => { router.push(`/hiring/responses/${Math.abs(parseInt(application.id)-1) % entries}`) } + return ( + + + +
+ +

Application {parseInt(application.id)+1} / {entries}

+ +
+ { + return new Date(application.createdAt).toLocaleString("en-US", { + month: "short", + day: "numeric", + }); + }, + ]} + /> +
+
+

About you (2 sentences)

+

{application.aboutAnswer}

+
+ +
+

+ If you could break any record what would it be? (1 sentence) +

+

{application.recordAnswer}

+
+
+ +
+ + + + {application.portfolioPath && ( + + + + )} +
+
+ ); +} diff --git a/src/app/hiring/responses/[id]/loading.tsx b/src/app/hiring/responses/[id]/loading.tsx new file mode 100644 index 0000000..b366361 --- /dev/null +++ b/src/app/hiring/responses/[id]/loading.tsx @@ -0,0 +1,11 @@ +"use client"; + +import { LoadingSpinnerCenter, MainWrapper } from "eclipse-components"; + +export default function Loading() { + return ( + + + + ); +} diff --git a/src/app/hiring/responses/[id]/page.tsx b/src/app/hiring/responses/[id]/page.tsx new file mode 100644 index 0000000..ac0ab5b --- /dev/null +++ b/src/app/hiring/responses/[id]/page.tsx @@ -0,0 +1,37 @@ +import hasPermission from "@/lib/user/hasPermission"; +import Client from "./client"; +import { prisma } from "@/lib/prisma"; +import { notFound } from "next/navigation"; +import { MainWrapper } from "eclipse-components"; + +/** + * Store the URL to redirect the user to if they are not authenticated. + */ +const REDIRECT_AUTH_URL = + process.env.NEXT_PUBLIC_REDIRECT_AUTH_URL ?? "/unauthorized"; + +type Props = { + params: { + id: string; + }; +}; + +export default async function Home({ params }: Props) { + // await hasPermission( + // ["canAccessAdmin", "canManageHiringApplications"], + // REDIRECT_AUTH_URL, + // ); + + const application = await prisma.hiringApplication.findUnique({ + where: { + id: params.id, + }, + }); + const entries = await prisma.hiringApplication.count(); + // const next = params.id = + if (!application) { + return notFound(); + } + + return ; // All the client side stuff is handled in the client.tsx file +} diff --git a/src/app/hiring/responses/client.tsx b/src/app/hiring/responses/client.tsx new file mode 100644 index 0000000..d13578b --- /dev/null +++ b/src/app/hiring/responses/client.tsx @@ -0,0 +1,60 @@ +"use client"; +import { parse } from 'json2csv' +import { HiringApplication } from "@prisma/client"; +import { + Button, + EclipseLogoTextOrbWhite, + MainWrapper, + ObjectTable, +} from "eclipse-components"; +import { useRouter } from "next/navigation"; +import NavBar from "@/components/NavBar"; + +type Props = { + applications: HiringApplication[]; +}; + +export default function Client({ applications }: Props) { + const router = useRouter(); + const downloadCSV =()=> { + const csv = parse(applications); + const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' }); + const url = URL.createObjectURL(blob); + const link = document.createElement('a'); + link.href = url; + link.setAttribute('download', 'applications.csv'); + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + }; + return ( + + + + { + router.push(`/hiring/responses/${application.id}`); + }} + computedColumns={[ + (application) => { + return new Date(application.createdAt).toLocaleString("en-US", { + month: "short", + day: "numeric", + }); + }, + ]} + > + + + + + + ); +} diff --git a/src/app/hiring/responses/loading.tsx b/src/app/hiring/responses/loading.tsx new file mode 100644 index 0000000..b366361 --- /dev/null +++ b/src/app/hiring/responses/loading.tsx @@ -0,0 +1,11 @@ +"use client"; + +import { LoadingSpinnerCenter, MainWrapper } from "eclipse-components"; + +export default function Loading() { + return ( + + + + ); +} diff --git a/src/app/hiring/responses/page.tsx b/src/app/hiring/responses/page.tsx new file mode 100644 index 0000000..82fa0fd --- /dev/null +++ b/src/app/hiring/responses/page.tsx @@ -0,0 +1,24 @@ +import hasPermission from "@/lib/user/hasPermission"; +import Client from "./client"; +import { prisma } from "@/lib/prisma"; + +/** + * Store the URL to redirect the user to if they are not authenticated. + */ +const REDIRECT_AUTH_URL = + process.env.NEXT_PUBLIC_REDIRECT_AUTH_URL ?? "/unauthorized"; + +export default async function Home() { + await hasPermission( + ["canAccessAdmin", "canManageHiringApplications"], + REDIRECT_AUTH_URL, + ); + + const applications = await prisma.hiringApplication.findMany({ + orderBy: { + createdAt: "desc", + }, + }); + + return ; // All the client side stuff is handled in the client.tsx file +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx new file mode 100644 index 0000000..6a743f7 --- /dev/null +++ b/src/app/layout.tsx @@ -0,0 +1,28 @@ +import type { Metadata } from "next"; +import { Inter } from "next/font/google"; +import "@/styles/globals.css"; +import Provider from "./_trpc/Provider"; +import Providers from "./Providers"; + +const inter = Inter({ subsets: ["latin"] }); + +export const metadata: Metadata = { + title: "Eclipse Expos | Admin Dashboard", + description: "Admin Dashboard for Eclipse Expos", +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + + + {children} + + + + ); +} diff --git a/src/app/loading.tsx b/src/app/loading.tsx new file mode 100644 index 0000000..b366361 --- /dev/null +++ b/src/app/loading.tsx @@ -0,0 +1,11 @@ +"use client"; + +import { LoadingSpinnerCenter, MainWrapper } from "eclipse-components"; + +export default function Loading() { + return ( + + + + ); +} diff --git a/src/app/page.tsx b/src/app/page.tsx new file mode 100644 index 0000000..3ded8dc --- /dev/null +++ b/src/app/page.tsx @@ -0,0 +1,20 @@ +import hasPermission from "@/lib/user/hasPermission"; +import Client from "./client"; +import { prisma } from "@/lib/prisma"; + +/** + * Store the URL to redirect the user to if they are not authenticated. + */ +const REDIRECT_AUTH_URL = + process.env.NEXT_PUBLIC_REDIRECT_AUTH_URL ?? "/unauthorized"; + +export default async function Home() { + await hasPermission(["canAccessAdmin", "canManageUsers"], REDIRECT_AUTH_URL); + const users = await prisma.user.findMany({ + include: { + mailingList: true, + }, + }); + + return ; // All the client side stuff is handled in the client.tsx file +} diff --git a/src/app/unauthorized/layout.tsx b/src/app/unauthorized/layout.tsx new file mode 100644 index 0000000..fa8fcdd --- /dev/null +++ b/src/app/unauthorized/layout.tsx @@ -0,0 +1,22 @@ +import type { Metadata } from "next"; +import { Inter } from "next/font/google"; +import "@/styles/globals.css"; + +const inter = Inter({ subsets: ["latin"] }); + +export const metadata: Metadata = { + title: "Eclipse Expos | Unauthorized", + description: "Admin Dashboard for Eclipse Expos", +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + {children} + + ); +} diff --git a/src/app/unauthorized/page.tsx b/src/app/unauthorized/page.tsx new file mode 100644 index 0000000..fc2321c --- /dev/null +++ b/src/app/unauthorized/page.tsx @@ -0,0 +1,30 @@ +"use client"; + +import ErrorMessage from "@/components/ErrorMessage"; +import MainWrapper from "@/components/MainWrapper"; + +/** + * The error page component. + */ +export default function ErrorPage() { + return ; +} + +/** + * The main page components. + */ +function Components() { + /** + * Return the page HTML contents. + * + * Since we're using the app router, we don't have to wrap the main page contents + * in a <>... tag -- Where we would also define the title, description, etc. + * + * To change the title, description, etc. of the page, go to the layout.tsx file. + */ + return ( + + You are unauthorized to access this path + + ); +} diff --git a/src/components/ErrorMessage.tsx b/src/components/ErrorMessage.tsx new file mode 100644 index 0000000..4dae6dc --- /dev/null +++ b/src/components/ErrorMessage.tsx @@ -0,0 +1,13 @@ +/** + * Error message component + * @returns JSX.Element + */ +export default function ErrorMessage({ + children, +}: { + children: string; +}): JSX.Element { + return ( +

{children}

+ ); +} diff --git a/src/components/Loading.tsx b/src/components/Loading.tsx new file mode 100644 index 0000000..3c17cb4 --- /dev/null +++ b/src/components/Loading.tsx @@ -0,0 +1,39 @@ +import { cn } from "@/lib/utils/cn"; + +/** + * Loading Component (Center) + * @returns JSX.Element + */ +export default function LoadingCenter(): JSX.Element { + return ( +
+ +
+ ); +} + +/** + * Loading Component (Relative) + * @param props + * @returns JSX.Element + */ +export function LoadingRelative(props: { className?: string }): JSX.Element { + return ( + + + + ); +} diff --git a/src/components/MainWrapper.tsx b/src/components/MainWrapper.tsx new file mode 100644 index 0000000..ee21996 --- /dev/null +++ b/src/components/MainWrapper.tsx @@ -0,0 +1,17 @@ +import { cn } from "@/lib/utils/cn"; +import { type PropsWithChildren } from "react"; + +export default function MainWrapper( + props: PropsWithChildren<{ className?: string }>, +): JSX.Element { + return ( +
+ {props.children} +
+ ); +} diff --git a/src/components/NavBar.tsx b/src/components/NavBar.tsx new file mode 100644 index 0000000..ec7c884 --- /dev/null +++ b/src/components/NavBar.tsx @@ -0,0 +1,116 @@ +/** + * NavBar Component + * @returns JSX.Element + */ +import { useState } from "react"; +export default function NavBar(): JSX.Element { + const [isNavOpen, setIsNavOpen] = useState(false); + + return ( +
+ + +
+); +} \ No newline at end of file diff --git a/src/components/PageHead.tsx b/src/components/PageHead.tsx new file mode 100644 index 0000000..30efb93 --- /dev/null +++ b/src/components/PageHead.tsx @@ -0,0 +1,16 @@ +import Head from "next/head"; + +type PageHeadProps = { + title: string; + description: string; +}; + +export default function PageHead(props: PageHeadProps): JSX.Element { + return ( + + {props.title} + + + + ); +} diff --git a/src/lib/crypto.ts b/src/lib/crypto.ts new file mode 100644 index 0000000..b3a6814 --- /dev/null +++ b/src/lib/crypto.ts @@ -0,0 +1,42 @@ +/** + * SHA256 Encryption + */ +export async function sha256(text: string): Promise { + const msgBuffer = new TextEncoder().encode(text); + const hash = await crypto.subtle.digest("SHA-256", msgBuffer); + const hashArray = Array.from(new Uint8Array(hash)); + return hashArray.map((b) => b.toString(16).padStart(2, "0")).join(""); +} + +/** + * Base64 Encoding + */ +export function base64encode(text: string): string { + const buff: number[] = []; + for (let i = 0; i < text.length; i++) { + buff.push(text.charCodeAt(i)); + } + + return btoa(String.fromCharCode.apply(null, buff)); +} + +/** + * Base64 Decoding + */ +export function base64decode(text: string): string { + const buff = atob(text); + const arr = []; + for (let i = 0; i < buff.length; i++) { + arr.push(buff.charCodeAt(i)); + } + + return String.fromCharCode.apply(null, arr); +} + +/** + * Generate a random id using nanoseconds + * @returns The random id + */ +export async function genId(): Promise { + return sha256(Math.random().toString() + ":" + Date.now()); +} diff --git a/src/lib/prisma.ts b/src/lib/prisma.ts new file mode 100644 index 0000000..e06eecd --- /dev/null +++ b/src/lib/prisma.ts @@ -0,0 +1,15 @@ +import { PrismaClient } from "@prisma/client"; + +const globalForPrisma = global as unknown as { + prisma?: PrismaClient | undefined; +}; + +export const prisma = + globalForPrisma.prisma ?? + new PrismaClient({ + log: ["query"], + }); + +if (process.env.NODE_ENV !== "production") { + globalForPrisma.prisma = prisma; +} diff --git a/src/lib/responses.ts b/src/lib/responses.ts new file mode 100644 index 0000000..3e4f3fc --- /dev/null +++ b/src/lib/responses.ts @@ -0,0 +1,81 @@ +import { base64encode } from "./crypto"; + +export class Response { + static get Success() { + const id = base64encode(Math.random().toString()); + const timestamp = Date.now(); + + return { + status: 200, + success: true, + message: "Success", + timestamp, + id, + }; + } + + static get InvalidQueryParams() { + const id = base64encode(Math.random().toString()); + const timestamp = Date.now(); + + return { + status: 400, + success: false, + message: "Invalid query parameters", + timestamp, + id, + }; + } + + static get InternalError() { + const id = base64encode(Math.random().toString()); + const timestamp = Date.now(); + + return { + status: 500, + success: false, + message: "Internal server error", + timestamp, + id, + }; + } + + static get InvalidInput() { + const id = base64encode(Math.random().toString()); + const timestamp = Date.now(); + + return { + status: 400, + success: false, + message: "Invalid request input", + timestamp, + id, + }; + } + + static get MethodNotAllowed() { + const id = base64encode(Math.random().toString()); + const timestamp = Date.now(); + + return { + status: 405, + success: false, + message: "Method not allowed", + timestamp, + id, + }; + } + + static get NotFound() { + const id = base64encode(Math.random().toString()); + const timestamp = Date.now(); + + return { + status: 404, + success: false, + message: "Not found", + timestamp, + id, + }; + } +} diff --git a/src/lib/server/index.ts b/src/lib/server/index.ts new file mode 100644 index 0000000..4fd89e1 --- /dev/null +++ b/src/lib/server/index.ts @@ -0,0 +1,9 @@ +import { prisma } from "@/lib/prisma"; +import { publicProcedure, router } from "./trpc"; +import { z } from "zod"; + +export const appRouter = router({}); + +// Export type router type signature, +// NOT the router itself. +export type AppRouter = typeof appRouter; diff --git a/src/lib/server/trpc.ts b/src/lib/server/trpc.ts new file mode 100644 index 0000000..be3ed16 --- /dev/null +++ b/src/lib/server/trpc.ts @@ -0,0 +1,6 @@ +import { initTRPC } from "@trpc/server"; + +const t = initTRPC.create(); + +export const router = t.router; +export const publicProcedure = t.procedure; diff --git a/src/lib/server/utils/zod.ts b/src/lib/server/utils/zod.ts new file mode 100644 index 0000000..47089bd --- /dev/null +++ b/src/lib/server/utils/zod.ts @@ -0,0 +1,13 @@ +import { z } from "zod"; + +export const zstring = (min?: number, max?: number) => + z + .string() + .min(min ?? 1) + .max(max ?? 255); + +export const znumber = (min?: number, max?: number) => + z + .number() + .min(min ?? 1) + .max(max ?? 1_000_000_000_000); diff --git a/src/lib/user/getSessionUser.ts b/src/lib/user/getSessionUser.ts new file mode 100644 index 0000000..a59588f --- /dev/null +++ b/src/lib/user/getSessionUser.ts @@ -0,0 +1,19 @@ +"use server"; + +import { getServerSession } from "next-auth"; +import { prisma } from "../prisma"; + +export async function getSessionUser() { + const session = await getServerSession(); + const email = session?.user?.email; + + if (!email) return null; + + const user = await prisma.user.findUnique({ + where: { + email: email, + }, + }); + + return user; +} diff --git a/src/lib/user/hasPermission.ts b/src/lib/user/hasPermission.ts new file mode 100644 index 0000000..c46d922 --- /dev/null +++ b/src/lib/user/hasPermission.ts @@ -0,0 +1,54 @@ +"use server"; + +import { UserPermission } from "@/types/types"; +import { getServerSession } from "next-auth"; +import { redirect } from "next/navigation"; +import { prisma } from "../prisma"; + +export default async function hasPermission( + permissions: UserPermission[], + redirectUrl?: string, +) { + const session = await getServerSession(); + + if (!session?.user.email) { + return redirectUrl ? redirect(redirectUrl) : false; + } + + const user = await prisma.user.findUnique({ + where: { + email: session.user.email, + }, + include: { + permissions: true, + }, + }); + + if (!user) { + return redirectUrl ? redirect(redirectUrl) : false; + } + + if (!user.permissions) { + // Might as well create the permissions if they don't exist + await prisma.userPermission.create({ + data: { + user: { + connect: { + id: user.id, + }, + }, + }, + }); + + return hasPermission(permissions, redirectUrl); + } + + for (const permission of permissions) { + if (!user.permissions[permission]) { + console.log(`User ${user.email} does not have permission ${permission}`); + return redirectUrl !== undefined ? redirect(redirectUrl) : false; + } + } + + return true; +} diff --git a/src/lib/utils/cn.ts b/src/lib/utils/cn.ts new file mode 100644 index 0000000..a0c6161 --- /dev/null +++ b/src/lib/utils/cn.ts @@ -0,0 +1,4 @@ +import { twMerge } from "tailwind-merge"; +import { clsx } from "clsx"; + +export const cn = (...inputs: (string | undefined)[]) => twMerge(clsx(inputs)); diff --git a/src/styles/globals.css b/src/styles/globals.css new file mode 100644 index 0000000..4f970d3 --- /dev/null +++ b/src/styles/globals.css @@ -0,0 +1,6 @@ +@import url("https://fonts.googleapis.com/css2?family=Montserrat:wght@100;200;300;400;500;600;700;800;900&family=Roboto&display=swap"); +@import url("https://fonts.googleapis.com/css2?family=Righteous&display=swap"); + +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/src/styles/stars.module.scss b/src/styles/stars.module.scss new file mode 100644 index 0000000..100d0d5 --- /dev/null +++ b/src/styles/stars.module.scss @@ -0,0 +1,37 @@ +// n is number of stars required +@function multiple-box-shadow($n) { + $value: "#{random(4000)}px #{random(4000)}px #aaa"; + @for $i from 2 through $n { + $value: "#{$value} , #{random(4000)}px #{random(4000)}px #aaa"; + } + + @return unquote($value); +} +$shadows-small: multiple-box-shadow(1900); +$shadows-medium: multiple-box-shadow(600); + +.background { + width: 1px; + height: 1px; + position: fixed; + box-shadow: $shadows-small; + animation: scroll 70s linear infinite; +} + +.foreground { + width: 2px; + height: 2px; + position: fixed; + background: transparent; + box-shadow: $shadows-medium; + animation: scroll 140s linear infinite; +} + +@keyframes scroll { + from { + transform: translateY(0px); + } + to { + transform: translateY(-2000px); + } +} diff --git a/src/types/debugTypes.d.ts b/src/types/debugTypes.d.ts new file mode 100644 index 0000000..c18f420 --- /dev/null +++ b/src/types/debugTypes.d.ts @@ -0,0 +1,9 @@ +// expands object types one level deep +type Expand = T extends infer O ? { [K in keyof O]: O[K] } : never; + +// expands object types recursively +type ExpandRecursively = T extends object + ? T extends infer O + ? { [K in keyof O]: ExpandRecursively } + : never + : T; diff --git a/src/types/next-auth.d.ts b/src/types/next-auth.d.ts new file mode 100644 index 0000000..629e307 --- /dev/null +++ b/src/types/next-auth.d.ts @@ -0,0 +1,21 @@ +import { type Permission } from "@/types/types"; +import "next-auth"; + +declare module "next-auth" { + /** + * Returned by `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context + */ + type User = { + id: string; + name: string; + email: string; + password?: string; + image: string; + accessToken: string; + permissions: Permission[]; + }; + + type Session = { + user: User; + }; +} diff --git a/src/types/types.ts b/src/types/types.ts new file mode 100644 index 0000000..fa87021 --- /dev/null +++ b/src/types/types.ts @@ -0,0 +1,34 @@ +import { trpc } from "@/app/_trpc/client"; +import { User, MailingList, Prisma } from "@prisma/client"; + +export type Response = { + success: boolean; + message: string; + status: number; + timestamp: number; + id: number; +}; + +export type UserWithMailingList = Prisma.UserGetPayload<{ + include: { mailingList: true }; +}>; + +export enum Status { + IDLE, + LOADING, + SUCCESS, + ERROR, +} + +export enum Permission { + DEFAULT = "default", + READ = "read", + WRITE = "write", + DELETE = "delete", + ADMIN = "admin", +} + +export type UserPermission = keyof Omit< + Prisma.UserPermissionGetPayload<{}>, + "id" | "userId" | "createdAt" | "updatedAt" +>; diff --git a/tailwind.config.ts b/tailwind.config.ts new file mode 100644 index 0000000..610b70d --- /dev/null +++ b/tailwind.config.ts @@ -0,0 +1,32 @@ +import type { Config } from "tailwindcss"; + +const config: Config = { + content: [ + "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", + "./src/components/**/*.{js,ts,jsx,tsx,mdx}", + "./src/app/**/*.{js,ts,jsx,tsx,mdx}", + ], + theme: { + extend: { + colors: { + background: "#101011", // previous: #111 + primary: "#ffffff", // previous: #eee + "eclipse-purple-base": "#622b81", + "eclipse-purple-dark": "#390d3e", + "eclipse-purple-black": "#141028", + "eclipse-red": "#b01e53", + "eclipse-orange": "#f26557", + "eclipse-pink": "#e54291", + "eclipse-green": "#a5d6af", + "eclipse-cyan": "#58c3ba", + "eclipse-blue-dark": "#0d3d60", + }, + fontFamily: { + righteous: ["Righteous", "sans-serif"], + montserrat: ["Montserrat", "sans-serif"], + }, + }, + }, + plugins: [], +}; +export default config; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..c5eef6e --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,42 @@ +{ + "compilerOptions": { + /* Base Options: */ + "esModuleInterop": true, + "skipLibCheck": true, + "target": "es2022", + "allowJs": true, + "resolveJsonModule": true, + "moduleDetection": "force", + "isolatedModules": true, + + /* Strictness */ + "strict": true, + "noUncheckedIndexedAccess": true, + "checkJs": true, + + /* Bundled projects */ + "lib": ["dom", "dom.iterable", "ES2022"], + "noEmit": true, + "module": "ESNext", + "moduleResolution": "Bundler", + "jsx": "preserve", + "plugins": [{ "name": "next" }], + "incremental": true, + + /* Path Aliases */ + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + }, + "include": [ + ".eslintrc.cjs", + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + "**/*.cjs", + "**/*.js", + ".next/types/**/*.ts" + ], + "exclude": ["node_modules"] +}