diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 77e25f701..e9bb9faaf 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -17,7 +17,7 @@ jobs: strategy: matrix: - node-version: [16.x] + node-version: [18.x] steps: - uses: actions/checkout@v3 diff --git a/packages/server/package.json b/packages/server/package.json index e6cd85434..54fa3848e 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -51,7 +51,7 @@ "fastify-plugin": "^4.5.0", "isomorphic-fetch": "^3.0.0", "jest": "^29.5.0", - "next": "^12.3.1", + "next": "^13.4.5", "rimraf": "^3.0.2", "supertest": "^6.3.3", "ts-jest": "^29.0.5", diff --git a/packages/server/src/next/app-route-handler.ts b/packages/server/src/next/app-route-handler.ts new file mode 100644 index 000000000..e642ac476 --- /dev/null +++ b/packages/server/src/next/app-route-handler.ts @@ -0,0 +1,85 @@ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ + +import { DbClientContract } from '@zenstackhq/runtime'; +import { ModelZodSchema, getModelZodSchemas } from '@zenstackhq/runtime/zod'; +import { NextRequest, NextResponse } from 'next/server'; +import { AppRouteRequestHandlerOptions } from '.'; +import RPCAPIHandler from '../api/rpc'; +import { buildUrlQuery, marshalToObject, unmarshalFromObject } from '../utils'; + +type Context = { params: { path: string[] } }; + +/** + * Creates a Next.js 13 "app dir" API route request handler which encapsulates Prisma CRUD operations. + * + * @param options Options for initialization + * @returns An API route request handler + */ +export default function factory( + options: AppRouteRequestHandlerOptions +): (req: NextRequest, context: Context) => Promise { + let zodSchemas: ModelZodSchema | undefined; + if (typeof options.zodSchemas === 'object') { + zodSchemas = options.zodSchemas; + } else if (options.zodSchemas === true) { + zodSchemas = getModelZodSchemas(); + } + + const requestHandler = options.handler || RPCAPIHandler(); + const useSuperJson = options.useSuperJson === true; + + return async (req: NextRequest, context: Context) => { + const prisma = (await options.getPrisma(req)) as DbClientContract; + if (!prisma) { + return NextResponse.json( + marshalToObject({ message: 'unable to get prisma from request context' }, useSuperJson), + { status: 500 } + ); + } + + const url = new URL(req.url); + let query: Record = Object.fromEntries(url.searchParams); + try { + query = buildUrlQuery(query, useSuperJson); + } catch { + return NextResponse.json(marshalToObject({ message: 'invalid query parameters' }, useSuperJson), { + status: 400, + }); + } + + if (!context.params.path) { + return NextResponse.json(marshalToObject({ message: 'missing path parameter' }, useSuperJson), { + status: 400, + }); + } + const path = context.params.path.join('/'); + + let requestBody: unknown; + if (req.body) { + try { + requestBody = await req.json(); + } catch { + // noop + } + } + + try { + const r = await requestHandler({ + method: req.method!, + path, + query, + requestBody: unmarshalFromObject(requestBody, useSuperJson), + prisma, + modelMeta: options.modelMeta, + zodSchemas, + logger: options.logger, + }); + return NextResponse.json(marshalToObject(r.body, useSuperJson), { status: r.status }); + } catch (err) { + return NextResponse.json( + marshalToObject({ message: `An unhandled error occurred: ${err}` }, useSuperJson), + { status: 500 } + ); + } + }; +} diff --git a/packages/server/src/next/index.ts b/packages/server/src/next/index.ts index c4a206552..33efdf18f 100644 --- a/packages/server/src/next/index.ts +++ b/packages/server/src/next/index.ts @@ -1,2 +1,52 @@ -export { default as NextRequestHandler } from './request-handler'; -export * from './request-handler'; +import { NextApiRequest, NextApiResponse } from 'next'; +import type { NextRequest } from 'next/server'; +import type { AdapterBaseOptions } from '../types'; +import { default as AppRouteHandler } from './app-route-handler'; +import { default as PagesRouteHandler } from './pages-route-handler'; + +/** + * Options for initializing a Next.js API endpoint request handler. + */ +export interface PagesRouteRequestHandlerOptions extends AdapterBaseOptions { + /** + * Callback method for getting a Prisma instance for the given request/response pair. + */ + getPrisma: (req: NextApiRequest, res: NextApiResponse) => Promise | unknown; + + /** + * Use Next.js 13 app dir or not + */ + useAppDir?: false | undefined; +} + +/** + * Options for initializing a Next.js 13 app dir API route handler. + */ +export interface AppRouteRequestHandlerOptions extends AdapterBaseOptions { + /** + * Callback method for getting a Prisma instance for the given request. + */ + getPrisma: (req: NextRequest) => Promise | unknown; + + /** + * Use Next.js 13 app dir or not + */ + useAppDir: true; +} + +/** + * Creates a Next.js API route handler. + * @see https://zenstack.dev/docs/reference/server-adapters/next + */ +export function NextRequestHandler(options: PagesRouteRequestHandlerOptions): ReturnType; +export function NextRequestHandler(options: AppRouteRequestHandlerOptions): ReturnType; +export function NextRequestHandler(options: PagesRouteRequestHandlerOptions | AppRouteRequestHandlerOptions) { + if (options.useAppDir === true) { + return AppRouteHandler(options); + } else { + return PagesRouteHandler(options); + } +} + +// for backward compatibility +export { PagesRouteRequestHandlerOptions as RequestHandlerOptions }; diff --git a/packages/server/src/next/request-handler.ts b/packages/server/src/next/pages-route-handler.ts similarity index 80% rename from packages/server/src/next/request-handler.ts rename to packages/server/src/next/pages-route-handler.ts index 9a3e0515e..d1c2043ab 100644 --- a/packages/server/src/next/request-handler.ts +++ b/packages/server/src/next/pages-route-handler.ts @@ -3,29 +3,18 @@ import { DbClientContract } from '@zenstackhq/runtime'; import { ModelZodSchema, getModelZodSchemas } from '@zenstackhq/runtime/zod'; import { NextApiRequest, NextApiResponse } from 'next'; +import { PagesRouteRequestHandlerOptions } from '.'; import RPCAPIHandler from '../api/rpc'; -import { AdapterBaseOptions } from '../types'; import { buildUrlQuery, marshalToObject, unmarshalFromObject } from '../utils'; /** - * Options for initializing a Next.js API endpoint request handler. - * @see requestHandler - */ -export interface RequestHandlerOptions extends AdapterBaseOptions { - /** - * Callback method for getting a Prisma instance for the given request/response pair. - */ - getPrisma: (req: NextApiRequest, res: NextApiResponse) => Promise | unknown; -} - -/** - * Creates a Next.js API endpoint request handler which encapsulates Prisma CRUD operations. + * Creates a Next.js API endpoint (traditional "pages" route) request handler which encapsulates Prisma CRUD operations. * * @param options Options for initialization * @returns An API endpoint request handler */ export default function factory( - options: RequestHandlerOptions + options: PagesRouteRequestHandlerOptions ): (req: NextApiRequest, res: NextApiResponse) => Promise { let zodSchemas: ModelZodSchema | undefined; if (typeof options.zodSchemas === 'object') { @@ -54,6 +43,10 @@ export default function factory( return; } + if (!req.query.path) { + res.status(400).json(marshalToObject({ message: 'missing path parameter' }, useSuperJson)); + return; + } const path = (req.query.path as string[]).join('/'); try { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5dcbcc319..ec0fc1eb0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,4 +1,8 @@ -lockfileVersion: '6.0' +lockfileVersion: '6.1' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false importers: @@ -60,7 +64,7 @@ importers: version: 2.4.1 jest: specifier: ^29.5.0 - version: 29.5.0 + version: 29.5.0(@types/node@14.18.29)(ts-node@10.9.1) react: specifier: ^17.0.2 || ^18 version: 18.2.0 @@ -149,7 +153,7 @@ importers: version: 8.35.0 jest: specifier: ^29.5.0 - version: 29.5.0 + version: 29.5.0(@types/node@14.18.29)(ts-node@10.9.1) pluralize: specifier: ^8.0.0 version: 8.0.0 @@ -223,7 +227,7 @@ importers: version: 2.4.1 jest: specifier: ^29.5.0 - version: 29.5.0 + version: 29.5.0(@types/node@14.18.29)(ts-node@10.9.1) react: specifier: ^17.0.2 || ^18 version: 18.2.0 @@ -297,7 +301,7 @@ importers: version: 2.4.1 jest: specifier: ^29.5.0 - version: 29.5.0 + version: 29.5.0(@types/node@14.18.29)(ts-node@10.9.1) react: specifier: ^17.0.2 || ^18 version: 18.2.0 @@ -374,7 +378,7 @@ importers: version: 2.4.1 jest: specifier: ^29.5.0 - version: 29.5.0 + version: 29.5.0(@types/node@14.18.29)(ts-node@10.9.1) react: specifier: ^17.0.2 || ^18 version: 18.2.0 @@ -442,7 +446,7 @@ importers: version: 2.4.1 jest: specifier: ^29.5.0 - version: 29.5.0 + version: 29.5.0(@types/node@14.18.29)(ts-node@10.9.1) rimraf: specifier: ^3.0.2 version: 3.0.2 @@ -461,7 +465,7 @@ importers: version: 2.2.0 '@prisma/client': specifier: ^4.0.0 - version: 4.7.1 + version: 4.7.1(prisma@4.7.0) '@types/bcryptjs': specifier: ^2.4.2 version: 2.4.2 @@ -816,10 +820,10 @@ importers: version: 3.0.0 jest: specifier: ^29.5.0 - version: 29.5.0 + version: 29.5.0(@types/node@14.18.29)(ts-node@10.9.1) next: - specifier: ^12.3.1 - version: 12.3.1(@babel/core@7.20.5)(react-dom@18.2.0)(react@18.2.0) + specifier: ^13.4.5 + version: 13.4.5(@babel/core@7.20.5)(react-dom@18.2.0)(react@18.2.0) rimraf: specifier: ^3.0.2 version: 3.0.2 @@ -937,7 +941,7 @@ importers: version: 8.30.0 eslint-plugin-jest: specifier: ^27.1.7 - version: 27.1.7(eslint@8.30.0)(jest@29.5.0)(typescript@4.8.3) + version: 27.1.7(@typescript-eslint/eslint-plugin@5.42.0)(eslint@8.27.0)(jest@29.5.0)(typescript@4.8.4) fs-extra: specifier: ^11.1.0 version: 11.1.0 @@ -1880,48 +1884,6 @@ packages: slash: 3.0.0 dev: true - /@jest/core@29.5.0: - resolution: {integrity: sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/console': 29.5.0 - '@jest/reporters': 29.5.0 - '@jest/test-result': 29.5.0 - '@jest/transform': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.14.2 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - ci-info: 3.7.1 - exit: 0.1.2 - graceful-fs: 4.2.10 - jest-changed-files: 29.5.0 - jest-config: 29.5.0(@types/node@18.14.2) - jest-haste-map: 29.5.0 - jest-message-util: 29.5.0 - jest-regex-util: 29.4.3 - jest-resolve: 29.5.0 - jest-resolve-dependencies: 29.5.0 - jest-runner: 29.5.0 - jest-runtime: 29.5.0 - jest-snapshot: 29.5.0 - jest-util: 29.5.0 - jest-validate: 29.5.0 - jest-watcher: 29.5.0 - micromatch: 4.0.5 - pretty-format: 29.5.0 - slash: 3.0.0 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - supports-color - - ts-node - dev: true - /@jest/core@29.5.0(ts-node@10.9.1): resolution: {integrity: sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -2220,6 +2182,10 @@ packages: /@next/env@12.3.1: resolution: {integrity: sha512-9P9THmRFVKGKt9DYqeC2aKIxm8rlvkK38V1P1sRE7qyoPBIs8l9oo79QoSdPtOWfzkbDAVUqvbQGgTMsb8BtJg==} + /@next/env@13.4.5: + resolution: {integrity: sha512-SG/gKH6eij4vwQy87b/3mbpQ1X3x2vUdnpwq6/qL2IQWjtq58EY/UuNAp9CoEZoC9sI4L9AD1r+73Z9r4d3uug==} + dev: true + /@next/swc-android-arm-eabi@12.3.1: resolution: {integrity: sha512-i+BvKA8tB//srVPPQxIQN5lvfROcfv4OB23/L1nXznP+N/TyKL8lql3l7oo2LNhnH66zWhfoemg3Q4VJZSruzQ==} engines: {node: '>= 10'} @@ -2244,6 +2210,15 @@ packages: requiresBuild: true optional: true + /@next/swc-darwin-arm64@13.4.5: + resolution: {integrity: sha512-XvTzi2ASUN5bECFIAAcBiSoDb0xsq+KLj4F0bof4d4rdc+FgOqLvseGQaOXwVi1TIh5bHa7o4b6droSJMO5+2g==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@next/swc-darwin-x64@12.3.1: resolution: {integrity: sha512-9S6EVueCVCyGf2vuiLiGEHZCJcPAxglyckTZcEwLdJwozLqN0gtS0Eq0bQlGS3dH49Py/rQYpZ3KVWZ9BUf/WA==} engines: {node: '>= 10'} @@ -2252,6 +2227,15 @@ packages: requiresBuild: true optional: true + /@next/swc-darwin-x64@13.4.5: + resolution: {integrity: sha512-NQdqal/VKAqlJTuzhjZmNtdo8QSqwmfO7b2xJSAengTEVxQvsH76oGEzQeIv8Ci4NP6DysAFtFrJq++TmIxcUA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@next/swc-freebsd-x64@12.3.1: resolution: {integrity: sha512-qcuUQkaBZWqzM0F1N4AkAh88lLzzpfE6ImOcI1P6YeyJSsBmpBIV8o70zV+Wxpc26yV9vpzb+e5gCyxNjKJg5Q==} engines: {node: '>= 10'} @@ -2276,6 +2260,15 @@ packages: requiresBuild: true optional: true + /@next/swc-linux-arm64-gnu@13.4.5: + resolution: {integrity: sha512-nB8TjtpJCXtzIFjYOMbnQu68ajkA8QK58TreHjTGojSQjsF0StDqo5zFHglVVVHrd8d3N/+EjC18yFNSWnd/ZA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@next/swc-linux-arm64-musl@12.3.1: resolution: {integrity: sha512-2WEasRxJzgAmP43glFNhADpe8zB7kJofhEAVNbDJZANp+H4+wq+/cW1CdDi8DqjkShPEA6/ejJw+xnEyDID2jg==} engines: {node: '>= 10'} @@ -2284,6 +2277,15 @@ packages: requiresBuild: true optional: true + /@next/swc-linux-arm64-musl@13.4.5: + resolution: {integrity: sha512-W126XUW599OV3giSH9Co40VpT8VAOT47xONVHXZaYEpeca0qEevjj6WUr5IJu/8u+XGWm5xI1S0DYWjR6W+olw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@next/swc-linux-x64-gnu@12.3.1: resolution: {integrity: sha512-JWEaMyvNrXuM3dyy9Pp5cFPuSSvG82+yABqsWugjWlvfmnlnx9HOQZY23bFq3cNghy5V/t0iPb6cffzRWylgsA==} engines: {node: '>= 10'} @@ -2292,6 +2294,15 @@ packages: requiresBuild: true optional: true + /@next/swc-linux-x64-gnu@13.4.5: + resolution: {integrity: sha512-ZbPLO/oztQdtjGmWvGhRmtkZ6j9kQqg65kiO7F7Ijj7ojTtu3hh/vY+XRsHa/4Cse6HgyJ8XGZJMGoLb8ecQfQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@next/swc-linux-x64-musl@12.3.1: resolution: {integrity: sha512-xoEWQQ71waWc4BZcOjmatuvPUXKTv6MbIFzpm4LFeCHsg2iwai0ILmNXf81rJR+L1Wb9ifEke2sQpZSPNz1Iyg==} engines: {node: '>= 10'} @@ -2300,6 +2311,15 @@ packages: requiresBuild: true optional: true + /@next/swc-linux-x64-musl@13.4.5: + resolution: {integrity: sha512-f+/h8KMNixVUoRB+2vza8I+jsthJ4KcvopGUsDIUHe7Q4t+m8nKwGFBeyNu9qNIenYK5g5QYEsSwYFEqZylrTQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@next/swc-win32-arm64-msvc@12.3.1: resolution: {integrity: sha512-hswVFYQYIeGHE2JYaBVtvqmBQ1CppplQbZJS/JgrVI3x2CurNhEkmds/yqvDONfwfbttTtH4+q9Dzf/WVl3Opw==} engines: {node: '>= 10'} @@ -2308,6 +2328,15 @@ packages: requiresBuild: true optional: true + /@next/swc-win32-arm64-msvc@13.4.5: + resolution: {integrity: sha512-dvtPQZ5+J+zUE1uq7gP853Oj63e+n0T1ydZ/yRdVh7d8zW9ZFuC9fFrg3MqP1cv1NPPur8rrTqDKN2mRBkSSBw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@next/swc-win32-ia32-msvc@12.3.1: resolution: {integrity: sha512-Kny5JBehkTbKPmqulr5i+iKntO5YMP+bVM8Hf8UAmjSMVo3wehyLVc9IZkNmcbxi+vwETnQvJaT5ynYBkJ9dWA==} engines: {node: '>= 10'} @@ -2316,6 +2345,15 @@ packages: requiresBuild: true optional: true + /@next/swc-win32-ia32-msvc@13.4.5: + resolution: {integrity: sha512-gK9zwGe25x31S4AjPy3Bf2niQvHIAbmwgkzmqWG3OmD4K2Z/Dh2ju4vuyzPzIt0pwQe4B520meP9NizTBmVWSg==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@next/swc-win32-x64-msvc@12.3.1: resolution: {integrity: sha512-W1ijvzzg+kPEX6LAc+50EYYSEo0FVu7dmTE+t+DM4iOLqgGHoW9uYSz9wCVdkXOEEMP9xhXfGpcSxsfDucyPkA==} engines: {node: '>= 10'} @@ -2324,6 +2362,15 @@ packages: requiresBuild: true optional: true + /@next/swc-win32-x64-msvc@13.4.5: + resolution: {integrity: sha512-iyNQVc7eGehrik9RJt9xGcnO6b/pi8C7GCfg8RGenx1IlalEKbYRgBJloF7DQzwlrV47E9bQl8swT+JawaNcKA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@noble/hashes@1.3.0: resolution: {integrity: sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==} dev: false @@ -2415,19 +2462,6 @@ packages: resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==} dev: true - /@prisma/client@4.7.1: - resolution: {integrity: sha512-/GbnOwIPtjiveZNUzGXOdp7RxTEkHL4DZP3vBaFNadfr6Sf0RshU5EULFzVaSi9i9PIK9PYd+1Rn7z2B2npb9w==} - engines: {node: '>=14.17'} - requiresBuild: true - peerDependencies: - prisma: '*' - peerDependenciesMeta: - prisma: - optional: true - dependencies: - '@prisma/engines-version': 4.7.1-1.272861e07ab64f234d3ffc4094e32bd61775599c - dev: false - /@prisma/client@4.7.1(prisma@4.7.0): resolution: {integrity: sha512-/GbnOwIPtjiveZNUzGXOdp7RxTEkHL4DZP3vBaFNadfr6Sf0RshU5EULFzVaSi9i9PIK9PYd+1Rn7z2B2npb9w==} engines: {node: '>=14.17'} @@ -2663,7 +2697,7 @@ packages: svelte: 3.59.1 tiny-glob: 0.2.9 undici: 5.22.1 - vite: 4.2.1 + vite: 4.2.1(@types/node@18.14.2) transitivePeerDependencies: - supports-color dev: true @@ -2681,7 +2715,7 @@ packages: magic-string: 0.30.0 svelte: 3.59.1 svelte-hmr: 0.15.1(svelte@3.59.1) - vite: 4.2.1 + vite: 4.2.1(@types/node@18.14.2) vitefu: 0.2.4(vite@4.2.1) transitivePeerDependencies: - supports-color @@ -2692,6 +2726,12 @@ packages: dependencies: tslib: 2.4.1 + /@swc/helpers@0.5.1: + resolution: {integrity: sha512-sJ902EfIzn1Fa+qYmjdQqh8tPsoxyBz+8yBKC2HKUxyezKJFwPGOn7pv4WY6QuQW//ySQi5lJjA/ZT9sNWWNTg==} + dependencies: + tslib: 2.4.1 + dev: true + /@tanstack/query-core@4.27.0: resolution: {integrity: sha512-sm+QncWaPmM73IPwFlmWSKPqjdTXZeFf/7aEmWh00z7yl2FjqophPt0dE1EHW9P1giMC5rMviv7OUbSDmWzXXA==} dev: true @@ -3218,27 +3258,6 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/typescript-estree@5.42.0(typescript@4.8.3): - resolution: {integrity: sha512-2O3vSq794x3kZGtV7i4SCWZWCwjEtkWfVqX4m5fbUBomOsEOyd6OAD1qU2lbvV5S8tgy/luJnOYluNyYVeOTTg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/types': 5.42.0 - '@typescript-eslint/visitor-keys': 5.42.0 - debug: 4.3.4 - globby: 11.1.0 - is-glob: 4.0.3 - semver: 7.3.8 - tsutils: 3.21.0(typescript@4.8.3) - typescript: 4.8.3 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/typescript-estree@5.42.0(typescript@4.8.4): resolution: {integrity: sha512-2O3vSq794x3kZGtV7i4SCWZWCwjEtkWfVqX4m5fbUBomOsEOyd6OAD1qU2lbvV5S8tgy/luJnOYluNyYVeOTTg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -3301,26 +3320,6 @@ packages: - typescript dev: true - /@typescript-eslint/utils@5.42.0(eslint@8.30.0)(typescript@4.8.3): - resolution: {integrity: sha512-JZ++3+h1vbeG1NUECXQZE3hg0kias9kOtcQr3+JVQ3whnjvKuMyktJAAIj6743OeNPnGBmjj7KEmiDL7qsdnCQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - '@types/json-schema': 7.0.11 - '@types/semver': 7.3.13 - '@typescript-eslint/scope-manager': 5.42.0 - '@typescript-eslint/types': 5.42.0 - '@typescript-eslint/typescript-estree': 5.42.0(typescript@4.8.3) - eslint: 8.30.0 - eslint-scope: 5.1.1 - eslint-utils: 3.0.0(eslint@8.30.0) - semver: 7.3.8 - transitivePeerDependencies: - - supports-color - - typescript - dev: true - /@typescript-eslint/utils@5.54.0(eslint@8.35.0)(typescript@4.9.5): resolution: {integrity: sha512-cuwm8D/Z/7AuyAeJ+T0r4WZmlnlxQ8wt7C7fLpFlKMR+dY6QO79Cq1WpJhvZbMA4ZeZGHiRWnht7ZJ8qkdAunw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -4163,6 +4162,10 @@ packages: string-width: 5.1.2 dev: true + /client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + dev: true + /cliui@6.0.0: resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} dependencies: @@ -5100,27 +5103,6 @@ packages: - typescript dev: true - /eslint-plugin-jest@27.1.7(eslint@8.30.0)(jest@29.5.0)(typescript@4.8.3): - resolution: {integrity: sha512-0QVzf+og4YI1Qr3UoprkqqhezAZjFffdi62b0IurkCXMqPtRW84/UT4CKsYT80h/D82LA9avjO/80Ou1LdgbaQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@typescript-eslint/eslint-plugin': ^5.0.0 - eslint: ^7.0.0 || ^8.0.0 - jest: '*' - peerDependenciesMeta: - '@typescript-eslint/eslint-plugin': - optional: true - jest: - optional: true - dependencies: - '@typescript-eslint/utils': 5.42.0(eslint@8.30.0)(typescript@4.8.3) - eslint: 8.30.0 - jest: 29.5.0(@types/node@14.18.29)(ts-node@10.9.1) - transitivePeerDependencies: - - supports-color - - typescript - dev: true - /eslint-scope@5.1.1: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} engines: {node: '>=8.0.0'} @@ -5896,6 +5878,10 @@ packages: is-glob: 4.0.3 dev: true + /glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + dev: true + /glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} dependencies: @@ -6495,34 +6481,6 @@ packages: - supports-color dev: true - /jest-cli@29.5.0: - resolution: {integrity: sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/core': 29.5.0 - '@jest/test-result': 29.5.0 - '@jest/types': 29.5.0 - chalk: 4.1.2 - exit: 0.1.2 - graceful-fs: 4.2.10 - import-local: 3.1.0 - jest-config: 29.5.0 - jest-util: 29.5.0 - jest-validate: 29.5.0 - prompts: 2.4.2 - yargs: 17.6.2 - transitivePeerDependencies: - - '@types/node' - - supports-color - - ts-node - dev: true - /jest-cli@29.5.0(@types/node@14.18.29)(ts-node@10.9.1): resolution: {integrity: sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -6579,44 +6537,6 @@ packages: - ts-node dev: true - /jest-config@29.5.0: - resolution: {integrity: sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@types/node': '*' - ts-node: '>=9.0.0' - peerDependenciesMeta: - '@types/node': - optional: true - ts-node: - optional: true - dependencies: - '@babel/core': 7.20.5 - '@jest/test-sequencer': 29.5.0 - '@jest/types': 29.5.0 - babel-jest: 29.5.0(@babel/core@7.20.5) - chalk: 4.1.2 - ci-info: 3.7.1 - deepmerge: 4.3.1 - glob: 7.2.3 - graceful-fs: 4.2.10 - jest-circus: 29.5.0 - jest-environment-node: 29.5.0 - jest-get-type: 29.4.3 - jest-regex-util: 29.4.3 - jest-resolve: 29.5.0 - jest-runner: 29.5.0 - jest-util: 29.5.0 - jest-validate: 29.5.0 - micromatch: 4.0.5 - parse-json: 5.2.0 - pretty-format: 29.5.0 - slash: 3.0.0 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - dev: true - /jest-config@29.5.0(@types/node@14.18.29)(ts-node@10.9.1): resolution: {integrity: sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -6697,45 +6617,6 @@ packages: - supports-color dev: true - /jest-config@29.5.0(@types/node@18.14.2): - resolution: {integrity: sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@types/node': '*' - ts-node: '>=9.0.0' - peerDependenciesMeta: - '@types/node': - optional: true - ts-node: - optional: true - dependencies: - '@babel/core': 7.20.5 - '@jest/test-sequencer': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.14.2 - babel-jest: 29.5.0(@babel/core@7.20.5) - chalk: 4.1.2 - ci-info: 3.7.1 - deepmerge: 4.3.1 - glob: 7.2.3 - graceful-fs: 4.2.10 - jest-circus: 29.5.0 - jest-environment-node: 29.5.0 - jest-get-type: 29.4.3 - jest-regex-util: 29.4.3 - jest-resolve: 29.5.0 - jest-runner: 29.5.0 - jest-util: 29.5.0 - jest-validate: 29.5.0 - micromatch: 4.0.5 - parse-json: 5.2.0 - pretty-format: 29.5.0 - slash: 3.0.0 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - dev: true - /jest-config@29.5.0(@types/node@18.14.2)(ts-node@10.9.1): resolution: {integrity: sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -7107,26 +6988,6 @@ packages: supports-color: 8.1.1 dev: true - /jest@29.5.0: - resolution: {integrity: sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/core': 29.5.0 - '@jest/types': 29.5.0 - import-local: 3.1.0 - jest-cli: 29.5.0 - transitivePeerDependencies: - - '@types/node' - - supports-color - - ts-node - dev: true - /jest@29.5.0(@types/node@14.18.29)(ts-node@10.9.1): resolution: {integrity: sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -7738,6 +7599,49 @@ packages: - '@babel/core' - babel-plugin-macros + /next@13.4.5(@babel/core@7.20.5)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-pfNsRLVM9e5Y1/z02VakJRfD6hMQkr24FaN2xc9GbcZDBxoOgiNAViSg5cXwlWCoMhtm4U315D7XYhgOr96Q3Q==} + engines: {node: '>=16.8.0'} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + fibers: '>= 3.1.0' + react: ^18.2.0 + react-dom: ^18.2.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + fibers: + optional: true + sass: + optional: true + dependencies: + '@next/env': 13.4.5 + '@swc/helpers': 0.5.1 + busboy: 1.6.0 + caniuse-lite: 1.0.30001439 + postcss: 8.4.14 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + styled-jsx: 5.1.1(@babel/core@7.20.5)(react@18.2.0) + watchpack: 2.4.0 + zod: 3.21.4 + optionalDependencies: + '@next/swc-darwin-arm64': 13.4.5 + '@next/swc-darwin-x64': 13.4.5 + '@next/swc-linux-arm64-gnu': 13.4.5 + '@next/swc-linux-arm64-musl': 13.4.5 + '@next/swc-linux-x64-gnu': 13.4.5 + '@next/swc-linux-x64-musl': 13.4.5 + '@next/swc-win32-arm64-msvc': 13.4.5 + '@next/swc-win32-ia32-msvc': 13.4.5 + '@next/swc-win32-x64-msvc': 13.4.5 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + dev: true + /no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} dependencies: @@ -9074,6 +8978,24 @@ packages: '@babel/core': 7.20.5 react: 18.2.0 + /styled-jsx@5.1.1(@babel/core@7.20.5)(react@18.2.0): + resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + dependencies: + '@babel/core': 7.20.5 + client-only: 0.0.1 + react: 18.2.0 + dev: true + /superagent@8.0.9: resolution: {integrity: sha512-4C7Bh5pyHTvU33KpZgwrNKh/VQnvgtCSqPRfJAUdmrtSYePVzVg4E4OzsrbkhJj9O7SO6Bnv75K/F8XVZT8YHA==} engines: {node: '>=6.4.0 <13 || >=14'} @@ -9442,7 +9364,7 @@ packages: '@babel/core': 7.20.5 bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 - jest: 29.5.0 + jest: 29.5.0(@types/node@14.18.29)(ts-node@10.9.1) jest-util: 29.4.3 json5: 2.2.3 lodash.memoize: 4.1.2 @@ -9476,7 +9398,7 @@ packages: '@babel/core': 7.20.5 bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 - jest: 29.5.0 + jest: 29.5.0(@types/node@14.18.29)(ts-node@10.9.1) jest-util: 29.5.0 json5: 2.2.3 lodash.memoize: 4.1.2 @@ -9577,16 +9499,6 @@ packages: /tslib@2.4.1: resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} - /tsutils@3.21.0(typescript@4.8.3): - resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} - engines: {node: '>= 6'} - peerDependencies: - typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - dependencies: - tslib: 1.14.1 - typescript: 4.8.3 - dev: true - /tsutils@3.21.0(typescript@4.8.4): resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} @@ -9905,39 +9817,6 @@ packages: - terser dev: true - /vite@4.2.1: - resolution: {integrity: sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==} - engines: {node: ^14.18.0 || >=16.0.0} - hasBin: true - peerDependencies: - '@types/node': '>= 14' - less: '*' - sass: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - dependencies: - esbuild: 0.17.14 - postcss: 8.4.21 - resolve: 1.22.1 - rollup: 3.20.2 - optionalDependencies: - fsevents: 2.3.2 - dev: true - /vite@4.2.1(@types/node@18.14.2): resolution: {integrity: sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==} engines: {node: ^14.18.0 || >=16.0.0} @@ -9980,7 +9859,7 @@ packages: vite: optional: true dependencies: - vite: 4.2.1 + vite: 4.2.1(@types/node@18.14.2) dev: true /vitest@0.29.7: @@ -10092,6 +9971,14 @@ packages: makeerror: 1.0.12 dev: true + /watchpack@2.4.0: + resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==} + engines: {node: '>=10.13.0'} + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.10 + dev: true + /wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} dependencies: @@ -10373,3 +10260,7 @@ packages: /zod@3.21.1: resolution: {integrity: sha512-+dTu2m6gmCbO9Ahm4ZBDapx2O6ZY9QSPXst2WXjcznPMwf2YNpn3RevLx4KkZp1OPW/ouFcoBtBzFz/LeY69oA==} dev: false + + /zod@3.21.4: + resolution: {integrity: sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==} + dev: true