diff --git a/.changeset/brown-years-heal.md b/.changeset/brown-years-heal.md new file mode 100644 index 000000000..62204fd91 --- /dev/null +++ b/.changeset/brown-years-heal.md @@ -0,0 +1,25 @@ +--- +'@vercel/blob': minor +'vercel-storage-integration-test-suite': minor +--- + +Add onUploadProgress feature to put/upload + +You can now track the upload progress in Node.js and all major browsers when +using put/upload in multipart, non-multipart and client upload modes. Basically +anywhere in our API you can upload a file, then you can follow the upload +progress. + +Here's a basic usage example: + +``` +const blob = await put('big-file.pdf', file, { + access: 'public', + onUploadProgress(event) { + console.log(event.loaded, event.total, event.percentage); + } +}); +``` + +Fixes #543 +Fixes #642 diff --git a/packages/blob/jest/setup.js b/packages/blob/jest/setup.js index a84bb9178..127808885 100644 --- a/packages/blob/jest/setup.js +++ b/packages/blob/jest/setup.js @@ -2,5 +2,11 @@ // but they are available everywhere else. // See https://stackoverflow.com/questions/68468203/why-am-i-getting-textencoder-is-not-defined-in-jest const { TextEncoder, TextDecoder } = require('node:util'); +// eslint-disable-next-line import/order -- On purpose to make requiring undici work +const { ReadableStream } = require('node:stream/web'); -Object.assign(global, { TextDecoder, TextEncoder }); +Object.assign(global, { TextDecoder, TextEncoder, ReadableStream }); + +const { Request, Response } = require('undici'); + +Object.assign(global, { Request, Response }); diff --git a/packages/blob/package.json b/packages/blob/package.json index 0ccdb3e57..50caa32ff 100644 --- a/packages/blob/package.json +++ b/packages/blob/package.json @@ -63,22 +63,24 @@ "async-retry": "^1.3.3", "bytes": "^3.1.2", "is-buffer": "^2.0.5", + "is-node-process": "^1.2.0", + "throttleit": "^2.1.0", "undici": "^5.28.4" }, "devDependencies": { "@edge-runtime/jest-environment": "2.3.10", "@edge-runtime/types": "2.2.9", - "@types/async-retry": "1.4.8", + "@types/async-retry": "1.4.9", "@types/bytes": "3.1.4", - "@types/jest": "29.5.13", - "@types/node": "22.7.3", + "@types/jest": "29.5.14", + "@types/node": "22.9.0", "eslint": "8.56.0", "eslint-config-custom": "workspace:*", "jest": "29.7.0", "jest-environment-jsdom": "29.7.0", "ts-jest": "29.2.5", "tsconfig": "workspace:*", - "tsup": "8.3.0" + "tsup": "8.3.5" }, "engines": { "node": ">=16.14" diff --git a/packages/blob/src/api.ts b/packages/blob/src/api.ts index c67057466..f22c66510 100644 --- a/packages/blob/src/api.ts +++ b/packages/blob/src/api.ts @@ -1,9 +1,20 @@ -import type { RequestInit, Response } from 'undici'; -import { fetch } from 'undici'; +import type { Response } from 'undici'; import retry from 'async-retry'; +import isNetworkError from './is-network-error'; import { debug } from './debug'; -import type { BlobCommandOptions } from './helpers'; -import { BlobError, getTokenFromOptionsOrEnv } from './helpers'; +import type { + BlobCommandOptions, + BlobRequestInit, + WithUploadProgress, +} from './helpers'; +import { + BlobError, + computeBodyLength, + getApiUrl, + getTokenFromOptionsOrEnv, +} from './helpers'; +import { blobRequest } from './request'; +import { DOMException } from './dom-exception'; // maximum pathname length is: // 1024 (provider limit) - 26 chars (vercel internal suffixes) - 31 chars (blob `-randomId` suffix) = 967 @@ -132,20 +143,6 @@ function getApiVersion(): string { return `${versionOverride ?? BLOB_API_VERSION}`; } -function getApiUrl(pathname = ''): string { - let baseUrl = null; - try { - // wrapping this code in a try/catch as this function is used in the browser and Vite doesn't define the process.env. - // As this varaible is NOT used in production, it will always default to production endpoint - baseUrl = - process.env.VERCEL_BLOB_API_URL || - process.env.NEXT_PUBLIC_VERCEL_BLOB_API_URL; - } catch { - // noop - } - return `${baseUrl || 'https://blob.vercel-storage.com'}${pathname}`; -} - function getRetries(): number { try { const retries = process.env.VERCEL_BLOB_RETRIES || '10'; @@ -175,7 +172,6 @@ async function getBlobError( try { const data = (await response.json()) as BlobApiError; - code = data.error?.code ?? 'unknown_error'; message = data.error?.message; } catch { @@ -254,8 +250,8 @@ async function getBlobError( export async function requestApi( pathname: string, - init: RequestInit, - commandOptions: BlobCommandOptions | undefined, + init: BlobRequestInit, + commandOptions: (BlobCommandOptions & WithUploadProgress) | undefined, ): Promise { const apiVersion = getApiVersion(); const token = getTokenFromOptionsOrEnv(commandOptions); @@ -264,6 +260,27 @@ export async function requestApi( const [, , , storeId = ''] = token.split('_'); const requestId = `${storeId}:${Date.now()}:${Math.random().toString(16).slice(2)}`; let retryCount = 0; + let bodyLength = 0; + let totalLoaded = 0; + const sendBodyLength = + commandOptions?.onUploadProgress || shouldUseXContentLength(); + + if ( + init.body && + // 1. For upload progress we always need to know the total size of the body + // 2. In development we need the header for put() to work correctly when passing a stream + sendBodyLength + ) { + bodyLength = computeBodyLength(init.body); + } + + if (commandOptions?.onUploadProgress) { + commandOptions.onUploadProgress({ + loaded: 0, + total: bodyLength, + percentage: 0, + }); + } const apiResponse = await retry( async (bail) => { @@ -271,16 +288,47 @@ export async function requestApi( // try/catch here to treat certain errors as not-retryable try { - res = await fetch(getApiUrl(pathname), { - ...init, - headers: { - 'x-api-blob-request-id': requestId, - 'x-api-blob-request-attempt': String(retryCount), - 'x-api-version': apiVersion, - authorization: `Bearer ${token}`, - ...extraHeaders, - ...init.headers, + res = await blobRequest({ + input: getApiUrl(pathname), + init: { + ...init, + headers: { + 'x-api-blob-request-id': requestId, + 'x-api-blob-request-attempt': String(retryCount), + 'x-api-version': apiVersion, + ...(sendBodyLength + ? { 'x-content-length': String(bodyLength) } + : {}), + authorization: `Bearer ${token}`, + ...extraHeaders, + ...init.headers, + }, }, + onUploadProgress: commandOptions?.onUploadProgress + ? (loaded) => { + const total = bodyLength !== 0 ? bodyLength : loaded; + totalLoaded = loaded; + const percentage = + bodyLength > 0 + ? Number(((loaded / total) * 100).toFixed(2)) + : 0; + + // Leave percentage 100 for the end of request + if (percentage === 100 && bodyLength > 0) { + return; + } + + commandOptions.onUploadProgress?.({ + loaded, + // When passing a stream to put(), we have no way to know the total size of the body. + // Instead of defining total as total?: number we decided to set the total to the currently + // loaded number. This is not inaccurate and way more practical for DX. + // Passing down a stream to put() is very rare + total, + percentage, + }); + } + : undefined, }); } catch (error) { // if the request was aborted, don't retry @@ -289,6 +337,18 @@ export async function requestApi( return; } + // We specifically target network errors because fetch network errors are regular TypeErrors + // We want to retry for network errors, but not for other TypeErrors + if (isNetworkError(error)) { + throw error; + } + + // If we messed up the request part, don't even retry + if (error instanceof TypeError) { + bail(error); + return; + } + // retry for any other erros thrown by fetch throw error; } @@ -314,7 +374,10 @@ export async function requestApi( { retries: getRetries(), onRetry: (error) => { - debug(`retrying API request to ${pathname}`, error.message); + if (error instanceof Error) { + debug(`retrying API request to ${pathname}`, error.message); + } + retryCount = retryCount + 1; }, }, @@ -324,6 +387,20 @@ export async function requestApi( throw new BlobUnknownError(); } + // Calling onUploadProgress here has two benefits: + // 1. It ensures 100% is only reached at the end of the request. While otherwise you can reach 100% + // before the request is fully done, as we only really measure what gets sent over the wire, not what + // has been processed by the server. + // 2. It makes the uploadProgress "work" even in rare cases where fetch/xhr onprogress is not working + // And in the case of multipart uploads it actually provides a simple progress indication (per part) + if (commandOptions?.onUploadProgress) { + commandOptions.onUploadProgress({ + loaded: totalLoaded, + total: totalLoaded, + percentage: 100, + }); + } + return (await apiResponse.json()) as TResponse; } @@ -333,16 +410,19 @@ function getProxyThroughAlternativeApiHeaderFromEnv(): { const extraHeaders: Record = {}; try { - if ('VERCEL_BLOB_PROXY_THROUGH_ALTERNATIVE_API' in process.env) { + if ( + 'VERCEL_BLOB_PROXY_THROUGH_ALTERNATIVE_API' in process.env && + process.env.VERCEL_BLOB_PROXY_THROUGH_ALTERNATIVE_API !== undefined + ) { extraHeaders['x-proxy-through-alternative-api'] = - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- we know it's here from the if - process.env.VERCEL_BLOB_PROXY_THROUGH_ALTERNATIVE_API!; + process.env.VERCEL_BLOB_PROXY_THROUGH_ALTERNATIVE_API; } else if ( - 'NEXT_PUBLIC_VERCEL_BLOB_PROXY_THROUGH_ALTERNATIVE_API' in process.env + 'NEXT_PUBLIC_VERCEL_BLOB_PROXY_THROUGH_ALTERNATIVE_API' in process.env && + process.env.NEXT_PUBLIC_VERCEL_BLOB_PROXY_THROUGH_ALTERNATIVE_API !== + undefined ) { extraHeaders['x-proxy-through-alternative-api'] = - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- we know it's here from the if - process.env.NEXT_PUBLIC_VERCEL_BLOB_PROXY_THROUGH_ALTERNATIVE_API!; + process.env.NEXT_PUBLIC_VERCEL_BLOB_PROXY_THROUGH_ALTERNATIVE_API; } } catch { // noop @@ -350,3 +430,11 @@ function getProxyThroughAlternativeApiHeaderFromEnv(): { return extraHeaders; } + +function shouldUseXContentLength(): boolean { + try { + return process.env.VERCEL_BLOB_USE_X_CONTENT_LENGTH === '1'; + } catch { + return false; + } +} diff --git a/packages/blob/src/client.browser.test.ts b/packages/blob/src/client.browser.test.ts index 8d24787f4..128ba306c 100644 --- a/packages/blob/src/client.browser.test.ts +++ b/packages/blob/src/client.browser.test.ts @@ -88,7 +88,6 @@ describe('client', () => { 'https://blob.vercel-storage.com/foo.txt', { body: 'Test file data', - duplex: 'half', headers: { authorization: 'Bearer vercel_blob_client_fake_123', 'x-api-blob-request-attempt': '0', @@ -232,7 +231,6 @@ describe('client', () => { 'x-mpu-part-number': '1', }, method: 'POST', - duplex: 'half', signal: internalAbortSignal, }, ); @@ -252,7 +250,6 @@ describe('client', () => { 'x-mpu-part-number': '2', }, method: 'POST', - duplex: 'half', signal: internalAbortSignal, }, ); @@ -376,7 +373,6 @@ describe('client', () => { 'x-mpu-part-number': '1', }, method: 'POST', - duplex: 'half', signal: internalAbortSignal, }, ); @@ -396,7 +392,6 @@ describe('client', () => { 'x-mpu-part-number': '2', }, method: 'POST', - duplex: 'half', signal: internalAbortSignal, }, ); diff --git a/packages/blob/src/client.ts b/packages/blob/src/client.ts index 646b43a2a..5eb6385e3 100644 --- a/packages/blob/src/client.ts +++ b/packages/blob/src/client.ts @@ -5,7 +5,7 @@ import type { IncomingMessage } from 'node:http'; // the `undici` module will be replaced with https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API // for browser contexts. See ./undici-browser.js and ./package.json import { fetch } from 'undici'; -import type { BlobCommandOptions } from './helpers'; +import type { BlobCommandOptions, WithUploadProgress } from './helpers'; import { BlobError, getTokenFromOptionsOrEnv } from './helpers'; import { createPutMethod } from './put'; import type { PutBlobResult } from './put-helpers'; @@ -42,7 +42,9 @@ export interface ClientTokenOptions { } // shared interface for put and upload -interface ClientCommonPutOptions extends ClientCommonCreateBlobOptions { +interface ClientCommonPutOptions + extends ClientCommonCreateBlobOptions, + WithUploadProgress { /** * Whether to use multipart upload. Use this when uploading large files. It will split the file into multiple parts, upload them in parallel and retry failed parts. */ @@ -89,7 +91,7 @@ export const put = createPutMethod({ // vercelBlob. createMultipartUpload() // vercelBlob. uploadPart() // vercelBlob. completeMultipartUpload() -// vercelBlob. createMultipartUploaded() +// vercelBlob. createMultipartUploader() export type ClientCreateMultipartUploadCommandOptions = ClientCommonCreateBlobOptions & ClientTokenOptions; @@ -110,7 +112,8 @@ export const createMultipartUploader = type ClientMultipartUploadCommandOptions = ClientCommonCreateBlobOptions & ClientTokenOptions & - CommonMultipartUploadOptions; + CommonMultipartUploadOptions & + WithUploadProgress; export const uploadPart = createUploadPartMethod({ diff --git a/packages/blob/src/dom-exception.ts b/packages/blob/src/dom-exception.ts new file mode 100644 index 000000000..82ae1e423 --- /dev/null +++ b/packages/blob/src/dom-exception.ts @@ -0,0 +1,13 @@ +// TODO: Once Node 16 is no more needed internally, we can remove this file and use the native DOMException type. +/* eslint-disable -- fine */ +export const DOMException = + globalThis.DOMException ?? + (() => { + // DOMException was only made a global in Node v17.0.0, + // but fetch supports >= v16.8. + try { + atob('~'); + } catch (err) { + return Object.getPrototypeOf(err).constructor; + } + })(); diff --git a/packages/blob/src/fetch.ts b/packages/blob/src/fetch.ts new file mode 100644 index 000000000..514350498 --- /dev/null +++ b/packages/blob/src/fetch.ts @@ -0,0 +1,64 @@ +import type { BodyInit } from 'undici'; +import { fetch } from 'undici'; +import type { BlobRequest } from './helpers'; +import { + createChunkTransformStream, + isStream, + supportsRequestStreams, +} from './helpers'; +import { toReadableStream } from './multipart/helpers'; +import type { PutBody } from './put-helpers'; +import { debug } from './debug'; + +export const hasFetch = typeof fetch === 'function'; + +export const hasFetchWithUploadProgress = hasFetch && supportsRequestStreams; + +const CHUNK_SIZE = 64 * 1024; + +export const blobFetch: BlobRequest = async ({ + input, + init, + onUploadProgress, +}) => { + debug('using fetch'); + let body: BodyInit | undefined; + + if (init.body) { + if (onUploadProgress) { + // We transform the body to a stream here instead of at the call site + // So that on retries we can reuse the original body, otherwise we would not be able to reuse it + const stream = await toReadableStream(init.body); + + let loaded = 0; + + const chunkTransformStream = createChunkTransformStream( + CHUNK_SIZE, + (newLoaded: number) => { + loaded += newLoaded; + onUploadProgress(loaded); + }, + ); + + body = stream.pipeThrough(chunkTransformStream); + } else { + body = init.body as BodyInit; + } + } + + // Only set duplex option when supported and dealing with a stream body + const duplex = + supportsRequestStreams && body && isStream(body as PutBody) + ? 'half' + : undefined; + + return fetch( + input, + // @ts-expect-error -- Blob and Nodejs Blob are triggering type errors, fine with it + { + ...init, + ...(init.body ? { body } : {}), + duplex, + }, + ); +}; diff --git a/packages/blob/src/helpers.ts b/packages/blob/src/helpers.ts index af3ae23bf..00063d43e 100644 --- a/packages/blob/src/helpers.ts +++ b/packages/blob/src/helpers.ts @@ -1,6 +1,12 @@ // common util interface for blob raw commands, not meant to be used directly // this is why it's not exported from index/client +import type { Readable } from 'node:stream'; +import type { RequestInit, Response } from 'undici'; +import { isNodeProcess } from 'is-node-process'; +import { isNodeJsReadableStream } from './multipart/helpers'; +import type { PutBody } from './put-helpers'; + export interface BlobCommandOptions { /** * Define your blob API token. @@ -36,6 +42,40 @@ export interface CommonCreateBlobOptions extends BlobCommandOptions { cacheControlMaxAge?: number; } +export interface UploadProgressEvent { + loaded: number; + total: number; + percentage: number; +} + +export type OnUploadProgressCallback = ( + progressEvent: UploadProgressEvent, +) => void; + +export type InternalOnUploadProgressCallback = (loaded: number) => void; + +export type BlobRequestInit = Omit & { body?: PutBody }; + +export type BlobRequest = ({ + input, + init, + onUploadProgress, +}: { + input: string | URL; + init: BlobRequestInit; + onUploadProgress?: InternalOnUploadProgressCallback; +}) => Promise; + +export interface WithUploadProgress { + /** + * Callback to track the upload progress. You will receive an object with the following properties: + * - `loaded`: The number of bytes uploaded + * - `total`: The total number of bytes to upload + * - `percentage`: The percentage of the upload that has been completed + */ + onUploadProgress?: OnUploadProgressCallback; +} + export function getTokenFromOptionsOrEnv(options?: BlobCommandOptions): string { if (options?.token) { return options.token; @@ -83,3 +123,131 @@ export function isPlainObject(value: unknown): boolean { } export const disallowedPathnameCharacters = ['#', '?', '//']; + +// Chrome: implemented https://developer.chrome.com/docs/capabilities/web-apis/fetch-streaming-requests +// Microsoft Edge: implemented (Chromium) +// Firefox: not implemented, BOO!! https://bugzilla.mozilla.org/show_bug.cgi?id=1469359 +// Safari: not implemented, BOO!! https://github.com/WebKit/standards-positions/issues/24 +export const supportsRequestStreams = (() => { + // The next line is mostly for Node.js 16 to avoid trying to do new Request() as it's not supported + // TODO: Can be removed when Node.js 16 is no more required internally + if (isNodeProcess()) { + return true; + } + + let duplexAccessed = false; + + const hasContentType = new Request(getApiUrl(), { + body: new ReadableStream(), + method: 'POST', + // @ts-expect-error -- TypeScript doesn't yet have duplex but it's in the spec: https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1729 + get duplex() { + duplexAccessed = true; + return 'half'; + }, + }).headers.has('Content-Type'); + + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- could be false + return duplexAccessed && !hasContentType; +})(); + +export function getApiUrl(pathname = ''): string { + let baseUrl = null; + try { + // wrapping this code in a try/catch as this function is used in the browser and Vite doesn't define the process.env. + // As this varaible is NOT used in production, it will always default to production endpoint + baseUrl = + process.env.VERCEL_BLOB_API_URL || + process.env.NEXT_PUBLIC_VERCEL_BLOB_API_URL; + } catch { + // noop + } + return `${baseUrl || 'https://blob.vercel-storage.com'}${pathname}`; +} + +const TEXT_ENCODER = + typeof TextEncoder === 'function' ? new TextEncoder() : null; + +export function computeBodyLength(body: PutBody): number { + if (!body) { + return 0; + } + + if (typeof body === 'string') { + if (TEXT_ENCODER) { + return TEXT_ENCODER.encode(body).byteLength; + } + + // React Native doesn't have TextEncoder + return new Blob([body]).size; + } + + if ('byteLength' in body && typeof body.byteLength === 'number') { + // handles Uint8Array, ArrayBuffer, Buffer, and ArrayBufferView + return body.byteLength; + } + + if ('size' in body && typeof body.size === 'number') { + // handles Blob and File + return body.size; + } + + return 0; +} + +export const createChunkTransformStream = ( + chunkSize: number, + onProgress?: (bytes: number) => void, +): TransformStream => { + let buffer = new Uint8Array(0); + + return new TransformStream({ + transform(chunk, controller) { + queueMicrotask(() => { + // Combine the new chunk with any leftover data + const newBuffer = new Uint8Array(buffer.length + chunk.byteLength); + newBuffer.set(buffer); + newBuffer.set(new Uint8Array(chunk), buffer.length); + buffer = newBuffer; + + // Output complete chunks + while (buffer.length >= chunkSize) { + const newChunk = buffer.slice(0, chunkSize); + controller.enqueue(newChunk); + onProgress?.(newChunk.byteLength); + buffer = buffer.slice(chunkSize); + } + }); + }, + + flush(controller) { + queueMicrotask(() => { + // Send any remaining data + if (buffer.length > 0) { + controller.enqueue(buffer); + onProgress?.(buffer.byteLength); + } + }); + }, + }); +}; + +export function isReadableStream(value: PutBody): value is ReadableStream { + return ( + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- Not present in Node.js 16 + globalThis.ReadableStream && // TODO: Can be removed once Node.js 16 is no more required internally + value instanceof ReadableStream + ); +} + +export function isStream(value: PutBody): value is ReadableStream | Readable { + if (isReadableStream(value)) { + return true; + } + + if (isNodeJsReadableStream(value)) { + return true; + } + + return false; +} diff --git a/packages/blob/src/index.node.test.ts b/packages/blob/src/index.node.test.ts index 6b49cea5c..518f4350a 100644 --- a/packages/blob/src/index.node.test.ts +++ b/packages/blob/src/index.node.test.ts @@ -396,6 +396,35 @@ describe('blob client', () => { contentDisposition: mockedFileMeta.contentDisposition, }; + it('has an onUploadProgress option', async () => { + mockClient + .intercept({ + path: () => true, + method: 'PUT', + }) + .reply(200, () => { + return mockedFileMetaPut; + }); + + const onUploadProgress = jest.fn(); + + await expect( + put('progress.txt', 'Test Body', { + access: 'public', + onUploadProgress, + }), + ).resolves.toMatchInlineSnapshot(` + { + "contentDisposition": "attachment; filename="foo.txt"", + "contentType": "text/plain", + "downloadUrl": "https://storeId.public.blob.vercel-storage.com/foo-id.txt?download=1", + "pathname": "foo.txt", + "url": "https://storeId.public.blob.vercel-storage.com/foo-id.txt", + } + `); + expect(onUploadProgress).toHaveBeenCalledTimes(1); + }); + it('should upload a file with a custom token', async () => { let path: string | null = null; let headers: Record = {}; diff --git a/packages/blob/src/index.ts b/packages/blob/src/index.ts index c9c48eed2..bf54b1e00 100644 --- a/packages/blob/src/index.ts +++ b/packages/blob/src/index.ts @@ -9,7 +9,12 @@ import type { CommonCreateBlobOptions } from './helpers'; import { createCreateMultipartUploaderMethod } from './multipart/create-uploader'; // expose generic BlobError and download url util -export { BlobError, getDownloadUrl } from './helpers'; +export { + BlobError, + getDownloadUrl, + type OnUploadProgressCallback, + type UploadProgressEvent, +} from './helpers'; // expose api BlobErrors export { @@ -39,7 +44,7 @@ export type { PutCommandOptions }; * If you want to upload from the browser directly, check out the documentation forAclient uploads: https://vercel.com/docs/storage/vercel-blob/using-blob-sdk#client-uploads * * @param pathname - The pathname to upload the blob to, including the extension. This will influence the url of your blob like https://$storeId.public.blob.vercel-storage.com/$pathname. - * @param body - The content of your blob, can be a: string, File, Blob, Buffer or Stream. We support everything fetch supports: https://developer.mozilla.org/en-US/docs/Web/API/RequestInit#body. + * @param body - The content of your blob, can be a: string, File, Blob, Buffer or Stream. We support almost everything fetch supports: https://developer.mozilla.org/en-US/docs/Web/API/RequestInit#body. * @param options - Additional options like `token` or `contentType`. */ export const put = createPutMethod({ @@ -73,7 +78,7 @@ export { copy } from './copy'; // vercelBlob. createMultipartUpload() // vercelBlob. uploadPart() // vercelBlob. completeMultipartUpload() -// vercelBlob. createMultipartUploaded() +// vercelBlob. createMultipartUploader() export const createMultipartUpload = createCreateMultipartUploadMethod({ diff --git a/packages/blob/src/is-network-error.ts b/packages/blob/src/is-network-error.ts new file mode 100644 index 000000000..424886508 --- /dev/null +++ b/packages/blob/src/is-network-error.ts @@ -0,0 +1,52 @@ +/* eslint-disable -- This file is copy pasted*/ +// @ts-nocheck -- This file is copy pasted + +// Source: https://github.com/sindresorhus/is-network-error/blob/main/index.js +// Why: Jest + ES6 modules = harder than maintaining a nuclear plant + +/** + * MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +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. + */ + +const objectToString = Object.prototype.toString; + +const isError = (value) => objectToString.call(value) === '[object Error]'; + +const errorMessages = new Set([ + 'network error', // Chrome + 'Failed to fetch', // Chrome + 'NetworkError when attempting to fetch resource.', // Firefox + 'The Internet connection appears to be offline.', // Safari 16 + 'Load failed', // Safari 17+ + 'Network request failed', // `cross-fetch` + 'fetch failed', // Undici (Node.js) + 'terminated', // Undici (Node.js) +]); + +export default function isNetworkError(error) { + const isValid = + error && + isError(error) && + error.name === 'TypeError' && + typeof error.message === 'string'; + + if (!isValid) { + return false; + } + + // We do an extra check for Safari 17+ as it has a very generic error message. + // Network errors in Safari have no stack. + if (error.message === 'Load failed') { + return error.stack === undefined; + } + + return errorMessages.has(error.message); +} diff --git a/packages/blob/src/multipart/create.ts b/packages/blob/src/multipart/create.ts index b4457453b..585d54e3f 100644 --- a/packages/blob/src/multipart/create.ts +++ b/packages/blob/src/multipart/create.ts @@ -65,8 +65,8 @@ export async function createMultipartUpload( (error.message === 'Failed to fetch' || error.message === 'fetch failed') ) { throw new BlobServiceNotAvailable(); - } else { - throw error; } + + throw error; } } diff --git a/packages/blob/src/multipart/helpers.ts b/packages/blob/src/multipart/helpers.ts index 148e139bf..d7906dc41 100644 --- a/packages/blob/src/multipart/helpers.ts +++ b/packages/blob/src/multipart/helpers.ts @@ -15,7 +15,27 @@ export interface Part { etag: string; } -export function toReadableStream(value: PutBody): ReadableStream { +const supportsNewBlobFromArrayBuffer = new Promise((resolve) => { + // React Native doesn't support creating a Blob from an ArrayBuffer, so we feature detect it + try { + const helloAsArrayBuffer = new Uint8Array([104, 101, 108, 108, 111]); + const blob = new Blob([helloAsArrayBuffer]); + blob + .text() + .then((text) => { + resolve(text === 'hello'); + }) + .catch(() => { + resolve(false); + }); + } catch { + resolve(false); + } +}); + +export async function toReadableStream( + value: PutBody, +): Promise> { // Already a ReadableStream, nothing to do if (value instanceof ReadableStream) { return value as ReadableStream; @@ -32,14 +52,23 @@ export function toReadableStream(value: PutBody): ReadableStream { return Readable.toWeb(value) as ReadableStream; } - let streamValue: Uint8Array | ArrayBuffer; + let streamValue: Uint8Array; + // While ArrayBuffer is valid as a fetch body, when used in a ReadableStream it will fail in Node.js with + // The "chunk" argument must be of type string or an instance of Buffer or Uint8Array. Received an instance of ArrayBuffer if (value instanceof ArrayBuffer) { + streamValue = new Uint8Array(value); + } else if (isNodeJsBuffer(value)) { streamValue = value; - } else if (isNodeJsBufferOrString(value)) { - streamValue = value.buffer; } else { - streamValue = stringToUint8Array(value); + // value is a string, we need to convert it to a Uint8Array to get create a stream from it + streamValue = stringToUint8Array(value as string); + } + + // This line ensures that even when we get a buffer of 70MB, we'll create a stream out of it so we can have + // better progress indication during uploads + if (await supportsNewBlobFromArrayBuffer) { + return new Blob([streamValue]).stream(); } // from https://github.com/sindresorhus/to-readable-stream/blob/main/index.js @@ -52,7 +81,7 @@ export function toReadableStream(value: PutBody): ReadableStream { } // From https://github.com/sindresorhus/is-stream/ -function isNodeJsReadableStream(value: PutBody): value is Readable { +export function isNodeJsReadableStream(value: PutBody): value is Readable { return ( typeof value === 'object' && typeof (value as Readable).pipe === 'function' && @@ -68,6 +97,6 @@ function stringToUint8Array(s: string): Uint8Array { return enc.encode(s); } -function isNodeJsBufferOrString(input: Buffer | string): input is Buffer { - return isBuffer(input); +function isNodeJsBuffer(value: PutBody): value is Buffer { + return isBuffer(value); } diff --git a/packages/blob/src/multipart/uncontrolled.ts b/packages/blob/src/multipart/uncontrolled.ts index 0fb2e12f8..5985ad784 100644 --- a/packages/blob/src/multipart/uncontrolled.ts +++ b/packages/blob/src/multipart/uncontrolled.ts @@ -1,5 +1,6 @@ import { debug } from '../debug'; -import type { BlobCommandOptions } from '../helpers'; +import { computeBodyLength } from '../helpers'; +import type { WithUploadProgress, BlobCommandOptions } from '../helpers'; import type { PutBody, PutBlobResult } from '../put-helpers'; import { completeMultipartUpload } from './complete'; import { createMultipartUpload } from './create'; @@ -11,19 +12,25 @@ export async function uncontrolledMultipartUpload( pathname: string, body: PutBody, headers: Record, - options: BlobCommandOptions, + options: BlobCommandOptions & WithUploadProgress, ): Promise { debug('mpu: init', 'pathname:', pathname, 'headers:', headers); - const stream = toReadableStream(body); + const optionsWithoutOnUploadProgress = { + ...options, + onUploadProgress: undefined, + }; // Step 1: Start multipart upload const createMultipartUploadResponse = await createMultipartUpload( pathname, headers, - options, + optionsWithoutOnUploadProgress, ); + const totalToLoad = computeBodyLength(body); + const stream = await toReadableStream(body); + // Step 2: Upload parts one by one const parts = await uploadAllParts({ uploadId: createMultipartUploadResponse.uploadId, @@ -32,6 +39,7 @@ export async function uncontrolledMultipartUpload( stream, headers, options, + totalToLoad, }); // Step 3: Complete multipart upload @@ -41,8 +49,12 @@ export async function uncontrolledMultipartUpload( pathname, parts, headers, - options, + options: optionsWithoutOnUploadProgress, }); + // changes: + // stream => set percentage to 0% even if loaded/total is valid + // stream => send onUploadProgress 100% at the end of the request here + return blob; } diff --git a/packages/blob/src/multipart/upload.ts b/packages/blob/src/multipart/upload.ts index 7152e60dc..00d4eae31 100644 --- a/packages/blob/src/multipart/upload.ts +++ b/packages/blob/src/multipart/upload.ts @@ -1,12 +1,12 @@ import bytes from 'bytes'; -import type { BodyInit } from 'undici'; +import throttle from 'throttleit'; import { BlobServiceNotAvailable, requestApi } from '../api'; import { debug } from '../debug'; -import { - type CommonCreateBlobOptions, - type BlobCommandOptions, - BlobError, - isPlainObject, +import { BlobError, isPlainObject } from '../helpers'; +import type { + WithUploadProgress, + CommonCreateBlobOptions, + BlobCommandOptions, } from '../helpers'; import { createPutHeaders, createPutOptions } from '../put-helpers'; import type { PutBody, CreatePutMethodOptions } from '../put-helpers'; @@ -74,7 +74,7 @@ export async function uploadPart({ key: string; pathname: string; headers: Record; - options: BlobCommandOptions; + options: BlobCommandOptions & WithUploadProgress; internalAbortController?: AbortController; part: PartInput; }): Promise { @@ -91,11 +91,7 @@ export async function uploadPart({ 'x-mpu-part-number': part.partNumber.toString(), }, // weird things between undici types and native fetch types - body: part.blob as BodyInit, - // required in order to stream some body types to Cloudflare - // currently only supported in Node.js, we may have to feature detect this - // note: this doesn't send a content-length to the server - duplex: 'half', + body: part.blob, }, options, ); @@ -145,13 +141,15 @@ export function uploadAllParts({ stream, headers, options, + totalToLoad, }: { uploadId: string; key: string; pathname: string; stream: ReadableStream; headers: Record; - options: BlobCommandOptions; + options: BlobCommandOptions & WithUploadProgress; + totalToLoad: number; }): Promise { debug('mpu: upload init', 'key:', key); const internalAbortController = new AbortController(); @@ -174,6 +172,28 @@ export function uploadAllParts({ let arrayBuffers: ArrayBuffer[] = []; let currentPartBytesRead = 0; + let onUploadProgress: (() => void) | undefined; + const totalLoadedPerPartNumber: Record = {}; + + if (options.onUploadProgress) { + onUploadProgress = throttle(() => { + const loaded = Object.values(totalLoadedPerPartNumber).reduce( + (acc, cur) => { + return acc + cur; + }, + 0, + ); + const total = totalToLoad || loaded; + const percentage = + totalToLoad > 0 + ? Number(((loaded / totalToLoad || loaded) * 100).toFixed(2)) + : 0; + + // we call the user's onUploadProgress callback + options.onUploadProgress?.({ loaded, total, percentage }); + }, 150); + } + read().catch(cancel); async function read(): Promise { @@ -279,12 +299,25 @@ export function uploadAllParts({ ); try { + const uploadProgressForPart: WithUploadProgress['onUploadProgress'] = + options.onUploadProgress + ? (event) => { + totalLoadedPerPartNumber[part.partNumber] = event.loaded; + if (onUploadProgress) { + onUploadProgress(); + } + } + : undefined; + const completedPart = await uploadPart({ uploadId, key, pathname, headers, - options, + options: { + ...options, + onUploadProgress: uploadProgressForPart, + }, internalAbortController, part, }); diff --git a/packages/blob/src/put-helpers.ts b/packages/blob/src/put-helpers.ts index b2a0cd42b..8abb48a01 100644 --- a/packages/blob/src/put-helpers.ts +++ b/packages/blob/src/put-helpers.ts @@ -1,5 +1,9 @@ // eslint-disable-next-line unicorn/prefer-node-protocol -- node:stream does not resolve correctly in browser and edge import type { Readable } from 'stream'; +// We use the undici types to ensure TS doesn't complain about native types (like ReadableStream) vs +// undici types fetch expects (like Blob is from node:buffer..) +// import type { Blob } from 'node:buffer'; +import type { File } from 'undici'; import type { ClientCommonCreateBlobOptions } from './client'; import type { CommonCreateBlobOptions } from './helpers'; import { BlobError, disallowedPathnameCharacters } from './helpers'; diff --git a/packages/blob/src/put.ts b/packages/blob/src/put.ts index cd48f869a..9f104910e 100644 --- a/packages/blob/src/put.ts +++ b/packages/blob/src/put.ts @@ -1,6 +1,6 @@ -import type { BodyInit } from 'undici'; +import throttle from 'throttleit'; import { requestApi } from './api'; -import type { CommonCreateBlobOptions } from './helpers'; +import type { CommonCreateBlobOptions, WithUploadProgress } from './helpers'; import { BlobError, isPlainObject } from './helpers'; import { uncontrolledMultipartUpload } from './multipart/uncontrolled'; import type { @@ -11,7 +11,9 @@ import type { } from './put-helpers'; import { createPutOptions, createPutHeaders } from './put-helpers'; -export interface PutCommandOptions extends CommonCreateBlobOptions { +export interface PutCommandOptions + extends CommonCreateBlobOptions, + WithUploadProgress { /** * Whether to use multipart upload. Use this when uploading large files. It will split the file into multiple parts, upload them in parallel and retry failed parts. * @defaultvalue false @@ -52,19 +54,22 @@ export function createPutMethod({ return uncontrolledMultipartUpload(pathname, body, headers, options); } + const onUploadProgress = options.onUploadProgress + ? throttle(options.onUploadProgress, 100) + : undefined; + const response = await requestApi( `/${pathname}`, { method: 'PUT', - body: body as BodyInit, + body, headers, - // required in order to stream some body types to Cloudflare - // currently only supported in Node.js, we may have to feature detect this - // note: this doesn't send a content-length to the server - duplex: 'half', signal: options.abortSignal, }, - options, + { + ...options, + onUploadProgress, + }, ); return { diff --git a/packages/blob/src/request.ts b/packages/blob/src/request.ts new file mode 100644 index 000000000..d3ce6467f --- /dev/null +++ b/packages/blob/src/request.ts @@ -0,0 +1,30 @@ +import type { Response } from 'undici'; +import { blobFetch, hasFetch, hasFetchWithUploadProgress } from './fetch'; +import { hasXhr, blobXhr } from './xhr'; +import type { BlobRequest } from './helpers'; + +export const blobRequest: BlobRequest = async ({ + input, + init, + onUploadProgress, +}): Promise => { + if (onUploadProgress) { + if (hasFetchWithUploadProgress) { + return blobFetch({ input, init, onUploadProgress }); + } + + if (hasXhr) { + return blobXhr({ input, init, onUploadProgress }); + } + } + + if (hasFetch) { + return blobFetch({ input, init }); + } + + if (hasXhr) { + return blobXhr({ input, init }); + } + + throw new Error('No request implementation available'); +}; diff --git a/packages/blob/src/xhr.ts b/packages/blob/src/xhr.ts new file mode 100644 index 000000000..2bb713547 --- /dev/null +++ b/packages/blob/src/xhr.ts @@ -0,0 +1,120 @@ +import type { Response as UndiciResponse } from 'undici'; +import { isReadableStream, type BlobRequest } from './helpers'; +import { debug } from './debug'; + +export const hasXhr = typeof XMLHttpRequest !== 'undefined'; + +export const blobXhr: BlobRequest = async ({ + input, + init, + onUploadProgress, +}) => { + debug('using xhr'); + let body: XMLHttpRequestBodyInit | null = null; + + // xhr.send only support XMLHttpRequestBodyInit types, excluding ReadableStream (web) + // and Readable (node) + // We do have to support ReadableStream being sent to xhr as our library allows + // for Safari to use put(path, ReadableStream, { onUploadProgress }) which would + // end up here. + // We do not have to support Readable being sent to xhr as using Node.js you would + // endup in the fetch implementation by default. + if (init.body) { + if (isReadableStream(init.body)) { + body = await new Response(init.body).blob(); + } else { + // We "type lie" here, what we should do instead: + // Exclude ReadableStream: + // body = init.body as Exclude; + // We can't do this because init.body (PutBody) relies on Blob (node:buffer) + // while XMLHttpRequestBodyInit relies on native Blob type. + // If we get rid of undici we can remove this trick. + body = init.body as XMLHttpRequestBodyInit; + } + } + + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open(init.method || 'GET', input.toString(), true); + + // Handle upload progress + if (onUploadProgress) { + xhr.upload.addEventListener('progress', (event) => { + if (event.lengthComputable) { + onUploadProgress(event.loaded); + } + }); + } + + // Handle response + xhr.onload = () => { + if (init.signal?.aborted) { + reject(new DOMException('The user aborted the request.', 'AbortError')); + return; + } + + const headers = new Headers(); + const rawHeaders = xhr + .getAllResponseHeaders() + .trim() + .split(/[\r\n]+/); + + // Parse headers + rawHeaders.forEach((line) => { + const parts = line.split(': '); + const key = parts.shift(); + const value = parts.join(': '); + if (key) headers.set(key.toLowerCase(), value); + }); + + // Create response object, api-blob sends back text and api.ts will turn it into json if necessary + const response = new Response(xhr.response as string, { + status: xhr.status, + statusText: xhr.statusText, + headers, + }) as unknown as UndiciResponse; + + resolve(response); + }; + + // Handle network errors + xhr.onerror = () => { + reject(new TypeError('Network request failed')); + }; + + // Handle timeouts + xhr.ontimeout = () => { + reject(new TypeError('Network request timed out')); + }; + + // Handle aborts + xhr.onabort = () => { + reject(new DOMException('The user aborted a request.', 'AbortError')); + }; + + // Set headers + if (init.headers) { + const headers = new Headers(init.headers as HeadersInit); + headers.forEach((value, key) => { + xhr.setRequestHeader(key, value); + }); + } + + // Handle abort signal + if (init.signal) { + init.signal.addEventListener('abort', () => { + xhr.abort(); + }); + + // If already aborted, abort xhr immediately + if (init.signal.aborted) { + xhr.abort(); + return; + } + } + + // We're cheating and saying that nobody is gonna use put() with a stream in an environment not supporting + // fetch with streams. If this ever happens please open an issue and we'll figure it out. + xhr.send(body); + }); +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1902c252e..a2747aa74 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,7 +25,7 @@ importers: version: 9.1.6 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@22.7.3) + version: 29.7.0 lint-staged: specifier: 15.2.10 version: 15.2.10 @@ -37,7 +37,7 @@ importers: version: 0.2.11 ts-jest: specifier: 29.2.5 - version: 29.2.5(@babel/core@7.25.8)(esbuild@0.23.1)(jest@29.7.0)(typescript@5.6.2) + version: 29.2.5(@babel/core@7.26.0)(jest@29.7.0)(typescript@5.6.2) turbo: specifier: 1.12.4 version: 1.12.4 @@ -56,6 +56,12 @@ importers: is-buffer: specifier: ^2.0.5 version: 2.0.5 + is-node-process: + specifier: ^1.2.0 + version: 1.2.0 + throttleit: + specifier: ^2.1.0 + version: 2.1.0 undici: specifier: ^5.28.4 version: 5.28.4 @@ -67,17 +73,17 @@ importers: specifier: 2.2.9 version: 2.2.9 '@types/async-retry': - specifier: 1.4.8 - version: 1.4.8 + specifier: 1.4.9 + version: 1.4.9 '@types/bytes': specifier: 3.1.4 version: 3.1.4 '@types/jest': - specifier: 29.5.13 - version: 29.5.13 + specifier: 29.5.14 + version: 29.5.14 '@types/node': - specifier: 22.7.3 - version: 22.7.3 + specifier: 22.9.0 + version: 22.9.0 eslint: specifier: 8.56.0 version: 8.56.0 @@ -86,19 +92,19 @@ importers: version: link:../../tooling/eslint-config-custom jest: specifier: 29.7.0 - version: 29.7.0(@types/node@22.7.3) + version: 29.7.0(@types/node@22.9.0) jest-environment-jsdom: specifier: 29.7.0 version: 29.7.0 ts-jest: specifier: 29.2.5 - version: 29.2.5(@babel/core@7.23.2)(esbuild@0.23.1)(jest@29.7.0)(typescript@5.6.3) + version: 29.2.5(@babel/core@7.26.0)(esbuild@0.24.0)(jest@29.7.0)(typescript@5.6.3) tsconfig: specifier: workspace:* version: link:../../tooling/tsconfig tsup: - specifier: 8.3.0 - version: 8.3.0(typescript@5.6.3) + specifier: 8.3.5 + version: 8.3.5(typescript@5.6.3) packages/edge-config: dependencies: @@ -144,7 +150,7 @@ importers: version: 3.3.3 ts-jest: specifier: 29.2.5 - version: 29.2.5(@babel/core@7.25.8)(esbuild@0.23.1)(jest@29.7.0)(typescript@5.6.2) + version: 29.2.5(@babel/core@7.26.0)(esbuild@0.23.1)(jest@29.7.0)(typescript@5.6.2) tsconfig: specifier: workspace:* version: link:../../tooling/tsconfig @@ -198,7 +204,7 @@ importers: version: 3.3.3 ts-jest: specifier: 29.2.5 - version: 29.2.5(@babel/core@7.25.8)(esbuild@0.23.1)(jest@29.7.0)(typescript@5.6.2) + version: 29.2.5(@babel/core@7.26.0)(esbuild@0.23.1)(jest@29.7.0)(typescript@5.6.2) tsconfig: specifier: workspace:* version: link:../../tooling/tsconfig @@ -253,7 +259,7 @@ importers: version: 3.3.3 ts-jest: specifier: 29.2.5 - version: 29.2.5(@babel/core@7.25.8)(esbuild@0.23.1)(jest@29.7.0)(typescript@5.6.2) + version: 29.2.5(@babel/core@7.26.0)(esbuild@0.23.1)(jest@29.7.0)(typescript@5.6.2) tsconfig: specifier: workspace:* version: link:../../tooling/tsconfig @@ -305,7 +311,7 @@ importers: version: 0.27.4 ts-jest: specifier: 29.2.5 - version: 29.2.5(@babel/core@7.25.8)(esbuild@0.23.1)(jest@29.7.0)(typescript@5.6.2) + version: 29.2.5(@babel/core@7.26.0)(esbuild@0.23.1)(jest@29.7.0)(typescript@5.6.2) tsconfig: specifier: workspace:* version: link:../../tooling/tsconfig @@ -319,17 +325,17 @@ importers: test/next: dependencies: '@tailwindcss/forms': - specifier: 0.5.7 - version: 0.5.7(tailwindcss@3.3.6) + specifier: 0.5.9 + version: 0.5.9(tailwindcss@3.4.14) '@types/node': - specifier: 22.5.4 - version: 22.5.4 + specifier: 22.9.0 + version: 22.9.0 '@types/react': - specifier: 18.2.42 - version: 18.2.42 + specifier: 18.3.12 + version: 18.3.12 '@types/react-dom': - specifier: 18.2.17 - version: 18.2.17 + specifier: 18.3.1 + version: 18.3.1 '@vercel/blob': specifier: workspace:* version: link:../../packages/blob @@ -344,22 +350,22 @@ importers: version: link:../../packages/postgres-kysely '@vercel/style-guide': specifier: 5.2.0 - version: 5.2.0(eslint@8.56.0)(jest@29.7.0)(prettier@3.3.3)(typescript@5.6.2) + version: 5.2.0(eslint@8.56.0)(jest@29.7.0)(prettier@3.3.3)(typescript@5.6.3) autoprefixer: - specifier: 10.4.16 - version: 10.4.16(postcss@8.4.32) + specifier: 10.4.20 + version: 10.4.20(postcss@8.4.47) axios: - specifier: 1.6.2 - version: 1.6.2 + specifier: 1.7.7 + version: 1.7.7 dotenv: - specifier: 16.3.1 - version: 16.3.1 + specifier: 16.4.5 + version: 16.4.5 eslint: specifier: 8.56.0 version: 8.56.0 eslint-config-next: - specifier: 14.0.4 - version: 14.0.4(eslint@8.56.0)(typescript@5.6.2) + specifier: 14.2.15 + version: 14.2.15(eslint@8.56.0)(typescript@5.6.3) got: specifier: 13.0.0 version: 13.0.0 @@ -370,39 +376,39 @@ importers: specifier: 2.1.3 version: 2.1.3 next: - specifier: 14.0.4 - version: 14.0.4(@babel/core@7.23.9)(react-dom@18.2.0)(react@18.2.0) + specifier: 14.2.15 + version: 14.2.15(@babel/core@7.23.9)(@playwright/test@1.48.2)(react-dom@18.3.1)(react@18.3.1) postcss: - specifier: 8.4.32 - version: 8.4.32 + specifier: 8.4.47 + version: 8.4.47 react: - specifier: 18.2.0 - version: 18.2.0 + specifier: 18.3.1 + version: 18.3.1 react-dom: - specifier: 18.2.0 - version: 18.2.0(react@18.2.0) + specifier: 18.3.1 + version: 18.3.1(react@18.3.1) swr: - specifier: 2.2.4 - version: 2.2.4(react@18.2.0) + specifier: 2.2.5 + version: 2.2.5(react@18.3.1) tailwindcss: - specifier: 3.3.6 - version: 3.3.6(ts-node@10.9.1) + specifier: 3.4.14 + version: 3.4.14(ts-node@10.9.2) ts-node: - specifier: 10.9.1 - version: 10.9.1(@types/node@22.5.4)(typescript@5.6.2) + specifier: 10.9.2 + version: 10.9.2(@types/node@22.9.0)(typescript@5.6.3) typescript: - specifier: 5.6.2 - version: 5.6.2 + specifier: 5.6.3 + version: 5.6.3 undici: - specifier: 5.28.2 - version: 5.28.2 + specifier: 6.20.1 + version: 6.20.1 devDependencies: '@playwright/test': - specifier: 1.48.0 - version: 1.48.0 + specifier: 1.48.2 + version: 1.48.2 '@types/json-stable-stringify': - specifier: 1.0.36 - version: 1.0.36 + specifier: 1.1.0 + version: 1.1.0 json-stable-stringify: specifier: 1.1.1 version: 1.1.1 @@ -481,20 +487,21 @@ packages: '@babel/highlight': 7.23.4 chalk: 2.4.2 - /@babel/code-frame@7.25.7: - resolution: {integrity: sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==} + /@babel/code-frame@7.26.2: + resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/highlight': 7.25.7 - picocolors: 1.1.0 + '@babel/helper-validator-identifier': 7.25.9 + js-tokens: 4.0.0 + picocolors: 1.1.1 dev: true /@babel/compat-data@7.23.5: resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==} engines: {node: '>=6.9.0'} - /@babel/compat-data@7.25.8: - resolution: {integrity: sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==} + /@babel/compat-data@7.26.2: + resolution: {integrity: sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==} engines: {node: '>=6.9.0'} dev: true @@ -542,20 +549,20 @@ packages: transitivePeerDependencies: - supports-color - /@babel/core@7.25.8: - resolution: {integrity: sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg==} + /@babel/core@7.26.0: + resolution: {integrity: sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==} engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.25.7 - '@babel/generator': 7.25.7 - '@babel/helper-compilation-targets': 7.25.7 - '@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.8) - '@babel/helpers': 7.25.7 - '@babel/parser': 7.25.8 - '@babel/template': 7.25.7 - '@babel/traverse': 7.25.7 - '@babel/types': 7.25.8 + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.2 + '@babel/helper-compilation-targets': 7.25.9 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) + '@babel/helpers': 7.26.0 + '@babel/parser': 7.26.2 + '@babel/template': 7.25.9 + '@babel/traverse': 7.25.9 + '@babel/types': 7.26.0 convert-source-map: 2.0.0 debug: 4.3.7 gensync: 1.0.0-beta.2 @@ -584,7 +591,7 @@ packages: dependencies: '@babel/types': 7.22.11 '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.18 + '@jridgewell/trace-mapping': 0.3.25 jsesc: 2.5.2 /@babel/generator@7.23.6: @@ -596,11 +603,12 @@ packages: '@jridgewell/trace-mapping': 0.3.22 jsesc: 2.5.2 - /@babel/generator@7.25.7: - resolution: {integrity: sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==} + /@babel/generator@7.26.2: + resolution: {integrity: sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.25.8 + '@babel/parser': 7.26.2 + '@babel/types': 7.26.0 '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 jsesc: 3.0.2 @@ -616,13 +624,13 @@ packages: lru-cache: 5.1.1 semver: 6.3.1 - /@babel/helper-compilation-targets@7.25.7: - resolution: {integrity: sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==} + /@babel/helper-compilation-targets@7.25.9: + resolution: {integrity: sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/compat-data': 7.25.8 - '@babel/helper-validator-option': 7.25.7 - browserslist: 4.24.0 + '@babel/compat-data': 7.26.2 + '@babel/helper-validator-option': 7.25.9 + browserslist: 4.24.2 lru-cache: 5.1.1 semver: 6.3.1 dev: true @@ -650,12 +658,12 @@ packages: dependencies: '@babel/types': 7.23.9 - /@babel/helper-module-imports@7.25.7: - resolution: {integrity: sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==} + /@babel/helper-module-imports@7.25.9: + resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/traverse': 7.25.7 - '@babel/types': 7.25.8 + '@babel/traverse': 7.25.9 + '@babel/types': 7.26.0 transitivePeerDependencies: - supports-color dev: true @@ -686,17 +694,16 @@ packages: '@babel/helper-split-export-declaration': 7.22.6 '@babel/helper-validator-identifier': 7.22.20 - /@babel/helper-module-transforms@7.25.7(@babel/core@7.25.8): - resolution: {integrity: sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==} + /@babel/helper-module-transforms@7.26.0(@babel/core@7.26.0): + resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.25.8 - '@babel/helper-module-imports': 7.25.7 - '@babel/helper-simple-access': 7.25.7 - '@babel/helper-validator-identifier': 7.25.7 - '@babel/traverse': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + '@babel/traverse': 7.25.9 transitivePeerDependencies: - supports-color dev: true @@ -711,16 +718,6 @@ packages: dependencies: '@babel/types': 7.23.9 - /@babel/helper-simple-access@7.25.7: - resolution: {integrity: sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/traverse': 7.25.7 - '@babel/types': 7.25.8 - transitivePeerDependencies: - - supports-color - dev: true - /@babel/helper-split-export-declaration@7.22.6: resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} engines: {node: '>=6.9.0'} @@ -735,8 +732,8 @@ packages: resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} engines: {node: '>=6.9.0'} - /@babel/helper-string-parser@7.25.7: - resolution: {integrity: sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==} + /@babel/helper-string-parser@7.25.9: + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} engines: {node: '>=6.9.0'} dev: true @@ -744,8 +741,8 @@ packages: resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} engines: {node: '>=6.9.0'} - /@babel/helper-validator-identifier@7.25.7: - resolution: {integrity: sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==} + /@babel/helper-validator-identifier@7.25.9: + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} engines: {node: '>=6.9.0'} dev: true @@ -753,8 +750,8 @@ packages: resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} engines: {node: '>=6.9.0'} - /@babel/helper-validator-option@7.25.7: - resolution: {integrity: sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==} + /@babel/helper-validator-option@7.25.9: + resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} engines: {node: '>=6.9.0'} dev: true @@ -768,12 +765,12 @@ packages: transitivePeerDependencies: - supports-color - /@babel/helpers@7.25.7: - resolution: {integrity: sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==} + /@babel/helpers@7.26.0: + resolution: {integrity: sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/template': 7.25.7 - '@babel/types': 7.25.8 + '@babel/template': 7.25.9 + '@babel/types': 7.26.0 dev: true /@babel/highlight@7.22.13: @@ -792,16 +789,6 @@ packages: chalk: 2.4.2 js-tokens: 4.0.0 - /@babel/highlight@7.25.7: - resolution: {integrity: sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-validator-identifier': 7.25.7 - chalk: 2.4.2 - js-tokens: 4.0.0 - picocolors: 1.1.0 - dev: true - /@babel/parser@7.23.9: resolution: {integrity: sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==} engines: {node: '>=6.0.0'} @@ -809,12 +796,12 @@ packages: dependencies: '@babel/types': 7.23.9 - /@babel/parser@7.25.8: - resolution: {integrity: sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==} + /@babel/parser@7.26.2: + resolution: {integrity: sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==} engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.25.8 + '@babel/types': 7.26.0 dev: true /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.23.2): @@ -946,13 +933,13 @@ packages: '@babel/parser': 7.23.9 '@babel/types': 7.23.9 - /@babel/template@7.25.7: - resolution: {integrity: sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==} + /@babel/template@7.25.9: + resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.25.7 - '@babel/parser': 7.25.8 - '@babel/types': 7.25.8 + '@babel/code-frame': 7.26.2 + '@babel/parser': 7.26.2 + '@babel/types': 7.26.0 dev: true /@babel/traverse@7.23.9: @@ -972,15 +959,15 @@ packages: transitivePeerDependencies: - supports-color - /@babel/traverse@7.25.7: - resolution: {integrity: sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==} + /@babel/traverse@7.25.9: + resolution: {integrity: sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.25.7 - '@babel/generator': 7.25.7 - '@babel/parser': 7.25.8 - '@babel/template': 7.25.7 - '@babel/types': 7.25.8 + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.2 + '@babel/parser': 7.26.2 + '@babel/template': 7.25.9 + '@babel/types': 7.26.0 debug: 4.3.7 globals: 11.12.0 transitivePeerDependencies: @@ -1003,13 +990,12 @@ packages: '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 - /@babel/types@7.25.8: - resolution: {integrity: sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==} + /@babel/types@7.26.0: + resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-string-parser': 7.25.7 - '@babel/helper-validator-identifier': 7.25.7 - to-fast-properties: 2.0.0 + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 dev: true /@bcoe/v8-coverage@0.2.3: @@ -1240,6 +1226,15 @@ packages: dev: true optional: true + /@esbuild/aix-ppc64@0.24.0: + resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-arm64@0.23.1: resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==} engines: {node: '>=18'} @@ -1249,6 +1244,15 @@ packages: dev: true optional: true + /@esbuild/android-arm64@0.24.0: + resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-arm@0.23.1: resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==} engines: {node: '>=18'} @@ -1258,6 +1262,15 @@ packages: dev: true optional: true + /@esbuild/android-arm@0.24.0: + resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-x64@0.23.1: resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==} engines: {node: '>=18'} @@ -1267,6 +1280,15 @@ packages: dev: true optional: true + /@esbuild/android-x64@0.24.0: + resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/darwin-arm64@0.23.1: resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==} engines: {node: '>=18'} @@ -1276,6 +1298,15 @@ packages: dev: true optional: true + /@esbuild/darwin-arm64@0.24.0: + resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@esbuild/darwin-x64@0.23.1: resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==} engines: {node: '>=18'} @@ -1285,6 +1316,15 @@ packages: dev: true optional: true + /@esbuild/darwin-x64@0.24.0: + resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@esbuild/freebsd-arm64@0.23.1: resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==} engines: {node: '>=18'} @@ -1294,6 +1334,15 @@ packages: dev: true optional: true + /@esbuild/freebsd-arm64@0.24.0: + resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/freebsd-x64@0.23.1: resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==} engines: {node: '>=18'} @@ -1303,6 +1352,15 @@ packages: dev: true optional: true + /@esbuild/freebsd-x64@0.24.0: + resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-arm64@0.23.1: resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==} engines: {node: '>=18'} @@ -1312,6 +1370,15 @@ packages: dev: true optional: true + /@esbuild/linux-arm64@0.24.0: + resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-arm@0.23.1: resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==} engines: {node: '>=18'} @@ -1321,6 +1388,15 @@ packages: dev: true optional: true + /@esbuild/linux-arm@0.24.0: + resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-ia32@0.23.1: resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==} engines: {node: '>=18'} @@ -1330,6 +1406,15 @@ packages: dev: true optional: true + /@esbuild/linux-ia32@0.24.0: + resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-loong64@0.23.1: resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==} engines: {node: '>=18'} @@ -1339,6 +1424,15 @@ packages: dev: true optional: true + /@esbuild/linux-loong64@0.24.0: + resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-mips64el@0.23.1: resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==} engines: {node: '>=18'} @@ -1348,6 +1442,15 @@ packages: dev: true optional: true + /@esbuild/linux-mips64el@0.24.0: + resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-ppc64@0.23.1: resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==} engines: {node: '>=18'} @@ -1357,6 +1460,15 @@ packages: dev: true optional: true + /@esbuild/linux-ppc64@0.24.0: + resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-riscv64@0.23.1: resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==} engines: {node: '>=18'} @@ -1366,6 +1478,15 @@ packages: dev: true optional: true + /@esbuild/linux-riscv64@0.24.0: + resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-s390x@0.23.1: resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==} engines: {node: '>=18'} @@ -1375,6 +1496,15 @@ packages: dev: true optional: true + /@esbuild/linux-s390x@0.24.0: + resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-x64@0.23.1: resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==} engines: {node: '>=18'} @@ -1384,6 +1514,15 @@ packages: dev: true optional: true + /@esbuild/linux-x64@0.24.0: + resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/netbsd-x64@0.23.1: resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==} engines: {node: '>=18'} @@ -1393,6 +1532,15 @@ packages: dev: true optional: true + /@esbuild/netbsd-x64@0.24.0: + resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/openbsd-arm64@0.23.1: resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==} engines: {node: '>=18'} @@ -1402,6 +1550,15 @@ packages: dev: true optional: true + /@esbuild/openbsd-arm64@0.24.0: + resolution: {integrity: sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/openbsd-x64@0.23.1: resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==} engines: {node: '>=18'} @@ -1411,6 +1568,15 @@ packages: dev: true optional: true + /@esbuild/openbsd-x64@0.24.0: + resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/sunos-x64@0.23.1: resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==} engines: {node: '>=18'} @@ -1420,6 +1586,15 @@ packages: dev: true optional: true + /@esbuild/sunos-x64@0.24.0: + resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-arm64@0.23.1: resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==} engines: {node: '>=18'} @@ -1429,6 +1604,15 @@ packages: dev: true optional: true + /@esbuild/win32-arm64@0.24.0: + resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-ia32@0.23.1: resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==} engines: {node: '>=18'} @@ -1438,6 +1622,15 @@ packages: dev: true optional: true + /@esbuild/win32-ia32@0.24.0: + resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-x64@0.23.1: resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==} engines: {node: '>=18'} @@ -1447,6 +1640,15 @@ packages: dev: true optional: true + /@esbuild/win32-x64@0.24.0: + resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@eslint-community/eslint-utils@4.4.0(eslint@8.56.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1480,8 +1682,8 @@ packages: resolution: {integrity: sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - /@fastify/busboy@2.1.0: - resolution: {integrity: sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==} + /@fastify/busboy@2.1.1: + resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} engines: {node: '>=14'} dev: false @@ -1512,7 +1714,6 @@ packages: strip-ansi-cjs: /strip-ansi@6.0.1 wrap-ansi: 8.1.0 wrap-ansi-cjs: /wrap-ansi@7.0.0 - dev: true /@istanbuljs/load-nyc-config@1.1.0: resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} @@ -1533,7 +1734,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 22.7.3 + '@types/node': 22.9.0 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -1553,14 +1754,14 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.7.3 + '@types/node': 22.9.0 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@22.7.3) + jest-config: 29.7.0(@types/node@22.9.0) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -1587,7 +1788,7 @@ packages: dependencies: '@jest/fake-timers': 29.5.0 '@jest/types': 29.6.3 - '@types/node': 22.7.3 + '@types/node': 22.9.0 jest-mock: 29.5.0 dev: true @@ -1597,7 +1798,7 @@ packages: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.7.3 + '@types/node': 22.9.0 jest-mock: 29.7.0 /@jest/expect-utils@29.7.0: @@ -1621,7 +1822,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 22.7.3 + '@types/node': 22.9.0 jest-message-util: 29.7.0 jest-mock: 29.5.0 jest-util: 29.5.0 @@ -1633,7 +1834,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.0.2 - '@types/node': 22.7.3 + '@types/node': 22.9.0 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -1664,7 +1865,7 @@ packages: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.18 - '@types/node': 22.7.3 + '@types/node': 22.9.0 chalk: 4.1.2 collect-v8-coverage: 1.0.1 exit: 0.1.2 @@ -1695,7 +1896,7 @@ packages: resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jridgewell/trace-mapping': 0.3.18 + '@jridgewell/trace-mapping': 0.3.25 callsites: 3.1.0 graceful-fs: 4.2.11 @@ -1746,7 +1947,7 @@ packages: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 22.7.3 + '@types/node': 22.9.0 '@types/yargs': 17.0.24 chalk: 4.1.2 @@ -1765,7 +1966,6 @@ packages: '@jridgewell/set-array': 1.2.1 '@jridgewell/sourcemap-codec': 1.5.0 '@jridgewell/trace-mapping': 0.3.25 - dev: true /@jridgewell/resolve-uri@3.1.0: resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} @@ -1782,7 +1982,6 @@ packages: /@jridgewell/set-array@1.2.1: resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} engines: {node: '>=6.0.0'} - dev: true /@jridgewell/sourcemap-codec@1.4.14: resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} @@ -1792,7 +1991,6 @@ packages: /@jridgewell/sourcemap-codec@1.5.0: resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - dev: true /@jridgewell/trace-mapping@0.3.18: resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==} @@ -1811,13 +2009,12 @@ packages: dependencies: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 - dev: true /@jridgewell/trace-mapping@0.3.9: resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} dependencies: - '@jridgewell/resolve-uri': 3.1.0 - '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 dev: false /@manypkg/find-root@1.1.0: @@ -1863,18 +2060,18 @@ packages: '@types/pg': 8.11.6 dev: true - /@next/env@14.0.4: - resolution: {integrity: sha512-irQnbMLbUNQpP1wcE5NstJtbuA/69kRfzBrpAD7Gsn8zm/CY6YQYc3HQBz8QPxwISG26tIm5afvvVbu508oBeQ==} + /@next/env@14.2.15: + resolution: {integrity: sha512-S1qaj25Wru2dUpcIZMjxeMVSwkt8BK4dmWHHiBuRstcIyOsMapqT4A4jSB6onvqeygkSSmOkyny9VVx8JIGamQ==} dev: false - /@next/eslint-plugin-next@14.0.4: - resolution: {integrity: sha512-U3qMNHmEZoVmHA0j/57nRfi3AscXNvkOnxDmle/69Jz/G0o/gWjXTDdlgILZdrxQ0Lw/jv2mPW8PGy0EGIHXhQ==} + /@next/eslint-plugin-next@14.2.15: + resolution: {integrity: sha512-pKU0iqKRBlFB/ocOI1Ip2CkKePZpYpnw5bEItEkuZ/Nr9FQP1+p7VDWr4VfOdff4i9bFmrOaeaU1bFEyAcxiMQ==} dependencies: - glob: 7.1.7 + glob: 10.3.10 dev: false - /@next/swc-darwin-arm64@14.0.4: - resolution: {integrity: sha512-mF05E/5uPthWzyYDyptcwHptucf/jj09i2SXBPwNzbgBNc+XnwzrL0U6BmPjQeOL+FiB+iG1gwBeq7mlDjSRPg==} + /@next/swc-darwin-arm64@14.2.15: + resolution: {integrity: sha512-Rvh7KU9hOUBnZ9TJ28n2Oa7dD9cvDBKua9IKx7cfQQ0GoYUwg9ig31O2oMwH3wm+pE3IkAQ67ZobPfEgurPZIA==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] @@ -1882,8 +2079,8 @@ packages: dev: false optional: true - /@next/swc-darwin-x64@14.0.4: - resolution: {integrity: sha512-IZQ3C7Bx0k2rYtrZZxKKiusMTM9WWcK5ajyhOZkYYTCc8xytmwSzR1skU7qLgVT/EY9xtXDG0WhY6fyujnI3rw==} + /@next/swc-darwin-x64@14.2.15: + resolution: {integrity: sha512-5TGyjFcf8ampZP3e+FyCax5zFVHi+Oe7sZyaKOngsqyaNEpOgkKB3sqmymkZfowy3ufGA/tUgDPPxpQx931lHg==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] @@ -1891,8 +2088,8 @@ packages: dev: false optional: true - /@next/swc-linux-arm64-gnu@14.0.4: - resolution: {integrity: sha512-VwwZKrBQo/MGb1VOrxJ6LrKvbpo7UbROuyMRvQKTFKhNaXjUmKTu7wxVkIuCARAfiI8JpaWAnKR+D6tzpCcM4w==} + /@next/swc-linux-arm64-gnu@14.2.15: + resolution: {integrity: sha512-3Bwv4oc08ONiQ3FiOLKT72Q+ndEMyLNsc/D3qnLMbtUYTQAmkx9E/JRu0DBpHxNddBmNT5hxz1mYBphJ3mfrrw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -1900,8 +2097,8 @@ packages: dev: false optional: true - /@next/swc-linux-arm64-musl@14.0.4: - resolution: {integrity: sha512-8QftwPEW37XxXoAwsn+nXlodKWHfpMaSvt81W43Wh8dv0gkheD+30ezWMcFGHLI71KiWmHK5PSQbTQGUiidvLQ==} + /@next/swc-linux-arm64-musl@14.2.15: + resolution: {integrity: sha512-k5xf/tg1FBv/M4CMd8S+JL3uV9BnnRmoe7F+GWC3DxkTCD9aewFRH1s5rJ1zkzDa+Do4zyN8qD0N8c84Hu96FQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -1909,8 +2106,8 @@ packages: dev: false optional: true - /@next/swc-linux-x64-gnu@14.0.4: - resolution: {integrity: sha512-/s/Pme3VKfZAfISlYVq2hzFS8AcAIOTnoKupc/j4WlvF6GQ0VouS2Q2KEgPuO1eMBwakWPB1aYFIA4VNVh667A==} + /@next/swc-linux-x64-gnu@14.2.15: + resolution: {integrity: sha512-kE6q38hbrRbKEkkVn62reLXhThLRh6/TvgSP56GkFNhU22TbIrQDEMrO7j0IcQHcew2wfykq8lZyHFabz0oBrA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -1918,8 +2115,8 @@ packages: dev: false optional: true - /@next/swc-linux-x64-musl@14.0.4: - resolution: {integrity: sha512-m8z/6Fyal4L9Bnlxde5g2Mfa1Z7dasMQyhEhskDATpqr+Y0mjOBZcXQ7G5U+vgL22cI4T7MfvgtrM2jdopqWaw==} + /@next/swc-linux-x64-musl@14.2.15: + resolution: {integrity: sha512-PZ5YE9ouy/IdO7QVJeIcyLn/Rc4ml9M2G4y3kCM9MNf1YKvFY4heg3pVa/jQbMro+tP6yc4G2o9LjAz1zxD7tQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -1927,8 +2124,8 @@ packages: dev: false optional: true - /@next/swc-win32-arm64-msvc@14.0.4: - resolution: {integrity: sha512-7Wv4PRiWIAWbm5XrGz3D8HUkCVDMMz9igffZG4NB1p4u1KoItwx9qjATHz88kwCEal/HXmbShucaslXCQXUM5w==} + /@next/swc-win32-arm64-msvc@14.2.15: + resolution: {integrity: sha512-2raR16703kBvYEQD9HNLyb0/394yfqzmIeyp2nDzcPV4yPjqNUG3ohX6jX00WryXz6s1FXpVhsCo3i+g4RUX+g==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] @@ -1936,8 +2133,8 @@ packages: dev: false optional: true - /@next/swc-win32-ia32-msvc@14.0.4: - resolution: {integrity: sha512-zLeNEAPULsl0phfGb4kdzF/cAVIfaC7hY+kt0/d+y9mzcZHsMS3hAS829WbJ31DkSlVKQeHEjZHIdhN+Pg7Gyg==} + /@next/swc-win32-ia32-msvc@14.2.15: + resolution: {integrity: sha512-fyTE8cklgkyR1p03kJa5zXEaZ9El+kDNM5A+66+8evQS5e/6v0Gk28LqA0Jet8gKSOyP+OTm/tJHzMlGdQerdQ==} engines: {node: '>= 10'} cpu: [ia32] os: [win32] @@ -1945,8 +2142,8 @@ packages: dev: false optional: true - /@next/swc-win32-x64-msvc@14.0.4: - resolution: {integrity: sha512-yEh2+R8qDlDCjxVpzOTEpBLQTEFAcP2A8fUFLaWNap9GitYKkKv1//y2S6XY6zsR4rCOPRpU7plYDR+az2n30A==} + /@next/swc-win32-x64-msvc@14.2.15: + resolution: {integrity: sha512-SzqGbsLsP9OwKNUG9nekShTwhj6JSB9ZLMWQ8g1gG6hdE5gQLncbnbymrwy2yVmH9nikSLYRYxYMFu78Ggp7/g==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -1986,20 +2183,18 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} requiresBuild: true - dev: true optional: true /@pkgr/core@0.1.1: resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - /@playwright/test@1.48.0: - resolution: {integrity: sha512-W5lhqPUVPqhtc/ySvZI5Q8X2ztBOUgZ8LbAFy0JQgrXZs2xaILrUcNO3rQjwbLPfGK13+rZsDa1FpG+tqYkT5w==} + /@playwright/test@1.48.2: + resolution: {integrity: sha512-54w1xCWfXuax7dz4W2M9uw0gDyh+ti/0K/MxcCUxChFh37kkdxPdfZDw5QBbuPUJHr1CiHJ1hXgSs+GgeQc5Zw==} engines: {node: '>=18'} hasBin: true dependencies: - playwright: 1.48.0 - dev: true + playwright: 1.48.2 /@rollup/rollup-android-arm-eabi@4.21.3: resolution: {integrity: sha512-MmKSfaB9GX+zXl6E8z4koOr/xU63AMVleLEa64v7R0QF/ZloMs5vcD1sHgM64GXXS1csaJutG+ddtzcueI/BLg==} @@ -2009,6 +2204,14 @@ packages: dev: true optional: true + /@rollup/rollup-android-arm-eabi@4.24.4: + resolution: {integrity: sha512-jfUJrFct/hTA0XDM5p/htWKoNNTbDLY0KRwEt6pyOA6k2fmk0WVwl65PdUdJZgzGEHWx+49LilkcSaumQRyNQw==} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + /@rollup/rollup-android-arm64@4.21.3: resolution: {integrity: sha512-zrt8ecH07PE3sB4jPOggweBjJMzI1JG5xI2DIsUbkA+7K+Gkjys6eV7i9pOenNSDJH3eOr/jLb/PzqtmdwDq5g==} cpu: [arm64] @@ -2017,6 +2220,14 @@ packages: dev: true optional: true + /@rollup/rollup-android-arm64@4.24.4: + resolution: {integrity: sha512-j4nrEO6nHU1nZUuCfRKoCcvh7PIywQPUCBa2UsootTHvTHIoIu2BzueInGJhhvQO/2FTRdNYpf63xsgEqH9IhA==} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + /@rollup/rollup-darwin-arm64@4.21.3: resolution: {integrity: sha512-P0UxIOrKNBFTQaXTxOH4RxuEBVCgEA5UTNV6Yz7z9QHnUJ7eLX9reOd/NYMO3+XZO2cco19mXTxDMXxit4R/eQ==} cpu: [arm64] @@ -2025,6 +2236,14 @@ packages: dev: true optional: true + /@rollup/rollup-darwin-arm64@4.24.4: + resolution: {integrity: sha512-GmU/QgGtBTeraKyldC7cDVVvAJEOr3dFLKneez/n7BvX57UdhOqDsVwzU7UOnYA7AAOt+Xb26lk79PldDHgMIQ==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@rollup/rollup-darwin-x64@4.21.3: resolution: {integrity: sha512-L1M0vKGO5ASKntqtsFEjTq/fD91vAqnzeaF6sfNAy55aD+Hi2pBI5DKwCO+UNDQHWsDViJLqshxOahXyLSh3EA==} cpu: [x64] @@ -2033,26 +2252,74 @@ packages: dev: true optional: true - /@rollup/rollup-linux-arm-gnueabihf@4.21.3: - resolution: {integrity: sha512-btVgIsCjuYFKUjopPoWiDqmoUXQDiW2A4C3Mtmp5vACm7/GnyuprqIDPNczeyR5W8rTXEbkmrJux7cJmD99D2g==} - cpu: [arm] - os: [linux] + /@rollup/rollup-darwin-x64@4.24.4: + resolution: {integrity: sha512-N6oDBiZCBKlwYcsEPXGDE4g9RoxZLK6vT98M8111cW7VsVJFpNEqvJeIPfsCzbf0XEakPslh72X0gnlMi4Ddgg==} + cpu: [x64] + os: [darwin] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-arm-musleabihf@4.21.3: - resolution: {integrity: sha512-zmjbSphplZlau6ZTkxd3+NMtE4UKVy7U4aVFMmHcgO5CUbw17ZP6QCgyxhzGaU/wFFdTfiojjbLG3/0p9HhAqA==} - cpu: [arm] - os: [linux] + /@rollup/rollup-freebsd-arm64@4.24.4: + resolution: {integrity: sha512-py5oNShCCjCyjWXCZNrRGRpjWsF0ic8f4ieBNra5buQz0O/U6mMXCpC1LvrHuhJsNPgRt36tSYMidGzZiJF6mw==} + cpu: [arm64] + os: [freebsd] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-arm64-gnu@4.21.3: - resolution: {integrity: sha512-nSZfcZtAnQPRZmUkUQwZq2OjQciR6tEoJaZVFvLHsj0MF6QhNMg0fQ6mUOsiCUpTqxTx0/O6gX0V/nYc7LrgPw==} - cpu: [arm64] - os: [linux] + /@rollup/rollup-freebsd-x64@4.24.4: + resolution: {integrity: sha512-L7VVVW9FCnTTp4i7KrmHeDsDvjB4++KOBENYtNYAiYl96jeBThFfhP6HVxL74v4SiZEVDH/1ILscR5U9S4ms4g==} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm-gnueabihf@4.21.3: + resolution: {integrity: sha512-btVgIsCjuYFKUjopPoWiDqmoUXQDiW2A4C3Mtmp5vACm7/GnyuprqIDPNczeyR5W8rTXEbkmrJux7cJmD99D2g==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm-gnueabihf@4.24.4: + resolution: {integrity: sha512-10ICosOwYChROdQoQo589N5idQIisxjaFE/PAnX2i0Zr84mY0k9zul1ArH0rnJ/fpgiqfu13TFZR5A5YJLOYZA==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm-musleabihf@4.21.3: + resolution: {integrity: sha512-zmjbSphplZlau6ZTkxd3+NMtE4UKVy7U4aVFMmHcgO5CUbw17ZP6QCgyxhzGaU/wFFdTfiojjbLG3/0p9HhAqA==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm-musleabihf@4.24.4: + resolution: {integrity: sha512-ySAfWs69LYC7QhRDZNKqNhz2UKN8LDfbKSMAEtoEI0jitwfAG2iZwVqGACJT+kfYvvz3/JgsLlcBP+WWoKCLcw==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm64-gnu@4.21.3: + resolution: {integrity: sha512-nSZfcZtAnQPRZmUkUQwZq2OjQciR6tEoJaZVFvLHsj0MF6QhNMg0fQ6mUOsiCUpTqxTx0/O6gX0V/nYc7LrgPw==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm64-gnu@4.24.4: + resolution: {integrity: sha512-uHYJ0HNOI6pGEeZ/5mgm5arNVTI0nLlmrbdph+pGXpC9tFHFDQmDMOEqkmUObRfosJqpU8RliYoGz06qSdtcjg==} + cpu: [arm64] + os: [linux] requiresBuild: true dev: true optional: true @@ -2065,6 +2332,14 @@ packages: dev: true optional: true + /@rollup/rollup-linux-arm64-musl@4.24.4: + resolution: {integrity: sha512-38yiWLemQf7aLHDgTg85fh3hW9stJ0Muk7+s6tIkSUOMmi4Xbv5pH/5Bofnsb6spIwD5FJiR+jg71f0CH5OzoA==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@rollup/rollup-linux-powerpc64le-gnu@4.21.3: resolution: {integrity: sha512-+W+p/9QNDr2vE2AXU0qIy0qQE75E8RTwTwgqS2G5CRQ11vzq0tbnfBd6brWhS9bCRjAjepJe2fvvkvS3dno+iw==} cpu: [ppc64] @@ -2073,6 +2348,14 @@ packages: dev: true optional: true + /@rollup/rollup-linux-powerpc64le-gnu@4.24.4: + resolution: {integrity: sha512-q73XUPnkwt9ZNF2xRS4fvneSuaHw2BXuV5rI4cw0fWYVIWIBeDZX7c7FWhFQPNTnE24172K30I+dViWRVD9TwA==} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@rollup/rollup-linux-riscv64-gnu@4.21.3: resolution: {integrity: sha512-yXH6K6KfqGXaxHrtr+Uoy+JpNlUlI46BKVyonGiaD74ravdnF9BUNC+vV+SIuB96hUMGShhKV693rF9QDfO6nQ==} cpu: [riscv64] @@ -2081,6 +2364,14 @@ packages: dev: true optional: true + /@rollup/rollup-linux-riscv64-gnu@4.24.4: + resolution: {integrity: sha512-Aie/TbmQi6UXokJqDZdmTJuZBCU3QBDA8oTKRGtd4ABi/nHgXICulfg1KI6n9/koDsiDbvHAiQO3YAUNa/7BCw==} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@rollup/rollup-linux-s390x-gnu@4.21.3: resolution: {integrity: sha512-R8cwY9wcnApN/KDYWTH4gV/ypvy9yZUHlbJvfaiXSB48JO3KpwSpjOGqO4jnGkLDSk1hgjYkTbTt6Q7uvPf8eg==} cpu: [s390x] @@ -2089,6 +2380,14 @@ packages: dev: true optional: true + /@rollup/rollup-linux-s390x-gnu@4.24.4: + resolution: {integrity: sha512-P8MPErVO/y8ohWSP9JY7lLQ8+YMHfTI4bAdtCi3pC2hTeqFJco2jYspzOzTUB8hwUWIIu1xwOrJE11nP+0JFAQ==} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@rollup/rollup-linux-x64-gnu@4.21.3: resolution: {integrity: sha512-kZPbX/NOPh0vhS5sI+dR8L1bU2cSO9FgxwM8r7wHzGydzfSjLRCFAT87GR5U9scj2rhzN3JPYVC7NoBbl4FZ0g==} cpu: [x64] @@ -2097,6 +2396,14 @@ packages: dev: true optional: true + /@rollup/rollup-linux-x64-gnu@4.24.4: + resolution: {integrity: sha512-K03TljaaoPK5FOyNMZAAEmhlyO49LaE4qCsr0lYHUKyb6QacTNF9pnfPpXnFlFD3TXuFbFbz7tJ51FujUXkXYA==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@rollup/rollup-linux-x64-musl@4.21.3: resolution: {integrity: sha512-S0Yq+xA1VEH66uiMNhijsWAafffydd2X5b77eLHfRmfLsRSpbiAWiRHV6DEpz6aOToPsgid7TI9rGd6zB1rhbg==} cpu: [x64] @@ -2105,6 +2412,14 @@ packages: dev: true optional: true + /@rollup/rollup-linux-x64-musl@4.24.4: + resolution: {integrity: sha512-VJYl4xSl/wqG2D5xTYncVWW+26ICV4wubwN9Gs5NrqhJtayikwCXzPL8GDsLnaLU3WwhQ8W02IinYSFJfyo34Q==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@rollup/rollup-win32-arm64-msvc@4.21.3: resolution: {integrity: sha512-9isNzeL34yquCPyerog+IMCNxKR8XYmGd0tHSV+OVx0TmE0aJOo9uw4fZfUuk2qxobP5sug6vNdZR6u7Mw7Q+Q==} cpu: [arm64] @@ -2113,6 +2428,14 @@ packages: dev: true optional: true + /@rollup/rollup-win32-arm64-msvc@4.24.4: + resolution: {integrity: sha512-ku2GvtPwQfCqoPFIJCqZ8o7bJcj+Y54cZSr43hHca6jLwAiCbZdBUOrqE6y29QFajNAzzpIOwsckaTFmN6/8TA==} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@rollup/rollup-win32-ia32-msvc@4.21.3: resolution: {integrity: sha512-nMIdKnfZfzn1Vsk+RuOvl43ONTZXoAPUUxgcU0tXooqg4YrAqzfKzVenqqk2g5efWh46/D28cKFrOzDSW28gTA==} cpu: [ia32] @@ -2121,6 +2444,14 @@ packages: dev: true optional: true + /@rollup/rollup-win32-ia32-msvc@4.24.4: + resolution: {integrity: sha512-V3nCe+eTt/W6UYNr/wGvO1fLpHUrnlirlypZfKCT1fG6hWfqhPgQV/K/mRBXBpxc0eKLIF18pIOFVPh0mqHjlg==} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@rollup/rollup-win32-x64-msvc@4.21.3: resolution: {integrity: sha512-fOvu7PCQjAj4eWDEuD8Xz5gpzFqXzGlxHZozHP4b9Jxv9APtdxL6STqztDzMLuRXEc4UpXGGhx029Xgm91QBeA==} cpu: [x64] @@ -2129,9 +2460,13 @@ packages: dev: true optional: true - /@rushstack/eslint-patch@1.6.0: - resolution: {integrity: sha512-2/U3GXA6YiPYQDLGwtGlnNgKYBSwCFIHf8Y9LUY5VATHdtbLlU0Y1R3QoBnT0aB4qv/BEiVVsj7LJXoQCgJ2vA==} - dev: false + /@rollup/rollup-win32-x64-msvc@4.24.4: + resolution: {integrity: sha512-LTw1Dfd0mBIEqUVCxbvTE/LLo+9ZxVC9k99v1v4ahg9Aak6FpqOfNu5kRkeTAn0wphoC4JU7No1/rL+bBCEwhg==} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true /@rushstack/eslint-patch@1.7.2: resolution: {integrity: sha512-RbhOOTCNoCrbfkRyoXODZp75MlpiHMgbE5MEBZAnnnLyQNgrigEj4p0lzsMDyc1zVsJDLrivB58tgg3emX0eEA==} @@ -2166,9 +2501,14 @@ packages: '@sinonjs/commons': 3.0.1 dev: true - /@swc/helpers@0.5.2: - resolution: {integrity: sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==} + /@swc/counter@0.1.3: + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + dev: false + + /@swc/helpers@0.5.5: + resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==} dependencies: + '@swc/counter': 0.1.3 tslib: 2.6.2 dev: false @@ -2179,13 +2519,13 @@ packages: defer-to-connect: 2.0.1 dev: false - /@tailwindcss/forms@0.5.7(tailwindcss@3.3.6): - resolution: {integrity: sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==} + /@tailwindcss/forms@0.5.9(tailwindcss@3.4.14): + resolution: {integrity: sha512-tM4XVr2+UVTxXJzey9Twx48c1gcxFStqn1pQz0tRsX8o3DvxhN5oY5pvyAbUx7VTaZxpej4Zzvc6h+1RJBzpIg==} peerDependencies: - tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1' + tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20' dependencies: mini-svg-data-uri: 1.4.4 - tailwindcss: 3.3.6(ts-node@10.9.1) + tailwindcss: 3.4.14(ts-node@10.9.2) dev: false /@tootallnate/once@2.0.0: @@ -2209,8 +2549,8 @@ packages: resolution: {integrity: sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==} dev: false - /@types/async-retry@1.4.8: - resolution: {integrity: sha512-Qup/B5PWLe86yI5I3av6ePGaeQrIHNKCwbsQotD6aHQ6YkHsMUxVZkZsmx/Ry3VZQ6uysHwTjQ7666+k6UjVJA==} + /@types/async-retry@1.4.9: + resolution: {integrity: sha512-s1ciZQJzRh3708X/m3vPExr5KJlzlZJvXsKpbtE2luqNcbROr64qU+3KpJsYHqWMeaxI839OvXf9PrUSw1Xtyg==} dependencies: '@types/retry': 0.12.5 dev: true @@ -2248,10 +2588,14 @@ packages: resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} dev: true + /@types/estree@1.0.6: + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + dev: true + /@types/graceful-fs@4.1.6: resolution: {integrity: sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==} dependencies: - '@types/node': 22.7.3 + '@types/node': 22.9.0 /@types/http-cache-semantics@4.0.4: resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} @@ -2277,10 +2621,17 @@ packages: pretty-format: 29.7.0 dev: true + /@types/jest@29.5.14: + resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} + dependencies: + expect: 29.7.0 + pretty-format: 29.7.0 + dev: true + /@types/jsdom@20.0.1: resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==} dependencies: - '@types/node': 22.7.3 + '@types/node': 22.9.0 '@types/tough-cookie': 4.0.2 parse5: 7.1.2 dev: true @@ -2288,8 +2639,8 @@ packages: /@types/json-schema@7.0.15: resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - /@types/json-stable-stringify@1.0.36: - resolution: {integrity: sha512-b7bq23s4fgBB76n34m2b3RBf6M369B0Z9uRR8aHTMd8kZISRkmDEpPD8hhpYvDFzr3bJCPES96cm3Q6qRNDbQw==} + /@types/json-stable-stringify@1.1.0: + resolution: {integrity: sha512-ESTsHWB72QQq+pjUFIbEz9uSCZppD31YrVkbt2rnUciTYEvcwN6uZIhX5JZeBHqRlFJ41x/7MewCs7E2Qux6Cg==} dev: true /@types/json5@0.0.29: @@ -2299,14 +2650,13 @@ packages: resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} dev: true - /@types/node@22.5.4: - resolution: {integrity: sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==} + /@types/node@22.7.3: + resolution: {integrity: sha512-qXKfhXXqGTyBskvWEzJZPUxSslAiLaB6JGP1ic/XTH9ctGgzdgYguuLP1C601aRTSDNlLb0jbKqXjZ48GNraSA==} dependencies: undici-types: 6.19.8 - dev: false - /@types/node@22.7.3: - resolution: {integrity: sha512-qXKfhXXqGTyBskvWEzJZPUxSslAiLaB6JGP1ic/XTH9ctGgzdgYguuLP1C601aRTSDNlLb0jbKqXjZ48GNraSA==} + /@types/node@22.9.0: + resolution: {integrity: sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==} dependencies: undici-types: 6.19.8 @@ -2320,21 +2670,20 @@ packages: pg-protocol: 1.6.1 pg-types: 4.0.2 - /@types/prop-types@15.7.11: - resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==} + /@types/prop-types@15.7.13: + resolution: {integrity: sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==} dev: false - /@types/react-dom@18.2.17: - resolution: {integrity: sha512-rvrT/M7Df5eykWFxn6MYt5Pem/Dbyc1N8Y0S9Mrkw2WFCRiqUgw9P7ul2NpwsXCSM1DVdENzdG9J5SreqfAIWg==} + /@types/react-dom@18.3.1: + resolution: {integrity: sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==} dependencies: - '@types/react': 18.2.42 + '@types/react': 18.3.12 dev: false - /@types/react@18.2.42: - resolution: {integrity: sha512-c1zEr96MjakLYus/wPnuWDo1/zErfdU9rNsIGmE+NV71nx88FG9Ttgo5dqorXTu/LImX2f63WBP986gJkMPNbA==} + /@types/react@18.3.12: + resolution: {integrity: sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==} dependencies: - '@types/prop-types': 15.7.11 - '@types/scheduler': 0.16.8 + '@types/prop-types': 15.7.13 csstype: 3.1.3 dev: false @@ -2342,10 +2691,6 @@ packages: resolution: {integrity: sha512-3xSjTp3v03X/lSQLkczaN9UIEwJMoMCA1+Nb5HfbJEQWogdeQIyVtTvxPXDQjZ5zws8rFQfVfRdz03ARihPJgw==} dev: true - /@types/scheduler@0.16.8: - resolution: {integrity: sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==} - dev: false - /@types/semver@7.5.7: resolution: {integrity: sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg==} @@ -2398,23 +2743,31 @@ packages: transitivePeerDependencies: - supports-color - /@typescript-eslint/parser@6.13.2(eslint@8.56.0)(typescript@5.6.2): - resolution: {integrity: sha512-MUkcC+7Wt/QOGeVlM8aGGJZy1XV5YKjTpq9jK6r6/iLsGXhBVaGP5N0UYvFsu9BFlSpwY9kMretzdBH01rkRXg==} + /@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.6.3): + resolution: {integrity: sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: + '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha eslint: ^7.0.0 || ^8.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 6.13.2 - '@typescript-eslint/types': 6.13.2 - '@typescript-eslint/typescript-estree': 6.13.2(typescript@5.6.2) - '@typescript-eslint/visitor-keys': 6.13.2 + '@eslint-community/regexpp': 4.10.0 + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.6.3) + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/type-utils': 6.21.0(eslint@8.56.0)(typescript@5.6.3) + '@typescript-eslint/utils': 6.21.0(eslint@8.56.0)(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 6.21.0 debug: 4.3.5 eslint: 8.56.0 - typescript: 5.6.2 + graphemer: 1.4.0 + ignore: 5.3.1 + natural-compare: 1.4.0 + semver: 7.6.3 + ts-api-utils: 1.2.1(typescript@5.6.3) + typescript: 5.6.3 transitivePeerDependencies: - supports-color dev: false @@ -2439,6 +2792,27 @@ packages: transitivePeerDependencies: - supports-color + /@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.6.3): + resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.3.5 + eslint: 8.56.0 + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + dev: false + /@typescript-eslint/scope-manager@5.62.0: resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2446,14 +2820,6 @@ packages: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 - /@typescript-eslint/scope-manager@6.13.2: - resolution: {integrity: sha512-CXQA0xo7z6x13FeDYCgBkjWzNqzBn8RXaE3QVQVIUm74fWJLkJkaHmHdKStrxQllGh6Q4eUGyNpMe0b1hMkXFA==} - engines: {node: ^16.0.0 || >=18.0.0} - dependencies: - '@typescript-eslint/types': 6.13.2 - '@typescript-eslint/visitor-keys': 6.13.2 - dev: false - /@typescript-eslint/scope-manager@6.21.0: resolution: {integrity: sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==} engines: {node: ^16.0.0 || >=18.0.0} @@ -2480,15 +2846,30 @@ packages: transitivePeerDependencies: - supports-color + /@typescript-eslint/type-utils@6.21.0(eslint@8.56.0)(typescript@5.6.3): + resolution: {integrity: sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.6.3) + '@typescript-eslint/utils': 6.21.0(eslint@8.56.0)(typescript@5.6.3) + debug: 4.3.5 + eslint: 8.56.0 + ts-api-utils: 1.2.1(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + dev: false + /@typescript-eslint/types@5.62.0: resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - /@typescript-eslint/types@6.13.2: - resolution: {integrity: sha512-7sxbQ+EMRubQc3wTfTsycgYpSujyVbI1xw+3UMRUcrhSy+pN09y/lWzeKDbvhoqcRbHdc+APLs/PWYi/cisLPg==} - engines: {node: ^16.0.0 || >=18.0.0} - dev: false - /@typescript-eslint/types@6.21.0: resolution: {integrity: sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==} engines: {node: ^16.0.0 || >=18.0.0} @@ -2513,23 +2894,23 @@ packages: transitivePeerDependencies: - supports-color - /@typescript-eslint/typescript-estree@6.13.2(typescript@5.6.2): - resolution: {integrity: sha512-SuD8YLQv6WHnOEtKv8D6HZUzOub855cfPnPMKvdM/Bh1plv1f7Q/0iFUDLKKlxHcEstQnaUU4QZskgQq74t+3w==} - engines: {node: ^16.0.0 || >=18.0.0} + /@typescript-eslint/typescript-estree@5.62.0(typescript@5.6.3): + resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@typescript-eslint/types': 6.13.2 - '@typescript-eslint/visitor-keys': 6.13.2 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/visitor-keys': 5.62.0 debug: 4.3.5 globby: 11.1.0 is-glob: 4.0.3 semver: 7.6.3 - ts-api-utils: 1.0.3(typescript@5.6.2) - typescript: 5.6.2 + tsutils: 3.21.0(typescript@5.6.3) + typescript: 5.6.3 transitivePeerDependencies: - supports-color dev: false @@ -2555,6 +2936,28 @@ packages: transitivePeerDependencies: - supports-color + /@typescript-eslint/typescript-estree@6.21.0(typescript@5.6.3): + resolution: {integrity: sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.3.5 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.3 + semver: 7.6.3 + ts-api-utils: 1.2.1(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + dev: false + /@typescript-eslint/utils@5.62.0(eslint@8.56.0)(typescript@5.6.2): resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2574,6 +2977,26 @@ packages: - supports-color - typescript + /@typescript-eslint/utils@5.62.0(eslint@8.56.0)(typescript@5.6.3): + resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.7 + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.6.3) + eslint: 8.56.0 + eslint-scope: 5.1.1 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + - typescript + dev: false + /@typescript-eslint/utils@6.21.0(eslint@8.56.0)(typescript@5.6.2): resolution: {integrity: sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==} engines: {node: ^16.0.0 || >=18.0.0} @@ -2592,6 +3015,25 @@ packages: - supports-color - typescript + /@typescript-eslint/utils@6.21.0(eslint@8.56.0)(typescript@5.6.3): + resolution: {integrity: sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.7 + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.6.3) + eslint: 8.56.0 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + - typescript + dev: false + /@typescript-eslint/visitor-keys@5.62.0: resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2599,14 +3041,6 @@ packages: '@typescript-eslint/types': 5.62.0 eslint-visitor-keys: 3.4.3 - /@typescript-eslint/visitor-keys@6.13.2: - resolution: {integrity: sha512-OGznFs0eAQXJsp+xSd6k/O1UbFi/K/L7WjqeRoFE7vadjAF9y0uppXhYNQNEqygjou782maGClOoZwPqF0Drlw==} - engines: {node: ^16.0.0 || >=18.0.0} - dependencies: - '@typescript-eslint/types': 6.13.2 - eslint-visitor-keys: 3.4.3 - dev: false - /@typescript-eslint/visitor-keys@6.21.0: resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==} engines: {node: ^16.0.0 || >=18.0.0} @@ -2649,7 +3083,7 @@ packages: eslint: 8.56.0 eslint-config-prettier: 9.1.0(eslint@8.56.0) eslint-import-resolver-alias: 1.1.2(eslint-plugin-import@2.29.1) - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0)(eslint-plugin-import@2.29.1)(eslint@8.56.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0) eslint-plugin-eslint-comments: 3.2.0(eslint@8.56.0) eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) eslint-plugin-jest: 27.8.0(@typescript-eslint/eslint-plugin@6.21.0)(eslint@8.56.0)(jest@29.7.0)(typescript@5.6.2) @@ -2669,6 +3103,53 @@ packages: - jest - supports-color + /@vercel/style-guide@5.2.0(eslint@8.56.0)(jest@29.7.0)(prettier@3.3.3)(typescript@5.6.3): + resolution: {integrity: sha512-fNSKEaZvSkiBoF6XEefs8CcgAV9K9e+MbcsDZjUsktHycKdA0jvjAzQi1W/FzLS+Nr5zZ6oejCwq/97dHUKe0g==} + engines: {node: '>=16'} + peerDependencies: + '@next/eslint-plugin-next': '>=12.3.0 <15' + eslint: '>=8.48.0 <9' + prettier: '>=3.0.0 <4' + typescript: '>=4.8.0 <6' + peerDependenciesMeta: + '@next/eslint-plugin-next': + optional: true + eslint: + optional: true + prettier: + optional: true + typescript: + optional: true + dependencies: + '@babel/core': 7.23.9 + '@babel/eslint-parser': 7.23.10(@babel/core@7.23.9)(eslint@8.56.0) + '@rushstack/eslint-patch': 1.7.2 + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.6.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.6.3) + eslint: 8.56.0 + eslint-config-prettier: 9.1.0(eslint@8.56.0) + eslint-import-resolver-alias: 1.1.2(eslint-plugin-import@2.29.1) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0) + eslint-plugin-eslint-comments: 3.2.0(eslint@8.56.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) + eslint-plugin-jest: 27.8.0(@typescript-eslint/eslint-plugin@6.21.0)(eslint@8.56.0)(jest@29.7.0)(typescript@5.6.3) + eslint-plugin-jsx-a11y: 6.8.0(eslint@8.56.0) + eslint-plugin-playwright: 0.16.0(eslint-plugin-jest@27.8.0)(eslint@8.56.0) + eslint-plugin-react: 7.33.2(eslint@8.56.0) + eslint-plugin-react-hooks: 4.6.0(eslint@8.56.0) + eslint-plugin-testing-library: 6.2.0(eslint@8.56.0)(typescript@5.6.3) + eslint-plugin-tsdoc: 0.2.17 + eslint-plugin-unicorn: 48.0.1(eslint@8.56.0) + prettier: 3.3.3 + prettier-plugin-packagejson: 2.4.11(prettier@3.3.3) + typescript: 5.6.3 + transitivePeerDependencies: + - eslint-import-resolver-node + - eslint-import-resolver-webpack + - jest + - supports-color + dev: false + /abab@2.0.6: resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} dev: true @@ -2696,12 +3177,6 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - /acorn@8.8.2: - resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: false - /acorn@8.9.0: resolution: {integrity: sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==} engines: {node: '>=0.4.0'} @@ -2750,7 +3225,6 @@ packages: /ansi-regex@6.1.0: resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} engines: {node: '>=12'} - dev: true /ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} @@ -2771,7 +3245,6 @@ packages: /ansi-styles@6.2.1: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} - dev: true /any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} @@ -2841,17 +3314,6 @@ packages: es-array-method-boxes-properly: 1.0.0 is-string: 1.0.7 - /array.prototype.findlastindex@1.2.3: - resolution: {integrity: sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.5 - define-properties: 1.2.1 - es-abstract: 1.22.3 - es-shim-unscopables: 1.0.2 - get-intrinsic: 1.2.2 - dev: false - /array.prototype.findlastindex@1.2.4: resolution: {integrity: sha512-hzvSHUshSpCflDR1QMUBLHGHP1VIEBegT4pix9H/Z92Xw3ySoy6c2qh7lJWTJnRJ8JCZ9bJNCgTyYaJGcJu6xQ==} engines: {node: '>= 0.4'} @@ -2935,19 +3397,19 @@ packages: /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - /autoprefixer@10.4.16(postcss@8.4.32): - resolution: {integrity: sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==} + /autoprefixer@10.4.20(postcss@8.4.47): + resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: - browserslist: 4.22.1 - caniuse-lite: 1.0.30001551 + browserslist: 4.24.0 + caniuse-lite: 1.0.30001668 fraction.js: 4.3.7 normalize-range: 0.1.2 - picocolors: 1.0.0 - postcss: 8.4.32 + picocolors: 1.1.0 + postcss: 8.4.47 postcss-value-parser: 4.2.0 dev: false @@ -2963,10 +3425,10 @@ packages: resolution: {integrity: sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==} engines: {node: '>=4'} - /axios@1.6.2: - resolution: {integrity: sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==} + /axios@1.7.7: + resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==} dependencies: - follow-redirects: 1.15.3 + follow-redirects: 1.15.9 form-data: 4.0.0 proxy-from-env: 1.1.0 transitivePeerDependencies: @@ -3076,17 +3538,6 @@ packages: dependencies: fill-range: 7.1.1 - /browserslist@4.22.1: - resolution: {integrity: sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - dependencies: - caniuse-lite: 1.0.30001551 - electron-to-chromium: 1.4.559 - node-releases: 2.0.13 - update-browserslist-db: 1.0.13(browserslist@4.22.1) - dev: false - /browserslist@4.23.0: resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -3106,6 +3557,17 @@ packages: electron-to-chromium: 1.5.36 node-releases: 2.0.18 update-browserslist-db: 1.1.1(browserslist@4.24.0) + dev: false + + /browserslist@4.24.2: + resolution: {integrity: sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001677 + electron-to-chromium: 1.5.51 + node-releases: 2.0.18 + update-browserslist-db: 1.1.1(browserslist@4.24.2) dev: true /bs-logger@0.2.6: @@ -3144,6 +3606,16 @@ packages: load-tsconfig: 0.2.5 dev: true + /bundle-require@5.0.0(esbuild@0.24.0): + resolution: {integrity: sha512-GuziW3fSSmopcx4KRymQEJVbZUfqlCqcq7dvs6TYwKRZiegK/2buMxQTPs6MGlNv50wms1699qYO54R8XfRX4w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.18' + dependencies: + esbuild: 0.24.0 + load-tsconfig: 0.2.5 + dev: true + /busboy@1.6.0: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} @@ -3213,19 +3685,15 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - /caniuse-lite@1.0.30001551: - resolution: {integrity: sha512-vtBAez47BoGMMzlbYhfXrMV1kvRF2WP/lqiMuDu1Sb4EE4LKEgjopFDSRtZfdVnslNRpOqV/woE+Xgrwj6VQlg==} - dev: false - - /caniuse-lite@1.0.30001566: - resolution: {integrity: sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==} - dev: false - /caniuse-lite@1.0.30001587: resolution: {integrity: sha512-HMFNotUmLXn71BQxg8cijvqxnIAofforZOwGsxyXJ0qugTdspUF4sPSJ2vhgprHCB996tIDzEq1ubumPDV8ULA==} /caniuse-lite@1.0.30001668: resolution: {integrity: sha512-nWLrdxqCdblixUO+27JtGJJE/txpJlyUy5YN1u53wLZkP0emYCo5zgS6QYft7VUYR42LGgi/S5hdLZTrnyIddw==} + dev: false + + /caniuse-lite@1.0.30001677: + resolution: {integrity: sha512-fmfjsOlJUpMWu+mAAtZZZHz7UEwsUxIIvu1TJfO1HqFQvB/B+ii0xr9B5HpbZY/mC4XZ8SvjHJqtAY6pDPQEog==} dev: true /chalk@2.4.2: @@ -3256,21 +3724,6 @@ packages: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} dev: true - /chokidar@3.5.3: - resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} - engines: {node: '>= 8.10.0'} - dependencies: - anymatch: 3.1.3 - braces: 3.0.3 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - dev: false - /chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -3284,6 +3737,12 @@ packages: readdirp: 3.6.0 optionalDependencies: fsevents: 2.3.3 + + /chokidar@4.0.1: + resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==} + engines: {node: '>= 14.16.0'} + dependencies: + readdirp: 4.0.2 dev: true /ci-info@3.9.0: @@ -3383,7 +3842,25 @@ packages: /convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - /create-jest@29.7.0(@types/node@22.7.3): + /create-jest@29.7.0(@types/node@22.7.3): + resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@22.7.3) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + /create-jest@29.7.0(@types/node@22.9.0): resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -3392,7 +3869,7 @@ packages: chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@22.7.3) + jest-config: 29.7.0(@types/node@22.9.0) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -3400,6 +3877,7 @@ packages: - babel-plugin-macros - supports-color - ts-node + dev: true /create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} @@ -3640,14 +4118,13 @@ packages: engines: {node: '>=12'} dev: false - /dotenv@16.3.1: - resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} + /dotenv@16.4.5: + resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} dev: false /eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - dev: true /ejs@3.1.10: resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} @@ -3657,15 +4134,15 @@ packages: jake: 10.9.2 dev: true - /electron-to-chromium@1.4.559: - resolution: {integrity: sha512-iS7KhLYCSJbdo3rUSkhDTVuFNCV34RKs2UaB9Ecr7VlqzjjWW//0nfsFF5dtDmyXlZQaDYYtID5fjtC/6lpRug==} - dev: false - /electron-to-chromium@1.4.672: resolution: {integrity: sha512-YYCy+goe3UqZqa3MOQCI5Mx/6HdBLzXL/mkbGCEWL3sP3Z1BP9zqAzeD3YEmLZlespYGFtyM8tRp5i2vfaUGCA==} /electron-to-chromium@1.5.36: resolution: {integrity: sha512-HYTX8tKge/VNp6FGO+f/uVDmUkq+cEfcxYhKf15Akc4M5yxt5YmorwlAitKWjWhWQnKcDRBAQKXkhqqXMqcrjw==} + dev: false + + /electron-to-chromium@1.5.51: + resolution: {integrity: sha512-kKeWV57KSS8jH4alKt/jKnvHPmJgBxXzGUSbMd4eQF+iOsVPl7bz2KUmu6eo80eMP8wVioTfTyTzdMgM15WXNg==} dev: true /emittery@0.13.1: @@ -3886,6 +4363,38 @@ packages: '@esbuild/win32-x64': 0.23.1 dev: true + /esbuild@0.24.0: + resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==} + engines: {node: '>=18'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/aix-ppc64': 0.24.0 + '@esbuild/android-arm': 0.24.0 + '@esbuild/android-arm64': 0.24.0 + '@esbuild/android-x64': 0.24.0 + '@esbuild/darwin-arm64': 0.24.0 + '@esbuild/darwin-x64': 0.24.0 + '@esbuild/freebsd-arm64': 0.24.0 + '@esbuild/freebsd-x64': 0.24.0 + '@esbuild/linux-arm': 0.24.0 + '@esbuild/linux-arm64': 0.24.0 + '@esbuild/linux-ia32': 0.24.0 + '@esbuild/linux-loong64': 0.24.0 + '@esbuild/linux-mips64el': 0.24.0 + '@esbuild/linux-ppc64': 0.24.0 + '@esbuild/linux-riscv64': 0.24.0 + '@esbuild/linux-s390x': 0.24.0 + '@esbuild/linux-x64': 0.24.0 + '@esbuild/netbsd-x64': 0.24.0 + '@esbuild/openbsd-arm64': 0.24.0 + '@esbuild/openbsd-x64': 0.24.0 + '@esbuild/sunos-x64': 0.24.0 + '@esbuild/win32-arm64': 0.24.0 + '@esbuild/win32-ia32': 0.24.0 + '@esbuild/win32-x64': 0.24.0 + dev: true + /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} @@ -3893,7 +4402,6 @@ packages: /escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} - dev: true /escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} @@ -3920,8 +4428,8 @@ packages: source-map: 0.6.1 dev: true - /eslint-config-next@14.0.4(eslint@8.56.0)(typescript@5.6.2): - resolution: {integrity: sha512-9/xbOHEQOmQtqvQ1UsTQZpnA7SlDMBtuKJ//S4JnoyK3oGLhILKXdBgu/UO7lQo/2xOykQULS1qQ6p2+EpHgAQ==} + /eslint-config-next@14.2.15(eslint@8.56.0)(typescript@5.6.3): + resolution: {integrity: sha512-mKg+NC/8a4JKLZRIOBplxXNdStgxy7lzWuedUaCc8tev+Al9mwDUTujQH6W6qXDH9kycWiVo28tADWGvpBsZcQ==} peerDependencies: eslint: ^7.23.0 || ^8.0.0 typescript: '>=3.3.1' @@ -3929,17 +4437,18 @@ packages: typescript: optional: true dependencies: - '@next/eslint-plugin-next': 14.0.4 - '@rushstack/eslint-patch': 1.6.0 - '@typescript-eslint/parser': 6.13.2(eslint@8.56.0)(typescript@5.6.2) + '@next/eslint-plugin-next': 14.2.15 + '@rushstack/eslint-patch': 1.7.2 + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.6.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.6.3) eslint: 8.56.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.13.2)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0)(eslint@8.56.0) - eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) eslint-plugin-jsx-a11y: 6.8.0(eslint@8.56.0) eslint-plugin-react: 7.33.2(eslint@8.56.0) eslint-plugin-react-hooks: 4.6.0(eslint@8.56.0) - typescript: 5.6.2 + typescript: 5.6.3 transitivePeerDependencies: - eslint-import-resolver-webpack - supports-color @@ -3979,30 +4488,7 @@ packages: transitivePeerDependencies: - supports-color - /eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.13.2)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0)(eslint@8.56.0): - resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - eslint: '*' - eslint-plugin-import: '*' - dependencies: - debug: 4.3.5 - enhanced-resolve: 5.15.0 - eslint: 8.56.0 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.13.2)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) - eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0) - fast-glob: 3.3.2 - get-tsconfig: 4.7.2 - is-core-module: 2.13.1 - is-glob: 4.0.3 - transitivePeerDependencies: - - '@typescript-eslint/parser' - - eslint-import-resolver-node - - eslint-import-resolver-webpack - - supports-color - dev: false - - /eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0)(eslint-plugin-import@2.29.1)(eslint@8.56.0): + /eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0): resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -4024,36 +4510,6 @@ packages: - eslint-import-resolver-webpack - supports-color - /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.13.2)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0): - resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint: - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: - optional: true - dependencies: - '@typescript-eslint/parser': 6.13.2(eslint@8.56.0)(typescript@5.6.2) - debug: 3.2.7 - eslint: 8.56.0 - eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.13.2)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0)(eslint@8.56.0) - transitivePeerDependencies: - - supports-color - dev: false - /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0): resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} engines: {node: '>=4'} @@ -4079,7 +4535,7 @@ packages: debug: 3.2.7 eslint: 8.56.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0)(eslint-plugin-import@2.29.1)(eslint@8.56.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0) transitivePeerDependencies: - supports-color @@ -4093,41 +4549,6 @@ packages: eslint: 8.56.0 ignore: 5.3.1 - /eslint-plugin-import@2.29.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0): - resolution: {integrity: sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - dependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.6.2) - array-includes: 3.1.7 - array.prototype.findlastindex: 1.2.3 - array.prototype.flat: 1.3.2 - array.prototype.flatmap: 1.3.2 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 8.56.0 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) - hasown: 2.0.0 - is-core-module: 2.13.1 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.7 - object.groupby: 1.0.1 - object.values: 1.1.7 - semver: 6.3.1 - tsconfig-paths: 3.14.2 - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - dev: false - /eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0): resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} engines: {node: '>=4'} @@ -4178,10 +4599,32 @@ packages: '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.6.2) '@typescript-eslint/utils': 5.62.0(eslint@8.56.0)(typescript@5.6.2) eslint: 8.56.0 - jest: 29.7.0(@types/node@22.7.3) + jest: 29.7.0 + transitivePeerDependencies: + - supports-color + - typescript + + /eslint-plugin-jest@27.8.0(@typescript-eslint/eslint-plugin@6.21.0)(eslint@8.56.0)(jest@29.7.0)(typescript@5.6.3): + resolution: {integrity: sha512-347hVFiu4ZKMYl5xFp0X81gLNwBdno0dl0CMpUMjwuAux9X/M2a7z+ab2VHmPL6XCT87q8nv1vaVzhIO4TE/hw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^5.0.0 || ^6.0.0 || ^7.0.0 + eslint: ^7.0.0 || ^8.0.0 + jest: '*' + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + jest: + optional: true + dependencies: + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.6.3) + '@typescript-eslint/utils': 5.62.0(eslint@8.56.0)(typescript@5.6.3) + eslint: 8.56.0 + jest: 29.7.0 transitivePeerDependencies: - supports-color - typescript + dev: false /eslint-plugin-jsx-a11y@6.8.0(eslint@8.56.0): resolution: {integrity: sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==} @@ -4263,6 +4706,19 @@ packages: - supports-color - typescript + /eslint-plugin-testing-library@6.2.0(eslint@8.56.0)(typescript@5.6.3): + resolution: {integrity: sha512-+LCYJU81WF2yQ+Xu4A135CgK8IszcFcyMF4sWkbiu6Oj+Nel0TrkZq/HvDw0/1WuO3dhDQsZA/OpEMGd0NfcUw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0, npm: '>=6'} + peerDependencies: + eslint: ^7.5.0 || ^8.0.0 + dependencies: + '@typescript-eslint/utils': 5.62.0(eslint@8.56.0)(typescript@5.6.3) + eslint: 8.56.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: false + /eslint-plugin-tsdoc@0.2.17: resolution: {integrity: sha512-xRmVi7Zx44lOBuYqG8vzTXuL6IdGOeF9nHX17bjJ8+VE6fsxpdGem0/SBTmAwgYMKYB1WBkqRJVQ+n8GK041pA==} dependencies: @@ -4506,6 +4962,17 @@ packages: picomatch: 4.0.2 dev: true + /fdir@6.4.2(picomatch@4.0.2): + resolution: {integrity: sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + dependencies: + picomatch: 4.0.2 + dev: true + /file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -4549,8 +5016,8 @@ packages: /flatted@3.2.9: resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} - /follow-redirects@1.15.3: - resolution: {integrity: sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==} + /follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -4570,7 +5037,6 @@ packages: dependencies: cross-spawn: 7.0.3 signal-exit: 4.1.0 - dev: true /form-data-encoder@2.1.4: resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} @@ -4615,7 +5081,6 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] requiresBuild: true - dev: true optional: true /fsevents@2.3.3: @@ -4723,8 +5188,16 @@ packages: dependencies: is-glob: 4.0.3 - /glob-to-regexp@0.4.1: - resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + /glob@10.3.10: + resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + dependencies: + foreground-child: 3.3.0 + jackspeak: 2.3.6 + minimatch: 9.0.5 + minipass: 7.1.2 + path-scurry: 1.11.1 dev: false /glob@10.4.5: @@ -4735,33 +5208,8 @@ packages: jackspeak: 3.4.3 minimatch: 9.0.5 minipass: 7.1.2 - package-json-from-dist: 1.0.0 + package-json-from-dist: 1.0.1 path-scurry: 1.11.1 - dev: true - - /glob@7.1.6: - resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==} - deprecated: Glob versions prior to v9 are no longer supported - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - dev: false - - /glob@7.1.7: - resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} - deprecated: Glob versions prior to v9 are no longer supported - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - dev: false /glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} @@ -5158,6 +5606,10 @@ packages: resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} engines: {node: '>= 0.4'} + /is-node-process@1.2.0: + resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} + dev: false + /is-number-object@1.0.7: resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} engines: {node: '>= 0.4'} @@ -5322,13 +5774,21 @@ packages: reflect.getprototypeof: 1.0.4 set-function-name: 2.0.1 + /jackspeak@2.3.6: + resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} + engines: {node: '>=14'} + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + dev: false + /jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} dependencies: '@isaacs/cliui': 8.0.2 optionalDependencies: '@pkgjs/parseargs': 0.11.0 - dev: true /jake@10.9.2: resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} @@ -5357,7 +5817,7 @@ packages: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.7.3 + '@types/node': 22.9.0 chalk: 4.1.2 co: 4.6.0 dedent: 1.2.0 @@ -5377,6 +5837,33 @@ packages: - babel-plugin-macros - supports-color + /jest-cli@29.7.0: + resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} + 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.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@22.7.3) + exit: 0.1.2 + import-local: 3.1.0 + jest-config: 29.7.0(@types/node@22.7.3) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + /jest-cli@29.7.0(@types/node@22.7.3): resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -5391,20 +5878,88 @@ packages: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@22.7.3) - exit: 0.1.2 - import-local: 3.1.0 - jest-config: 29.7.0(@types/node@22.7.3) + create-jest: 29.7.0(@types/node@22.7.3) + exit: 0.1.2 + import-local: 3.1.0 + jest-config: 29.7.0(@types/node@22.7.3) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + dev: true + + /jest-cli@29.7.0(@types/node@22.9.0): + resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} + 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.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@22.9.0) + exit: 0.1.2 + import-local: 3.1.0 + jest-config: 29.7.0(@types/node@22.9.0) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + dev: true + + /jest-config@29.7.0(@types/node@22.7.3): + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + 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.23.2 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.7.3 + babel-jest: 29.7.0(@babel/core@7.23.2) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 jest-util: 29.7.0 jest-validate: 29.7.0 - yargs: 17.7.2 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 transitivePeerDependencies: - - '@types/node' - babel-plugin-macros - supports-color - - ts-node - /jest-config@29.7.0(@types/node@22.7.3): + /jest-config@29.7.0(@types/node@22.9.0): resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -5419,7 +5974,7 @@ packages: '@babel/core': 7.23.2 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.7.3 + '@types/node': 22.9.0 babel-jest: 29.7.0(@babel/core@7.23.2) chalk: 4.1.2 ci-info: 3.9.0 @@ -5481,7 +6036,7 @@ packages: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 '@types/jsdom': 20.0.1 - '@types/node': 22.7.3 + '@types/node': 22.9.0 jest-mock: 29.7.0 jest-util: 29.7.0 jsdom: 20.0.3 @@ -5498,7 +6053,7 @@ packages: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.7.3 + '@types/node': 22.9.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -5521,7 +6076,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.6 - '@types/node': 22.7.3 + '@types/node': 22.9.0 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -5568,7 +6123,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 22.7.3 + '@types/node': 22.9.0 jest-util: 29.5.0 dev: true @@ -5577,7 +6132,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 22.7.3 + '@types/node': 22.9.0 jest-util: 29.7.0 /jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): @@ -5707,7 +6262,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 22.7.3 + '@types/node': 22.9.0 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -5719,7 +6274,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 22.7.3 + '@types/node': 22.9.0 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -5742,7 +6297,7 @@ packages: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.7.3 + '@types/node': 22.9.0 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -5753,11 +6308,31 @@ packages: resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 22.7.3 + '@types/node': 22.9.0 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 + /jest@29.7.0: + resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} + 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.7.0 + '@jest/types': 29.6.3 + import-local: 3.1.0 + jest-cli: 29.7.0 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + /jest@29.7.0(@types/node@22.7.3): resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -5777,6 +6352,28 @@ packages: - babel-plugin-macros - supports-color - ts-node + dev: true + + /jest@29.7.0(@types/node@22.9.0): + resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} + 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.7.0 + '@jest/types': 29.6.3 + import-local: 3.1.0 + jest-cli: 29.7.0(@types/node@22.9.0) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + dev: true /jiti@1.21.0: resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} @@ -6063,7 +6660,6 @@ packages: /lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - dev: true /lru-cache@4.1.5: resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} @@ -6098,14 +6694,6 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - /micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} - engines: {node: '>=8.6'} - dependencies: - braces: 3.0.3 - picomatch: 2.3.1 - dev: false - /micromatch@4.0.7: resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} engines: {node: '>=8.6'} @@ -6186,7 +6774,6 @@ packages: engines: {node: '>=16 || 14 >=14.17'} dependencies: brace-expansion: 2.0.1 - dev: true /minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} @@ -6194,7 +6781,6 @@ packages: /minipass@7.1.2: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} - dev: true /mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} @@ -6223,41 +6809,44 @@ packages: /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - /next@14.0.4(@babel/core@7.23.9)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-qbwypnM7327SadwFtxXnQdGiKpkuhaRLE2uq62/nRul9cj9KhQ5LhHmlziTNqUidZotw/Q1I9OjirBROdUJNgA==} + /next@14.2.15(@babel/core@7.23.9)(@playwright/test@1.48.2)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-h9ctmOokpoDphRvMGnwOJAedT6zKhwqyZML9mDtspgf4Rh3Pn7UTYKqePNoDvhsWBAO5GoPNYshnAUGIazVGmw==} engines: {node: '>=18.17.0'} hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 react: ^18.2.0 react-dom: ^18.2.0 sass: ^1.3.0 peerDependenciesMeta: '@opentelemetry/api': optional: true + '@playwright/test': + optional: true sass: optional: true dependencies: - '@next/env': 14.0.4 - '@swc/helpers': 0.5.2 + '@next/env': 14.2.15 + '@playwright/test': 1.48.2 + '@swc/helpers': 0.5.5 busboy: 1.6.0 - caniuse-lite: 1.0.30001566 + caniuse-lite: 1.0.30001668 graceful-fs: 4.2.11 postcss: 8.4.31 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - styled-jsx: 5.1.1(@babel/core@7.23.9)(react@18.2.0) - watchpack: 2.4.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + styled-jsx: 5.1.1(@babel/core@7.23.9)(react@18.3.1) 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 + '@next/swc-darwin-arm64': 14.2.15 + '@next/swc-darwin-x64': 14.2.15 + '@next/swc-linux-arm64-gnu': 14.2.15 + '@next/swc-linux-arm64-musl': 14.2.15 + '@next/swc-linux-x64-gnu': 14.2.15 + '@next/swc-linux-x64-musl': 14.2.15 + '@next/swc-win32-arm64-msvc': 14.2.15 + '@next/swc-win32-ia32-msvc': 14.2.15 + '@next/swc-win32-x64-msvc': 14.2.15 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros @@ -6287,16 +6876,11 @@ packages: /node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - /node-releases@2.0.13: - resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} - dev: false - /node-releases@2.0.14: resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} /node-releases@2.0.18: resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} - dev: true /normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} @@ -6410,15 +6994,6 @@ packages: define-properties: 1.2.1 es-abstract: 1.22.3 - /object.groupby@1.0.1: - resolution: {integrity: sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==} - dependencies: - call-bind: 1.0.5 - define-properties: 1.2.1 - es-abstract: 1.22.3 - get-intrinsic: 1.2.2 - dev: false - /object.groupby@1.0.2: resolution: {integrity: sha512-bzBq58S+x+uo0VjurFT0UktpKHOZmv4/xePiOA1nbB9pMqpGK7rUPNgf+1YC+7mE+0HzhTMqNUuCqvKhj6FnBw==} dependencies: @@ -6547,9 +7122,8 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} - /package-json-from-dist@1.0.0: - resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} - dev: true + /package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} /package-manager-detector@0.2.0: resolution: {integrity: sha512-E385OSk9qDcXhcM9LNSe4sdhx8a9mAPrZ4sMLW+tmxl5ZuGtPUcdFu+MPP2jbgiWAZ6Pfe5soGFMd+0Db5Vrog==} @@ -6602,7 +7176,6 @@ packages: dependencies: lru-cache: 10.4.3 minipass: 7.1.2 - dev: true /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} @@ -6631,13 +7204,13 @@ packages: postgres-interval: 3.0.0 postgres-range: 1.1.4 - /picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - dev: false - /picocolors@1.1.0: resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} + /picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + dev: true + /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} @@ -6677,49 +7250,47 @@ packages: dependencies: find-up: 4.1.0 - /playwright-core@1.48.0: - resolution: {integrity: sha512-RBvzjM9rdpP7UUFrQzRwR8L/xR4HyC1QXMzGYTbf1vjw25/ya9NRAVnXi/0fvFopjebvyPzsmoK58xxeEOaVvA==} + /playwright-core@1.48.2: + resolution: {integrity: sha512-sjjw+qrLFlriJo64du+EK0kJgZzoQPsabGF4lBvsid+3CNIZIYLgnMj9V6JY5VhM2Peh20DJWIVpVljLLnlawA==} engines: {node: '>=18'} hasBin: true - dev: true - /playwright@1.48.0: - resolution: {integrity: sha512-qPqFaMEHuY/ug8o0uteYJSRfMGFikhUysk8ZvAtfKmUK3kc/6oNl/y3EczF8OFGYIi/Ex2HspMfzYArk6+XQSA==} + /playwright@1.48.2: + resolution: {integrity: sha512-NjYvYgp4BPmiwfe31j4gHLa3J7bD2WiBz8Lk2RoSsmX38SVIARZ18VYjxLjAcDsAhA+F4iSEXTSGgjua0rrlgQ==} engines: {node: '>=18'} hasBin: true dependencies: - playwright-core: 1.48.0 + playwright-core: 1.48.2 optionalDependencies: fsevents: 2.3.2 - dev: true /pluralize@8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} - /postcss-import@15.1.0(postcss@8.4.32): + /postcss-import@15.1.0(postcss@8.4.47): resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} engines: {node: '>=14.0.0'} peerDependencies: postcss: ^8.0.0 dependencies: - postcss: 8.4.32 + postcss: 8.4.47 postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.8 dev: false - /postcss-js@4.0.1(postcss@8.4.32): + /postcss-js@4.0.1(postcss@8.4.47): resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} engines: {node: ^12 || ^14 || >= 16} peerDependencies: postcss: ^8.4.21 dependencies: camelcase-css: 2.0.1 - postcss: 8.4.32 + postcss: 8.4.47 dev: false - /postcss-load-config@4.0.2(postcss@8.4.32)(ts-node@10.9.1): + /postcss-load-config@4.0.2(postcss@8.4.47)(ts-node@10.9.2): resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} engines: {node: '>= 14'} peerDependencies: @@ -6732,9 +7303,9 @@ packages: optional: true dependencies: lilconfig: 3.1.2 - postcss: 8.4.32 - ts-node: 10.9.1(@types/node@22.5.4)(typescript@5.6.2) - yaml: 2.4.5 + postcss: 8.4.47 + ts-node: 10.9.2(@types/node@22.9.0)(typescript@5.6.3) + yaml: 2.5.1 dev: false /postcss-load-config@6.0.1: @@ -6758,13 +7329,13 @@ packages: lilconfig: 3.1.2 dev: true - /postcss-nested@6.0.1(postcss@8.4.32): + /postcss-nested@6.0.1(postcss@8.4.47): resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==} engines: {node: '>=12.0'} peerDependencies: postcss: ^8.2.14 dependencies: - postcss: 8.4.32 + postcss: 8.4.47 postcss-selector-parser: 6.0.13 dev: false @@ -6789,13 +7360,13 @@ packages: source-map-js: 1.0.2 dev: false - /postcss@8.4.32: - resolution: {integrity: sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==} + /postcss@8.4.47: + resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} engines: {node: ^10 || ^12 || >=14} dependencies: nanoid: 3.3.7 - picocolors: 1.0.0 - source-map-js: 1.0.2 + picocolors: 1.1.0 + source-map-js: 1.2.1 dev: false /postgres-array@3.0.2: @@ -6923,14 +7494,14 @@ packages: engines: {node: '>=10'} dev: false - /react-dom@18.2.0(react@18.2.0): - resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} + /react-dom@18.3.1(react@18.3.1): + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} peerDependencies: - react: ^18.2.0 + react: ^18.3.1 dependencies: loose-envify: 1.4.0 - react: 18.2.0 - scheduler: 0.23.0 + react: 18.3.1 + scheduler: 0.23.2 dev: false /react-is@16.13.1: @@ -6939,8 +7510,8 @@ packages: /react-is@18.2.0: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} - /react@18.2.0: - resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} + /react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} dependencies: loose-envify: 1.4.0 @@ -6985,6 +7556,11 @@ packages: dependencies: picomatch: 2.3.1 + /readdirp@4.0.2: + resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==} + engines: {node: '>= 14.16.0'} + dev: true + /reflect.getprototypeof@1.0.4: resolution: {integrity: sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==} engines: {node: '>= 0.4'} @@ -7141,6 +7717,34 @@ packages: fsevents: 2.3.3 dev: true + /rollup@4.24.4: + resolution: {integrity: sha512-vGorVWIsWfX3xbcyAS+I047kFKapHYivmkaT63Smj77XwvLSJos6M1xGqZnBPFQFBRZDOcG1QnYEIxAvTr/HjA==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + dependencies: + '@types/estree': 1.0.6 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.24.4 + '@rollup/rollup-android-arm64': 4.24.4 + '@rollup/rollup-darwin-arm64': 4.24.4 + '@rollup/rollup-darwin-x64': 4.24.4 + '@rollup/rollup-freebsd-arm64': 4.24.4 + '@rollup/rollup-freebsd-x64': 4.24.4 + '@rollup/rollup-linux-arm-gnueabihf': 4.24.4 + '@rollup/rollup-linux-arm-musleabihf': 4.24.4 + '@rollup/rollup-linux-arm64-gnu': 4.24.4 + '@rollup/rollup-linux-arm64-musl': 4.24.4 + '@rollup/rollup-linux-powerpc64le-gnu': 4.24.4 + '@rollup/rollup-linux-riscv64-gnu': 4.24.4 + '@rollup/rollup-linux-s390x-gnu': 4.24.4 + '@rollup/rollup-linux-x64-gnu': 4.24.4 + '@rollup/rollup-linux-x64-musl': 4.24.4 + '@rollup/rollup-win32-arm64-msvc': 4.24.4 + '@rollup/rollup-win32-ia32-msvc': 4.24.4 + '@rollup/rollup-win32-x64-msvc': 4.24.4 + fsevents: 2.3.3 + dev: true + /run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: @@ -7197,8 +7801,8 @@ packages: xmlchars: 2.2.0 dev: true - /scheduler@0.23.0: - resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} + /scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} dependencies: loose-envify: 1.4.0 dev: false @@ -7288,7 +7892,6 @@ packages: /signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - dev: true /sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -7337,6 +7940,11 @@ packages: engines: {node: '>=0.10.0'} dev: false + /source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + dev: false + /source-map-support@0.5.13: resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} dependencies: @@ -7420,7 +8028,6 @@ packages: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 strip-ansi: 7.1.0 - dev: true /string-width@7.2.0: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} @@ -7477,7 +8084,6 @@ packages: engines: {node: '>=12'} dependencies: ansi-regex: 6.1.0 - dev: true /strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} @@ -7506,7 +8112,7 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - /styled-jsx@5.1.1(@babel/core@7.23.9)(react@18.2.0): + /styled-jsx@5.1.1(@babel/core@7.23.9)(react@18.3.1): resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} engines: {node: '>= 12.0.0'} peerDependencies: @@ -7521,21 +8127,7 @@ packages: dependencies: '@babel/core': 7.23.9 client-only: 0.0.1 - react: 18.2.0 - dev: false - - /sucrase@3.34.0: - resolution: {integrity: sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==} - engines: {node: '>=8'} - hasBin: true - dependencies: - '@jridgewell/gen-mapping': 0.3.3 - commander: 4.1.1 - glob: 7.1.6 - lines-and-columns: 1.2.4 - mz: 2.7.0 - pirates: 4.0.6 - ts-interface-checker: 0.1.13 + react: 18.3.1 dev: false /sucrase@3.35.0: @@ -7550,7 +8142,6 @@ packages: mz: 2.7.0 pirates: 4.0.6 ts-interface-checker: 0.1.13 - dev: true /supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} @@ -7574,14 +8165,14 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - /swr@2.2.4(react@18.2.0): - resolution: {integrity: sha512-njiZ/4RiIhoOlAaLYDqwz5qH/KZXVilRLvomrx83HjzCWTfa+InyfAjv05PSFxnmLzZkNO9ZfvgoqzAaEI4sGQ==} + /swr@2.2.5(react@18.3.1): + resolution: {integrity: sha512-QtxqyclFeAsxEUeZIYmsaQ0UjimSq1RZ9Un7I68/0ClKK/U3LoyQunwkQfJZr2fc22DfIXLNDc2wFyTEikCUpg==} peerDependencies: react: ^16.11.0 || ^17.0.0 || ^18.0.0 dependencies: client-only: 0.0.1 - react: 18.2.0 - use-sync-external-store: 1.2.0(react@18.2.0) + react: 18.3.1 + use-sync-external-store: 1.2.0(react@18.3.1) dev: false /symbol-tree@3.2.4: @@ -7595,14 +8186,14 @@ packages: '@pkgr/core': 0.1.1 tslib: 2.6.2 - /tailwindcss@3.3.6(ts-node@10.9.1): - resolution: {integrity: sha512-AKjF7qbbLvLaPieoKeTjG1+FyNZT6KaJMJPFeQyLfIp7l82ggH1fbHJSsYIvnbTFQOlkh+gBYpyby5GT1LIdLw==} + /tailwindcss@3.4.14(ts-node@10.9.2): + resolution: {integrity: sha512-IcSvOcTRcUtQQ7ILQL5quRDg7Xs93PdJEk1ZLbhhvJc7uj/OAhYOnruEiwnGgBvUtaUAJ8/mhSw1o8L2jCiENA==} engines: {node: '>=14.0.0'} hasBin: true dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 - chokidar: 3.5.3 + chokidar: 3.6.0 didyoumean: 1.2.2 dlv: 1.1.3 fast-glob: 3.3.2 @@ -7610,18 +8201,18 @@ packages: is-glob: 4.0.3 jiti: 1.21.0 lilconfig: 2.1.0 - micromatch: 4.0.5 + micromatch: 4.0.8 normalize-path: 3.0.0 object-hash: 3.0.0 - picocolors: 1.0.0 - postcss: 8.4.32 - postcss-import: 15.1.0(postcss@8.4.32) - postcss-js: 4.0.1(postcss@8.4.32) - postcss-load-config: 4.0.2(postcss@8.4.32)(ts-node@10.9.1) - postcss-nested: 6.0.1(postcss@8.4.32) + picocolors: 1.1.0 + postcss: 8.4.47 + postcss-import: 15.1.0(postcss@8.4.47) + postcss-js: 4.0.1(postcss@8.4.47) + postcss-load-config: 4.0.2(postcss@8.4.47)(ts-node@10.9.2) + postcss-nested: 6.0.1(postcss@8.4.47) postcss-selector-parser: 6.0.13 resolve: 1.22.8 - sucrase: 3.34.0 + sucrase: 3.35.0 transitivePeerDependencies: - ts-node dev: false @@ -7657,6 +8248,23 @@ packages: dependencies: any-promise: 1.3.0 + /throttleit@2.1.0: + resolution: {integrity: sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==} + engines: {node: '>=18'} + dev: false + + /tinyexec@0.3.1: + resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} + dev: true + + /tinyglobby@0.2.10: + resolution: {integrity: sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==} + engines: {node: '>=12.0.0'} + dependencies: + fdir: 6.4.2(picomatch@4.0.2) + picomatch: 4.0.2 + dev: true + /tinyglobby@0.2.6: resolution: {integrity: sha512-NbBoFBpqfcgd1tCiO8Lkfdk+xrA7mlLR9zgvZcZWQQwU63XAfUePyd6wZBaU93Hqw347lHnwFzttAkemHzzz4g==} engines: {node: '>=12.0.0'} @@ -7717,27 +8325,27 @@ packages: hasBin: true dev: true - /ts-api-utils@1.0.3(typescript@5.6.2): - resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} - engines: {node: '>=16.13.0'} + /ts-api-utils@1.2.1(typescript@5.6.2): + resolution: {integrity: sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==} + engines: {node: '>=16'} peerDependencies: typescript: '>=4.2.0' dependencies: typescript: 5.6.2 - dev: false - /ts-api-utils@1.2.1(typescript@5.6.2): + /ts-api-utils@1.2.1(typescript@5.6.3): resolution: {integrity: sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==} engines: {node: '>=16'} peerDependencies: typescript: '>=4.2.0' dependencies: - typescript: 5.6.2 + typescript: 5.6.3 + dev: false /ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - /ts-jest@29.2.5(@babel/core@7.23.2)(esbuild@0.23.1)(jest@29.7.0)(typescript@5.6.3): + /ts-jest@29.2.5(@babel/core@7.26.0)(esbuild@0.23.1)(jest@29.7.0)(typescript@5.6.2): resolution: {integrity: sha512-KD8zB2aAZrcKIdGk4OwpJggeLcH1FgrICqDSROWqlnJXGCXK4Mn6FcdK2B6670Xr73lHMG1kHw8R87A0ecZ+vA==} engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} hasBin: true @@ -7761,7 +8369,7 @@ packages: esbuild: optional: true dependencies: - '@babel/core': 7.23.2 + '@babel/core': 7.26.0 bs-logger: 0.2.6 ejs: 3.1.10 esbuild: 0.23.1 @@ -7772,11 +8380,50 @@ packages: lodash.memoize: 4.1.2 make-error: 1.3.6 semver: 7.6.3 + typescript: 5.6.2 + yargs-parser: 21.1.1 + dev: true + + /ts-jest@29.2.5(@babel/core@7.26.0)(esbuild@0.24.0)(jest@29.7.0)(typescript@5.6.3): + resolution: {integrity: sha512-KD8zB2aAZrcKIdGk4OwpJggeLcH1FgrICqDSROWqlnJXGCXK4Mn6FcdK2B6670Xr73lHMG1kHw8R87A0ecZ+vA==} + engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/transform': ^29.0.0 + '@jest/types': ^29.0.0 + babel-jest: ^29.0.0 + esbuild: '*' + jest: ^29.0.0 + typescript: '>=4.3 <6' + peerDependenciesMeta: + '@babel/core': + optional: true + '@jest/transform': + optional: true + '@jest/types': + optional: true + babel-jest: + optional: true + esbuild: + optional: true + dependencies: + '@babel/core': 7.26.0 + bs-logger: 0.2.6 + ejs: 3.1.10 + esbuild: 0.24.0 + fast-json-stable-stringify: 2.1.0 + jest: 29.7.0(@types/node@22.9.0) + jest-util: 29.7.0 + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.6.3 typescript: 5.6.3 yargs-parser: 21.1.1 dev: true - /ts-jest@29.2.5(@babel/core@7.25.8)(esbuild@0.23.1)(jest@29.7.0)(typescript@5.6.2): + /ts-jest@29.2.5(@babel/core@7.26.0)(jest@29.7.0)(typescript@5.6.2): resolution: {integrity: sha512-KD8zB2aAZrcKIdGk4OwpJggeLcH1FgrICqDSROWqlnJXGCXK4Mn6FcdK2B6670Xr73lHMG1kHw8R87A0ecZ+vA==} engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} hasBin: true @@ -7800,12 +8447,11 @@ packages: esbuild: optional: true dependencies: - '@babel/core': 7.25.8 + '@babel/core': 7.26.0 bs-logger: 0.2.6 ejs: 3.1.10 - esbuild: 0.23.1 fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@22.7.3) + jest: 29.7.0 jest-util: 29.7.0 json5: 2.2.3 lodash.memoize: 4.1.2 @@ -7815,8 +8461,8 @@ packages: yargs-parser: 21.1.1 dev: true - /ts-node@10.9.1(@types/node@22.5.4)(typescript@5.6.2): - resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + /ts-node@10.9.2(@types/node@22.9.0)(typescript@5.6.3): + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} hasBin: true peerDependencies: '@swc/core': '>=1.2.50' @@ -7834,27 +8480,18 @@ packages: '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.3 - '@types/node': 22.5.4 - acorn: 8.8.2 + '@types/node': 22.9.0 + acorn: 8.11.3 acorn-walk: 8.2.0 arg: 4.1.3 create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 5.6.2 + typescript: 5.6.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 dev: false - /tsconfig-paths@3.14.2: - resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==} - dependencies: - '@types/json5': 0.0.29 - json5: 1.0.2 - minimist: 1.2.8 - strip-bom: 3.0.0 - dev: false - /tsconfig-paths@3.15.0: resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} dependencies: @@ -7912,8 +8549,8 @@ packages: - yaml dev: true - /tsup@8.3.0(typescript@5.6.3): - resolution: {integrity: sha512-ALscEeyS03IomcuNdFdc0YWGVIkwH1Ws7nfTbAPuoILvEV2hpGQAY72LIOjglGo4ShWpZfpBqP/jpQVCzqYQag==} + /tsup@8.3.5(typescript@5.6.3): + resolution: {integrity: sha512-Tunf6r6m6tnZsG9GYWndg0z8dEV7fD733VBFzFJ5Vcm1FtlXB8xBD/rtrBi2a3YKEV7hHtxiZtW5EAVADoe1pA==} engines: {node: '>=18'} hasBin: true peerDependencies: @@ -7931,21 +8568,21 @@ packages: typescript: optional: true dependencies: - bundle-require: 5.0.0(esbuild@0.23.1) + bundle-require: 5.0.0(esbuild@0.24.0) cac: 6.7.14 - chokidar: 3.6.0 + chokidar: 4.0.1 consola: 3.2.3 debug: 4.3.7 - esbuild: 0.23.1 - execa: 5.1.1 + esbuild: 0.24.0 joycon: 3.1.1 - picocolors: 1.1.0 + picocolors: 1.1.1 postcss-load-config: 6.0.1 resolve-from: 5.0.0 - rollup: 4.21.3 + rollup: 4.24.4 source-map: 0.8.0-beta.0 sucrase: 3.35.0 - tinyglobby: 0.2.6 + tinyexec: 0.3.1 + tinyglobby: 0.2.10 tree-kill: 1.2.2 typescript: 5.6.3 transitivePeerDependencies: @@ -7964,6 +8601,16 @@ packages: tslib: 1.14.1 typescript: 5.6.2 + /tsutils@3.21.0(typescript@5.6.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: 5.6.3 + dev: false + /turbo-darwin-64@1.12.4: resolution: {integrity: sha512-dBwFxhp9isTa9RS/fz2gDVk5wWhKQsPQMozYhjM7TT4jTrnYn0ZJMzr7V3B/M/T8QF65TbniW7w1gtgxQgX5Zg==} cpu: [x64] @@ -8108,7 +8755,6 @@ packages: resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} engines: {node: '>=14.17'} hasBin: true - dev: true /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} @@ -8121,18 +8767,16 @@ packages: /undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} - /undici@5.28.2: - resolution: {integrity: sha512-wh1pHJHnUeQV5Xa8/kyQhO7WFa8M34l026L5P/+2TYiakvGy5Rdc8jWZVyG7ieht/0WgJLEd3kcU5gKx+6GC8w==} - engines: {node: '>=14.0'} - dependencies: - '@fastify/busboy': 2.1.0 - dev: false - /undici@5.28.4: resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} engines: {node: '>=14.0'} dependencies: - '@fastify/busboy': 2.1.0 + '@fastify/busboy': 2.1.1 + dev: false + + /undici@6.20.1: + resolution: {integrity: sha512-AjQF1QsmqfJys+LXfGTNum+qw4S88CojRInG/6t31W/1fk6G59s92bnAvGz5Cmur+kQv2SURXEvvudLmbrE8QA==} + engines: {node: '>=18.17'} dev: false /universalify@0.1.2: @@ -8145,34 +8789,34 @@ packages: engines: {node: '>= 4.0.0'} dev: true - /update-browserslist-db@1.0.13(browserslist@4.22.1): + /update-browserslist-db@1.0.13(browserslist@4.23.0): resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: - browserslist: 4.22.1 + browserslist: 4.23.0 escalade: 3.1.1 picocolors: 1.1.0 - dev: false - /update-browserslist-db@1.0.13(browserslist@4.23.0): - resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} + /update-browserslist-db@1.1.1(browserslist@4.24.0): + resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: - browserslist: 4.23.0 - escalade: 3.1.1 + browserslist: 4.24.0 + escalade: 3.2.0 picocolors: 1.1.0 + dev: false - /update-browserslist-db@1.1.1(browserslist@4.24.0): + /update-browserslist-db@1.1.1(browserslist@4.24.2): resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: - browserslist: 4.24.0 + browserslist: 4.24.2 escalade: 3.2.0 picocolors: 1.1.0 dev: true @@ -8189,12 +8833,12 @@ packages: requires-port: 1.0.0 dev: true - /use-sync-external-store@1.2.0(react@18.2.0): + /use-sync-external-store@1.2.0(react@18.3.1): resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - react: 18.2.0 + react: 18.3.1 dev: false /util-deprecate@1.0.2: @@ -8209,7 +8853,7 @@ packages: resolution: {integrity: sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==} engines: {node: '>=10.12.0'} dependencies: - '@jridgewell/trace-mapping': 0.3.18 + '@jridgewell/trace-mapping': 0.3.25 '@types/istanbul-lib-coverage': 2.0.4 convert-source-map: 1.9.0 @@ -8231,14 +8875,6 @@ packages: dependencies: makeerror: 1.0.12 - /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.11 - dev: false - /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} dev: true @@ -8375,7 +9011,6 @@ packages: ansi-styles: 6.2.1 string-width: 5.1.2 strip-ansi: 7.1.0 - dev: true /wrap-ansi@9.0.0: resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} @@ -8430,17 +9065,10 @@ packages: /yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - /yaml@2.4.5: - resolution: {integrity: sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==} - engines: {node: '>= 14'} - hasBin: true - dev: false - /yaml@2.5.1: resolution: {integrity: sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==} engines: {node: '>= 14'} hasBin: true - dev: true /yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} diff --git a/test/next/.eslintrc.js b/test/next/.eslintrc.js index 7f97c6e29..34c0be4c9 100644 --- a/test/next/.eslintrc.js +++ b/test/next/.eslintrc.js @@ -10,6 +10,9 @@ module.exports = { project: ['./tsconfig.json'], tsconfigRootDir: __dirname, }, + rules: { + 'no-console': 'off', + }, overrides: [ { files: [ diff --git a/test/next/package.json b/test/next/package.json index b3aea05d5..e542965ac 100644 --- a/test/next/package.json +++ b/test/next/package.json @@ -11,36 +11,36 @@ "type-check": "tsc --noEmit" }, "dependencies": { - "@tailwindcss/forms": "0.5.7", - "@types/node": "22.5.4", - "@types/react": "18.2.42", - "@types/react-dom": "18.2.17", + "@tailwindcss/forms": "0.5.9", + "@types/node": "22.9.0", + "@types/react": "18.3.12", + "@types/react-dom": "18.3.1", "@vercel/blob": "workspace:*", "@vercel/edge-config": "workspace:*", "@vercel/postgres": "workspace:*", "@vercel/postgres-kysely": "workspace:*", "@vercel/style-guide": "5.2.0", - "autoprefixer": "10.4.16", - "axios": "1.6.2", - "dotenv": "16.3.1", + "autoprefixer": "10.4.20", + "axios": "1.7.7", + "dotenv": "16.4.5", "eslint": "8.56.0", - "eslint-config-next": "14.0.4", + "eslint-config-next": "14.2.15", "got": "13.0.0", "kysely": "0.26.3", "ms": "2.1.3", - "next": "14.0.4", - "postcss": "8.4.32", - "react": "18.2.0", - "react-dom": "18.2.0", - "swr": "2.2.4", - "tailwindcss": "3.3.6", - "ts-node": "10.9.1", - "typescript": "5.6.2", - "undici": "5.28.2" + "next": "14.2.15", + "postcss": "8.4.47", + "react": "18.3.1", + "react-dom": "18.3.1", + "swr": "2.2.5", + "tailwindcss": "3.4.14", + "ts-node": "10.9.2", + "typescript": "5.6.3", + "undici": "6.20.1" }, "devDependencies": { - "@playwright/test": "1.48.0", - "@types/json-stable-stringify": "1.0.36", + "@playwright/test": "1.48.2", + "@types/json-stable-stringify": "1.1.0", "json-stable-stringify": "1.1.1" } } diff --git a/test/next/playwright.config.ts b/test/next/playwright.config.ts index 5dbe76205..0065429a3 100644 --- a/test/next/playwright.config.ts +++ b/test/next/playwright.config.ts @@ -70,6 +70,12 @@ const config: PlaywrightTestConfig = { ...devices['Desktop Safari'], }, }, + { + name: 'Desktop Edge', + use: { + ...devices['Desktop Edge'], + }, + }, ], }; diff --git a/test/next/public/15mb-video.mp4 b/test/next/public/15mb-video.mp4 new file mode 100644 index 000000000..7281fd83c Binary files /dev/null and b/test/next/public/15mb-video.mp4 differ diff --git a/test/next/src/app/vercel/blob/app/client-multipart/page.tsx b/test/next/src/app/vercel/blob/app/client-multipart/page.tsx index 7c837ef43..c264dcc93 100644 --- a/test/next/src/app/vercel/blob/app/client-multipart/page.tsx +++ b/test/next/src/app/vercel/blob/app/client-multipart/page.tsx @@ -25,11 +25,13 @@ export default function AppClientUpload(): JSX.Element { access: 'public', handleUploadUrl: `/vercel/blob/api/app/handle-blob-upload/edge`, multipart: true, + onUploadProgress(progressEvent) { + console.log('upload progress', progressEvent); + }, }); setBlob(blobResult); } catch (error: unknown) { - // eslint-disable-next-line no-console -- Fine for tests console.log('error', error); } }} diff --git a/test/next/src/app/vercel/blob/app/client/page.tsx b/test/next/src/app/vercel/blob/app/client/page.tsx index 4ca3ee0ad..26ed47a7f 100644 --- a/test/next/src/app/vercel/blob/app/client/page.tsx +++ b/test/next/src/app/vercel/blob/app/client/page.tsx @@ -1,12 +1,18 @@ +/* eslint-disable -- I gave up making TS and ESLint happy here for now */ + 'use client'; import { type PutBlobResult } from '@vercel/blob'; import { upload } from '@vercel/blob/client'; import { useRef, useState } from 'react'; +import { useSearchParams } from 'next/navigation'; export default function AppClientUpload(): JSX.Element { const inputFileRef = useRef(null); const [blob, setBlob] = useState(null); + const [progressEvents, setProgressEvents] = useState([]); + const searchParams = useSearchParams(); + return ( <>

App Router Client Upload

@@ -20,28 +26,70 @@ export default function AppClientUpload(): JSX.Element { return; } - const blobResult = await upload(file.name, file, { - access: 'public', - handleUploadUrl: `/vercel/blob/api/app/handle-blob-upload/edge`, - }); + setProgressEvents([]); // Clear previous events - setBlob(blobResult); + try { + const blobResult = await upload(file.name, file, { + access: 'public', + multipart: searchParams?.get('multipart') === '1', + handleUploadUrl: `/vercel/blob/api/app/handle-blob-upload/serverless`, + onUploadProgress(progressEvent) { + setProgressEvents((prev) => [ + ...prev, + JSON.stringify(progressEvent), + ]); + }, + }); + setBlob(blobResult); + } catch (error) { + console.error(error); + } }} > - + + + {progressEvents.length > 0 && ( +
+

+ Upload Progress Events: +

+
    + {progressEvents.map((event, index) => ( +
  • + {event} +
  • + ))} +
+
+ )} + {blob ? ( -
- Blob url: {blob.url} +
+

+ Blob url:{' '} + + {blob.url} + +

{blob.url.endsWith('.mp4') ? ( - // eslint-disable-next-line jsx-a11y/media-has-caption -- no caption for tests, this is fine -