diff --git a/.eslintrc b/.eslintrc index 4d3e8020fdbb..683087ac0f73 100644 --- a/.eslintrc +++ b/.eslintrc @@ -44,7 +44,8 @@ { "files": ["docs/**", "packages/web-worker/**", "test/web-worker/**"], "rules": { - "no-restricted-globals": "off" + "no-restricted-globals": "off", + "import/first": "off" } }, { diff --git a/docs/.vitepress/style/vars.css b/docs/.vitepress/style/vars.css index 65e72f6fda32..eca8f6b73fcd 100644 --- a/docs/.vitepress/style/vars.css +++ b/docs/.vitepress/style/vars.css @@ -5,17 +5,14 @@ :root { --vp-c-accent: #dab40b; --vp-c-brand: #6da13f; + --vp-c-brand-1: var(--vp-c-brand-dark); + --vp-c-brand-2: var(--vp-c-brand-darker); --vp-c-brand-light: #7ec242; --vp-c-brand-lighter: #93d31c; --vp-c-brand-dark: #668d11; --vp-c-brand-darker: #52730d; --vp-c-text-code: #5d6f5d; --vp-code-block-bg: rgba(125,125,125,0.04); - /* fix TIP on light: the default one is too light (2 in contrast) */ - --vp-custom-block-tip-text: rgb(12, 124, 108); - --vp-custom-block-tip-border: rgba(12, 124, 108, 0.5); - --vp-custom-block-tip-bg: rgba(18, 181, 157, 0.1); - /* fix contrast on gray cards: used by --vp-c-text-2 */ --vp-c-text-light-2: rgba(56 56 56 / 70%); /* fix contrast: lang name on gray code block */ --vp-c-text-dark-3: rgba(180, 180, 180, 0.7); @@ -27,10 +24,6 @@ .dark { --vp-code-block-bg: rgba(0,0,0,0.2); --vp-c-text-code: #c0cec0; - /* fix TIP: check the same above (these are the defaults) */ - --vp-custom-block-tip-text: rgb(18, 181, 157); - --vp-custom-block-tip-border: rgba(18, 181, 157, 0.5); - --vp-custom-block-tip-bg: rgba(18, 181, 157, 0.1); /* fix contrast on gray cards: check the same above (this is the default) */ --vp-c-text-dark-2: rgba(235, 235, 235, 0.60); /* fix lang name: check the same above (this is the default) */ diff --git a/docs/advanced/metadata.md b/docs/advanced/metadata.md index 1e40a6a02be1..d7b852c6bfde 100644 --- a/docs/advanced/metadata.md +++ b/docs/advanced/metadata.md @@ -46,7 +46,7 @@ Vitest uses different methods to communicate with the Node.js process. - If Vitest runs tests inside worker threads, it will send data via [message port](https://developer.mozilla.org/en-US/docs/Web/API/MessagePort) - If Vitest uses child process, the data will be send as a serialized Buffer via [`process.send`](https://nodejs.org/api/process.html#processsendmessage-sendhandle-options-callback) API -- If Vitest run tests in the browser, the data will be stringified using [flatted](https://www.npmjs.com/package/flatted) package +- If Vitest runs tests in the browser, the data will be stringified using [flatted](https://www.npmjs.com/package/flatted) package The general rule of thumb is that you can send almost anything, except for functions, Promises, regexp (`v8.stringify` cannot serialize it, but you can send a string version and parse it in the Node.js process yourself), and other non-serializable data, but you can have cyclic references inside. diff --git a/docs/advanced/reporters.md b/docs/advanced/reporters.md index d3250860e7f8..f78d2926ff53 100644 --- a/docs/advanced/reporters.md +++ b/docs/advanced/reporters.md @@ -58,7 +58,7 @@ export default defineConfig({ ## Exported reporters -`vitest` comes with a few built-in reporters that you can use out of the box. +`vitest` comes with a few [built-in reporters](/guide/reporters) that you can use out of the box. ### Built-in reporters: diff --git a/docs/advanced/runner.md b/docs/advanced/runner.md index 1f80150de190..662a9b582ad8 100644 --- a/docs/advanced/runner.md +++ b/docs/advanced/runner.md @@ -108,7 +108,7 @@ Snapshot support and some other features depend on the runner. If you don't want ## Your task function -You can extend Vitest task system with your tasks. A task is an object that is part of a suite. It is automatically added to the current suite with a `suite.custom` method: +You can extend Vitest task system with your tasks. A task is an object that is part of a suite. It is automatically added to the current suite with a `suite.task` method: ```js // ./utils/custom.js @@ -116,24 +116,27 @@ import { createTaskCollector, getCurrentSuite, setFn } from 'vitest/suite' export { describe, beforeAll, afterAll } from 'vitest' -// this function will be called when Vitest collects tasks -// createTaskCollector just provides all "todo"/"each"/... support, you don't have to use it -// To support custom tasks, you just need to call "getCurrentSuite().task()" -export const myCustomTask = createTaskCollector(function (name, fn, timeout) { - getCurrentSuite().task(name, { - ...this, // so "todo"/"skip" is tracked correctly - meta: { - customPropertyToDifferentiateTask: true - }, - handler: fn, - timeout, - }) -}) +// this function will be called during collection phase: +// don't call function handler here, add it to suite tasks +// with "getCurrentSuite().task()" method +// note: createTaskCollector provides support for "todo"/"each"/... +export const myCustomTask = createTaskCollector( + function (name, fn, timeout) { + getCurrentSuite().task(name, { + ...this, // so "todo"/"skip"/... is tracked correctly + meta: { + customPropertyToDifferentiateTask: true + }, + handler: fn, + timeout, + }) + } +) ``` ```js // ./garden/tasks.test.js -import { afterAll, beforeAll, describe, myCustomTask } from '../utils/custom.js' +import { afterAll, beforeAll, describe, myCustomTask } from '../custom.js' import { gardener } from './gardener.js' describe('take care of the garden', () => { diff --git a/docs/api/mock.md b/docs/api/mock.md index 9f331263029c..fd9d8c0d43ad 100644 --- a/docs/api/mock.md +++ b/docs/api/mock.md @@ -1,6 +1,6 @@ # Mock Functions -You can create a spy function (mock) to track its execution with `vi.fn` method. If you want to track a method on an already created object, you can use `vi.spyOn` method: +You can create a mock function to track its execution with `vi.fn` method. If you want to track a method on an already created object, you can use `vi.spyOn` method: ```js import { vi } from 'vitest' @@ -18,229 +18,244 @@ market.getApples() getApplesSpy.mock.calls.length === 1 ``` -You should use spy assertions (e.g., [`toHaveBeenCalled`](/api/expect#tohavebeencalled)) on [`expect`](/api/expect) to assert spy result. This API reference describes available properties and methods to manipulate spy behavior. +You should use mock assertions (e.g., [`toHaveBeenCalled`](/api/expect#tohavebeencalled)) on [`expect`](/api/expect) to assert mock result. This API reference describes available properties and methods to manipulate mock behavior. + +## getMockImplementation + +- **Type:** `(...args: any) => any` + +Returns current mock implementation if there is one. + +If mock was created with [`vi.fn`](/api/vi#vi-fn), it will consider passed down method as a mock implementation. + +If mock was created with [`vi.spyOn`](/api/vi#vi-spyon), it will return `undefined` unless a custom implementation was provided. ## getMockName - **Type:** `() => string` - Use it to return the name given to mock with method `.mockName(name)`. +Use it to return the name given to mock with method `.mockName(name)`. ## mockClear - **Type:** `() => MockInstance` - Clears all information about every call. After calling it, [`spy.mock.calls`](#mock-calls), [`spy.mock.results`](#mock-results) will return empty arrays. It is useful if you need to clean up spy between different assertions. - - If you want this method to be called before each test automatically, you can enable [`clearMocks`](/config/#clearmocks) setting in config. +Clears all information about every call. After calling it, all properties on `.mock` will return empty state. This method does not reset implementations. It is useful if you need to clean up mock between different assertions. +If you want this method to be called before each test automatically, you can enable [`clearMocks`](/config/#clearmocks) setting in config. ## mockName - **Type:** `(name: string) => MockInstance` - Sets internal mock name. Useful to see what mock has failed the assertion. +Sets internal mock name. Useful to see the name of the mock if assertion fails. ## mockImplementation - **Type:** `(fn: Function) => MockInstance` - Accepts a function that will be used as an implementation of the mock. - - For example: +Accepts a function that will be used as an implementation of the mock. - ```ts - const mockFn = vi.fn().mockImplementation(apples => apples + 1) - // or: vi.fn(apples => apples + 1); +```ts +const mockFn = vi.fn().mockImplementation(apples => apples + 1) +// or: vi.fn(apples => apples + 1); - const NelliesBucket = mockFn(0) - const BobsBucket = mockFn(1) +const NelliesBucket = mockFn(0) +const BobsBucket = mockFn(1) - NelliesBucket === 1 // true - BobsBucket === 2 // true +NelliesBucket === 1 // true +BobsBucket === 2 // true - mockFn.mock.calls[0][0] === 0 // true - mockFn.mock.calls[1][0] === 1 // true - ``` +mockFn.mock.calls[0][0] === 0 // true +mockFn.mock.calls[1][0] === 1 // true +``` ## mockImplementationOnce - **Type:** `(fn: Function) => MockInstance` - Accepts a function that will be used as an implementation of the mock for one call to the mocked function. Can be chained so that multiple function calls produce different results. +Accepts a function that will be used as mock's implementation during the next call. Can be chained so that multiple function calls produce different results. - ```ts - const myMockFn = vi - .fn() - .mockImplementationOnce(() => true) - .mockImplementationOnce(() => false) +```ts +const myMockFn = vi + .fn() + .mockImplementationOnce(() => true) + .mockImplementationOnce(() => false) - myMockFn() // true - myMockFn() // false - ``` +myMockFn() // true +myMockFn() // false +``` - When the mocked function runs out of implementations, it will invoke the default implementation that was set with `vi.fn(() => defaultValue)` or `.mockImplementation(() => defaultValue)` if they were called: +When the mocked function runs out of implementations, it will invoke the default implementation that was set with `vi.fn(() => defaultValue)` or `.mockImplementation(() => defaultValue)` if they were called: - ```ts - const myMockFn = vi - .fn(() => 'default') - .mockImplementationOnce(() => 'first call') - .mockImplementationOnce(() => 'second call') +```ts +const myMockFn = vi + .fn(() => 'default') + .mockImplementationOnce(() => 'first call') + .mockImplementationOnce(() => 'second call') - // 'first call', 'second call', 'default', 'default' - console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn()) - ``` +// 'first call', 'second call', 'default', 'default' +console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn()) +``` ## withImplementation - **Type:** `(fn: Function, callback: () => void) => MockInstance` - **Type:** `(fn: Function, callback: () => Promise) => Promise` - Overrides the original mock implementation temporarily while the callback is being executed. +Overrides the original mock implementation temporarily while the callback is being executed. - ```js - const myMockFn = vi.fn(() => 'original') +```js +const myMockFn = vi.fn(() => 'original') - myMockFn.withImplementation(() => 'temp', () => { - myMockFn() // 'temp' - }) +myMockFn.withImplementation(() => 'temp', () => { + myMockFn() // 'temp' +}) - myMockFn() // 'original' - ``` +myMockFn() // 'original' +``` - Can be used with an asynchronous callback. The method has to be awaited to use the original implementation afterward. +Can be used with an asynchronous callback. The method has to be awaited to use the original implementation afterward. - ```ts - test('async callback', () => { - const myMockFn = vi.fn(() => 'original') +```ts +test('async callback', () => { + const myMockFn = vi.fn(() => 'original') - // We await this call since the callback is async - await myMockFn.withImplementation( - () => 'temp', - async () => { - myMockFn() // 'temp' - }, - ) + // We await this call since the callback is async + await myMockFn.withImplementation( + () => 'temp', + async () => { + myMockFn() // 'temp' + }, + ) - myMockFn() // 'original' - }) - ``` + myMockFn() // 'original' +}) +``` - Also, it takes precedence over the [`mockImplementationOnce`](https://vitest.dev/api/mock.html#mockimplementationonce). +Note that this method takes precedence over the [`mockImplementationOnce`](https://vitest.dev/api/mock.html#mockimplementationonce). ## mockRejectedValue - **Type:** `(value: any) => MockInstance` - Accepts an error that will be rejected, when async function will be called. +Accepts an error that will be rejected when async function is called. - ```ts - const asyncMock = vi.fn().mockRejectedValue(new Error('Async error')) +```ts +const asyncMock = vi.fn().mockRejectedValue(new Error('Async error')) - await asyncMock() // throws "Async error" - ``` +await asyncMock() // throws "Async error" +``` ## mockRejectedValueOnce - **Type:** `(value: any) => MockInstance` - Accepts a value that will be rejected for one call to the mock function. If chained, every consecutive call will reject passed value. +Accepts a value that will be rejected during the next function call. If chained, every consecutive call will reject specified value. - ```ts - const asyncMock = vi - .fn() - .mockResolvedValueOnce('first call') - .mockRejectedValueOnce(new Error('Async error')) +```ts +const asyncMock = vi + .fn() + .mockResolvedValueOnce('first call') + .mockRejectedValueOnce(new Error('Async error')) - await asyncMock() // first call - await asyncMock() // throws "Async error" - ``` +await asyncMock() // first call +await asyncMock() // throws "Async error" +``` ## mockReset - **Type:** `() => MockInstance` - Does what `mockClear` does and makes inner implementation an empty function (returning `undefined`, when invoked). This is useful when you want to completely reset a mock back to its initial state. +Does what `mockClear` does and makes inner implementation an empty function (returning `undefined` when invoked). This also resets all "once" implementations. This is useful when you want to completely reset a mock to the default state. - If you want this method to be called before each test automatically, you can enable [`mockReset`](/config/#mockreset) setting in config. +If you want this method to be called before each test automatically, you can enable [`mockReset`](/config/#mockreset) setting in config. ## mockRestore - **Type:** `() => MockInstance` - Does what `mockReset` does and restores inner implementation to the original function. +Does what `mockReset` does and restores inner implementation to the original function. - Note that restoring mock from `vi.fn()` will set implementation to an empty function that returns `undefined`. Restoring a `vi.fn(impl)` will restore implementation to `impl`. +Note that restoring mock from `vi.fn()` will set implementation to an empty function that returns `undefined`. Restoring a `vi.fn(impl)` will restore implementation to `impl`. - If you want this method to be called before each test automatically, you can enable [`restoreMocks`](/config/#restoreMocks) setting in config. +If you want this method to be called before each test automatically, you can enable [`restoreMocks`](/config/#restoreMocks) setting in config. ## mockResolvedValue - **Type:** `(value: any) => MockInstance` - Accepts a value that will be resolved, when async function will be called. +Accepts a value that will be resolved when async function is called. - ```ts - const asyncMock = vi.fn().mockResolvedValue(43) +```ts +const asyncMock = vi.fn().mockResolvedValue(42) - await asyncMock() // 43 - ``` +await asyncMock() // 42 +``` ## mockResolvedValueOnce - **Type:** `(value: any) => MockInstance` - Accepts a value that will be resolved for one call to the mock function. If chained, every consecutive call will resolve passed value. +Accepts a value that will be resolved during the next function call. If chained, every consecutive call will resolve specified value. - ```ts - const asyncMock = vi - .fn() - .mockResolvedValue('default') - .mockResolvedValueOnce('first call') - .mockResolvedValueOnce('second call') +```ts +const asyncMock = vi + .fn() + .mockResolvedValue('default') + .mockResolvedValueOnce('first call') + .mockResolvedValueOnce('second call') - await asyncMock() // first call - await asyncMock() // second call - await asyncMock() // default - await asyncMock() // default - ``` +await asyncMock() // first call +await asyncMock() // second call +await asyncMock() // default +await asyncMock() // default +``` ## mockReturnThis - **Type:** `() => MockInstance` - Sets inner implementation to return `this` context. +Use this if you need to return `this` context from the method without invoking actual implementation. This is a shorthand for: + +```ts +spy.mockImplementation(function () { + return this +}) +``` ## mockReturnValue - **Type:** `(value: any) => MockInstance` - Accepts a value that will be returned whenever the mock function is called. +Accepts a value that will be returned whenever the mock function is called. - ```ts - const mock = vi.fn() - mock.mockReturnValue(42) - mock() // 42 - mock.mockReturnValue(43) - mock() // 43 - ``` +```ts +const mock = vi.fn() +mock.mockReturnValue(42) +mock() // 42 +mock.mockReturnValue(43) +mock() // 43 +``` ## mockReturnValueOnce - **Type:** `(value: any) => MockInstance` - Accepts a value that will be returned for one call to the mock function. If chained, every consecutive call will return the passed value. When there are no more `mockReturnValueOnce` values to use, call a function specified by `mockImplementation` or other `mockReturn*` methods. +Accepts a value that will be returned during the next function call. If chained, every consecutive call will return the specified value. + +When there are no more `mockReturnValueOnce` values to use, mock will fallback to preivously defined implementation if there is one. - ```ts - const myMockFn = vi - .fn() - .mockReturnValue('default') - .mockReturnValueOnce('first call') - .mockReturnValueOnce('second call') +```ts +const myMockFn = vi + .fn() + .mockReturnValue('default') + .mockReturnValueOnce('first call') + .mockReturnValueOnce('second call') - // 'first call', 'second call', 'default', 'default' - console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn()) - ``` +// 'first call', 'second call', 'default', 'default' +console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn()) +``` ## mock.calls @@ -250,29 +265,31 @@ This is an array containing all arguments for each call. One item of the array i const fn = vi.fn() fn('arg1', 'arg2') -fn('arg3', 'arg4') +fn('arg3') fn.mock.calls === [ ['arg1', 'arg2'], // first call - ['arg3', 'arg4'], // second call + ['arg3'], // second call ] ``` ## mock.lastCall -This contains the arguments of the last call. If spy wasn't called, will return `undefined`. +This contains the arguments of the last call. If mock wasn't called, will return `undefined`. ## mock.results -This is an array containing all values, that were `returned` from the function. One item of the array is an object with properties `type` and `value`. Available types are: +This is an array containing all values that were `returned` from the function. One item of the array is an object with properties `type` and `value`. Available types are: - `'return'` - function returned without throwing. - `'throw'` - function threw a value. -The `value` property contains the returned value or thrown error. If the function returned a promise, when it resolves the `value` property will become the value the promise resolved to. +The `value` property contains the returned value or thrown error. If the function returned a promise, the `value` will be the _resolved_ value, not the actual `Promise`, unless it was never resolved. ```js const fn = vi.fn() + .mockReturnValueOnce('result') + .mockImplementationOnce(() => { throw new Error('thrown error') }) const result = fn() // returned 'result' @@ -295,9 +312,25 @@ fn.mock.results === [ ] ``` +## mock.invocationCallOrder + +The order of mock's execution. This returns an array of numbers that are shared between all defined mocks. + +```js +const fn1 = vi.fn() +const fn2 = vi.fn() + +fn1() +fn2() +fn1() + +fn1.mock.invocationCallOrder === [1, 3] +fn2.mock.invocationCallOrder === [2] +``` + ## mock.instances -This is an array containing all instances that were instantiated when mock was called with a `new` keyword. Note, this is an actual context (`this`) of the function, not a return value. +This is an array containing all instances that were instantiated when mock was called with a `new` keyword. Note that this is an actual context (`this`) of the function, not a return value. ::: warning If mock was instantiated with `new MyClass()`, then `mock.instances` will be an array with one value: diff --git a/docs/api/vi.md b/docs/api/vi.md index c949bc09c06a..d63cc86d6aed 100644 --- a/docs/api/vi.md +++ b/docs/api/vi.md @@ -1,409 +1,432 @@ +--- +outline: deep +--- + # Vi -Vitest provides utility functions to help you out through its `vi` helper. You can access it globally (when [globals configuration](/config/#globals) is **enabled**), or import from `vitest`: +Vitest provides utility functions to help you out through its `vi` helper. You can access it globally (when [globals configuration](/config/#globals) is enabled), or import it from `vitest` directly: ```js import { vi } from 'vitest' ``` -## vi.advanceTimersByTime - -- **Type:** `(ms: number) => Vitest` - - Works just like `runAllTimers`, but will end after passed milliseconds. For example this will log `1, 2, 3` and will not throw: - - ```ts - let i = 0 - setInterval(() => console.log(++i), 50) +## Mock Modules - vi.advanceTimersByTime(150) - ``` +This section describes the API that you can use when [mocking a module](/guide/mocking#modules). Beware that Vitest doesn't support mocking modules imported using `require()`. -### vi.advanceTimersByTimeAsync - -- **Type:** `(ms: number) => Promise` +### vi.mock - Works just like `runAllTimersAsync`, but will end after passed milliseconds. This will include asynchronously set timers. For example this will log `1, 2, 3` and will not throw: +- **Type**: `(path: string, factory?: (importOriginal: () => unknown) => unknown) => void` - ```ts - let i = 0 - setInterval(() => Promise.resolve().then(() => console.log(++i)), 50) +Substitutes all imported modules from provided `path` with another module. You can use configured Vite aliases inside a path. The call to `vi.mock` is hoisted, so it doesn't matter where you call it. It will always be executed before all imports. If you need to reference some variables outside of its scope, you can define them inside [`vi.hoisted`](/api/vi#vi-hoisted) and reference them inside `vi.mock`. - await vi.advanceTimersByTimeAsync(150) - ``` +::: warning +`vi.mock` works only for modules that were imported with the `import` keyword. It doesn't work with `require`. -## vi.advanceTimersToNextTimer +In order to hoist `vi.mock`, Vitest statically analyzes your files. It indicates that `vi` that was not directly imported from the `vitest` package (for example, from some utility file) cannot be used. Use `vi.mock` with `vi` imported from `vitest`, or enable [`globals`](/config/#globals) config option. -- **Type:** `() => Vitest` +Vitest will not mock modules that were imported inside a [setup file](/config/#setupfiles) because they are cached by the time a test file is running. You can call [`vi.resetModules()`](#vi-resetmodules) inside [`vi.hoisted`](#vi-hoisted) to clear all module caches before running a test file. +::: - Will call next available timer. Useful to make assertions between each timer call. You can chain call it to manage timers by yourself. +::: warning +The [browser mode](/guide/browser) does not presently support mocking modules. You can track this feature in the GitHub issue. +::: - ```ts - let i = 0 - setInterval(() => console.log(++i), 50) +If `factory` is defined, all imports will return its result. Vitest calls factory only once and caches results for all subsequent imports until [`vi.unmock`](#vi-unmock) or [`vi.doUnmock`](#vi-dounmock) is called. - vi.advanceTimersToNextTimer() // log 1 - .advanceTimersToNextTimer() // log 2 - .advanceTimersToNextTimer() // log 3 - ``` +Unlike in `jest`, the factory can be asynchronous, so you can use [`vi.importActual`](#vi-importactual) or a helper, received as the first argument, inside to get the original module. -### vi.advanceTimersToNextTimerAsync +```js +// when using JavaScript + +vi.mock('./path/to/module.js', async (importOriginal) => { + const mod = await importOriginal() + return { + ...mod, + // replace some exports + namedExport: vi.fn(), + } +}) +``` -- **Type:** `() => Promise` +```ts +// when using TypeScript + +vi.mock('./path/to/module.js', async (importOriginal) => { + const mod = await importOriginal() + return { + ...mod, + // replace some exports + namedExport: vi.fn(), + } +}) +``` - Will call next available timer even if it was set asynchronously. Useful to make assertions between each timer call. You can chain call it to manage timers by yourself. +::: warning +`vi.mock` is hoisted (in other words, _moved_) to **top of the file**. It means that whenever you write it (be it inside `beforeEach` or `test`), it will actually be called before that. - ```ts - let i = 0 - setInterval(() => Promise.resolve().then(() => console.log(++i)), 50) +This also means that you cannot use any variables inside the factory that are defined outside the factory. - vi.advanceTimersToNextTimerAsync() // log 1 - .advanceTimersToNextTimerAsync() // log 2 - .advanceTimersToNextTimerAsync() // log 3 - ``` +If you need to use variables inside the factory, try [`vi.doMock`](#vi-domock). It works the same way but isn't hoisted. Beware that it only mocks subsequent imports. -## vi.getTimerCount +You can also reference variables defined by `vi.hoisted` method if it was declared before `vi.mock`: -- **Type:** `() => number` +```ts +import { namedExport } from './path/to/module.js' - Get the number of waiting timers. +const mocks = vi.hoisted(() => { + return { + namedExport: vi.fn(), + } +}) -## vi.clearAllMocks +vi.mock('./path/to/module.js', () => { + return { + namedExport: mocks.namedExport, + } +}) - Will call [`.mockClear()`](/api/mock#mockclear) on all spies. This will clear mock history, but not reset its implementation to the default one. +vi.mocked(namedExport).mockReturnValue(100) -## vi.clearAllTimers +expect(namedExport()).toBe(100) +expect(namedExport).toBe(mocks.namedExport) +``` +::: - Removes all timers that are scheduled to run. These timers will never run in the future. +::: warning +If you are mocking a module with default export, you will need to provide a `default` key within the returned factory function object. This is an ES module-specific caveat; therefore, `jest` documentation may differ as `jest` uses CommonJS modules. For example, -## vi.dynamicImportSettled +```ts +vi.mock('./path/to/module.js', () => { + return { + default: { myDefaultKey: vi.fn() }, + namedExport: vi.fn(), + // etc... + } +}) +``` +::: - Wait for all imports to load. Useful, if you have a synchronous call that starts importing a module, that you cannot wait otherwise. +If there is a `__mocks__` folder alongside a file that you are mocking, and the factory is not provided, Vitest will try to find a file with the same name in the `__mocks__` subfolder and use it as an actual module. If you are mocking a dependency, Vitest will try to find a `__mocks__` folder in the [root](/config/#root) of the project (default is `process.cwd()`). You can tell Vitest where the dependencies are located through the [deps.moduleDirectories](/config/#deps-moduledirectories) config option. -## vi.fn +For example, you have this file structure: -- **Type:** `(fn?: Function) => Mock` +``` +- __mocks__ + - axios.js +- src + __mocks__ + - increment.js + - increment.js +- tests + - increment.test.js +``` - Creates a spy on a function, though can be initiated without one. Every time a function is invoked, it stores its call arguments, returns, and instances. Also, you can manipulate its behavior with [methods](/api/mock). - If no function is given, mock will return `undefined`, when invoked. +If you call `vi.mock` in a test file without a factory provided, it will find a file in the `__mocks__` folder to use as a module: - ```ts - const getApples = vi.fn(() => 0) +```ts +// increment.test.js +import { vi } from 'vitest' - getApples() +// axios is a default export from `__mocks__/axios.js` +import axios from 'axios' - expect(getApples).toHaveBeenCalled() - expect(getApples).toHaveReturnedWith(0) +// increment is a named export from `src/__mocks__/increment.js` +import { increment } from '../increment.js' - getApples.mockReturnValueOnce(5) +vi.mock('axios') +vi.mock('../increment.js') - const res = getApples() - expect(res).toBe(5) - expect(getApples).toHaveNthReturnedWith(2, 5) - ``` +axios.get(`/apples/${increment(1)}`) +``` -## vi.getMockedSystemTime +::: warning +Beware that if you don't call `vi.mock`, modules **are not** mocked automatically. To replicate Jest's automocking behaviour, you can call `vi.mock` for each required module inside [`setupFiles`](/config/#setupfiles). +::: -- **Type**: `() => Date | null` +If there is no `__mocks__` folder or a factory provided, Vitest will import the original module and auto-mock all its exports. For the rules applied, see [algorithm](/guide/mocking#automocking-algorithm). - Returns mocked current date that was set using `setSystemTime`. If date is not mocked, will return `null`. +### vi.doMock -## vi.getRealSystemTime +- **Type**: `(path: string, factory?: (importOriginal: () => unknown) => unknown) => void` -- **Type**: `() => number` +The same as [`vi.mock`](#vi-mock), but it's not hoisted to the top of the file, so you can reference variables in the global file scope. The next [dynamic import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) of the module will be mocked. - When using `vi.useFakeTimers`, `Date.now` calls are mocked. If you need to get real time in milliseconds, you can call this function. +::: warning +This will not mock modules that were imported before this was called. Don't forget that all static imports in ESM are always [hoisted](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#hoisting), so putting this before static import will not force it to be called before the import: -## vi.hoisted +```ts +vi.doMock('./increment.js') // this will be called _after_ the import statement -- **Type**: `(factory: () => T) => T` -- **Version**: Since Vitest 0.31.0 +import { increment } from './increment.js' +``` +::: - All static `import` statements in ES modules are hoisted to top of the file, so any code that is define before the imports will actually be executed after imports are evaluated. +```ts +// ./increment.js +export function increment(number) { + return number + 1 +} +``` - Hovewer it can be useful to invoke some side effect like mocking dates before importing a module. +```ts +import { beforeEach, test } from 'vitest' +import { increment } from './increment.js' - To bypass this limitation, you can rewrite static imports into dynamic ones like this: +// the module is not mocked, because vi.doMock is not called yet +increment(1) === 2 - ```diff - callFunctionWithSideEffect() - - import { value } from './some/module.ts' - + const { value } = await import('./some/module.ts') - ``` +let mockedIncrement = 100 - When running `vitest`, you can do this automatically by using `vi.hoisted` method. +beforeEach(() => { + // you can access variables inside a factory + vi.doMock('./increment.js', () => ({ increment: () => ++mockedIncrement })) +}) - ```diff - - callFunctionWithSideEffect() - import { value } from './some/module.ts' - + vi.hoisted(() => callFunctionWithSideEffect()) - ``` +test('importing the next module imports mocked one', async () => { + // original import WAS NOT MOCKED, because vi.doMock is evaluated AFTER imports + expect(increment(1)).toBe(2) + const { increment: mockedIncrement } = await import('./increment.js') + // new dynamic import returns mocked module + expect(mockedIncrement(1)).toBe(101) + expect(mockedIncrement(1)).toBe(102) + expect(mockedIncrement(1)).toBe(103) +}) +``` - This method returns the value that was returned from the factory. You can use that value in your `vi.mock` factories if you need an easy access to locally defined variables: +### vi.mocked - ```ts - import { expect, vi } from 'vitest' - import { originalMethod } from './path/to/module.js' +- **Type**: `(obj: T, deep?: boolean) => MaybeMockedDeep` +- **Type**: `(obj: T, options?: { partial?: boolean; deep?: boolean }) => MaybePartiallyMockedDeep` - const { mockedMethod } = vi.hoisted(() => { - return { mockedMethod: vi.fn() } - }) +Type helper for TypeScript. Just returns the object that was passed. - vi.mock('./path/to/module.js', () => { - return { originalMethod: mockedMethod } - }) +When `partial` is `true` it will expect a `Partial` as a return value. By default, this will only make TypeScript believe that the first level values are mocked. You can pass down `{ deep: true }` as a second argument to tell TypeScript that the whole object is mocked, if it actually is. - mockedMethod.mockReturnValue(100) - expect(originalMethod()).toBe(100) - ``` +```ts +import example from './example.js' +vi.mock('./example.js') -## vi.mock +test('1 + 1 equals 10', async () => { + vi.mocked(example.calc).mockReturnValue(10) + expect(example.calc(1, '+', 1)).toBe(10) +}) +``` -- **Type**: `(path: string, factory?: () => unknown) => void` +### vi.importActual - Substitutes all imported modules from provided `path` with another module. You can use configured Vite aliases inside a path. The call to `vi.mock` is hoisted, so it doesn't matter where you call it. It will always be executed before all imports. If you need to reference some variables outside of its scope, you can define them inside [`vi.hoisted`](/api/vi#vi-hoisted) and reference them inside `vi.mock`. +- **Type**: `(path: string) => Promise` - ::: warning - `vi.mock` works only for modules that were imported with the `import` keyword. It doesn't work with `require`. +Imports module, bypassing all checks if it should be mocked. Can be useful if you want to mock module partially. - Vitest statically analyzes your files to hoist `vi.mock`. It means that you cannot use `vi` that was not imported directly from `vitest` package (for example, from some utility file). To fix this, always use `vi.mock` with `vi` imported from `vitest`, or enable [`globals`](/config/#globals) config option. - ::: +```ts +vi.mock('./example.js', async () => { + const axios = await vi.importActual('./example.js') - ::: warning - Mocking modules is not currently supported in the [browser mode](/guide/browser). You can track this feature in the GitHub issue. - ::: + return { ...axios, get: vi.fn() } +}) +``` - If `factory` is defined, all imports will return its result. Vitest calls factory only once and caches result for all subsequent imports until [`vi.unmock`](#vi-unmock) or [`vi.doUnmock`](#vi-dounmock) is called. +### vi.importMock - Unlike in `jest`, the factory can be asynchronous, so you can use [`vi.importActual`](#vi-importactual) or a helper, received as the first argument, inside to get the original module. +- **Type**: `(path: string) => Promise>` - ```ts - vi.mock('./path/to/module.js', async (importOriginal) => { - const mod = await importOriginal() - return { - ...mod, - // replace some exports - namedExport: vi.fn(), - } - }) - ``` +Imports a module with all of its properties (including nested properties) mocked. Follows the same rules that [`vi.mock`](#vi-mock) does. For the rules applied, see [algorithm](/guide/mocking#automocking-algorithm). - ::: warning - `vi.mock` is hoisted (in other words, _moved_) to **top of the file**. It means that whenever you write it (be it inside `beforeEach` or `test`), it will actually be called before that. +### vi.unmock - This also means that you cannot use any variables inside the factory that are defined outside the factory. +- **Type**: `(path: string) => void` - If you need to use variables inside the factory, try [`vi.doMock`](#vi-domock). It works the same way but isn't hoisted. Beware that it only mocks subsequent imports. +Removes module from the mocked registry. All calls to import will return the original module even if it was mocked before. This call is hoisted to the top of the file, so it will only unmock modules that were defined in `setupFiles`, for example. - You can also reference variables defined by `vi.hoisted` method if it was declared before `vi.mock`: +### vi.doUnmock - ```ts - import { namedExport } from './path/to/module.js' +- **Type**: `(path: string) => void` - const mocks = vi.hoisted(() => { - return { - namedExport: vi.fn(), - } - }) +The same as [`vi.unmock`](#vi-unmock), but is not hoisted to the top of the file. The next import of the module will import the original module instead of the mock. This will not unmock previously imported modules. - vi.mock('./path/to/module.js', () => { - return { - namedExport: mocks.namedExport, - } - }) +```ts +// ./increment.js +export function increment(number) { + return number + 1 +} +``` - vi.mocked(namedExport).mockReturnValue(100) +```ts +import { increment } from './increment.js' - expect(namedExport()).toBe(100) - expect(namedExport).toBe(mocks.namedExport) - ``` - ::: +// increment is already mocked, because vi.mock is hoisted +increment(1) === 100 - ::: warning - If you are mocking a module with default export, you will need to provide a `default` key within the returned factory function object. This is an ES modules-specific caveat, therefore `jest` documentation may differ as `jest` uses CommonJS modules. For example, +// this is hoisted, and factory is called before the import on line 1 +vi.mock('./increment.js', () => ({ increment: () => 100 })) - ```ts - vi.mock('./path/to/module.js', () => { - return { - default: { myDefaultKey: vi.fn() }, - namedExport: vi.fn(), - // etc... - } - }) - ``` - ::: +// all calls are mocked, and `increment` always returns 100 +increment(1) === 100 +increment(30) === 100 - If there is a `__mocks__` folder alongside a file that you are mocking, and the factory is not provided, Vitest will try to find a file with the same name in the `__mocks__` subfolder and use it as an actual module. If you are mocking a dependency, Vitest will try to find a `__mocks__` folder in the [root](/config/#root) of the project (default is `process.cwd()`). You can tell Vitest where the dependencies are located through the [deps.moduleDirectories](/config/#deps-moduledirectories) config option. +// this is not hoisted, so other import will return unmocked module +vi.doUnmock('./increment.js') - For example, you have this file structure: +// this STILL returns 100, because `vi.doUnmock` doesn't reevaluate a module +increment(1) === 100 +increment(30) === 100 - ``` - - __mocks__ - - axios.js - - src - __mocks__ - - increment.js - - increment.js - - tests - - increment.test.js - ``` +// the next import is unmocked, now `increment` is the original function that returns count + 1 +const { increment: unmockedIncrement } = await import('./increment.js') - If you call `vi.mock` in a test file without a factory provided, it will find a file in the `__mocks__` folder to use as a module: +unmockedIncrement(1) === 2 +unmockedIncrement(30) === 31 +``` - ```ts - // increment.test.js - import { vi } from 'vitest' +### vi.resetModules - // axios is a default export from `__mocks__/axios.js` - import axios from 'axios' +- **Type**: `() => Vitest` - // increment is a named export from `src/__mocks__/increment.js` - import { increment } from '../increment.js' +Resets modules registry by clearing the cache of all modules. This allows modules to be reevaluated when reimported. Top-level imports cannot be re-evaluated. Might be useful to isolate modules where local state conflicts between tests. - vi.mock('axios') - vi.mock('../increment.js') +```ts +import { vi } from 'vitest' - axios.get(`/apples/${increment(1)}`) - ``` +import { data } from './data.js' // Will not get reevaluated beforeEach test - ::: warning - Beware that if you don't call `vi.mock`, modules **are not** mocked automatically. To replicate Jest's automocking behaviour, you can call `vi.mock` for each required module inside [`setupFiles`](/config/#setupfiles). - ::: +beforeEach(() => { + vi.resetModules() +}) - If there is no `__mocks__` folder or a factory provided, Vitest will import the original module and auto-mock all its exports. For the rules applied, see [algorithm](/guide/mocking#automocking-algorithm). +test('change state', async () => { + const mod = await import('./some/path.js') // Will get reevaluated + mod.changeLocalState('new value') + expect(mod.getLocalState()).toBe('new value') +}) -## vi.doMock +test('module has old state', async () => { + const mod = await import('./some/path.js') // Will get reevaluated + expect(mod.getLocalState()).toBe('old value') +}) +``` -- **Type**: `(path: string, factory?: () => unknown) => void` +::: warning +Does not reset mocks registry. To clear mocks registry, use [`vi.unmock`](#vi-unmock) or [`vi.doUnmock`](#vi-dounmock). +::: - The same as [`vi.mock`](#vi-mock), but it's not hoisted at the top of the file, so you can reference variables in the global file scope. The next [dynamic import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) of the module will be mocked. This will not mock modules that were imported before this was called. +### vi.dynamicImportSettled -```ts -// ./increment.js -export function increment(number) { - return number + 1 -} -``` +Wait for all imports to load. Useful, if you have a synchronous call that starts importing a module that you cannot wait otherwise. ```ts -import { beforeEach, test } from 'vitest' -import { increment } from './increment.js' +import { expect, test } from 'vitest' -// the module is not mocked, because vi.doMock is not called yet -increment(1) === 2 - -let mockedIncrement = 100 - -beforeEach(() => { - // you can access variables inside a factory - vi.doMock('./increment.js', () => ({ increment: () => ++mockedIncrement })) -}) +// cannot track import because Promise is not returned +function renderComponent() { + import('./component.js').then(({ render }) => { + render() + }) +} -test('importing the next module imports mocked one', async () => { - // original import WAS NOT MOCKED, because vi.doMock is evaluated AFTER imports - expect(increment(1)).toBe(2) - const { increment: mockedIncrement } = await import('./increment.js') - // new dynamic import returns mocked module - expect(mockedIncrement(1)).toBe(101) - expect(mockedIncrement(1)).toBe(102) - expect(mockedIncrement(1)).toBe(103) +test('operations are resolved', async () => { + renderComponent() + await vi.dynamicImportSettled() + expect(document.querySelector('.component')).not.toBeNull() }) ``` -## vi.mocked +::: tip +If during a dynamic import another dynamic import is initiated, this method will wait unti all of them are resolved. -- **Type**: `(obj: T, deep?: boolean) => MaybeMockedDeep` -- **Type**: `(obj: T, options?: { partial?: boolean; deep?: boolean }) => MaybePartiallyMockedDeep` +This method will also wait for the next `setTimeout` tick after the import is resolved so all synchronous operations should be completed by the time it's resolved. +::: - Type helper for TypeScript. In reality just returns the object that was passed. +## Mocking Functions and Objects - When `partial` is `true` it will expect a `Partial` as a return value. - ```ts - import example from './example.js' +This section describes how to work with [method mocks](/api/mock) and replace environmental and global variables. - vi.mock('./example.js') +### vi.fn - test('1+1 equals 2', async () => { - vi.mocked(example.calc).mockRestore() +- **Type:** `(fn?: Function) => Mock` - const res = example.calc(1, '+', 1) +Creates a spy on a function, though can be initiated without one. Every time a function is invoked, it stores its call arguments, returns, and instances. Also, you can manipulate its behavior with [methods](/api/mock). +If no function is given, mock will return `undefined`, when invoked. - expect(res).toBe(2) - }) - ``` +```ts +const getApples = vi.fn(() => 0) -## vi.importActual +getApples() -- **Type**: `(path: string) => Promise` +expect(getApples).toHaveBeenCalled() +expect(getApples).toHaveReturnedWith(0) - Imports module, bypassing all checks if it should be mocked. Can be useful if you want to mock module partially. +getApples.mockReturnValueOnce(5) - ```ts - vi.mock('./example.js', async () => { - const axios = await vi.importActual('./example.js') +const res = getApples() +expect(res).toBe(5) +expect(getApples).toHaveNthReturnedWith(2, 5) +``` - return { ...axios, get: vi.fn() } - }) - ``` +### vi.isMockFunction -## vi.importMock +- **Type:** `(fn: Function) => boolean` -- **Type**: `(path: string) => Promise>` +Checks that a given parameter is a mock function. If you are using TypeScript, it will also narrow down its type. - Imports a module with all of its properties (including nested properties) mocked. Follows the same rules that [`vi.mock`](#vi-mock) follows. For the rules applied, see [algorithm](/guide/mocking#automocking-algorithm). +### vi.clearAllMocks -## vi.resetAllMocks +Will call [`.mockClear()`](/api/mock#mockclear) on all spies. This will clear mock history, but not reset its implementation to the default one. - Will call [`.mockReset()`](/api/mock#mockreset) on all spies. This will clear mock history and reset its implementation to an empty function (will return `undefined`). +### vi.resetAllMocks -## vi.resetConfig +Will call [`.mockReset()`](/api/mock#mockreset) on all spies. This will clear mock history and reset its implementation to an empty function (will return `undefined`). -- **Type**: `RuntimeConfig` +### vi.restoreAllMocks - If [`vi.setConfig`](#vi-setconfig) was called before, this will reset config to the original state. +Will call [`.mockRestore()`](/api/mock#mockrestore) on all spies. This will clear mock history and reset its implementation to the original one. -## vi.resetModules +### vi.spyOn -- **Type**: `() => Vitest` +- **Type:** `(object: T, method: K, accessType?: 'get' | 'set') => MockInstance` - Resets modules registry by clearing cache of all modules. This allows modules to be reevaluated when reimported. Top-level imports cannot be reevaluated. Might be useful to isolate modules where local state conflicts between tests. +Creates a spy on a method or getter/setter of an object simillar to [`vi.fn()`](/#vi-fn). It returns a [mock function](/api/mock). - ```ts - import { vi } from 'vitest' +```ts +let apples = 0 +const cart = { + getApples: () => 42, +} - import { data } from './data.js' // Will not get reevaluated beforeEach test +const spy = vi.spyOn(cart, 'getApples').mockImplementation(() => apples) +apples = 1 - beforeEach(() => { - vi.resetModules() - }) +expect(cart.getApples()).toBe(1) - test('change state', async () => { - const mod = await import('./some/path.js') // Will get reevaluated - mod.changeLocalState('new value') - expect(mod.getLocalState()).toBe('new value') - }) +expect(spy).toHaveBeenCalled() +expect(spy).toHaveReturnedWith(1) +``` - test('module has old state', async () => { - const mod = await import('./some/path.js') // Will get reevaluated - expect(mod.getLocalState()).toBe('old value') - }) - ``` +::: tip +You can call [`vi.restoreAllMocks`](#vi-restoreallmocks) inside [`afterEach`](/api/#aftereach) (or enable [`test.restoreMocks`](/config/#restoreMocks)) to restore all methods to their original implementations. This will restore the original [object descriptor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty), so you won't be able to change method's implementation: -::: warning -Does not reset mocks registry. To clear mocks registry, use [`vi.unmock`](#vi-unmock) or [`vi.doUnmock`](#vi-dounmock). -::: +```ts +const cart = { + getApples: () => 42, +} -## vi.restoreAllMocks +const spy = vi.spyOn(cart, 'getApples').mockReturnValue(10) - Will call [`.mockRestore()`](/api/mock#mockrestore) on all spies. This will clear mock history and reset its implementation to the original one. +console.log(cart.getApples()) // 10 +vi.restoreAllMocks() +console.log(cart.getApples()) // 42 +spy.mockReturnValue(10) +console.log(cart.getApples()) // still 42! +``` +::: -## vi.stubEnv +### vi.stubEnv - **Type:** `(name: string, value: string) => Vitest` - **Version:** Since Vitest 0.26.0 - Changes the value of environmental variable on `process.env` and `import.meta.env`. You can restore its value by calling `vi.unstubAllEnvs`. +Changes the value of environmental variable on `process.env` and `import.meta.env`. You can restore its value by calling `vi.unstubAllEnvs`. ```ts import { vi } from 'vitest' @@ -427,12 +450,12 @@ import.meta.env.MODE = 'test' ``` ::: -## vi.unstubAllEnvs +### vi.unstubAllEnvs - **Type:** `() => Vitest` - **Version:** Since Vitest 0.26.0 - Restores all `import.meta.env` and `process.env` values that were changed with `vi.stubEnv`. When it's called for the first time, Vitest remembers the original value and will store it, until `unstubAllEnvs` is called again. +Restores all `import.meta.env` and `process.env` values that were changed with `vi.stubEnv`. When it's called for the first time, Vitest remembers the original value and will store it, until `unstubAllEnvs` is called again. ```ts import { vi } from 'vitest' @@ -457,11 +480,11 @@ process.env.NODE_ENV === 'development' import.meta.env.NODE_ENV === 'development' ``` -## vi.stubGlobal +### vi.stubGlobal - **Type:** `(name: string | number | symbol, value: unknown) => Vitest` - Changes the value of global variable. You can restore its original value by calling `vi.unstubAllGlobals`. +Changes the value of global variable. You can restore its original value by calling `vi.unstubAllGlobals`. ```ts import { vi } from 'vitest' @@ -486,12 +509,12 @@ window.innerWidth = 100 ``` ::: -## vi.unstubAllGlobals +### vi.unstubAllGlobals - **Type:** `() => Vitest` - **Version:** Since Vitest 0.26.0 - Restores all global values on `globalThis`/`global` (and `window`/`top`/`self`/`parent`, if you are using `jsdom` or `happy-dom` environment) that were changed with `vi.stubGlobal`. When it's called for the first time, Vitest remembers the original value and will store it, until `unstubAllGlobals` is called again. +Restores all global values on `globalThis`/`global` (and `window`/`top`/`self`/`parent`, if you are using `jsdom` or `happy-dom` environment) that were changed with `vi.stubGlobal`. When it's called for the first time, Vitest remembers the original value and will store it, until `unstubAllGlobals` is called again. ```ts import { vi } from 'vitest' @@ -516,211 +539,238 @@ globalThis.IntersectionObserver === undefined IntersectionObserver === undefined ``` -## vi.runAllTicks +## Fake Timers -- **Type:** `() => Vitest` +This sections descibes how to work with [fake timers](/guide/mocking#timers). - Calls every microtask that was queued by `process.nextTick`. This will also run all microtasks scheduled by themselves. +### vi.advanceTimersByTime -## vi.runAllTimers +- **Type:** `(ms: number) => Vitest` -- **Type:** `() => Vitest` +This method will invoke every initiated timer until the specified number of milliseconds is passed or the queue is empty - whatever comes first. - This method will invoke every initiated timer until the timers queue is empty. It means that every timer called during `runAllTimers` will be fired. If you have an infinite interval, - it will throw after 10 000 tries. For example this will log `1, 2, 3`: +```ts +let i = 0 +setInterval(() => console.log(++i), 50) - ```ts - let i = 0 - setTimeout(() => console.log(++i)) - const interval = setInterval(() => { - console.log(++i) - if (i === 3) - clearInterval(interval) +vi.advanceTimersByTime(150) - }, 50) +// log: 1 +// log: 2 +// log: 3 +``` - vi.runAllTimers() - ``` +### vi.advanceTimersByTimeAsync -### vi.runAllTimersAsync +- **Type:** `(ms: number) => Promise` -- **Type:** `() => Promise` +This method will invoke every initiated timer until the specified number of milliseconds is passed or the queue is empty - whatever comes first. This will include asynchronously set timers. - This method will asynchronously invoke every initiated timer until the timers queue is empty. It means that every timer called during `runAllTimersAsync` will be fired even asynchronous timers. If you have an infinite interval, - it will throw after 10 000 tries. For example this will log `result`: +```ts +let i = 0 +setInterval(() => Promise.resolve().then(() => console.log(++i)), 50) - ```ts - setTimeout(async () => { - console.log(await Promise.resolve('result')) - }, 100) +await vi.advanceTimersByTimeAsync(150) - await vi.runAllTimersAsync() - ``` +// log: 1 +// log: 2 +// log: 3 +``` -## vi.runOnlyPendingTimers +### vi.advanceTimersToNextTimer - **Type:** `() => Vitest` - This method will call every timer that was initiated after `vi.useFakeTimers()` call. It will not fire any timer that was initiated during its call. For example this will only log `1`: +Will call next available timer. Useful to make assertions between each timer call. You can chain call it to manage timers by yourself. - ```ts - let i = 0 - setInterval(() => console.log(++i), 50) +```ts +let i = 0 +setInterval(() => console.log(++i), 50) - vi.runOnlyPendingTimers() - ``` +vi.advanceTimersToNextTimer() // log: 1 + .advanceTimersToNextTimer() // log: 2 + .advanceTimersToNextTimer() // log: 3 +``` -### vi.runOnlyPendingTimersAsync +### vi.advanceTimersToNextTimerAsync - **Type:** `() => Promise` - This method will asynchronously call every timer that was initiated after `vi.useFakeTimers()` call, even asynchronous ones. It will not fire any timer that was initiated during its call. For example this will log `2, 3, 3, 1`: +Will call next available timer and wait until it's resolved if it was set asynchronously. Useful to make assertions between each timer call. - ```ts - setTimeout(() => { - console.log(1) - }, 100) - setTimeout(() => { - Promise.resolve().then(() => { - console.log(2) - setInterval(() => { - console.log(3) - }, 40) - }) - }, 10) +```ts +let i = 0 +setInterval(() => Promise.resolve().then(() => console.log(++i)), 50) + +await vi.advanceTimersToNextTimerAsync() // log: 1 +expect(console.log).toHaveBeenCalledWith(1) - await vi.runOnlyPendingTimersAsync() - ``` +await vi.advanceTimersToNextTimerAsync() // log: 2 +await vi.advanceTimersToNextTimerAsync() // log: 3 +``` -## vi.setSystemTime +### vi.getTimerCount -- **Type**: `(date: string | number | Date) => void` +- **Type:** `() => number` - Sets current date to the one that was passed. All `Date` calls will return this date. +Get the number of waiting timers. - Useful if you need to test anything that depends on the current date - for example [luxon](https://github.com/moment/luxon/) calls inside your code. +### vi.clearAllTimers - ```ts - const date = new Date(1998, 11, 19) +Removes all timers that are scheduled to run. These timers will never run in the future. - vi.useFakeTimers() - vi.setSystemTime(date) +### vi.getMockedSystemTime - expect(Date.now()).toBe(date.valueOf()) +- **Type**: `() => Date | null` - vi.useRealTimers() - ``` +Returns mocked current date that was set using `setSystemTime`. If date is not mocked the method will return `null`. -## vi.setConfig +### vi.getRealSystemTime -- **Type**: `RuntimeConfig` +- **Type**: `() => number` - Updates config for the current test file. You can only affect values that are used, when executing tests. +When using `vi.useFakeTimers`, `Date.now` calls are mocked. If you need to get real time in milliseconds, you can call this function. -## vi.spyOn +### vi.runAllTicks -- **Type:** `(object: T, method: K, accessType?: 'get' | 'set') => MockInstance` +- **Type:** `() => Vitest` - Creates a spy on a method or getter/setter of an object. +Calls every microtask that was queued by `process.nextTick`. This will also run all microtasks scheduled by themselves. - ```ts - let apples = 0 - const cart = { - getApples: () => 13, - } +### vi.runAllTimers - const spy = vi.spyOn(cart, 'getApples').mockImplementation(() => apples) - apples = 1 +- **Type:** `() => Vitest` - expect(cart.getApples()).toBe(1) +This method will invoke every initiated timer until the timer queue is empty. It means that every timer called during `runAllTimers` will be fired. If you have an infinite interval, it will throw after 10 000 tries (can be configured with [`fakeTimers.loopLimit`](/config/#faketimers-looplimit)). - expect(spy).toHaveBeenCalled() - expect(spy).toHaveReturnedWith(1) - ``` +```ts +let i = 0 +setTimeout(() => console.log(++i)) +const interval = setInterval(() => { + console.log(++i) + if (i === 3) + clearInterval(interval) -## vi.stubGlobal +}, 50) -- **Type**: `(key: keyof globalThis & Window, value: any) => Vitest` +vi.runAllTimers() - Puts a value on global variable. If you are using `jsdom` or `happy-dom`, also puts the value on `window` object. +// log: 1 +// log: 2 +// log: 3 +``` - Read more in ["Mocking Globals" section](/guide/mocking.html#globals). +### vi.runAllTimersAsync -## vi.unmock +- **Type:** `() => Promise` -- **Type**: `(path: string) => void` +This method will asynchronously invoke every initiated timer until the timer queue is empty. It means that every timer called during `runAllTimersAsync` will be fired even asynchronous timers. If you have an infinite interval, +it will throw after 10 000 tries (can be configured with [`fakeTimers.loopLimit`](/config/#faketimers-looplimit)). - Removes module from the mocked registry. All calls to import will return the original module even if it was mocked before. This call is hoisted (moved) to the top of the file, so it will only unmock modules that were defined in `setupFiles`, for example. +```ts +setTimeout(async () => { + console.log(await Promise.resolve('result')) +}, 100) -## vi.doUnmock +await vi.runAllTimersAsync() -- **Type**: `(path: string) => void` +// log: result +``` + +### vi.runOnlyPendingTimers + +- **Type:** `() => Vitest` - The same as [`vi.unmock`](#vi-unmock), but is not hoisted to the top of the file. The next import of the module will import the original module instead of the mock. This will not unmock previously imported modules. +This method will call every timer that was initiated after [`vi.useFakeTimers`](#vi-usefaketimers) call. It will not fire any timer that was initiated during its call. ```ts -// ./increment.js -export function increment(number) { - return number + 1 -} +let i = 0 +setInterval(() => console.log(++i), 50) + +vi.runOnlyPendingTimers() + +// log: 1 ``` +### vi.runOnlyPendingTimersAsync + +- **Type:** `() => Promise` + +This method will asynchronously call every timer that was initiated after [`vi.useFakeTimers`](#vi-usefaketimers) call, even asynchronous ones. It will not fire any timer that was initiated during its call. + ```ts -import { increment } from './increment.js' +setTimeout(() => { + console.log(1) +}, 100) +setTimeout(() => { + Promise.resolve().then(() => { + console.log(2) + setInterval(() => { + console.log(3) + }, 40) + }) +}, 10) -// increment is already mocked, because vi.mock is hoisted -increment(1) === 100 +await vi.runOnlyPendingTimersAsync() -// this is hoisted, and factory is called before the import on line 1 -vi.mock('./increment.js', () => ({ increment: () => 100 })) +// log: 2 +// log: 3 +// log: 3 +// log: 1 +``` -// all calls are mocked, and `increment` always returns 100 -increment(1) === 100 -increment(30) === 100 +### vi.setSystemTime -// this is not hoisted, so other import will return unmocked module -vi.doUnmock('./increment.js') +- **Type**: `(date: string | number | Date) => void` -// this STILL returns 100, because `vi.doUnmock` doesn't reevaluate a module -increment(1) === 100 -increment(30) === 100 +If fake timers are enabled, this method simulates a user changing the system clock (will affect date related API like `hrtime`, `performance.now` or `new Date()`) - however, it will not fire any timers. If fake timers are not enabled, this method will only mock `Date.*` calls. -// the next import is unmocked, now `increment` is the original function that returns count + 1 -const { increment: unmockedIncrement } = await import('./increment.js') +Useful if you need to test anything that depends on the current date - for example [luxon](https://github.com/moment/luxon/) calls inside your code. -unmockedIncrement(1) === 2 -unmockedIncrement(30) === 31 +```ts +const date = new Date(1998, 11, 19) + +vi.useFakeTimers() +vi.setSystemTime(date) + +expect(Date.now()).toBe(date.valueOf()) + +vi.useRealTimers() ``` -## vi.useFakeTimers +### vi.useFakeTimers - **Type:** `() => Vitest` - To enable mocking timers, you need to call this method. It will wrap all further calls to timers (such as `setTimeout`, `setInterval`, `clearTimeout`, `clearInterval`, `nextTick`, `setImmediate`, `clearImmediate`, and `Date`), until [`vi.useRealTimers()`](#vi-userealtimers) is called. +To enable mocking timers, you need to call this method. It will wrap all further calls to timers (such as `setTimeout`, `setInterval`, `clearTimeout`, `clearInterval`, `nextTick`, `setImmediate`, `clearImmediate`, and `Date`), until [`vi.useRealTimers()`](#vi-userealtimers) is called. - Mocking `nextTick` is not supported when running Vitest inside `node:child_process` by using `--pool=forks`. NodeJS uses `process.nextTick` internally in `node:child_process` and hangs when it is mocked. Mocking `nextTick` is supported when running Vitest with `--pool=threads`. +Mocking `nextTick` is not supported when running Vitest inside `node:child_process` by using `--pool=forks`. NodeJS uses `process.nextTick` internally in `node:child_process` and hangs when it is mocked. Mocking `nextTick` is supported when running Vitest with `--pool=threads`. - The implementation is based internally on [`@sinonjs/fake-timers`](https://github.com/sinonjs/fake-timers). +The implementation is based internally on [`@sinonjs/fake-timers`](https://github.com/sinonjs/fake-timers). - ::: tip - Since version `0.35.0` `vi.useFakeTimers()` no longer automatically mocks `process.nextTick`. - It can still be mocked by specyfing the option in `toFake` argument: `vi.useFakeTimers({ toFake: ['nextTick'] })`. - ::: +::: tip +Since version `0.35.0` `vi.useFakeTimers()` no longer automatically mocks `process.nextTick`. +It can still be mocked by specyfing the option in `toFake` argument: `vi.useFakeTimers({ toFake: ['nextTick'] })`. +::: -## vi.isFakeTimers +### vi.isFakeTimers - **Type:** `() => boolean` - **Version:** Since Vitest 0.34.5 - Returns `true` if fake timers are enabled. +Returns `true` if fake timers are enabled. -## vi.useRealTimers +### vi.useRealTimers - **Type:** `() => Vitest` - When timers are run out, you may call this method to return mocked timers to its original implementations. All timers that were run before will not be restored. +When timers are run out, you may call this method to return mocked timers to its original implementations. All timers that were scheduled before will be discarded. + +## Miscellaneous -## vi.waitFor +A set of useful helper functions that Vitest provides. + +### vi.waitFor - **Type:** `(callback: WaitForCallback, options?: number | WaitForOptions) => Promise` - **Version**: Since Vitest 0.34.5 @@ -779,7 +829,7 @@ test('Element exists in a DOM', async () => { If `vi.useFakeTimers` is used, `vi.waitFor` automatically calls `vi.advanceTimersByTime(interval)` in every check callback. -## vi.waitUntil +### vi.waitUntil - **Type:** `(callback: WaitUntilCallback, options?: number | WaitUntilOptions) => Promise` - **Version**: Since Vitest 0.34.5 @@ -804,3 +854,86 @@ test('Element render correctly', async () => { expect(element.querySelector('.element-child')).toBeTruthy() }) ``` + +### vi.hoisted + +- **Type**: `(factory: () => T) => T` +- **Version**: Since Vitest 0.31.0 + +All static `import` statements in ES modules are hoisted to the top of the file, so any code that is defined before the imports will actually be executed after imports are evaluated. + +However, it can be useful to invoke some side effects like mocking dates before importing a module. + +To bypass this limitation, you can rewrite static imports into dynamic ones like this: + +```diff +callFunctionWithSideEffect() +- import { value } from './some/module.ts' ++ const { value } = await import('./some/module.ts') +``` + +When running `vitest`, you can do this automatically by using `vi.hoisted` method. + +```diff +- callFunctionWithSideEffect() +import { value } from './some/module.ts' ++ vi.hoisted(() => callFunctionWithSideEffect()) +``` + +This method returns the value that was returned from the factory. You can use that value in your `vi.mock` factories if you need easy access to locally defined variables: + +```ts +import { expect, vi } from 'vitest' +import { originalMethod } from './path/to/module.js' + +const { mockedMethod } = vi.hoisted(() => { + return { mockedMethod: vi.fn() } +}) + +vi.mock('./path/to/module.js', () => { + return { originalMethod: mockedMethod } +}) + +mockedMethod.mockReturnValue(100) +expect(originalMethod()).toBe(100) +``` + +Note that this method can also be called asynchronously even if your environment doesn't support top-level await: + +```ts +const promised = await vi.hoisted(async () => { + const response = await fetch('https://jsonplaceholder.typicode.com/posts') + return response.json() +}) +``` + +### vi.setConfig + +- **Type**: `RuntimeConfig` + +Updates config for the current test file. This method supports only config options that will affect the current test file: + +```ts +vi.setConfig({ + allowOnly: true, + testTimeout: 10_000, + hookTimeout: 10_000, + clearMocks: true, + restoreMocks: true, + fakeTimers: { + now: new Date(2021, 11, 19), + // supports the whole object + }, + maxConcurrency: 10, + sequence: { + hooks: 'stack' + // supports only "sequence.hooks" + } +}) +``` + +### vi.resetConfig + +- **Type**: `RuntimeConfig` + +If [`vi.setConfig`](#vi-setconfig) was called before, this will reset config to the original state. diff --git a/docs/config/index.md b/docs/config/index.md index e5585da5d37c..0a391b5628dc 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -87,6 +87,16 @@ export default defineConfig(configEnv => mergeConfig( :::tip In addition to the following options, you can also use any configuration option from [Vite](https://vitejs.dev/config/). For example, `define` to define global variables, or `resolve.alias` to define aliases. + +_All_ listed options here are located on a `test` property inside the config: + +```ts +export default defineConfig({ + test: { + exclude: [], + }, +}) +``` ::: ::: tip @@ -1860,3 +1870,54 @@ export default defineConfig({ }) ``` ::: + +### fakeTimers + +- **Type:** `FakeTimerInstallOpts` + +Options that Vitest will pass down to [`@sinon/fake-timers`](https://www.npmjs.com/package/@sinonjs/fake-timers) when using [`vi.useFakeTimers()`](/api/vi#vi-usefaketimers). + +#### fakeTimers.now + +- **Type:** `number | Date` +- **Default:** `Date.now()` + +Installs fake timers with the specified unix epoch. + +#### fakeTimers.toFake + +- **Type:** `FakeMethod[]` + +An array with names of global methods and APIs to fake. By default, Vitest does not replace `nextTick()` and `queueMicrotask()`. + +To only mock `setTimeout()` and `nextTick()`, specify this property as `['setTimeout', 'nextTick']`. + +Mocking `nextTick` is not supported when running Vitest inside `node:child_process` by using `--pool=forks`. NodeJS uses `process.nextTick` internally in `node:child_process` and hangs when it is mocked. Mocking `nextTick` is supported when running Vitest with `--pool=threads`. + +#### fakeTimers.loopLimit + +- **Type:** `number` +- **Default:** `10_000` + +The maximum number of timers that will be run when calling [`vi.runAllTimers()`](/api/vi#vi-runalltimers). + +#### fakeTimers.shouldAdvanceTime + +- **Type:** `boolean` +- **Default:** `false` + +Tells @sinonjs/fake-timers to increment mocked time automatically based on the real system time shift (e.g. the mocked time will be incremented by 20ms for every 20ms change in the real system time). + +#### fakeTimers.advanceTimeDelta + +- **Type:** `number` +- **Default:** `20` + +Relevant only when using with `shouldAdvanceTime: true`. increment mocked time by advanceTimeDelta ms every advanceTimeDelta ms change in the real system time. + +#### fakeTimers.shouldClearNativeTimers + +- **Type:** `boolean` +- **Default:** `false` + +Tells fake timers to clear "native" (i.e. not fake) timers by delegating to their respective handlers. These are not cleared by default, leading to potentially unexpected behavior if timers existed prior to starting fake timers session. diff --git a/docs/guide/reporters.md b/docs/guide/reporters.md index 37117f655a66..239c3228765b 100644 --- a/docs/guide/reporters.md +++ b/docs/guide/reporters.md @@ -1,5 +1,6 @@ --- title: Reporters | Guide +outline: deep --- # Reporters @@ -434,7 +435,7 @@ export default defineConfig({ ``` ::: -Additionally, you can define your own custom reporters and use them by specifying their file path: +Additionally, you can define your own [custom reporters](/advanced/reporters) and use them by specifying their file path: ```bash npx vitest --reporter=./path/to/reporter.ts diff --git a/docs/package.json b/docs/package.json index bf8368cd3261..906a85b1b0a9 100644 --- a/docs/package.json +++ b/docs/package.json @@ -13,25 +13,24 @@ "generate-pwa-icons": "pwa-assets-generator" }, "dependencies": { - "@vueuse/core": "^10.2.1", - "jiti": "^1.18.2", + "@vueuse/core": "^10.5.0", "vue": "latest" }, "devDependencies": { - "@iconify-json/carbon": "^1.1.18", + "@iconify-json/carbon": "^1.1.21", "@unocss/reset": "^0.53.4", - "@vite-pwa/assets-generator": "^0.0.3", - "@vite-pwa/vitepress": "^0.2.0", + "@vite-pwa/assets-generator": "^0.0.10", + "@vite-pwa/vitepress": "^0.2.3", "@vitejs/plugin-vue": "latest", - "esno": "^0.16.3", - "fast-glob": "^3.3.0", + "esno": "^0.17.0", + "fast-glob": "^3.3.1", "fs-extra": "^11.1.1", "https-localhost": "^4.7.1", "unocss": "^0.53.4", - "unplugin-vue-components": "^0.25.1", + "unplugin-vue-components": "^0.25.2", "vite": "^4.5.0", - "vite-plugin-pwa": "^0.16.4", - "vitepress": "1.0.0-beta.5", + "vite-plugin-pwa": "^0.16.6", + "vitepress": "^1.0.0-rc.24", "workbox-window": "^7.0.0" } } diff --git a/packages/expect/src/jest-expect.ts b/packages/expect/src/jest-expect.ts index 471e9bdee9cf..c9162bf8ca52 100644 --- a/packages/expect/src/jest-expect.ts +++ b/packages/expect/src/jest-expect.ts @@ -1,6 +1,6 @@ import { assertTypes, getColors } from '@vitest/utils' import type { Constructable } from '@vitest/utils' -import type { EnhancedSpy } from '@vitest/spy' +import type { MockInstance } from '@vitest/spy' import { isMockFunction } from '@vitest/spy' import type { Test } from '@vitest/runner' import type { Assertion, ChaiPlugin } from './types' @@ -344,7 +344,7 @@ export const JestChaiExpect: ChaiPlugin = (chai, utils) => { } const getSpy = (assertion: any) => { assertIsMock(assertion) - return assertion._obj as EnhancedSpy + return assertion._obj as MockInstance } const ordinalOf = (i: number) => { const j = i % 10 @@ -361,7 +361,7 @@ export const JestChaiExpect: ChaiPlugin = (chai, utils) => { return `${i}th` } - const formatCalls = (spy: EnhancedSpy, msg: string, actualCall?: any) => { + const formatCalls = (spy: MockInstance, msg: string, actualCall?: any) => { if (spy.mock.calls) { msg += c().gray(`\n\nReceived: \n\n${spy.mock.calls.map((callArg, i) => { let methodCall = c().bold(` ${ordinalOf(i + 1)} ${spy.getMockName()} call:\n\n`) @@ -377,7 +377,7 @@ export const JestChaiExpect: ChaiPlugin = (chai, utils) => { msg += c().gray(`\n\nNumber of calls: ${c().bold(spy.mock.calls.length)}\n`) return msg } - const formatReturns = (spy: EnhancedSpy, msg: string, actualReturn?: any) => { + const formatReturns = (spy: MockInstance, msg: string, actualReturn?: any) => { msg += c().gray(`\n\nReceived: \n\n${spy.mock.results.map((callReturn, i) => { let methodCall = c().bold(` ${ordinalOf(i + 1)} ${spy.getMockName()} call return:\n\n`) if (actualReturn) diff --git a/packages/spy/src/index.ts b/packages/spy/src/index.ts index 54af57cfec66..beed20cf0922 100644 --- a/packages/spy/src/index.ts +++ b/packages/spy/src/index.ts @@ -3,6 +3,9 @@ import * as tinyspy from 'tinyspy' interface MockResultReturn { type: 'return' + /** + * The value that was returned from the function. If function returned a Promise, then this will be a resolved value. + */ value: T } interface MockResultIncomplete { @@ -11,16 +14,81 @@ interface MockResultIncomplete { } interface MockResultThrow { type: 'throw' + /** + * An error that was thrown during function execution. + */ value: any } type MockResult = MockResultReturn | MockResultThrow | MockResultIncomplete export interface MockContext { + /** + * This is an array containing all arguments for each call. One item of the array is the arguments of that call. + * + * @example + * const fn = vi.fn() + * + * fn('arg1', 'arg2') + * fn('arg3') + * + * fn.mock.calls === [ + * ['arg1', 'arg2'], // first call + * ['arg3'], // second call + * ] + */ calls: TArgs[] + /** + * This is an array containing all instances that were instantiated when mock was called with a `new` keyword. Note that this is an actual context (`this`) of the function, not a return value. + */ instances: TReturns[] + /** + * The order of mock's execution. This returns an array of numbers which are shared between all defined mocks. + * + * @example + * const fn1 = vi.fn() + * const fn2 = vi.fn() + * + * fn1() + * fn2() + * fn1() + * + * fn1.mock.invocationCallOrder === [1, 3] + * fn2.mock.invocationCallOrder === [2] + */ invocationCallOrder: number[] + /** + * This is an array containing all values that were `returned` from the function. + * + * The `value` property contains the returned value or thrown error. If the function returned a promise, the `value` will be the _resolved_ value, not the actual `Promise`, unless it was never resolved. + * + * @example + * const fn = vi.fn() + * .mockReturnValueOnce('result') + * .mockImplementationOnce(() => { throw new Error('thrown error') }) + * + * const result = fn() + * + * try { + * fn() + * } + * catch {} + * + * fn.mock.results === [ + * { + * type: 'return', + * value: 'result', + * }, + * { + * type: 'throw', + * value: Error, + * }, + * ] + */ results: MockResult[] + /** + * This contains the arguments of the last call. If spy wasn't called, will return `undefined`. + */ lastCall: TArgs | undefined } @@ -36,33 +104,146 @@ type Classes = { [K in keyof T]: T[K] extends new (...args: any[]) => any ? K : never }[keyof T] & (string | symbol) -export interface SpyInstance { +/** + * @deprecated Use MockInstance instead + */ +export interface SpyInstance extends MockInstance {} + +export interface MockInstance { + /** + * Use it to return the name given to mock with method `.mockName(name)`. + */ getMockName(): string + /** + * Sets internal mock name. Useful to see the name of the mock if an assertion fails. + */ mockName(n: string): this + /** + * Current context of the mock. It stores information about all invocation calls, instances, and results. + */ mock: MockContext + /** + * Clears all information about every call. After calling it, all properties on `.mock` will return an empty state. This method does not reset implementations. + * + * It is useful if you need to clean up mock between different assertions. + */ mockClear(): this + /** + * Does what `mockClear` does and makes inner implementation an empty function (returning `undefined` when invoked). This also resets all "once" implementations. + * + * This is useful when you want to completely reset a mock to the default state. + */ mockReset(): this + /** + * Does what `mockReset` does and restores inner implementation to the original function. + * + * Note that restoring mock from `vi.fn()` will set implementation to an empty function that returns `undefined`. Restoring a `vi.fn(impl)` will restore implementation to `impl`. + */ mockRestore(): void + /** + * Returns current mock implementation if there is one. + * + * If mock was created with `vi.fn`, it will consider passed down method as a mock implementation. + * + * If mock was created with `vi.spyOn`, it will return `undefined` unless a custom implementation was provided. + */ getMockImplementation(): ((...args: TArgs) => TReturns) | undefined + /** + * Accepts a function that will be used as an implementation of the mock. + * @example + * const increment = vi.fn().mockImplementation(count => count + 1); + * expect(fincrementn(3)).toBe(4); + */ mockImplementation(fn: ((...args: TArgs) => TReturns) | (() => Promise)): this + /** + * Accepts a function that will be used as a mock implementation during the next call. Can be chained so that multiple function calls produce different results. + * @example + * const fn = vi.fn(count => count).mockImplementationOnce(count => count + 1); + * expect(fn(3)).toBe(4); + * expect(fn(3)).toBe(3); + */ mockImplementationOnce(fn: ((...args: TArgs) => TReturns) | (() => Promise)): this + /** + * Overrides the original mock implementation temporarily while the callback is being executed. + * @example + * const myMockFn = vi.fn(() => 'original') + * + * myMockFn.withImplementation(() => 'temp', () => { + * myMockFn() // 'temp' + * }) + * + * myMockFn() // 'original' + */ withImplementation(fn: ((...args: TArgs) => TReturns), cb: () => T): T extends Promise ? Promise : this + /** + * Use this if you need to return `this` context from the method without invoking actual implementation. + */ mockReturnThis(): this + /** + * Accepts a value that will be returned whenever the mock function is called. + */ mockReturnValue(obj: TReturns): this + /** + * Accepts a value that will be returned during the next function call. If chained, every consecutive call will return the specified value. + * + * When there are no more `mockReturnValueOnce` values to use, mock will fallback to the previously defined implementation if there is one. + * @example + * const myMockFn = vi + * .fn() + * .mockReturnValue('default') + * .mockReturnValueOnce('first call') + * .mockReturnValueOnce('second call') + * + * // 'first call', 'second call', 'default' + * console.log(myMockFn(), myMockFn(), myMockFn()) + */ mockReturnValueOnce(obj: TReturns): this + /** + * Accepts a value that will be resolved when async function is called. + * @example + * const asyncMock = vi.fn().mockResolvedValue(42) + * asyncMock() // Promise<42> + */ mockResolvedValue(obj: Awaited): this + /** + * Accepts a value that will be resolved during the next function call. If chained, every consecutive call will resolve specified value. + * @example + * const myMockFn = vi + * .fn() + * .mockResolvedValue('default') + * .mockResolvedValueOnce('first call') + * .mockResolvedValueOnce('second call') + * + * // Promise<'first call'>, Promise<'second call'>, Promise<'default'> + * console.log(myMockFn(), myMockFn(), myMockFn()) + */ mockResolvedValueOnce(obj: Awaited): this + /** + * Accepts an error that will be rejected when async function is called. + * @example + * const asyncMock = vi.fn().mockRejectedValue(new Error('Async error')) + * await asyncMock() // throws 'Async error' + */ mockRejectedValue(obj: any): this + /** + * Accepts a value that will be rejected during the next function call. If chained, every consecutive call will reject specified value. + * @example + * const asyncMock = vi + * .fn() + * .mockResolvedValueOnce('first call') + * .mockRejectedValueOnce(new Error('Async error')) + * + * await asyncMock() // first call + * await asyncMock() // throws "Async error" + */ mockRejectedValueOnce(obj: any): this } -export interface MockInstance extends SpyInstance {} - -export interface Mock extends SpyInstance { +export interface Mock extends MockInstance { new (...args: TArgs): TReturns (...args: TArgs): TReturns } -export interface PartialMock extends SpyInstance> ? Promise>> : Partial> { +export interface PartialMock extends MockInstance> ? Promise>> : Partial> { new (...args: TArgs): TReturns (...args: TArgs): TReturns } @@ -135,11 +316,9 @@ export type Mocked = { } & T -export type EnhancedSpy = SpyInstance & SpyInternalImpl - -export const spies = new Set() +export const mocks = new Set() -export function isMockFunction(fn: any): fn is EnhancedSpy { +export function isMockFunction(fn: any): fn is MockInstance { return typeof fn === 'function' && '_isMockFunction' in fn && fn._isMockFunction @@ -149,21 +328,21 @@ export function spyOn>>( obj: T, methodName: S, accessType: 'get', -): SpyInstance<[], T[S]> +): MockInstance<[], T[S]> export function spyOn>>( obj: T, methodName: G, accessType: 'set', -): SpyInstance<[T[G]], void> +): MockInstance<[T[G]], void> export function spyOn> | Methods>)>( obj: T, methodName: M, -): Required[M] extends ({ new (...args: infer A): infer R }) | ((...args: infer A) => infer R) ? SpyInstance : never +): Required[M] extends ({ new (...args: infer A): infer R }) | ((...args: infer A) => infer R) ? MockInstance : never export function spyOn( obj: T, method: K, accessType?: 'get' | 'set', -): SpyInstance { +): MockInstance { const dictionary = { get: 'getter', set: 'setter', @@ -172,15 +351,15 @@ export function spyOn( const stub = tinyspy.internalSpyOn(obj, objMethod as any) - return enhanceSpy(stub) as SpyInstance + return enhanceSpy(stub) as MockInstance } let callOrder = 0 function enhanceSpy( spy: SpyInternalImpl, -): SpyInstance { - const stub = spy as unknown as EnhancedSpy +): MockInstance { + const stub = spy as unknown as MockInstance let implementation: ((...args: TArgs) => TReturns) | undefined @@ -261,9 +440,9 @@ function enhanceSpy( return stub } - function withImplementation(fn: (...args: TArgs) => TReturns, cb: () => void): EnhancedSpy - function withImplementation(fn: (...args: TArgs) => TReturns, cb: () => Promise): Promise> - function withImplementation(fn: (...args: TArgs) => TReturns, cb: () => void | Promise): EnhancedSpy | Promise> { + function withImplementation(fn: (...args: TArgs) => TReturns, cb: () => void): MockInstance + function withImplementation(fn: (...args: TArgs) => TReturns, cb: () => Promise): Promise> + function withImplementation(fn: (...args: TArgs) => TReturns, cb: () => void | Promise): MockInstance | Promise> { const originalImplementation = implementation implementation = fn @@ -317,7 +496,7 @@ function enhanceSpy( state.willCall(mockCall) - spies.add(stub) + mocks.add(stub) return stub as any } diff --git a/packages/vitest/src/integrations/vi.ts b/packages/vitest/src/integrations/vi.ts index 2206bd7561d7..fb4ce7a82f44 100644 --- a/packages/vitest/src/integrations/vi.ts +++ b/packages/vitest/src/integrations/vi.ts @@ -7,99 +7,248 @@ import type { MockFactoryWithHelper } from '../types/mocker' import { getWorkerState } from '../utils/global' import { resetModules, waitForImportsToResolve } from '../utils/modules' import { FakeTimers } from './mock/timers' -import type { EnhancedSpy, MaybeMocked, MaybeMockedDeep, MaybePartiallyMocked, MaybePartiallyMockedDeep } from './spy' -import { fn, isMockFunction, spies, spyOn } from './spy' +import type { MaybeMocked, MaybeMockedDeep, MaybePartiallyMocked, MaybePartiallyMockedDeep, MockInstance } from './spy' +import { fn, isMockFunction, mocks, spyOn } from './spy' import { waitFor, waitUntil } from './wait' +type ESModuleExports = Record + export interface VitestUtils { + /** + * Checks if fake timers are enabled. + */ isFakeTimers(): boolean - useFakeTimers(config?: FakeTimerInstallOpts): this - useRealTimers(): this - runOnlyPendingTimers(): this - runOnlyPendingTimersAsync(): Promise - runAllTimers(): this - runAllTimersAsync(): Promise - runAllTicks(): this - advanceTimersByTime(ms: number): this - advanceTimersByTimeAsync(ms: number): Promise - advanceTimersToNextTimer(): this - advanceTimersToNextTimerAsync(): Promise + /** + * This method wraps all further calls to timers until [`vi.useRealTimers()`](https://vitest.dev/api/vi#vi-userealtimers) is called. + */ + useFakeTimers(config?: FakeTimerInstallOpts): VitestUtils + /** + * Restores mocked timers to their original implementations. All timers that were scheduled before will be discarded. + */ + useRealTimers(): VitestUtils + /** + * This method will call every timer that was initiated after [`vi.useFakeTimers`](https://vitest.dev/api/vi#vi-usefaketimers) call. + * It will not fire any timer that was initiated during its call. + */ + runOnlyPendingTimers(): VitestUtils + /** + * This method will asynchronously call every timer that was initiated after [`vi.useFakeTimers`](https://vitest.dev/api/vi#vi-usefaketimers) call, even asynchronous ones. + * It will not fire any timer that was initiated during its call. + */ + runOnlyPendingTimersAsync(): Promise + /** + * This method will invoke every initiated timer until the timer queue is empty. It means that every timer called during `runAllTimers` will be fired. + * If you have an infinite interval, it will throw after 10,000 tries (can be configured with [`fakeTimers.loopLimit`](https://vitest.dev/config/#faketimers-looplimit)). + */ + runAllTimers(): VitestUtils + /** + * This method will asynchronously invoke every initiated timer until the timer queue is empty. It means that every timer called during `runAllTimersAsync` will be fired even asynchronous timers. + * If you have an infinite interval, it will throw after 10 000 tries (can be configured with [`fakeTimers.loopLimit`](https://vitest.dev/config/#faketimers-looplimit)). + */ + runAllTimersAsync(): Promise + /** + * Calls every microtask that was queued by `process.nextTick`. This will also run all microtasks scheduled by themselves. + */ + runAllTicks(): VitestUtils + /** + * This method will invoke every initiated timer until the specified number of milliseconds is passed or the queue is empty - whatever comes first. + */ + advanceTimersByTime(ms: number): VitestUtils + /** + * This method will invoke every initiated timer until the specified number of milliseconds is passed or the queue is empty - whatever comes first. This will include and await asynchronously set timers. + */ + advanceTimersByTimeAsync(ms: number): Promise + /** + * Will call next available timer. Useful to make assertions between each timer call. You can chain call it to manage timers by yourself. + */ + advanceTimersToNextTimer(): VitestUtils + /** + * Will call next available timer and wait until it's resolved if it was set asynchronously. Useful to make assertions between each timer call. + */ + advanceTimersToNextTimerAsync(): Promise + /** + * Get the number of waiting timers. + */ getTimerCount(): number - setSystemTime(time: number | string | Date): this + /** + * If fake timers are enabled, this method simulates a user changing the system clock (will affect date related API like `hrtime`, `performance.now` or `new Date()`) - however, it will not fire any timers. + * If fake timers are not enabled, this method will only mock `Date.*` and `new Date()` calls. + */ + setSystemTime(time: number | string | Date): VitestUtils + /** + * Returns mocked current date that was set using `setSystemTime`. If date is not mocked the method will return `null`. + */ getMockedSystemTime(): Date | null + /** + * When using `vi.useFakeTimers`, `Date.now` calls are mocked. If you need to get real time in milliseconds, you can call this function. + */ getRealSystemTime(): number - clearAllTimers(): this + /** + * Removes all timers that are scheduled to run. These timers will never run in the future. + */ + clearAllTimers(): VitestUtils + /** + * Creates a spy on a method or getter/setter of an object similar to [`vi.fn()`](https://vitest.dev/api/vi#vi-fn). It returns a [mock function](https://vitest.dev/api/mock). + * + * @example + * const cart = { + * getApples: () => 42 + * } + * + * const spy = vi.spyOn(cart, 'getApples').mockReturnValue(10) + * + * expect(cart.getApples()).toBe(10) + * expect(spy).toHaveBeenCalled() + * expect(spy).toHaveReturnedWith(10) + */ spyOn: typeof spyOn + + /** + * Creates a spy on a function, though can be initiated without one. Every time a function is invoked, it stores its call arguments, returns, and instances. Also, you can manipulate its behavior with [methods](https://vitest.dev/api/mock). + * + * If no function is given, mock will return `undefined`, when invoked. + * + * @example + * const getApples = vi.fn(() => 0) + * + * getApples() + * + * expect(getApples).toHaveBeenCalled() + * expect(getApples).toHaveReturnedWith(0) + * + * getApples.mockReturnValueOnce(5) + * + * expect(getApples()).toBe(5) + * expect(getApples).toHaveNthReturnedWith(2, 5) + */ fn: typeof fn + + /** + * Wait for the callback to execute successfully. If the callback throws an error or returns a rejected promise it will continue to wait until it succeeds or times out. + * + * This is very useful when you need to wait for some asynchronous action to complete, for example, when you start a server and need to wait for it to start. + * + * @example + * const server = createServer() + * + * await vi.waitFor( + * () => { + * if (!server.isReady) + * throw new Error('Server not started') + * + * console.log('Server started') + * }, { + * timeout: 500, // default is 1000 + * interval: 20, // default is 50 + * } + * ) + */ waitFor: typeof waitFor + + /** + * This is similar to [`vi.waitFor`](https://vitest.dev/api/vi#vi-waitfor), but if the callback throws any errors, execution is immediately interrupted and an error message is received. + * + * If the callback returns a falsy value, the next check will continue until a truthy value is returned. This is useful when you need to wait for something to exist before taking the next step. + * + * @example + * const element = await vi.waitUntil( + * () => document.querySelector('.element'), + * { + * timeout: 500, // default is 1000 + * interval: 20, // default is 50 + * } + * ) + * + * // do something with the element + * expect(element.querySelector('.element-child')).toBeTruthy() + */ waitUntil: typeof waitUntil /** * Run the factory before imports are evaluated. You can return a value from the factory - * to reuse it inside your `vi.mock` factory and tests. + * to reuse it inside your [`vi.mock`](https://vitest.dev/api/vi#vi-mock) factory and tests. + * + * If used with [`vi.mock`](https://vitest.dev/api/vi#vi-mock), both will be hoisted in the order they are defined in. */ hoisted(factory: () => T): T /** - * Makes all `imports` to passed module to be mocked. - * - If there is a factory, will return it's result. The call to `vi.mock` is hoisted to the top of the file, - * so you don't have access to variables declared in the global file scope, if you didn't put them before imports! - * - If `__mocks__` folder with file of the same name exist, all imports will - * return it. - * - If there is no `__mocks__` folder or a file with the same name inside, will call original - * module and mock it. - * @param path Path to the module. Can be aliased, if your config supports it - * @param factory Factory for the mocked module. Has the highest priority. + * Mocks every import call to the module even if it was already statically imported. + * + * The call to `vi.mock` is hoisted to the top of the file, so you don't have access to variables declared in the global file scope + * unless they are defined with [`vi.hoisted`](https://vitest.dev/api/vi#vi-hoisted) before this call. + * + * Mocking algorithm is described in [documentation](https://vitest.dev/guide/mocking#modules). + * @param path Path to the module. Can be aliased, if your Vitest config supports it + * @param factory Mocked module factory. The result of this function will be an exports object */ mock(path: string, factory?: MockFactoryWithHelper): void /** - * Removes module from mocked registry. All subsequent calls to import will - * return original module even if it was mocked. - * @param path Path to the module. Can be aliased, if your config supports it + * Removes module from mocked registry. All calls to import will return the original module even if it was mocked before. + * + * This call is hoisted to the top of the file, so it will only unmock modules that were defined in `setupFiles`, for example. + * @param path Path to the module. Can be aliased, if your Vitest config supports it */ unmock(path: string): void - doMock(path: string, factory?: () => any): void + /** + * Mocks every subsequent [dynamic import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) call. + * + * Unlike [`vi.mock`](https://vitest.dev/api/vi#vi-mock), this method will not mock statically imported modules because it is not hoisted to the top of the file. + * + * Mocking algorithm is described in [documentation](https://vitest.dev/guide/mocking#modules). + * @param path Path to the module. Can be aliased, if your Vitest config supports it + * @param factory Mocked module factory. The result of this function will be an exports object + */ + doMock(path: string, factory?: MockFactoryWithHelper): void + /** + * Removes module from mocked registry. All subsequent calls to import will return original module. + * + * Unlike [`vi.unmock`](https://vitest.dev/api/vi#vi-unmock), this method is not hoisted to the top of the file. + * @param path Path to the module. Can be aliased, if your Vitest config supports it + */ doUnmock(path: string): void /** * Imports module, bypassing all checks if it should be mocked. * Can be useful if you want to mock module partially. * @example - * vi.mock('./example', async () => { - * const axios = await vi.importActual('./example') + * vi.mock('./example.js', async () => { + * const axios = await vi.importActual('./example.js') * * return { ...axios, get: vi.fn() } * }) * @param path Path to the module. Can be aliased, if your config supports it - * @returns Actual module without spies */ - importActual(path: string): Promise + importActual(path: string): Promise /** * Imports a module with all of its properties and nested properties mocked. - * For the rules applied, see docs. + * + * Mocking algorithm is described in [documentation](https://vitest.dev/guide/mocking#modules). + * @example + * const example = await vi.importMock('./example.js') + * example.calc.mockReturnValue(10) + * expect(example.calc()).toBe(10) * @param path Path to the module. Can be aliased, if your config supports it * @returns Fully mocked module */ - importMock(path: string): Promise> + importMock(path: string): Promise> /** - * Type helpers for TypeScript. In reality just returns the object that was passed. + * Type helper for TypeScript. Just returns the object that was passed. * - * When `partial` is `true` it will expect a `Partial` as a return value. + * When `partial` is `true` it will expect a `Partial` as a return value. By default, this will only make TypeScript believe that + * the first level values are mocked. You can pass down `{ deep: true }` as a second argument to tell TypeScript that the whole object is mocked, if it actually is. * @example - * import example from './example' - * vi.mock('./example') - * - * test('1+1 equals 2' async () => { - * vi.mocked(example.calc).mockRestore() + * import example from './example.js' + * vi.mock('./example.js') * - * const res = example.calc(1, '+', 1) - * - * expect(res).toBe(2) + * test('1 + 1 equals 10' async () => { + * vi.mocked(example.calc).mockReturnValue(10) + * expect(example.calc(1, '+', 1)).toBe(10) * }) * @param item Anything that can be mocked * @param deep If the object is deeply mocked @@ -113,36 +262,60 @@ export interface VitestUtils { mocked(item: T, options: { partial: true; deep: true }): MaybePartiallyMockedDeep mocked(item: T): MaybeMocked - isMockFunction(fn: any): fn is EnhancedSpy + /** + * Checks that a given parameter is a mock function. If you are using TypeScript, it will also narrow down its type. + */ + isMockFunction(fn: any): fn is MockInstance + + /** + * Calls [`.mockClear()`](https://vitest.dev/api/mock#mockclear) on every mocked function. This will only empty `.mock` state, it will not reset implementation. + * + * It is useful if you need to clean up mock between different assertions. + */ + clearAllMocks(): VitestUtils + + /** + * Calls [`.mockReset()`](https://vitest.dev/api/mock#mockreset) on every mocked function. This will empty `.mock` state, reset "once" implementations and force the base implementation to return `undefined` when invoked. + * + * This is useful when you want to completely reset a mock to the default state. + */ + resetAllMocks(): VitestUtils - clearAllMocks(): this - resetAllMocks(): this - restoreAllMocks(): this + /** + * Calls [`.mockRestore()`](https://vitest.dev/api/mock#mockrestore) on every mocked function. This will restore all original implementations. + */ + restoreAllMocks(): VitestUtils /** * Makes value available on global namespace. * Useful, if you want to have global variables available, like `IntersectionObserver`. * You can return it back to original value with `vi.unstubAllGlobals`, or by enabling `unstubGlobals` config option. */ - stubGlobal(name: string | symbol | number, value: unknown): this + stubGlobal(name: string | symbol | number, value: unknown): VitestUtils /** * Changes the value of `import.meta.env` and `process.env`. * You can return it back to original value with `vi.unstubAllEnvs`, or by enabling `unstubEnvs` config option. */ - stubEnv(name: string, value: string): this + stubEnv(name: string, value: string): VitestUtils /** * Reset the value to original value that was available before first `vi.stubGlobal` was called. */ - unstubAllGlobals(): this + unstubAllGlobals(): VitestUtils /** * Reset environmental variables to the ones that were available before first `vi.stubEnv` was called. */ - unstubAllEnvs(): this + unstubAllEnvs(): VitestUtils - resetModules(): this + /** + * Resets modules registry by clearing the cache of all modules. This allows modules to be reevaluated when reimported. + * Top-level imports cannot be re-evaluated. Might be useful to isolate modules where local state conflicts between tests. + * + * This method does not reset mocks registry. To clear mocks registry, use [`vi.unmock`](https://vitest.dev/api/vi#vi-unmock) or [`vi.doUnmock`](https://vitest.dev/api/vi#vi-dounmock). + */ + resetModules(): VitestUtils /** * Wait for all imports to load. Useful, if you have a synchronous call that starts @@ -328,8 +501,13 @@ function createVitest(): VitestUtils { _mocker.queueUnmock(path, getImporter()) }, - doMock(path: string, factory?: () => any) { - _mocker.queueMock(path, getImporter(), factory) + doMock(path: string, factory?: MockFactoryWithHelper) { + const importer = getImporter() + _mocker.queueMock( + path, + importer, + factory ? () => factory(() => _mocker.importActual(path, importer)) : undefined, + ) }, doUnmock(path: string) { @@ -348,22 +526,22 @@ function createVitest(): VitestUtils { return item as any }, - isMockFunction(fn: any): fn is EnhancedSpy { + isMockFunction(fn: any): fn is MockInstance { return isMockFunction(fn) }, clearAllMocks() { - spies.forEach(spy => spy.mockClear()) + mocks.forEach(spy => spy.mockClear()) return utils }, resetAllMocks() { - spies.forEach(spy => spy.mockReset()) + mocks.forEach(spy => spy.mockReset()) return utils }, restoreAllMocks() { - spies.forEach(spy => spy.mockRestore()) + mocks.forEach(spy => spy.mockRestore()) return utils }, diff --git a/packages/vitest/src/types/index.ts b/packages/vitest/src/types/index.ts index a1cb1f5c5ec5..3da526a29867 100644 --- a/packages/vitest/src/types/index.ts +++ b/packages/vitest/src/types/index.ts @@ -15,7 +15,6 @@ export type * from './coverage' export type * from './benchmark' export type { DiffOptions } from '@vitest/utils/diff' export type { - EnhancedSpy, MockedFunction, MockedObject, SpyInstance, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a3b57f94d4f5..5ed0c82b1310 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -117,36 +117,33 @@ importers: docs: dependencies: '@vueuse/core': - specifier: ^10.2.1 - version: 10.2.1(vue@3.3.4) - jiti: - specifier: ^1.18.2 - version: 1.18.2 + specifier: ^10.5.0 + version: 10.5.0(vue@3.3.4) vue: specifier: latest version: 3.3.4 devDependencies: '@iconify-json/carbon': - specifier: ^1.1.18 - version: 1.1.18 + specifier: ^1.1.21 + version: 1.1.21 '@unocss/reset': specifier: ^0.53.4 version: 0.53.4 '@vite-pwa/assets-generator': - specifier: ^0.0.3 - version: 0.0.3 + specifier: ^0.0.10 + version: 0.0.10 '@vite-pwa/vitepress': - specifier: ^0.2.0 - version: 0.2.0(vite-plugin-pwa@0.16.4) + specifier: ^0.2.3 + version: 0.2.3(vite-plugin-pwa@0.16.6) '@vitejs/plugin-vue': specifier: latest version: 4.4.0(vite@4.5.0)(vue@3.3.4) esno: - specifier: ^0.16.3 - version: 0.16.3 + specifier: ^0.17.0 + version: 0.17.0 fast-glob: - specifier: ^3.3.0 - version: 3.3.0 + specifier: ^3.3.1 + version: 3.3.1 fs-extra: specifier: ^11.1.1 version: 11.1.1 @@ -157,17 +154,17 @@ importers: specifier: ^0.53.4 version: 0.53.4(postcss@8.4.31)(rollup@2.79.1)(vite@4.5.0) unplugin-vue-components: - specifier: ^0.25.1 - version: 0.25.1(rollup@2.79.1)(vue@3.3.4) + specifier: ^0.25.2 + version: 0.25.2(rollup@2.79.1)(vue@3.3.4) vite: specifier: ^4.5.0 version: 4.5.0(@types/node@18.16.19)(less@4.1.3) vite-plugin-pwa: - specifier: ^0.16.4 - version: 0.16.4(vite@4.5.0)(workbox-build@7.0.0)(workbox-window@7.0.0) + specifier: ^0.16.6 + version: 0.16.6(vite@4.5.0)(workbox-build@7.0.0)(workbox-window@7.0.0) vitepress: - specifier: 1.0.0-beta.5 - version: 1.0.0-beta.5(@types/node@18.16.19)(search-insights@2.9.0) + specifier: ^1.0.0-rc.24 + version: 1.0.0-rc.24(@types/node@18.16.19)(postcss@8.4.31)(search-insights@2.9.0)(typescript@5.1.6) workbox-window: specifier: ^7.0.0 version: 7.0.0 @@ -2085,30 +2082,30 @@ packages: resolution: {integrity: sha512-+u76oB43nOHrF4DDWRLWDCtci7f3QJoEBigemIdIeTi1ODqjx6Tad9NCVnPRwewWlKkVab5PlK8DCtPTyX7S8g==} dev: true - /@algolia/autocomplete-core@1.9.3(algoliasearch@4.14.2)(search-insights@2.9.0): + /@algolia/autocomplete-core@1.9.3(algoliasearch@4.20.0)(search-insights@2.9.0): resolution: {integrity: sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==} dependencies: - '@algolia/autocomplete-plugin-algolia-insights': 1.9.3(algoliasearch@4.14.2)(search-insights@2.9.0) - '@algolia/autocomplete-shared': 1.9.3(algoliasearch@4.14.2) + '@algolia/autocomplete-plugin-algolia-insights': 1.9.3(algoliasearch@4.20.0)(search-insights@2.9.0) + '@algolia/autocomplete-shared': 1.9.3(algoliasearch@4.20.0) transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - search-insights dev: true - /@algolia/autocomplete-plugin-algolia-insights@1.9.3(algoliasearch@4.14.2)(search-insights@2.9.0): + /@algolia/autocomplete-plugin-algolia-insights@1.9.3(algoliasearch@4.20.0)(search-insights@2.9.0): resolution: {integrity: sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==} peerDependencies: search-insights: '>= 1 < 3' dependencies: - '@algolia/autocomplete-shared': 1.9.3(algoliasearch@4.14.2) + '@algolia/autocomplete-shared': 1.9.3(algoliasearch@4.20.0) search-insights: 2.9.0 transitivePeerDependencies: - '@algolia/client-search' - algoliasearch dev: true - /@algolia/autocomplete-preset-algolia@1.9.3(algoliasearch@4.14.2): + /@algolia/autocomplete-preset-algolia@1.9.3(algoliasearch@4.20.0): resolution: {integrity: sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==} peerDependencies: '@algolia/client-search': '>= 4.9.1 < 6' @@ -2117,11 +2114,11 @@ packages: '@algolia/client-search': optional: true dependencies: - '@algolia/autocomplete-shared': 1.9.3(algoliasearch@4.14.2) - algoliasearch: 4.14.2 + '@algolia/autocomplete-shared': 1.9.3(algoliasearch@4.20.0) + algoliasearch: 4.20.0 dev: true - /@algolia/autocomplete-shared@1.9.3(algoliasearch@4.14.2): + /@algolia/autocomplete-shared@1.9.3(algoliasearch@4.20.0): resolution: {integrity: sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==} peerDependencies: '@algolia/client-search': '>= 4.9.1 < 6' @@ -2130,97 +2127,97 @@ packages: '@algolia/client-search': optional: true dependencies: - algoliasearch: 4.14.2 + algoliasearch: 4.20.0 dev: true - /@algolia/cache-browser-local-storage@4.14.2: - resolution: {integrity: sha512-FRweBkK/ywO+GKYfAWbrepewQsPTIEirhi1BdykX9mxvBPtGNKccYAxvGdDCumU1jL4r3cayio4psfzKMejBlA==} + /@algolia/cache-browser-local-storage@4.20.0: + resolution: {integrity: sha512-uujahcBt4DxduBTvYdwO3sBfHuJvJokiC3BP1+O70fglmE1ShkH8lpXqZBac1rrU3FnNYSUs4pL9lBdTKeRPOQ==} dependencies: - '@algolia/cache-common': 4.14.2 + '@algolia/cache-common': 4.20.0 dev: true - /@algolia/cache-common@4.14.2: - resolution: {integrity: sha512-SbvAlG9VqNanCErr44q6lEKD2qoK4XtFNx9Qn8FK26ePCI8I9yU7pYB+eM/cZdS9SzQCRJBbHUumVr4bsQ4uxg==} + /@algolia/cache-common@4.20.0: + resolution: {integrity: sha512-vCfxauaZutL3NImzB2G9LjLt36vKAckc6DhMp05An14kVo8F1Yofb6SIl6U3SaEz8pG2QOB9ptwM5c+zGevwIQ==} dev: true - /@algolia/cache-in-memory@4.14.2: - resolution: {integrity: sha512-HrOukWoop9XB/VFojPv1R5SVXowgI56T9pmezd/djh2JnVN/vXswhXV51RKy4nCpqxyHt/aGFSq2qkDvj6KiuQ==} + /@algolia/cache-in-memory@4.20.0: + resolution: {integrity: sha512-Wm9ak/IaacAZXS4mB3+qF/KCoVSBV6aLgIGFEtQtJwjv64g4ePMapORGmCyulCFwfePaRAtcaTbMcJF+voc/bg==} dependencies: - '@algolia/cache-common': 4.14.2 + '@algolia/cache-common': 4.20.0 dev: true - /@algolia/client-account@4.14.2: - resolution: {integrity: sha512-WHtriQqGyibbb/Rx71YY43T0cXqyelEU0lB2QMBRXvD2X0iyeGl4qMxocgEIcbHyK7uqE7hKgjT8aBrHqhgc1w==} + /@algolia/client-account@4.20.0: + resolution: {integrity: sha512-GGToLQvrwo7am4zVkZTnKa72pheQeez/16sURDWm7Seyz+HUxKi3BM6fthVVPUEBhtJ0reyVtuK9ArmnaKl10Q==} dependencies: - '@algolia/client-common': 4.14.2 - '@algolia/client-search': 4.14.2 - '@algolia/transporter': 4.14.2 + '@algolia/client-common': 4.20.0 + '@algolia/client-search': 4.20.0 + '@algolia/transporter': 4.20.0 dev: true - /@algolia/client-analytics@4.14.2: - resolution: {integrity: sha512-yBvBv2mw+HX5a+aeR0dkvUbFZsiC4FKSnfqk9rrfX+QrlNOKEhCG0tJzjiOggRW4EcNqRmaTULIYvIzQVL2KYQ==} + /@algolia/client-analytics@4.20.0: + resolution: {integrity: sha512-EIr+PdFMOallRdBTHHdKI3CstslgLORQG7844Mq84ib5oVFRVASuuPmG4bXBgiDbcsMLUeOC6zRVJhv1KWI0ug==} dependencies: - '@algolia/client-common': 4.14.2 - '@algolia/client-search': 4.14.2 - '@algolia/requester-common': 4.14.2 - '@algolia/transporter': 4.14.2 + '@algolia/client-common': 4.20.0 + '@algolia/client-search': 4.20.0 + '@algolia/requester-common': 4.20.0 + '@algolia/transporter': 4.20.0 dev: true - /@algolia/client-common@4.14.2: - resolution: {integrity: sha512-43o4fslNLcktgtDMVaT5XwlzsDPzlqvqesRi4MjQz2x4/Sxm7zYg5LRYFol1BIhG6EwxKvSUq8HcC/KxJu3J0Q==} + /@algolia/client-common@4.20.0: + resolution: {integrity: sha512-P3WgMdEss915p+knMMSd/fwiHRHKvDu4DYRrCRaBrsfFw7EQHon+EbRSm4QisS9NYdxbS04kcvNoavVGthyfqQ==} dependencies: - '@algolia/requester-common': 4.14.2 - '@algolia/transporter': 4.14.2 + '@algolia/requester-common': 4.20.0 + '@algolia/transporter': 4.20.0 dev: true - /@algolia/client-personalization@4.14.2: - resolution: {integrity: sha512-ACCoLi0cL8CBZ1W/2juehSltrw2iqsQBnfiu/Rbl9W2yE6o2ZUb97+sqN/jBqYNQBS+o0ekTMKNkQjHHAcEXNw==} + /@algolia/client-personalization@4.20.0: + resolution: {integrity: sha512-N9+zx0tWOQsLc3K4PVRDV8GUeOLAY0i445En79Pr3zWB+m67V+n/8w4Kw1C5LlbHDDJcyhMMIlqezh6BEk7xAQ==} dependencies: - '@algolia/client-common': 4.14.2 - '@algolia/requester-common': 4.14.2 - '@algolia/transporter': 4.14.2 + '@algolia/client-common': 4.20.0 + '@algolia/requester-common': 4.20.0 + '@algolia/transporter': 4.20.0 dev: true - /@algolia/client-search@4.14.2: - resolution: {integrity: sha512-L5zScdOmcZ6NGiVbLKTvP02UbxZ0njd5Vq9nJAmPFtjffUSOGEp11BmD2oMJ5QvARgx2XbX4KzTTNS5ECYIMWw==} + /@algolia/client-search@4.20.0: + resolution: {integrity: sha512-zgwqnMvhWLdpzKTpd3sGmMlr4c+iS7eyyLGiaO51zDZWGMkpgoNVmltkzdBwxOVXz0RsFMznIxB9zuarUv4TZg==} dependencies: - '@algolia/client-common': 4.14.2 - '@algolia/requester-common': 4.14.2 - '@algolia/transporter': 4.14.2 + '@algolia/client-common': 4.20.0 + '@algolia/requester-common': 4.20.0 + '@algolia/transporter': 4.20.0 dev: true - /@algolia/logger-common@4.14.2: - resolution: {integrity: sha512-/JGlYvdV++IcMHBnVFsqEisTiOeEr6cUJtpjz8zc0A9c31JrtLm318Njc72p14Pnkw3A/5lHHh+QxpJ6WFTmsA==} + /@algolia/logger-common@4.20.0: + resolution: {integrity: sha512-xouigCMB5WJYEwvoWW5XDv7Z9f0A8VoXJc3VKwlHJw/je+3p2RcDXfksLI4G4lIVncFUYMZx30tP/rsdlvvzHQ==} dev: true - /@algolia/logger-console@4.14.2: - resolution: {integrity: sha512-8S2PlpdshbkwlLCSAB5f8c91xyc84VM9Ar9EdfE9UmX+NrKNYnWR1maXXVDQQoto07G1Ol/tYFnFVhUZq0xV/g==} + /@algolia/logger-console@4.20.0: + resolution: {integrity: sha512-THlIGG1g/FS63z0StQqDhT6bprUczBI8wnLT3JWvfAQDZX5P6fCg7dG+pIrUBpDIHGszgkqYEqECaKKsdNKOUA==} dependencies: - '@algolia/logger-common': 4.14.2 + '@algolia/logger-common': 4.20.0 dev: true - /@algolia/requester-browser-xhr@4.14.2: - resolution: {integrity: sha512-CEh//xYz/WfxHFh7pcMjQNWgpl4wFB85lUMRyVwaDPibNzQRVcV33YS+63fShFWc2+42YEipFGH2iPzlpszmDw==} + /@algolia/requester-browser-xhr@4.20.0: + resolution: {integrity: sha512-HbzoSjcjuUmYOkcHECkVTwAelmvTlgs48N6Owt4FnTOQdwn0b8pdht9eMgishvk8+F8bal354nhx/xOoTfwiAw==} dependencies: - '@algolia/requester-common': 4.14.2 + '@algolia/requester-common': 4.20.0 dev: true - /@algolia/requester-common@4.14.2: - resolution: {integrity: sha512-73YQsBOKa5fvVV3My7iZHu1sUqmjjfs9TteFWwPwDmnad7T0VTCopttcsM3OjLxZFtBnX61Xxl2T2gmG2O4ehg==} + /@algolia/requester-common@4.20.0: + resolution: {integrity: sha512-9h6ye6RY/BkfmeJp7Z8gyyeMrmmWsMOCRBXQDs4mZKKsyVlfIVICpcSibbeYcuUdurLhIlrOUkH3rQEgZzonng==} dev: true - /@algolia/requester-node-http@4.14.2: - resolution: {integrity: sha512-oDbb02kd1o5GTEld4pETlPZLY0e+gOSWjWMJHWTgDXbv9rm/o2cF7japO6Vj1ENnrqWvLBmW1OzV9g6FUFhFXg==} + /@algolia/requester-node-http@4.20.0: + resolution: {integrity: sha512-ocJ66L60ABSSTRFnCHIEZpNHv6qTxsBwJEPfYaSBsLQodm0F9ptvalFkHMpvj5DfE22oZrcrLbOYM2bdPJRHng==} dependencies: - '@algolia/requester-common': 4.14.2 + '@algolia/requester-common': 4.20.0 dev: true - /@algolia/transporter@4.14.2: - resolution: {integrity: sha512-t89dfQb2T9MFQHidjHcfhh6iGMNwvuKUvojAj+JsrHAGbuSy7yE4BylhLX6R0Q1xYRoC4Vvv+O5qIw/LdnQfsQ==} + /@algolia/transporter@4.20.0: + resolution: {integrity: sha512-Lsii1pGWOAISbzeyuf+r/GPhvHMPHSPrTDWNcIzOE1SG1inlJHICaVe2ikuoRjcpgxZNU54Jl+if15SUCsaTUg==} dependencies: - '@algolia/cache-common': 4.14.2 - '@algolia/logger-common': 4.14.2 - '@algolia/requester-common': 4.14.2 + '@algolia/cache-common': 4.20.0 + '@algolia/logger-common': 4.20.0 + '@algolia/requester-common': 4.20.0 dev: true /@ampproject/remapping@2.2.0: @@ -2354,6 +2351,10 @@ packages: resolution: {integrity: sha512-dlR6LdS+0SzOAPx/TPRhnoi7hE251OVeT2Snw0RguNbBSbjUHdWr0l3vcUUDg26rEysT89kCbtw1lVorBXLLCg==} dev: true + /@antfu/utils@0.7.6: + resolution: {integrity: sha512-pvFiLP2BeOKA/ZOS6jxx4XhKzdVLHDhGlFEaZ2flWWYf2xOqVniqpk38I04DFRyz+L0ASggl7SkItTc+ZLju4w==} + dev: true + /@apideck/better-ajv-errors@0.3.6(ajv@8.12.0): resolution: {integrity: sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==} engines: {node: '>=10'} @@ -6309,14 +6310,14 @@ packages: engines: {node: '>=10.0.0'} dev: true - /@docsearch/css@3.5.1: - resolution: {integrity: sha512-2Pu9HDg/uP/IT10rbQ+4OrTQuxIWdKVUEdcw9/w7kZJv9NeHS6skJx1xuRiFyoGKwAzcHXnLp7csE99sj+O1YA==} + /@docsearch/css@3.5.2: + resolution: {integrity: sha512-SPiDHaWKQZpwR2siD0KQUwlStvIAnEyK6tAE2h2Wuoq8ue9skzhlyVQ1ddzOxX6khULnAALDiR/isSF3bnuciA==} dev: true - /@docsearch/js@3.5.1(search-insights@2.9.0): - resolution: {integrity: sha512-EXi8de5njxgP6TV3N9ytnGRLG9zmBNTEZjR4VzwPcpPLbZxxTLG2gaFyJyKiFVQxHW/DPlMrDJA3qoRRGEkgZw==} + /@docsearch/js@3.5.2(search-insights@2.9.0): + resolution: {integrity: sha512-p1YFTCDflk8ieHgFJYfmyHBki1D61+U9idwrLh+GQQMrBSP3DLGKpy0XUJtPjAOPltcVbqsTjiPFfH7JImjUNg==} dependencies: - '@docsearch/react': 3.5.1(search-insights@2.9.0) + '@docsearch/react': 3.5.2(search-insights@2.9.0) preact: 10.15.1 transitivePeerDependencies: - '@algolia/client-search' @@ -6326,12 +6327,13 @@ packages: - search-insights dev: true - /@docsearch/react@3.5.1(search-insights@2.9.0): - resolution: {integrity: sha512-t5mEODdLzZq4PTFAm/dvqcvZFdPDMdfPE5rJS5SC8OUq9mPzxEy6b+9THIqNM9P0ocCb4UC5jqBrxKclnuIbzQ==} + /@docsearch/react@3.5.2(search-insights@2.9.0): + resolution: {integrity: sha512-9Ahcrs5z2jq/DcAvYtvlqEBHImbm4YJI8M9y0x6Tqg598P40HTEkX7hsMcIuThI+hTFxRGZ9hll0Wygm2yEjng==} peerDependencies: '@types/react': '>= 16.8.0 < 19.0.0' react: '>= 16.8.0 < 19.0.0' react-dom: '>= 16.8.0 < 19.0.0' + search-insights: '>= 1 < 3' peerDependenciesMeta: '@types/react': optional: true @@ -6339,14 +6341,16 @@ packages: optional: true react-dom: optional: true + search-insights: + optional: true dependencies: - '@algolia/autocomplete-core': 1.9.3(algoliasearch@4.14.2)(search-insights@2.9.0) - '@algolia/autocomplete-preset-algolia': 1.9.3(algoliasearch@4.14.2) - '@docsearch/css': 3.5.1 - algoliasearch: 4.14.2 + '@algolia/autocomplete-core': 1.9.3(algoliasearch@4.20.0)(search-insights@2.9.0) + '@algolia/autocomplete-preset-algolia': 1.9.3(algoliasearch@4.20.0) + '@docsearch/css': 3.5.2 + algoliasearch: 4.20.0 + search-insights: 2.9.0 transitivePeerDependencies: - '@algolia/client-search' - - search-insights dev: true /@edge-runtime/primitives@1.1.0-beta.31: @@ -7091,8 +7095,8 @@ packages: resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} dev: true - /@iconify-json/carbon@1.1.18: - resolution: {integrity: sha512-RbKET6KS9xUMeYVq1FUH3UUA7AYNcnApkHt2AccCwTWTQQs/O58ji4Of6z6PhRajGlbfvrJzT/Uqh19OKECRvA==} + /@iconify-json/carbon@1.1.21: + resolution: {integrity: sha512-bK2cMVM4noBU+FGlay433flpXLRzQu0ED095iAnoO6ka3yb4uz0lvb8acpN5gthyGLJ89C4HpfIbQZLQnMKQww==} dependencies: '@iconify/types': 2.0.0 dev: true @@ -7107,11 +7111,11 @@ packages: resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} dev: true - /@iconify/utils@2.1.7: - resolution: {integrity: sha512-P8S3z/L1LcV4Qem9AoCfVAaTFGySEMzFEY4CHZLkfRj0Fv9LiR+AwjDgrDrzyI93U2L2mg9JHsbTJ52mF8suNw==} + /@iconify/utils@2.1.11: + resolution: {integrity: sha512-M/w3PkN8zQYXi8N6qK/KhnYMfEbbb6Sk8RZVn8g+Pmmu5ybw177RpsaGwpziyHeUsu4etrexYSWq3rwnIqzYCg==} dependencies: '@antfu/install-pkg': 0.1.1 - '@antfu/utils': 0.7.5 + '@antfu/utils': 0.7.6 '@iconify/types': 2.0.0 debug: 4.3.4(supports-color@8.1.1) kolorist: 1.8.0 @@ -8413,7 +8417,7 @@ packages: estree-walker: 2.0.2 picomatch: 2.3.1 - /@rollup/pluginutils@5.0.2(rollup@2.79.1): + /@rollup/pluginutils@5.0.2(rollup@3.29.4): resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==} engines: {node: '>=14.0.0'} peerDependencies: @@ -8425,11 +8429,11 @@ packages: '@types/estree': 1.0.1 estree-walker: 2.0.2 picomatch: 2.3.1 - rollup: 2.79.1 + rollup: 3.29.4 dev: true - /@rollup/pluginutils@5.0.2(rollup@3.29.4): - resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==} + /@rollup/pluginutils@5.0.4(rollup@2.79.1): + resolution: {integrity: sha512-0KJnIoRI8A+a1dqOYLxH8vBf8bphDmty5QvIm2hqm7oFCFYKCAZWWd2hXgMibaPsNDhI0AtpYfQZJG47pt/k4g==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^1.20.0||^2.0.0||^3.0.0 @@ -8440,10 +8444,10 @@ packages: '@types/estree': 1.0.1 estree-walker: 2.0.2 picomatch: 2.3.1 - rollup: 3.29.4 + rollup: 2.79.1 dev: true - /@rollup/pluginutils@5.0.4(rollup@2.79.1): + /@rollup/pluginutils@5.0.4(rollup@3.29.4): resolution: {integrity: sha512-0KJnIoRI8A+a1dqOYLxH8vBf8bphDmty5QvIm2hqm7oFCFYKCAZWWd2hXgMibaPsNDhI0AtpYfQZJG47pt/k4g==} engines: {node: '>=14.0.0'} peerDependencies: @@ -8455,19 +8459,34 @@ packages: '@types/estree': 1.0.1 estree-walker: 2.0.2 picomatch: 2.3.1 + rollup: 3.29.4 + dev: true + + /@rollup/pluginutils@5.0.5(rollup@2.79.1): + resolution: {integrity: sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@types/estree': 1.0.3 + estree-walker: 2.0.2 + picomatch: 2.3.1 rollup: 2.79.1 dev: true - /@rollup/pluginutils@5.0.4(rollup@3.29.4): - resolution: {integrity: sha512-0KJnIoRI8A+a1dqOYLxH8vBf8bphDmty5QvIm2hqm7oFCFYKCAZWWd2hXgMibaPsNDhI0AtpYfQZJG47pt/k4g==} + /@rollup/pluginutils@5.0.5(rollup@3.29.4): + resolution: {integrity: sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0 + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: rollup: optional: true dependencies: - '@types/estree': 1.0.1 + '@types/estree': 1.0.3 estree-walker: 2.0.2 picomatch: 2.3.1 rollup: 3.29.4 @@ -10462,7 +10481,7 @@ packages: resolution: {integrity: sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==} dependencies: '@types/eslint': 8.4.6 - '@types/estree': 1.0.1 + '@types/estree': 1.0.3 dev: true /@types/eslint-scope@3.7.6: @@ -10475,7 +10494,7 @@ packages: /@types/eslint@8.4.6: resolution: {integrity: sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g==} dependencies: - '@types/estree': 1.0.1 + '@types/estree': 1.0.3 '@types/json-schema': 7.0.11 dev: true @@ -10676,16 +10695,31 @@ packages: '@types/node': 20.8.8 dev: true + /@types/linkify-it@3.0.4: + resolution: {integrity: sha512-hPpIeeHb/2UuCw06kSNAOVWgehBLXEo0/fUs0mw3W2qhqX89PI2yvok83MnuctYGCPrabGIoi0fFso4DQ+sNUQ==} + dev: true + /@types/lodash@4.14.195: resolution: {integrity: sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg==} dev: true + /@types/markdown-it@13.0.5: + resolution: {integrity: sha512-QhJP7hkq3FCrFNx0szMNCT/79CXfcEgUIA3jc5GBfeXqoKsk3R8JZm2wRXJ2DiyjbPE4VMFOSDemLFcUTZmHEQ==} + dependencies: + '@types/linkify-it': 3.0.4 + '@types/mdurl': 1.0.4 + dev: true + /@types/mdast@3.0.10: resolution: {integrity: sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==} dependencies: '@types/unist': 2.0.6 dev: true + /@types/mdurl@1.0.4: + resolution: {integrity: sha512-ARVxjAEX5TARFRzpDRVC6cEk0hUIXCCwaMhz8y7S1/PxU6zZS1UMjyobz7q4w/D/R552r4++EhwmXK1N2rAy0A==} + dev: true + /@types/micromatch@4.0.2: resolution: {integrity: sha512-oqXqVb0ci19GtH0vOA/U2TmHTcRY9kuZl4mqUxe0QmJAlIW13kzhuK5pi1i9+ngav8FjpSb9FVS/GE00GLX1VA==} dependencies: @@ -11000,6 +11034,10 @@ packages: /@types/web-bluetooth@0.0.17: resolution: {integrity: sha512-4p9vcSmxAayx72yn70joFoL44c9MO/0+iVEBIQXe3v2h2SiAsEIo/G5v6ObFWvNKRFjbrVadNf9LqEEZeQPzdA==} + dev: true + + /@types/web-bluetooth@0.0.18: + resolution: {integrity: sha512-v/ZHEj9xh82usl8LMR3GarzFY1IrbXJw5L4QfQhokjRV91q+SelFqxQWSep1ucXEZ22+dSTwLFkXeur25sPIbw==} /@types/webpack-env@1.18.0: resolution: {integrity: sha512-56/MAlX5WMsPVbOg7tAxnYvNYMMWr/QJiIp6BxVSW3JJXUVzzOn64qW8TzQyMSqSUFM2+PVI4aUHcHOzIz/1tg==} @@ -11230,15 +11268,15 @@ packages: hasBin: true dependencies: '@ampproject/remapping': 2.2.1 - '@rollup/pluginutils': 5.0.4(rollup@2.79.1) + '@rollup/pluginutils': 5.0.5(rollup@2.79.1) '@unocss/config': 0.53.4 '@unocss/core': 0.53.4 '@unocss/preset-uno': 0.53.4 cac: 6.7.14 chokidar: 3.5.3 colorette: 2.0.20 - consola: 3.1.0 - fast-glob: 3.3.0 + consola: 3.2.3 + fast-glob: 3.3.1 magic-string: 0.30.5 pathe: 1.1.1 perfect-debounce: 1.0.0 @@ -11252,15 +11290,15 @@ packages: hasBin: true dependencies: '@ampproject/remapping': 2.2.1 - '@rollup/pluginutils': 5.0.4(rollup@3.29.4) + '@rollup/pluginutils': 5.0.5(rollup@3.29.4) '@unocss/config': 0.53.4 '@unocss/core': 0.53.4 '@unocss/preset-uno': 0.53.4 cac: 6.7.14 chokidar: 3.5.3 colorette: 2.0.20 - consola: 3.1.0 - fast-glob: 3.3.0 + consola: 3.2.3 + fast-glob: 3.3.1 magic-string: 0.30.5 pathe: 1.1.1 perfect-debounce: 1.0.0 @@ -11273,7 +11311,7 @@ packages: engines: {node: '>=14'} dependencies: '@unocss/core': 0.53.4 - unconfig: 0.3.9 + unconfig: 0.3.11 dev: true /@unocss/core@0.53.4: @@ -11302,7 +11340,7 @@ packages: '@unocss/config': 0.53.4 '@unocss/core': 0.53.4 css-tree: 2.3.1 - fast-glob: 3.3.0 + fast-glob: 3.3.1 magic-string: 0.30.5 postcss: 8.4.31 dev: true @@ -11316,7 +11354,7 @@ packages: /@unocss/preset-icons@0.53.4: resolution: {integrity: sha512-PSc1svzDq/o7lKLrZohFIMf0ZqOypYdBY1Wvfp+Gd6Zc4uybnCTVme3pnlgYIcjSO24ilt/PeWgx3SxD8ypMcw==} dependencies: - '@iconify/utils': 2.1.7 + '@iconify/utils': 2.1.11 '@unocss/core': 0.53.4 ofetch: 1.3.3 transitivePeerDependencies: @@ -11410,14 +11448,14 @@ packages: vite: ^4.5.0 dependencies: '@ampproject/remapping': 2.2.1 - '@rollup/pluginutils': 5.0.4(rollup@2.79.1) + '@rollup/pluginutils': 5.0.5(rollup@2.79.1) '@unocss/config': 0.53.4 '@unocss/core': 0.53.4 '@unocss/inspector': 0.53.4 '@unocss/scope': 0.53.4 '@unocss/transformer-directives': 0.53.4 chokidar: 3.5.3 - fast-glob: 3.3.0 + fast-glob: 3.3.1 magic-string: 0.30.5 vite: 4.5.0(@types/node@18.16.19)(less@4.1.3) transitivePeerDependencies: @@ -11430,39 +11468,39 @@ packages: vite: ^4.5.0 dependencies: '@ampproject/remapping': 2.2.1 - '@rollup/pluginutils': 5.0.4(rollup@3.29.4) + '@rollup/pluginutils': 5.0.5(rollup@3.29.4) '@unocss/config': 0.53.4 '@unocss/core': 0.53.4 '@unocss/inspector': 0.53.4 '@unocss/scope': 0.53.4 '@unocss/transformer-directives': 0.53.4 chokidar: 3.5.3 - fast-glob: 3.3.0 + fast-glob: 3.3.1 magic-string: 0.30.5 vite: 4.5.0(@types/node@18.16.19)(less@4.1.3) transitivePeerDependencies: - rollup dev: true - /@vite-pwa/assets-generator@0.0.3: - resolution: {integrity: sha512-rGjzFTGAZsY9fIf9qGbvXbo38Yj0MbAtTxAaL/GBlEU0+q/m6upw+4HKE58p2MnjUAOOBHf0871u3onHtkPWlQ==} + /@vite-pwa/assets-generator@0.0.10: + resolution: {integrity: sha512-Ya3iE0EWIV+0g0XFXIjqSU8ZnhpJeLi9/xx+VfbSyXThKjk168GUYqd1z+SOuRO03bSRFDeK8wGixtwWuedjqg==} engines: {node: '>=16.14.0'} hasBin: true dependencies: cac: 6.7.14 colorette: 2.0.20 - consola: 3.1.0 - sharp: 0.32.1 + consola: 3.2.3 + sharp: 0.32.6 sharp-ico: 0.1.5 - unconfig: 0.3.9 + unconfig: 0.3.11 dev: true - /@vite-pwa/vitepress@0.2.0(vite-plugin-pwa@0.16.4): - resolution: {integrity: sha512-dVQVaP6NB9woCFe4UASUqRp7uwBQJOVXlJlqK4krqXcbb3NuXIXIWOnU7HLpJnHqZj5U/81gKtLN6gs5gJBwiQ==} + /@vite-pwa/vitepress@0.2.3(vite-plugin-pwa@0.16.6): + resolution: {integrity: sha512-6k9151CmILbSJQ88hLEMLL+MOQZDURKg2c4Wo5UcaEaOWU0jv7S+mo8nqyg86sM6ry8Jlnp6Zfv6AE0FqnfEyQ==} peerDependencies: - vite-plugin-pwa: '>=0.16.3 <1' + vite-plugin-pwa: '>=0.16.5 <1' dependencies: - vite-plugin-pwa: 0.16.4(vite@4.5.0)(workbox-build@7.0.0)(workbox-window@7.0.0) + vite-plugin-pwa: 0.16.6(vite@4.5.0)(workbox-build@7.0.0)(workbox-window@7.0.0) dev: true /@vitejs/plugin-react@1.3.2: @@ -11566,6 +11604,17 @@ packages: vue: 3.3.4 dev: true + /@vitejs/plugin-vue@4.3.1(vite@4.5.0)(vue@3.3.7): + resolution: {integrity: sha512-tUBEtWcF7wFtII7ayNiLNDTCE1X1afySEo+XNVMNkFXaThENyCowIEX095QqbJZGTgoOcSVDJGlnde2NG4jtbQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.5.0 + vue: ^3.2.25 + dependencies: + vite: 4.5.0(@types/node@18.16.19)(less@4.1.3) + vue: 3.3.7(typescript@5.1.6) + dev: true + /@vitejs/plugin-vue@4.4.0(vite@4.5.0)(vue@3.3.4): resolution: {integrity: sha512-xdguqb+VUwiRpSg+nsc2HtbAUSGak25DXYvpQQi4RVU1Xq1uworyoH/md9Rfd8zMmPR/pSghr309QNcftUVseg==} engines: {node: ^14.18.0 || >=16.0.0} @@ -11655,6 +11704,15 @@ packages: estree-walker: 2.0.2 source-map-js: 1.0.2 + /@vue/compiler-core@3.3.7: + resolution: {integrity: sha512-pACdY6YnTNVLXsB86YD8OF9ihwpolzhhtdLVHhBL6do/ykr6kKXNYABRtNMGrsQXpEXXyAdwvWWkuTbs4MFtPQ==} + dependencies: + '@babel/parser': 7.23.0 + '@vue/shared': 3.3.7 + estree-walker: 2.0.2 + source-map-js: 1.0.2 + dev: true + /@vue/compiler-dom@3.2.39: resolution: {integrity: sha512-HMFI25Be1C8vLEEv1hgEO1dWwG9QQ8LTTPmCkblVJY/O3OvWx6r1+zsox5mKPMGvqYEZa6l8j+xgOfUspgo7hw==} dependencies: @@ -11667,6 +11725,13 @@ packages: '@vue/compiler-core': 3.3.4 '@vue/shared': 3.3.4 + /@vue/compiler-dom@3.3.7: + resolution: {integrity: sha512-0LwkyJjnUPssXv/d1vNJ0PKfBlDoQs7n81CbO6Q0zdL7H1EzqYRrTVXDqdBVqro0aJjo/FOa1qBAPVI4PGSHBw==} + dependencies: + '@vue/compiler-core': 3.3.7 + '@vue/shared': 3.3.7 + dev: true + /@vue/compiler-sfc@2.7.10: resolution: {integrity: sha512-55Shns6WPxlYsz4WX7q9ZJBL77sKE1ZAYNYStLs6GbhIOMrNtjMvzcob6gu3cGlfpCR4bT7NXgyJ3tly2+Hx8Q==} dependencies: @@ -11702,6 +11767,21 @@ packages: postcss: 8.4.29 source-map-js: 1.0.2 + /@vue/compiler-sfc@3.3.7: + resolution: {integrity: sha512-7pfldWy/J75U/ZyYIXRVqvLRw3vmfxDo2YLMwVtWVNew8Sm8d6wodM+OYFq4ll/UxfqVr0XKiVwti32PCrruAw==} + dependencies: + '@babel/parser': 7.23.0 + '@vue/compiler-core': 3.3.7 + '@vue/compiler-dom': 3.3.7 + '@vue/compiler-ssr': 3.3.7 + '@vue/reactivity-transform': 3.3.7 + '@vue/shared': 3.3.7 + estree-walker: 2.0.2 + magic-string: 0.30.5 + postcss: 8.4.31 + source-map-js: 1.0.2 + dev: true + /@vue/compiler-ssr@3.2.39: resolution: {integrity: sha512-EoGCJ6lincKOZGW+0Ky4WOKsSmqL7hp1ZYgen8M7u/mlvvEQUaO9tKKOy7K43M9U2aA3tPv0TuYYQFrEbK2eFQ==} dependencies: @@ -11714,10 +11794,21 @@ packages: '@vue/compiler-dom': 3.3.4 '@vue/shared': 3.3.4 + /@vue/compiler-ssr@3.3.7: + resolution: {integrity: sha512-TxOfNVVeH3zgBc82kcUv+emNHo+vKnlRrkv8YvQU5+Y5LJGJwSNzcmLUoxD/dNzv0bhQ/F0s+InlgV0NrApJZg==} + dependencies: + '@vue/compiler-dom': 3.3.7 + '@vue/shared': 3.3.7 + dev: true + /@vue/devtools-api@6.5.0: resolution: {integrity: sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==} dev: true + /@vue/devtools-api@6.5.1: + resolution: {integrity: sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA==} + dev: true + /@vue/language-core@1.8.20(typescript@5.2.2): resolution: {integrity: sha512-vNJaqjCTSrWEr+erSq6Rq0CqDC8MOAwyxirxwK8esOxd+1LmAUJUTG2p7I84Mj1Izy5uHiHQAkRTVR2QxMBY+A==} peerDependencies: @@ -11755,6 +11846,16 @@ packages: estree-walker: 2.0.2 magic-string: 0.30.5 + /@vue/reactivity-transform@3.3.7: + resolution: {integrity: sha512-APhRmLVbgE1VPGtoLQoWBJEaQk4V8JUsqrQihImVqKT+8U6Qi3t5ATcg4Y9wGAPb3kIhetpufyZ1RhwbZCIdDA==} + dependencies: + '@babel/parser': 7.23.0 + '@vue/compiler-core': 3.3.7 + '@vue/shared': 3.3.7 + estree-walker: 2.0.2 + magic-string: 0.30.5 + dev: true + /@vue/reactivity@3.2.39: resolution: {integrity: sha512-vlaYX2a3qMhIZfrw3Mtfd+BuU+TZmvDrPMa+6lpfzS9k/LnGxkSuf0fhkP0rMGfiOHPtyKoU9OJJJFGm92beVQ==} dependencies: @@ -11765,6 +11866,12 @@ packages: dependencies: '@vue/shared': 3.3.4 + /@vue/reactivity@3.3.7: + resolution: {integrity: sha512-cZNVjWiw00708WqT0zRpyAgduG79dScKEPYJXq2xj/aMtk3SKvL3FBt2QKUlh6EHBJ1m8RhBY+ikBUzwc7/khg==} + dependencies: + '@vue/shared': 3.3.7 + dev: true + /@vue/runtime-core@3.2.39: resolution: {integrity: sha512-xKH5XP57JW5JW+8ZG1khBbuLakINTgPuINKL01hStWLTTGFOrM49UfCFXBcFvWmSbci3gmJyLl2EAzCaZWsx8g==} dependencies: @@ -11777,6 +11884,13 @@ packages: '@vue/reactivity': 3.3.4 '@vue/shared': 3.3.4 + /@vue/runtime-core@3.3.7: + resolution: {integrity: sha512-LHq9du3ubLZFdK/BP0Ysy3zhHqRfBn80Uc+T5Hz3maFJBGhci1MafccnL3rpd5/3wVfRHAe6c+PnlO2PAavPTQ==} + dependencies: + '@vue/reactivity': 3.3.7 + '@vue/shared': 3.3.7 + dev: true + /@vue/runtime-dom@3.2.39: resolution: {integrity: sha512-4G9AEJP+sLhsqf5wXcyKVWQKUhI+iWfy0hWQgea+CpaTD7BR0KdQzvoQdZhwCY6B3oleSyNLkLAQwm0ya/wNoA==} dependencies: @@ -11791,6 +11905,14 @@ packages: '@vue/shared': 3.3.4 csstype: 3.1.2 + /@vue/runtime-dom@3.3.7: + resolution: {integrity: sha512-PFQU1oeJxikdDmrfoNQay5nD4tcPNYixUBruZzVX/l0eyZvFKElZUjW4KctCcs52nnpMGO6UDK+jF5oV4GT5Lw==} + dependencies: + '@vue/runtime-core': 3.3.7 + '@vue/shared': 3.3.7 + csstype: 3.1.2 + dev: true + /@vue/server-renderer@3.2.39(vue@3.2.39): resolution: {integrity: sha512-1yn9u2YBQWIgytFMjz4f/t0j43awKytTGVptfd3FtBk76t1pd8mxbek0G/DrnjJhd2V7mSTb5qgnxMYt8Z5iSQ==} peerDependencies: @@ -11809,12 +11931,26 @@ packages: '@vue/shared': 3.3.4 vue: 3.3.4 + /@vue/server-renderer@3.3.7(vue@3.3.7): + resolution: {integrity: sha512-UlpKDInd1hIZiNuVVVvLgxpfnSouxKQOSE2bOfQpBuGwxRV/JqqTCyyjXUWiwtVMyeRaZhOYYqntxElk8FhBhw==} + peerDependencies: + vue: 3.3.7 + dependencies: + '@vue/compiler-ssr': 3.3.7 + '@vue/shared': 3.3.7 + vue: 3.3.7(typescript@5.1.6) + dev: true + /@vue/shared@3.2.39: resolution: {integrity: sha512-D3dl2ZB9qE6mTuWPk9RlhDeP1dgNRUKC3NJxji74A4yL8M2MwlhLKUC/49WHjrNzSPug58fWx/yFbaTzGAQSBw==} /@vue/shared@3.3.4: resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==} + /@vue/shared@3.3.7: + resolution: {integrity: sha512-N/tbkINRUDExgcPTBvxNkvHGu504k8lzlNQRITVnm6YjOjwa4r0nnbd4Jb01sNpur5hAllyRJzSK5PvB9PPwRg==} + dev: true + /@vue/test-utils@1.3.0(vue-template-compiler@2.7.10)(vue@2.7.10): resolution: {integrity: sha512-Xk2Xiyj2k5dFb8eYUKkcN9PzqZSppTlx7LaQWBbdA8tqh3jHr/KHX2/YLhNFc/xwDrgeLybqd+4ZCPJSGPIqeA==} peerDependencies: @@ -11877,6 +12013,31 @@ packages: transitivePeerDependencies: - '@vue/composition-api' - vue + dev: true + + /@vueuse/core@10.5.0(vue@3.3.4): + resolution: {integrity: sha512-z/tI2eSvxwLRjOhDm0h/SXAjNm8N5ld6/SC/JQs6o6kpJ6Ya50LnEL8g5hoYu005i28L0zqB5L5yAl8Jl26K3A==} + dependencies: + '@types/web-bluetooth': 0.0.18 + '@vueuse/metadata': 10.5.0 + '@vueuse/shared': 10.5.0(vue@3.3.4) + vue-demi: 0.14.6(vue@3.3.4) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + dev: false + + /@vueuse/core@10.5.0(vue@3.3.7): + resolution: {integrity: sha512-z/tI2eSvxwLRjOhDm0h/SXAjNm8N5ld6/SC/JQs6o6kpJ6Ya50LnEL8g5hoYu005i28L0zqB5L5yAl8Jl26K3A==} + dependencies: + '@types/web-bluetooth': 0.0.18 + '@vueuse/metadata': 10.5.0 + '@vueuse/shared': 10.5.0(vue@3.3.7) + vue-demi: 0.14.6(vue@3.3.7) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + dev: true /@vueuse/core@8.9.4(vue@3.2.39): resolution: {integrity: sha512-B/Mdj9TK1peFyWaPof+Zf/mP9XuGAngaJZBwPaXBvU3aCTZlx3ltlrFFFyMV4iGBwsjSCeUCgZrtkEj9dS2Y3Q==} @@ -11896,8 +12057,8 @@ packages: vue-demi: 0.14.0(vue@3.2.39) dev: false - /@vueuse/integrations@10.2.1(focus-trap@7.4.3)(vue@3.3.4): - resolution: {integrity: sha512-FDP5lni+z9FjHE9H3xuvwSjoRV9U8jmDvJpmHPCBjUgPGYRynwb60eHWXCFJXLUtb4gSIHy0e+iaEbrKdalCkQ==} + /@vueuse/integrations@10.5.0(focus-trap@7.5.4)(vue@3.3.7): + resolution: {integrity: sha512-fm5sXLCK0Ww3rRnzqnCQRmfjDURaI4xMsx+T+cec0ngQqHx/JgUtm8G0vRjwtonIeTBsH1Q8L3SucE+7K7upJQ==} peerDependencies: async-validator: '*' axios: '*' @@ -11937,10 +12098,10 @@ packages: universal-cookie: optional: true dependencies: - '@vueuse/core': 10.2.1(vue@3.3.4) - '@vueuse/shared': 10.2.1(vue@3.3.4) - focus-trap: 7.4.3 - vue-demi: 0.14.5(vue@3.3.4) + '@vueuse/core': 10.5.0(vue@3.3.7) + '@vueuse/shared': 10.5.0(vue@3.3.7) + focus-trap: 7.5.4 + vue-demi: 0.14.6(vue@3.3.7) transitivePeerDependencies: - '@vue/composition-api' - vue @@ -11992,6 +12153,10 @@ packages: /@vueuse/metadata@10.2.1: resolution: {integrity: sha512-3Gt68mY/i6bQvFqx7cuGBzrCCQu17OBaGWS5JdwISpMsHnMKKjC2FeB5OAfMcCQ0oINfADP3i9A4PPRo0peHdQ==} + dev: true + + /@vueuse/metadata@10.5.0: + resolution: {integrity: sha512-fEbElR+MaIYyCkeM0SzWkdoMtOpIwO72x8WsZHRE7IggiOlILttqttM69AS13nrDxosnDBYdyy3C5mR1LCxHsw==} /@vueuse/metadata@8.9.4: resolution: {integrity: sha512-IwSfzH80bnJMzqhaapqJl9JRIiyQU0zsRGEgnxN6jhq7992cPUJIRfV+JHRIZXjYqbwt07E1gTEp0R0zPJ1aqw==} @@ -12004,6 +12169,25 @@ packages: transitivePeerDependencies: - '@vue/composition-api' - vue + dev: true + + /@vueuse/shared@10.5.0(vue@3.3.4): + resolution: {integrity: sha512-18iyxbbHYLst9MqU1X1QNdMHIjks6wC7XTVf0KNOv5es/Ms6gjVFCAAWTVP2JStuGqydg3DT+ExpFORUEi9yhg==} + dependencies: + vue-demi: 0.14.6(vue@3.3.4) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + dev: false + + /@vueuse/shared@10.5.0(vue@3.3.7): + resolution: {integrity: sha512-18iyxbbHYLst9MqU1X1QNdMHIjks6wC7XTVf0KNOv5es/Ms6gjVFCAAWTVP2JStuGqydg3DT+ExpFORUEi9yhg==} + dependencies: + vue-demi: 0.14.6(vue@3.3.7) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + dev: true /@vueuse/shared@8.9.4(vue@3.2.39): resolution: {integrity: sha512-wt+T30c4K6dGRMVqPddexEVLa28YwxW5OFIPmzUHICjphfAuBFTTdDoyqREZNDOFJZ44ARH1WWQNCUK8koJ+Ag==} @@ -12613,6 +12797,14 @@ packages: acorn: 7.4.1 dev: true + /acorn-jsx@5.3.2(acorn@8.10.0): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.10.0 + dev: true + /acorn-jsx@5.3.2(acorn@8.9.0): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -12766,23 +12958,23 @@ packages: uri-js: 4.4.1 dev: true - /algoliasearch@4.14.2: - resolution: {integrity: sha512-ngbEQonGEmf8dyEh5f+uOIihv4176dgbuOZspiuhmTTBRBuzWu3KCGHre6uHj5YyuC7pNvQGzB6ZNJyZi0z+Sg==} + /algoliasearch@4.20.0: + resolution: {integrity: sha512-y+UHEjnOItoNy0bYO+WWmLWBlPwDjKHW6mNHrPi0NkuhpQOOEbrkwQH/wgKFDLh7qlKjzoKeiRtlpewDPDG23g==} dependencies: - '@algolia/cache-browser-local-storage': 4.14.2 - '@algolia/cache-common': 4.14.2 - '@algolia/cache-in-memory': 4.14.2 - '@algolia/client-account': 4.14.2 - '@algolia/client-analytics': 4.14.2 - '@algolia/client-common': 4.14.2 - '@algolia/client-personalization': 4.14.2 - '@algolia/client-search': 4.14.2 - '@algolia/logger-common': 4.14.2 - '@algolia/logger-console': 4.14.2 - '@algolia/requester-browser-xhr': 4.14.2 - '@algolia/requester-common': 4.14.2 - '@algolia/requester-node-http': 4.14.2 - '@algolia/transporter': 4.14.2 + '@algolia/cache-browser-local-storage': 4.20.0 + '@algolia/cache-common': 4.20.0 + '@algolia/cache-in-memory': 4.20.0 + '@algolia/client-account': 4.20.0 + '@algolia/client-analytics': 4.20.0 + '@algolia/client-common': 4.20.0 + '@algolia/client-personalization': 4.20.0 + '@algolia/client-search': 4.20.0 + '@algolia/logger-common': 4.20.0 + '@algolia/logger-console': 4.20.0 + '@algolia/requester-browser-xhr': 4.20.0 + '@algolia/requester-common': 4.20.0 + '@algolia/requester-node-http': 4.20.0 + '@algolia/transporter': 4.20.0 dev: true /ansi-align@3.0.1: @@ -13698,10 +13890,6 @@ packages: - supports-color dev: true - /body-scroll-lock@4.0.0-beta.0: - resolution: {integrity: sha512-a7tP5+0Mw3YlUJcGAKUqIBkYYGlYxk2fnCasq/FUph1hadxlTRjF+gAcZksxANnaMnALjxEddmSi/H3OR8ugcQ==} - dev: true - /boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} dev: true @@ -13930,7 +14118,7 @@ packages: '@jsdevtools/ez-spawn': 3.0.4 c12: 1.4.1 cac: 6.7.14 - fast-glob: 3.3.0 + fast-glob: 3.3.1 prompts: 2.4.2 semver: 7.5.2 transitivePeerDependencies: @@ -14740,8 +14928,9 @@ packages: proto-list: 1.2.4 dev: true - /consola@3.1.0: - resolution: {integrity: sha512-rrrJE6rP0qzl/Srg+C9x/AE5Kxfux7reVm1Wh0wCjuXvih6DqZgqDZe8auTD28fzJ9TF0mHlSDrPpWlujQRo1Q==} + /consola@3.2.3: + resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} + engines: {node: ^14.18.0 || >=16.10.0} dev: true /console-browserify@1.2.0: @@ -15660,8 +15849,8 @@ packages: engines: {node: '>=8'} dev: true - /detect-libc@2.0.1: - resolution: {integrity: sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==} + /detect-libc@2.0.2: + resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} engines: {node: '>=8'} dev: true @@ -17017,6 +17206,13 @@ packages: tsx: 3.11.0 dev: true + /esno@0.17.0: + resolution: {integrity: sha512-w78cQGlptQfsBYfootUCitsKS+MD74uR5L6kNsvwVkJsfzEepIafbvWsx2xK4rcFP4IUftt4F6J8EhagUxX+Bg==} + hasBin: true + dependencies: + tsx: 3.14.0 + dev: true + /espree@9.2.0: resolution: {integrity: sha512-oP3utRkynpZWF/F2x/HZJ+AGtnIclaR7z1pYPxy7NYM2fSO6LgK/Rkny8anRSPK/VwEA1eqm2squui0T7ZMOBg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -17030,8 +17226,8 @@ packages: resolution: {integrity: sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - acorn: 8.9.0 - acorn-jsx: 5.3.2(acorn@8.9.0) + acorn: 8.10.0 + acorn-jsx: 5.3.2(acorn@8.10.0) eslint-visitor-keys: 3.4.1 dev: true @@ -17430,6 +17626,17 @@ packages: merge2: 1.4.1 micromatch: 4.0.5 + /fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + dev: true + /fast-json-parse@1.0.3: resolution: {integrity: sha512-FRWsaZRWEJ1ESVNbDWmsAlqDk96gPQezzLghafp5J4GUKjbCz3OkAHuZs5TuPEtkbVQERysLp9xv6c24fBm8Aw==} dev: true @@ -17724,10 +17931,10 @@ packages: readable-stream: 2.3.7 dev: true - /focus-trap@7.4.3: - resolution: {integrity: sha512-BgSSbK4GPnS2VbtZ50VtOv1Sti6DIkj3+LkVjiWMNjLeAp1SH1UlLx3ULu/DCu4vq5R4/uvTm+zrvsMsuYmGLg==} + /focus-trap@7.5.4: + resolution: {integrity: sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==} dependencies: - tabbable: 6.1.2 + tabbable: 6.2.0 dev: true /follow-redirects@1.15.1: @@ -18359,7 +18566,7 @@ packages: '@types/glob': 7.2.0 array-union: 2.1.0 dir-glob: 3.0.1 - fast-glob: 3.3.0 + fast-glob: 3.3.1 glob: 7.2.3 ignore: 5.2.0 merge2: 1.4.1 @@ -18372,7 +18579,7 @@ packages: dependencies: array-union: 2.1.0 dir-glob: 3.0.1 - fast-glob: 3.3.0 + fast-glob: 3.3.1 ignore: 5.2.0 merge2: 1.4.1 slash: 3.0.0 @@ -20467,6 +20674,12 @@ packages: /jiti@1.18.2: resolution: {integrity: sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==} hasBin: true + dev: true + + /jiti@1.20.0: + resolution: {integrity: sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA==} + hasBin: true + dev: true /js-beautify@1.14.9: resolution: {integrity: sha512-coM7xq1syLcMyuVGyToxcj2AlzhkDjmfklL8r0JgJ7A76wyGMpJ1oA35mr4APdYNO/o/4YY8H54NQIJzhMbhBg==} @@ -21859,6 +22072,15 @@ packages: pkg-types: 1.0.3 ufo: 1.1.2 + /mlly@1.4.2: + resolution: {integrity: sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg==} + dependencies: + acorn: 8.10.0 + pathe: 1.1.1 + pkg-types: 1.0.3 + ufo: 1.3.1 + dev: true + /moment@2.29.4: resolution: {integrity: sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==} dev: true @@ -23379,7 +23601,7 @@ packages: engines: {node: '>=10'} hasBin: true dependencies: - detect-libc: 2.0.1 + detect-libc: 2.0.2 expand-template: 2.0.3 github-from-package: 0.0.0 minimist: 1.2.8 @@ -23436,8 +23658,8 @@ packages: engines: {node: '>=6'} dev: true - /pretty-bytes@6.0.0: - resolution: {integrity: sha512-6UqkYefdogmzqAZWzJ7laYeJnaXDy2/J+ZqiiMtS7t7OfpXWTlaeGMwX8U6EFvPV/YWWEKRkS8hKS4k60WHTOg==} + /pretty-bytes@6.1.1: + resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==} engines: {node: ^14.13.1 || >=16.0.0} dev: true @@ -25234,21 +25456,21 @@ packages: dependencies: decode-ico: 0.4.1 ico-endec: 0.1.6 - sharp: 0.32.1 + sharp: 0.32.6 dev: true - /sharp@0.32.1: - resolution: {integrity: sha512-kQTFtj7ldpUqSe8kDxoGLZc1rnMFU0AO2pqbX6pLy3b7Oj8ivJIdoKNwxHVQG2HN6XpHPJqCSM2nsma2gOXvOg==} + /sharp@0.32.6: + resolution: {integrity: sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==} engines: {node: '>=14.15.0'} requiresBuild: true dependencies: color: 4.2.3 - detect-libc: 2.0.1 + detect-libc: 2.0.2 node-addon-api: 6.1.0 prebuild-install: 7.1.1 semver: 7.5.4 simple-get: 4.0.1 - tar-fs: 2.1.1 + tar-fs: 3.0.4 tunnel-agent: 0.6.0 dev: true @@ -25280,8 +25502,8 @@ packages: resolution: {integrity: sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==} dev: true - /shiki@0.14.3: - resolution: {integrity: sha512-U3S/a+b0KS+UkTyMjoNojvTgrBHjgp7L6ovhFVZsXmBGnVdQ4K4U9oK0z63w538S91ATngv1vXigHCSWOwnr+g==} + /shiki@0.14.5: + resolution: {integrity: sha512-1gCAYOcmCFONmErGTrS1fjzJLA7MGZmKzrBNX7apqSwhyITJg2O102uFzXUeBxNnEkDA9vHIKLyeKq0V083vIw==} dependencies: ansi-sequence-parser: 1.1.0 jsonc-parser: 3.2.0 @@ -26111,7 +26333,7 @@ packages: dependencies: '@jridgewell/trace-mapping': 0.3.18 chokidar: 3.5.3 - fast-glob: 3.3.0 + fast-glob: 3.3.1 import-fresh: 3.3.0 picocolors: 1.0.0 sade: 1.8.1 @@ -26273,8 +26495,8 @@ packages: resolution: {integrity: sha512-AsS729u2RHUfEra9xJrE39peJcc2stq2+poBXX8bcM08Y6g9j/i/PUzwNQqkaJde7Ntg1TO7bSREbR5sdosQ+g==} dev: true - /tabbable@6.1.2: - resolution: {integrity: sha512-qCN98uP7i9z0fIS4amQ5zbGBOq+OSigYeGvPy7NDk8Y9yncqDZ9pRPgfsc2PJIVM9RrJj7GIfuRgmjoUU9zTHQ==} + /tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} dev: true /tapable@1.1.3: @@ -26789,6 +27011,17 @@ packages: fsevents: 2.3.3 dev: true + /tsx@3.14.0: + resolution: {integrity: sha512-xHtFaKtHxM9LOklMmJdI3BEnQq/D5F73Of2E1GDrITi9sgoVkvIsrQUTY1G8FlmGtA+awCI4EBlTRRYxkL2sRg==} + hasBin: true + dependencies: + esbuild: 0.18.20 + get-tsconfig: 4.7.2 + source-map-support: 0.5.21 + optionalDependencies: + fsevents: 2.3.3 + dev: true + /tsx@3.9.0: resolution: {integrity: sha512-ofxsE+qjqCYYq4UBt5khglvb+ESgxef1YpuNcdQI92kvcAT2tZVrnSK3g4bRXTUhLmKHcC5q8vIZA47os/stng==} hasBin: true @@ -27007,12 +27240,13 @@ packages: through: 2.3.8 dev: true - /unconfig@0.3.9: - resolution: {integrity: sha512-8yhetFd48M641mxrkWA+C/lZU4N0rCOdlo3dFsyFPnBHBjMJfjT/3eAZBRT2RxCRqeBMAKBVgikejdS6yeBjMw==} + /unconfig@0.3.11: + resolution: {integrity: sha512-bV/nqePAKv71v3HdVUn6UefbsDKQWRX+bJIkiSm0+twIds6WiD2bJLWWT3i214+J/B4edufZpG2w7Y63Vbwxow==} dependencies: - '@antfu/utils': 0.7.5 + '@antfu/utils': 0.7.6 defu: 6.1.2 - jiti: 1.18.2 + jiti: 1.20.0 + mlly: 1.4.2 dev: true /undici-types@5.25.3: @@ -27080,9 +27314,9 @@ packages: /unimport@3.0.14(rollup@3.29.4): resolution: {integrity: sha512-67Rh/sGpEuVqdHWkXaZ6NOq+I7sKt86o+DUtKeGB6dh4Hk1A8AQrzyVGg2+LaVEYotStH7HwvV9YSaRjyT7Uqg==} dependencies: - '@rollup/pluginutils': 5.0.4(rollup@3.29.4) + '@rollup/pluginutils': 5.0.5(rollup@3.29.4) escape-string-regexp: 5.0.0 - fast-glob: 3.3.0 + fast-glob: 3.3.1 local-pkg: 0.4.3 magic-string: 0.30.5 mlly: 1.4.0 @@ -27098,9 +27332,9 @@ packages: /unimport@3.0.7(rollup@3.29.4): resolution: {integrity: sha512-2dVQUxJEGcrSZ0U4qtwJVODrlfyGcwmIOoHVqbAFFUx7kPoEN5JWr1cZFhLwoAwTmZOvqAm3YIkzv1engIQocg==} dependencies: - '@rollup/pluginutils': 5.0.4(rollup@3.29.4) + '@rollup/pluginutils': 5.0.5(rollup@3.29.4) escape-string-regexp: 5.0.0 - fast-glob: 3.3.0 + fast-glob: 3.3.1 local-pkg: 0.4.3 magic-string: 0.30.5 mlly: 1.4.0 @@ -27328,7 +27562,7 @@ packages: dependencies: '@antfu/utils': 0.7.5 '@rollup/pluginutils': 5.0.4(rollup@3.29.4) - fast-glob: 3.3.0 + fast-glob: 3.3.1 local-pkg: 0.4.3 magic-string: 0.30.5 minimatch: 9.0.3 @@ -27338,7 +27572,7 @@ packages: - rollup dev: true - /unplugin-vue-components@0.25.1(rollup@2.79.1)(vue@3.3.4): + /unplugin-vue-components@0.25.1(rollup@3.29.4)(vue@3.3.4): resolution: {integrity: sha512-kzS2ZHVMaGU2XEO2keYQcMjNZkanDSGDdY96uQT9EPe+wqSZwwgbFfKVJ5ti0+8rGAcKHColwKUvctBhq2LJ3A==} engines: {node: '>=14'} peerDependencies: @@ -27352,10 +27586,10 @@ packages: optional: true dependencies: '@antfu/utils': 0.7.5 - '@rollup/pluginutils': 5.0.2(rollup@2.79.1) + '@rollup/pluginutils': 5.0.2(rollup@3.29.4) chokidar: 3.5.3 debug: 4.3.4(supports-color@8.1.1) - fast-glob: 3.3.0 + fast-glob: 3.3.1 local-pkg: 0.4.3 magic-string: 0.30.5 minimatch: 9.0.3 @@ -27367,8 +27601,8 @@ packages: - supports-color dev: true - /unplugin-vue-components@0.25.1(rollup@3.29.4)(vue@3.3.4): - resolution: {integrity: sha512-kzS2ZHVMaGU2XEO2keYQcMjNZkanDSGDdY96uQT9EPe+wqSZwwgbFfKVJ5ti0+8rGAcKHColwKUvctBhq2LJ3A==} + /unplugin-vue-components@0.25.2(rollup@2.79.1)(vue@3.3.4): + resolution: {integrity: sha512-OVmLFqILH6w+eM8fyt/d/eoJT9A6WO51NZLf1vC5c1FZ4rmq2bbGxTy8WP2Jm7xwFdukaIdv819+UI7RClPyCA==} engines: {node: '>=14'} peerDependencies: '@babel/parser': ^7.15.8 @@ -27381,15 +27615,15 @@ packages: optional: true dependencies: '@antfu/utils': 0.7.5 - '@rollup/pluginutils': 5.0.2(rollup@3.29.4) + '@rollup/pluginutils': 5.0.4(rollup@2.79.1) chokidar: 3.5.3 debug: 4.3.4(supports-color@8.1.1) - fast-glob: 3.3.0 + fast-glob: 3.3.1 local-pkg: 0.4.3 magic-string: 0.30.5 minimatch: 9.0.3 - resolve: 1.22.3 - unplugin: 1.3.2 + resolve: 1.22.8 + unplugin: 1.4.0 vue: 3.3.4 transitivePeerDependencies: - rollup @@ -27413,7 +27647,7 @@ packages: '@rollup/pluginutils': 5.0.4(rollup@3.29.4) chokidar: 3.5.3 debug: 4.3.4(supports-color@8.1.1) - fast-glob: 3.3.0 + fast-glob: 3.3.1 local-pkg: 0.4.3 magic-string: 0.30.5 minimatch: 9.0.3 @@ -27714,7 +27948,7 @@ packages: debug: 4.3.4(supports-color@8.1.1) deep-equal: 2.2.1 extract-comments: 1.1.0 - fast-glob: 3.3.0 + fast-glob: 3.3.1 json5: 2.2.3 local-pkg: 0.4.3 picocolors: 1.0.0 @@ -27724,8 +27958,8 @@ packages: - supports-color dev: true - /vite-plugin-pwa@0.16.4(vite@4.5.0)(workbox-build@7.0.0)(workbox-window@7.0.0): - resolution: {integrity: sha512-lmwHFIs9zI2H9bXJld/zVTbCqCQHZ9WrpyDMqosICDV0FVnCJwniX1NMDB79HGTIZzOQkY4gSZaVTJTw6maz/Q==} + /vite-plugin-pwa@0.16.6(vite@4.5.0)(workbox-build@7.0.0)(workbox-window@7.0.0): + resolution: {integrity: sha512-bQPDOWvhPMwydMoWqohXvIzvrq4X8iuCF+q95qEiaM4yC0ybViGKWMnWcpWp0vcnoLk7QvxHDlK65KUZvqB3Sg==} engines: {node: '>=16.0.0'} peerDependencies: vite: ^4.5.0 @@ -27733,8 +27967,8 @@ packages: workbox-window: ^7.0.0 dependencies: debug: 4.3.4(supports-color@8.1.1) - fast-glob: 3.3.0 - pretty-bytes: 6.0.0 + fast-glob: 3.3.1 + pretty-bytes: 6.1.1 vite: 4.5.0(@types/node@18.16.19)(less@4.1.3) workbox-build: 7.0.0 workbox-window: 7.0.0 @@ -27748,7 +27982,7 @@ packages: vite: ^4.5.0 dependencies: debug: 4.3.4(supports-color@8.1.1) - fast-glob: 3.3.0 + fast-glob: 3.3.1 vite: 4.5.0(@types/node@18.16.19)(less@4.1.3) transitivePeerDependencies: - supports-color @@ -27856,23 +28090,32 @@ packages: vite: 4.5.0(@types/node@18.16.19)(less@4.1.3) dev: true - /vitepress@1.0.0-beta.5(@types/node@18.16.19)(search-insights@2.9.0): - resolution: {integrity: sha512-/RjqqRsSEKkzF6HhK5e5Ij+bZ7ETb9jNCRRgIMm10gJ+ZLC3D1OqkE465lEqCeJUgt2HZ6jmWjDqIBfrJSpv7w==} + /vitepress@1.0.0-rc.24(@types/node@18.16.19)(postcss@8.4.31)(search-insights@2.9.0)(typescript@5.1.6): + resolution: {integrity: sha512-RpnL8cnOGwiRlBbrYQUm9sYkJbtyOt/wYXk2diTcokY4yvks/5lq9LuSt+MURWB6ZqwpSNHvTmxgaSfLoG0/OA==} hasBin: true + peerDependencies: + markdown-it-mathjax3: ^4.3.2 + postcss: ^8.4.31 + peerDependenciesMeta: + markdown-it-mathjax3: + optional: true + postcss: + optional: true dependencies: - '@docsearch/css': 3.5.1 - '@docsearch/js': 3.5.1(search-insights@2.9.0) - '@vitejs/plugin-vue': 4.4.0(vite@4.5.0)(vue@3.3.4) - '@vue/devtools-api': 6.5.0 - '@vueuse/core': 10.2.1(vue@3.3.4) - '@vueuse/integrations': 10.2.1(focus-trap@7.4.3)(vue@3.3.4) - body-scroll-lock: 4.0.0-beta.0 - focus-trap: 7.4.3 + '@docsearch/css': 3.5.2 + '@docsearch/js': 3.5.2(search-insights@2.9.0) + '@types/markdown-it': 13.0.5 + '@vitejs/plugin-vue': 4.3.1(vite@4.5.0)(vue@3.3.7) + '@vue/devtools-api': 6.5.1 + '@vueuse/core': 10.5.0(vue@3.3.7) + '@vueuse/integrations': 10.5.0(focus-trap@7.5.4)(vue@3.3.7) + focus-trap: 7.5.4 mark.js: 8.11.1 minisearch: 6.1.0 - shiki: 0.14.3 + postcss: 8.4.31 + shiki: 0.14.5 vite: 4.5.0(@types/node@18.16.19)(less@4.1.3) - vue: 3.3.4 + vue: 3.3.7(typescript@5.1.6) transitivePeerDependencies: - '@algolia/client-search' - '@types/node' @@ -27897,6 +28140,7 @@ packages: - stylus - sugarss - terser + - typescript - universal-cookie dev: true @@ -27969,6 +28213,37 @@ packages: optional: true dependencies: vue: 3.3.4 + dev: true + + /vue-demi@0.14.6(vue@3.3.4): + resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + dependencies: + vue: 3.3.4 + dev: false + + /vue-demi@0.14.6(vue@3.3.7): + resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + dependencies: + vue: 3.3.7(typescript@5.1.6) + dev: true /vue-eslint-parser@9.3.1(eslint@8.44.0): resolution: {integrity: sha512-Clr85iD2XFZ3lJ52/ppmUDG/spxQu6+MAeHXjjyI4I1NUYZ9xmenQp4N0oaHJhrA8OOxltCVxMRfANGa70vU0g==} @@ -28057,6 +28332,22 @@ packages: '@vue/server-renderer': 3.3.4(vue@3.3.4) '@vue/shared': 3.3.4 + /vue@3.3.7(typescript@5.1.6): + resolution: {integrity: sha512-YEMDia1ZTv1TeBbnu6VybatmSteGOS3A3YgfINOfraCbf85wdKHzscD6HSS/vB4GAtI7sa1XPX7HcQaJ1l24zA==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@vue/compiler-dom': 3.3.7 + '@vue/compiler-sfc': 3.3.7 + '@vue/runtime-dom': 3.3.7 + '@vue/server-renderer': 3.3.7(vue@3.3.7) + '@vue/shared': 3.3.7 + typescript: 5.1.6 + dev: true + /w3c-hr-time@1.0.2: resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==} dependencies: