diff --git a/.gitignore b/.gitignore index 3971946..641dcc9 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ tsconfig.tsbuildinfo next-env.d.ts build .docusaurus +.idea/ diff --git a/package.json b/package.json index 566ef76..a909f56 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "eslint-plugin-import": "2.28.1", "eslint-plugin-n": "16.0.2", "eslint-plugin-promise": "6.1.1", - "next": "15.4.8", + "next": "16.2.4", "prettier": "3.0.2", "typescript": "5.2.2", "zod": "^4.1.13" diff --git a/packages/next-rest-framework/package.json b/packages/next-rest-framework/package.json index a5d0012..a6dc362 100644 --- a/packages/next-rest-framework/package.json +++ b/packages/next-rest-framework/package.json @@ -1,6 +1,6 @@ { "name": "next-rest-framework", - "version": "6.1.1", + "version": "6.1.3", "description": "Next REST Framework - Type-safe, self-documenting APIs for Next.js", "keywords": [ "nextjs", @@ -39,9 +39,9 @@ "chalk": "4.1.2", "commander": "10.0.1", "formidable": "^3.5.1", - "lodash": "4.17.21", + "lodash": "4.18.1", "prettier": "3.0.2", - "qs": "6.14.1" + "qs": "6.15.1" }, "devDependencies": { "@types/formidable": "^3.4.5", diff --git a/packages/next-rest-framework/src/app-router/docs-route.ts b/packages/next-rest-framework/src/app-router/docs-route.ts index ccbe066..7cb5404 100644 --- a/packages/next-rest-framework/src/app-router/docs-route.ts +++ b/packages/next-rest-framework/src/app-router/docs-route.ts @@ -25,7 +25,10 @@ export const docsRoute = (_config?: NextRestFrameworkConfig) => { } }); } catch (error) { - logNextRestFrameworkError(error); + logNextRestFrameworkError(error, { + method: _req.method, + url: _req.url + }); return NextResponse.json( { message: DEFAULT_ERRORS.unexpectedError }, diff --git a/packages/next-rest-framework/src/app-router/route-operation.ts b/packages/next-rest-framework/src/app-router/route-operation.ts index 83fee48..99acf5d 100644 --- a/packages/next-rest-framework/src/app-router/route-operation.ts +++ b/packages/next-rest-framework/src/app-router/route-operation.ts @@ -19,10 +19,13 @@ import { import { NextResponse, type NextRequest } from 'next/server'; import { type ZodType, type z } from 'zod'; import { type ValidMethod } from '../constants'; -import { type I18NConfig } from 'next/dist/server/config-shared'; -import { type NextURL } from 'next/dist/server/web/next-url'; import { type OpenAPIV3_1 } from 'openapi-types'; -import { type ResponseCookies } from 'next/dist/compiled/@edge-runtime/cookies'; +import { type NextConfig } from 'next'; + +// Use public API types instead of internal Next.js paths to avoid cross-version type incompatibilities. +type NextURL = NextRequest['nextUrl']; +type ResponseCookies = NextResponse['cookies']; +type I18NConfig = NonNullable; interface TypedSearchParams extends URLSearchParams { get: (key: K) => string | null; diff --git a/packages/next-rest-framework/src/app-router/route.ts b/packages/next-rest-framework/src/app-router/route.ts index 20b7669..09b3b7b 100644 --- a/packages/next-rest-framework/src/app-router/route.ts +++ b/packages/next-rest-framework/src/app-router/route.ts @@ -2,7 +2,10 @@ import { NextRequest, NextResponse } from 'next/server'; import qs from 'qs'; import { DEFAULT_ERRORS } from '../constants'; import { validateSchema } from '../shared'; -import { logNextRestFrameworkError } from '../shared/logging'; +import { + logNextRestFrameworkError, + logNextRestFrameworkResponse +} from '../shared/logging'; import { getPathsFromRoute } from '../shared/paths'; import { type FormDataContentType, @@ -30,10 +33,19 @@ export const route = >( _req: NextRequest, context: { params: Promise } ) => { + let operationId: string | undefined; + try { - const operation = Object.entries(operations).find( + const operationEntry = Object.entries(operations).find( ([_operationId, operation]) => operation.method === _req.method - )?.[1]; + ); + operationId = operationEntry?.[0]; + const operation = operationEntry?.[1]; + const logContext = { + method: _req.method, + operationId, + url: _req.url + }; if (!operation) { return NextResponse.json( @@ -75,6 +87,7 @@ export const route = >( typeof res === 'object'; if (res instanceof Response) { + await logNextRestFrameworkResponse(res, logContext); return res; } else if (isOptionsResponse(res)) { middlewareOptions = res; @@ -88,6 +101,7 @@ export const route = >( ); if (res2 instanceof Response) { + await logNextRestFrameworkResponse(res2, logContext); return res2; } else if (isOptionsResponse(res2)) { middlewareOptions = res2; @@ -101,6 +115,7 @@ export const route = >( ); if (res3 instanceof Response) { + await logNextRestFrameworkResponse(res3, logContext); return res3; } else if (isOptionsResponse(res3)) { middlewareOptions = res3; @@ -295,9 +310,14 @@ export const route = >( ); } + await logNextRestFrameworkResponse(res, logContext); return res; } catch (error) { - logNextRestFrameworkError(error); + logNextRestFrameworkError(error, { + method: _req.method, + operationId, + url: _req.url + }); return NextResponse.json( { message: DEFAULT_ERRORS.unexpectedError }, { status: 500 } diff --git a/packages/next-rest-framework/src/app-router/rpc-route.ts b/packages/next-rest-framework/src/app-router/rpc-route.ts index 5229bd5..b619f4a 100644 --- a/packages/next-rest-framework/src/app-router/rpc-route.ts +++ b/packages/next-rest-framework/src/app-router/rpc-route.ts @@ -31,6 +31,8 @@ export const rpcRoute = < req: NextRequest, { params }: { params: Promise } ) => { + let operationId: string | undefined; + try { if (req.method !== ValidMethod.POST) { return NextResponse.json( @@ -44,7 +46,8 @@ export const rpcRoute = < ); } - const operation = operations[(await params).operationId ?? '']; + operationId = (await params).operationId ?? ''; + const operation = operations[operationId]; if (!operation) { return NextResponse.json( @@ -221,7 +224,11 @@ export const rpcRoute = < } }); } catch (error) { - logNextRestFrameworkError(error); + logNextRestFrameworkError(error, { + method: req.method, + operationId, + url: req.url + }); return NextResponse.json( { message: DEFAULT_ERRORS.unexpectedError }, diff --git a/packages/next-rest-framework/src/pages-router/api-route.ts b/packages/next-rest-framework/src/pages-router/api-route.ts index 4825ac7..82418a5 100644 --- a/packages/next-rest-framework/src/pages-router/api-route.ts +++ b/packages/next-rest-framework/src/pages-router/api-route.ts @@ -40,10 +40,14 @@ export const apiRoute = >( ); } + let operationId: string | undefined; + try { - const operation = Object.entries(operations).find( + const operationEntry = Object.entries(operations).find( ([_operationId, operation]) => operation.method === req.method - )?.[1]; + ); + operationId = operationEntry?.[0]; + const operation = operationEntry?.[1]; if (!operation) { res.setHeader( @@ -247,7 +251,11 @@ export const apiRoute = >( res.status(501).json({ message: DEFAULT_ERRORS.notImplemented }); } } catch (error) { - logNextRestFrameworkError(error); + logNextRestFrameworkError(error, { + method: req.method, + operationId, + url: req.url + }); res.status(500).json({ message: DEFAULT_ERRORS.unexpectedError }); } }; diff --git a/packages/next-rest-framework/src/pages-router/docs-api-route.ts b/packages/next-rest-framework/src/pages-router/docs-api-route.ts index 6678a6c..4e3c413 100644 --- a/packages/next-rest-framework/src/pages-router/docs-api-route.ts +++ b/packages/next-rest-framework/src/pages-router/docs-api-route.ts @@ -35,7 +35,10 @@ export const docsApiRoute = (_config?: NextRestFrameworkConfig) => { res.setHeader('Content-Type', 'text/html'); res.status(200).send(html); } catch (error) { - logNextRestFrameworkError(error); + logNextRestFrameworkError(error, { + method: req.method, + url: req.url + }); res.status(500).json({ message: DEFAULT_ERRORS.unexpectedError }); } }; diff --git a/packages/next-rest-framework/src/pages-router/rpc-api-route.ts b/packages/next-rest-framework/src/pages-router/rpc-api-route.ts index 8cc9326..38b04a1 100644 --- a/packages/next-rest-framework/src/pages-router/rpc-api-route.ts +++ b/packages/next-rest-framework/src/pages-router/rpc-api-route.ts @@ -42,6 +42,8 @@ export const rpcApiRoute = < ); } + let operationId: string | undefined; + try { if (req.method !== ValidMethod.POST) { res.setHeader('Allow', 'POST'); @@ -49,7 +51,8 @@ export const rpcApiRoute = < return; } - const operation = operations[req.query.operationId?.toString() ?? '']; + operationId = req.query.operationId?.toString() ?? ''; + const operation = operations[operationId]; if (!operation) { res.status(400).json({ message: DEFAULT_ERRORS.operationNotAllowed }); @@ -202,7 +205,11 @@ export const rpcApiRoute = < const json = await parseRpcOperationResponseJson(_res); res.status(200).json(json); } catch (error) { - logNextRestFrameworkError(error); + logNextRestFrameworkError(error, { + method: req.method, + operationId, + url: req.url + }); res.status(400).json({ message: DEFAULT_ERRORS.unexpectedError }); } }; diff --git a/packages/next-rest-framework/src/shared/logging.ts b/packages/next-rest-framework/src/shared/logging.ts index a9ebfa2..9fdf7ff 100644 --- a/packages/next-rest-framework/src/shared/logging.ts +++ b/packages/next-rest-framework/src/shared/logging.ts @@ -1,5 +1,65 @@ import chalk from 'chalk'; +export type NextRestFrameworkErrorLogContext = { + method?: string; + operationId?: string; + route?: string; + url?: string; +}; + +const formatValue = (value: unknown) => { + if (typeof value === 'string') { + return value; + } + + try { + return JSON.stringify(value, null, 2); + } catch { + return String(value); + } +}; + +const formatError = (error: unknown, depth = 0): string => { + const lines: string[] = []; + + if (error instanceof Error) { + lines.push(error.stack ?? `${error.name}: ${error.message}`); + + const props = Object.fromEntries( + Object.entries(error).filter(([key]) => key !== 'cause') + ); + + if (Object.keys(props).length > 0) { + lines.push(`properties: ${formatValue(props)}`); + } + + const cause = (error as Error & { cause?: unknown }).cause; + if (cause !== undefined && depth < 3) { + lines.push(`cause:\n${formatError(cause, depth + 1)}`); + } + } else { + lines.push(formatValue(error)); + } + + return lines.join('\n'); +}; + +const formatContext = (context?: NextRestFrameworkErrorLogContext) => { + if (!context) { + return ''; + } + + const entries = Object.entries(context).filter( + ([, value]) => value !== undefined && value !== '' + ); + + if (entries.length === 0) { + return ''; + } + + return `${entries.map(([key, value]) => `${key}: ${value}`).join('\n')}\n`; +}; + export const logPagesEdgeRuntimeErrorForRoute = (route: string) => { console.error( chalk.red(`--- @@ -18,10 +78,42 @@ Please use \`docsRoute\` instead: https://vercel.com/docs/functions/edge-functio ); }; -export const logNextRestFrameworkError = (error: unknown) => { +export const logNextRestFrameworkError = ( + error: unknown, + context?: NextRestFrameworkErrorLogContext +) => { console.error( chalk.red(`Next REST Framework encountered an error: -${error}`) +${formatContext(context)}${formatError(error)}`) + ); +}; + +export const logNextRestFrameworkResponse = async ( + response: Response, + context?: NextRestFrameworkErrorLogContext +) => { + if (response.status < 500) { + return; + } + + let body: unknown; + try { + const text = await response.clone().text(); + if (text) { + try { + body = JSON.parse(text); + } catch { + body = text; + } + } + } catch (error) { + body = `Failed to read response body: ${formatError(error)}`; + } + + console.error( + chalk.red(`Next REST Framework returned an error response: +${formatContext(context)}status: ${response.status} +body: ${formatValue(body)}`) ); }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cedd0e3..dc37c0f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -49,8 +49,8 @@ importers: specifier: 6.1.1 version: 6.1.1(eslint@8.47.0) next: - specifier: 15.4.8 - version: 15.4.8(@babel/core@7.22.11)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: 16.2.4 + version: 16.2.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) prettier: specifier: 3.0.2 version: 3.0.2 @@ -135,14 +135,14 @@ importers: specifier: ^3.5.1 version: 3.5.1 lodash: - specifier: 4.17.21 - version: 4.17.21 + specifier: 4.18.1 + version: 4.18.1 prettier: specifier: 3.0.2 version: 3.0.2 qs: - specifier: 6.14.1 - version: 6.14.1 + specifier: 6.15.1 + version: 6.15.1 devDependencies: '@types/formidable': specifier: ^3.4.5 @@ -1333,89 +1333,105 @@ packages: resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-arm@1.2.4': resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-ppc64@1.2.4': resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} cpu: [ppc64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-riscv64@1.2.4': resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} cpu: [riscv64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-s390x@1.2.4': resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-x64@1.2.4': resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linuxmusl-arm64@1.2.4': resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-libvips-linuxmusl-x64@1.2.4': resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-linux-arm64@0.34.5': resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-linux-arm@0.34.5': resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-linux-ppc64@0.34.5': resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ppc64] os: [linux] + libc: [glibc] '@img/sharp-linux-riscv64@0.34.5': resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [riscv64] os: [linux] + libc: [glibc] '@img/sharp-linux-s390x@0.34.5': resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-linux-x64@0.34.5': resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-linuxmusl-arm64@0.34.5': resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-linuxmusl-x64@0.34.5': resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-wasm32@0.34.5': resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} @@ -1562,6 +1578,9 @@ packages: '@next/env@15.4.8': resolution: {integrity: sha512-LydLa2MDI1NMrOFSkO54mTc8iIHSttj6R6dthITky9ylXV2gCGi0bHQjVCtLGRshdRPjyh2kXbxJukDtBWQZtQ==} + '@next/env@16.2.4': + resolution: {integrity: sha512-dKkkOzOSwFYe5RX6y26fZgkSpVAlIOJKQHIiydQcrWH6y/97+RceSOAdjZ14Qa3zLduVUy0TXcn+EiM6t4rPgw==} + '@next/eslint-plugin-next@14.0.4': resolution: {integrity: sha512-U3qMNHmEZoVmHA0j/57nRfi3AscXNvkOnxDmle/69Jz/G0o/gWjXTDdlgILZdrxQ0Lw/jv2mPW8PGy0EGIHXhQ==} @@ -1571,35 +1590,79 @@ packages: cpu: [arm64] os: [darwin] + '@next/swc-darwin-arm64@16.2.4': + resolution: {integrity: sha512-OXTFFox5EKN1Ym08vfrz+OXxmCcEjT4SFMbNRsWZE99dMqt2Kcusl5MqPXcW232RYkMLQTy0hqgAMEsfEd/l2A==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + '@next/swc-darwin-x64@15.4.8': resolution: {integrity: sha512-xla6AOfz68a6kq3gRQccWEvFC/VRGJmA/QuSLENSO7CZX5WIEkSz7r1FdXUjtGCQ1c2M+ndUAH7opdfLK1PQbw==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] + '@next/swc-darwin-x64@16.2.4': + resolution: {integrity: sha512-XhpVnUfmYWvD3YrXu55XdcAkQtOnvaI6wtQa8fuF5fGoKoxIUZ0kWPtcOfqJEWngFF/lOS9l3+O9CcownhiQxQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + '@next/swc-linux-arm64-gnu@15.4.8': resolution: {integrity: sha512-y3fmp+1Px/SJD+5ntve5QLZnGLycsxsVPkTzAc3zUiXYSOlTPqT8ynfmt6tt4fSo1tAhDPmryXpYKEAcoAPDJw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [glibc] + + '@next/swc-linux-arm64-gnu@16.2.4': + resolution: {integrity: sha512-Mx/tjlNA3G8kg14QvuGAJ4xBwPk1tUHq56JxZ8CXnZwz1Etz714soCEzGQQzVMz4bEnGPowzkV6Xrp6wAkEWOQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [glibc] '@next/swc-linux-arm64-musl@15.4.8': resolution: {integrity: sha512-DX/L8VHzrr1CfwaVjBQr3GWCqNNFgyWJbeQ10Lx/phzbQo3JNAxUok1DZ8JHRGcL6PgMRgj6HylnLNndxn4Z6A==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [musl] + + '@next/swc-linux-arm64-musl@16.2.4': + resolution: {integrity: sha512-iVMMp14514u7Nup2umQS03nT/bN9HurK8ufylC3FZNykrwjtx7V1A7+4kvhbDSCeonTVqV3Txnv0Lu+m2oDXNg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [musl] '@next/swc-linux-x64-gnu@15.4.8': resolution: {integrity: sha512-9fLAAXKAL3xEIFdKdzG5rUSvSiZTLLTCc6JKq1z04DR4zY7DbAPcRvNm3K1inVhTiQCs19ZRAgUerHiVKMZZIA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [glibc] + + '@next/swc-linux-x64-gnu@16.2.4': + resolution: {integrity: sha512-EZOvm1aQWgnI/N/xcWOlnS3RQBk0VtVav5Zo7n4p0A7UKyTDx047k8opDbXgBpHl4CulRqRfbw3QrX2w5UOXMQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [glibc] '@next/swc-linux-x64-musl@15.4.8': resolution: {integrity: sha512-s45V7nfb5g7dbS7JK6XZDcapicVrMMvX2uYgOHP16QuKH/JA285oy6HcxlKqwUNaFY/UC6EvQ8QZUOo19cBKSA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [musl] + + '@next/swc-linux-x64-musl@16.2.4': + resolution: {integrity: sha512-h9FxsngCm9cTBf71AR4fGznDEDx1hS7+kSEiIRjq5kO1oXWm07DxVGZjCvk0SGx7TSjlUqhI8oOyz7NfwAdPoA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [musl] '@next/swc-win32-arm64-msvc@15.4.8': resolution: {integrity: sha512-KjgeQyOAq7t/HzAJcWPGA8X+4WY03uSCZ2Ekk98S9OgCFsb6lfBE3dbUzUuEQAN2THbwYgFfxX2yFTCMm8Kehw==} @@ -1607,12 +1670,24 @@ packages: cpu: [arm64] os: [win32] + '@next/swc-win32-arm64-msvc@16.2.4': + resolution: {integrity: sha512-3NdJV5OXMSOeJYijX+bjaLge3mJBlh4ybydbT4GFoB/2hAojWHtMhl3CYlYoMrjPuodp0nzFVi4Tj2+WaMg+Ow==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + '@next/swc-win32-x64-msvc@15.4.8': resolution: {integrity: sha512-Exsmf/+42fWVnLMaZHzshukTBxZrSwuuLKFvqhGHJ+mC1AokqieLY/XzAl3jc/CqhXLqLY3RRjkKJ9YnLPcRWg==} engines: {node: '>= 10'} cpu: [x64] os: [win32] + '@next/swc-win32-x64-msvc@16.2.4': + resolution: {integrity: sha512-kMVGgsqhO5YTYODD9IPGGhA6iprWidQckK3LmPeW08PIFENRmgfb4MjXHO+p//d+ts2rpjvK5gXWzXSMrPl9cw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -1661,26 +1736,31 @@ packages: resolution: {integrity: sha512-TVYVWD/SYwWzGGnbfTkrNpdE4HON46orgMNHCivlXmlsSGQOx/OHHYiQcMIOx38/GWgwr/po2LBn7wypkWw/Mg==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.9.4': resolution: {integrity: sha512-XcKvuendwizYYhFxpvQ3xVpzje2HHImzg33wL9zvxtj77HvPStbSGI9czrdbfrf8DGMcNNReH9pVZv8qejAQ5A==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-riscv64-gnu@4.9.4': resolution: {integrity: sha512-LFHS/8Q+I9YA0yVETyjonMJ3UA+DczeBd/MqNEzsGSTdNvSJa1OJZcSH8GiXLvcizgp9AlHs2walqRcqzjOi3A==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.9.4': resolution: {integrity: sha512-dIYgo+j1+yfy81i0YVU5KnQrIJZE8ERomx17ReU4GREjGtDW4X+nvkBak2xAUpyqLs4eleDSj3RrV72fQos7zw==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.9.4': resolution: {integrity: sha512-RoaYxjdHQ5TPjaPrLsfKqR3pakMr3JGqZ+jZM0zP2IkDtsGa4CqYaWSfQmZVgFUCgLrTnzX+cnHS3nfl+kB6ZQ==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-win32-arm64-msvc@4.9.4': resolution: {integrity: sha512-T8Q3XHV+Jjf5e49B4EAaLKV74BbX7/qYBRQ8Wop/+TyyU0k+vSjiLVSHNWdVd1goMjZcbhDmYZUYW5RFqkBNHQ==} @@ -2411,6 +2491,11 @@ packages: base16@1.0.0: resolution: {integrity: sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ==} + baseline-browser-mapping@2.10.19: + resolution: {integrity: sha512-qCkNLi2sfBOn8XhZQ0FXsT1Ki/Yo5P90hrkRamVFRS7/KV9hpfA4HkoWNU152+8w0zPjnxo5psx5NL3PSGgv5g==} + engines: {node: '>=6.0.0'} + hasBin: true + batch@0.6.1: resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==} @@ -4492,6 +4577,9 @@ packages: lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -4696,6 +4784,27 @@ packages: sass: optional: true + next@16.2.4: + resolution: {integrity: sha512-kPvz56wF5frc+FxlHI5qnklCzbq53HTwORaWBGdT0vNoKh1Aya9XC8aPauH4NJxqtzbWsS5mAbctm4cr+EkQ2Q==} + engines: {node: '>=20.9.0'} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.51.1 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} @@ -5336,8 +5445,8 @@ packages: resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} engines: {node: '>=0.6'} - qs@6.14.1: - resolution: {integrity: sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==} + qs@6.15.1: + resolution: {integrity: sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==} engines: {node: '>=0.6'} querystringify@2.2.0: @@ -6832,7 +6941,7 @@ snapshots: debug: 4.3.4 gensync: 1.0.0-beta.2 json5: 2.2.3 - lodash: 4.17.21 + lodash: 4.18.1 resolve: 1.22.4 semver: 5.7.2 source-map: 0.5.7 @@ -7845,7 +7954,7 @@ snapshots: cheerio: 1.0.0-rc.12 feed: 4.2.2 fs-extra: 10.1.0 - lodash: 4.17.21 + lodash: 4.18.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) reading-time: 1.5.0 @@ -7884,7 +7993,7 @@ snapshots: fs-extra: 10.1.0 import-fresh: 3.3.0 js-yaml: 4.1.0 - lodash: 4.17.21 + lodash: 4.18.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) tslib: 2.6.2 @@ -8185,7 +8294,7 @@ snapshots: clsx: 1.2.1 eta: 1.14.2 fs-extra: 10.1.0 - lodash: 4.17.21 + lodash: 4.18.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) tslib: 2.6.2 @@ -8265,7 +8374,7 @@ snapshots: globby: 11.1.0 gray-matter: 4.0.3 js-yaml: 4.1.0 - lodash: 4.17.21 + lodash: 4.18.1 micromatch: 4.0.5 resolve-pathname: 3.0.0 shelljs: 0.8.5 @@ -8737,6 +8846,8 @@ snapshots: '@next/env@15.4.8': {} + '@next/env@16.2.4': {} + '@next/eslint-plugin-next@14.0.4': dependencies: glob: 7.1.7 @@ -8744,27 +8855,51 @@ snapshots: '@next/swc-darwin-arm64@15.4.8': optional: true + '@next/swc-darwin-arm64@16.2.4': + optional: true + '@next/swc-darwin-x64@15.4.8': optional: true + '@next/swc-darwin-x64@16.2.4': + optional: true + '@next/swc-linux-arm64-gnu@15.4.8': optional: true + '@next/swc-linux-arm64-gnu@16.2.4': + optional: true + '@next/swc-linux-arm64-musl@15.4.8': optional: true + '@next/swc-linux-arm64-musl@16.2.4': + optional: true + '@next/swc-linux-x64-gnu@15.4.8': optional: true + '@next/swc-linux-x64-gnu@16.2.4': + optional: true + '@next/swc-linux-x64-musl@15.4.8': optional: true + '@next/swc-linux-x64-musl@16.2.4': + optional: true + '@next/swc-win32-arm64-msvc@15.4.8': optional: true + '@next/swc-win32-arm64-msvc@16.2.4': + optional: true + '@next/swc-win32-x64-msvc@15.4.8': optional: true + '@next/swc-win32-x64-msvc@16.2.4': + optional: true + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -9697,6 +9832,8 @@ snapshots: base16@1.0.0: {} + baseline-browser-mapping@2.10.19: {} + batch@0.6.1: {} big.js@5.2.2: {} @@ -11407,7 +11544,7 @@ snapshots: dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 - lodash: 4.17.21 + lodash: 4.18.1 pretty-error: 4.0.0 tapable: 2.2.1 webpack: 5.88.2 @@ -12255,6 +12392,8 @@ snapshots: lodash@4.17.21: {} + lodash@4.18.1: {} + loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 @@ -12428,6 +12567,30 @@ snapshots: - '@babel/core' - babel-plugin-macros + next@16.2.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + dependencies: + '@next/env': 16.2.4 + '@swc/helpers': 0.5.15 + baseline-browser-mapping: 2.10.19 + caniuse-lite: 1.0.30001759 + postcss: 8.4.31 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + styled-jsx: 5.1.6(@babel/core@7.22.11)(react@18.2.0) + optionalDependencies: + '@next/swc-darwin-arm64': 16.2.4 + '@next/swc-darwin-x64': 16.2.4 + '@next/swc-linux-arm64-gnu': 16.2.4 + '@next/swc-linux-arm64-musl': 16.2.4 + '@next/swc-linux-x64-gnu': 16.2.4 + '@next/swc-linux-x64-musl': 16.2.4 + '@next/swc-win32-arm64-msvc': 16.2.4 + '@next/swc-win32-x64-msvc': 16.2.4 + sharp: 0.34.5 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + no-case@3.0.4: dependencies: lower-case: 2.0.2 @@ -12435,7 +12598,7 @@ snapshots: node-emoji@1.11.0: dependencies: - lodash: 4.17.21 + lodash: 4.18.1 node-fetch@2.7.0: dependencies: @@ -12962,7 +13125,7 @@ snapshots: pretty-error@4.0.0: dependencies: - lodash: 4.17.21 + lodash: 4.18.1 renderkid: 3.0.0 pretty-format@29.6.3: @@ -13030,7 +13193,7 @@ snapshots: dependencies: side-channel: 1.0.4 - qs@6.14.1: + qs@6.15.1: dependencies: side-channel: 1.1.0 @@ -13327,7 +13490,7 @@ snapshots: css-select: 4.3.0 dom-converter: 0.2.0 htmlparser2: 6.1.0 - lodash: 4.17.21 + lodash: 4.18.1 strip-ansi: 6.0.1 repeat-string@1.6.1: {} @@ -14323,7 +14486,7 @@ snapshots: dependencies: axios: 0.25.0 joi: 17.9.2 - lodash: 4.17.21 + lodash: 4.18.1 minimist: 1.2.8 rxjs: 7.8.1 transitivePeerDependencies: @@ -14358,7 +14521,7 @@ snapshots: chalk: 4.1.2 commander: 7.2.0 gzip-size: 6.0.0 - lodash: 4.17.21 + lodash: 4.18.1 opener: 1.5.2 sirv: 1.0.19 ws: 7.5.9